/* ->max_key_inside() method for this item plugin. */ reiser4_key *max_key_inside_cde(const coord_t * coord /* coord of item */ , reiser4_key * result /* resulting key */ ) { assert("nikita-1342", coord != NULL); item_key_by_coord(coord, result); set_key_ordering(result, get_key_ordering(reiser4_max_key())); set_key_fulloid(result, get_key_fulloid(reiser4_max_key())); set_key_offset(result, get_key_offset(reiser4_max_key())); return result; }
/* main function that handles common parts of tree traversal: starting (fake znode handling), restarts, error handling, completion */ static lookup_result traverse_tree(cbk_handle * h/* search handle */) { int done; int iterations; int vroot_used; assert("nikita-365", h != NULL); assert("nikita-366", h->tree != NULL); assert("nikita-367", h->key != NULL); assert("nikita-368", h->coord != NULL); assert("nikita-369", (h->bias == FIND_EXACT) || (h->bias == FIND_MAX_NOT_MORE_THAN)); assert("nikita-370", h->stop_level >= LEAF_LEVEL); assert("nikita-2949", !(h->flags & CBK_DKSET)); assert("zam-355", lock_stack_isclean(get_current_lock_stack())); done = 0; iterations = 0; vroot_used = 0; /* loop for restarts */ restart: assert("nikita-3024", reiser4_schedulable()); h->result = CBK_COORD_FOUND; /* connect_znode() needs it */ h->ld_key = *reiser4_min_key(); h->rd_key = *reiser4_max_key(); h->flags |= CBK_DKSET; h->error = NULL; if (!vroot_used && h->object != NULL) { vroot_used = 1; done = prepare_object_lookup(h); if (done == LOOKUP_REST) goto restart; else if (done == LOOKUP_DONE) return h->result; } if (h->parent_lh->node == NULL) { done = get_uber_znode(h->tree, ZNODE_READ_LOCK, ZNODE_LOCK_LOPRI, h->parent_lh); assert("nikita-1637", done != -E_DEADLOCK); h->block = h->tree->root_block; h->level = h->tree->height; h->coord->node = h->parent_lh->node; if (done != 0) return done; } /* loop descending a tree */ while (!done) { if (unlikely((iterations > REISER4_CBK_ITERATIONS_LIMIT) && IS_POW(iterations))) { warning("nikita-1481", "Too many iterations: %i", iterations); reiser4_print_key("key", h->key); ++iterations; } else if (unlikely(iterations > REISER4_MAX_CBK_ITERATIONS)) { h->error = "reiser-2018: Too many iterations. Tree corrupted, or (less likely) starvation occurring."; h->result = RETERR(-EIO); break; } switch (cbk_level_lookup(h)) { case LOOKUP_CONT: move_lh(h->parent_lh, h->active_lh); continue; default: wrong_return_value("nikita-372", "cbk_level"); case LOOKUP_DONE: done = 1; break; case LOOKUP_REST: hput(h); /* deadlock avoidance is normal case. */ if (h->result != -E_DEADLOCK) ++iterations; reiser4_preempt_point(); goto restart; } } /* that's all. The rest is error handling */ if (unlikely(h->error != NULL)) { warning("nikita-373", "%s: level: %i, " "lock_level: %i, stop_level: %i " "lock_mode: %s, bias: %s", h->error, h->level, h->lock_level, h->stop_level, lock_mode_name(h->lock_mode), bias_name(h->bias)); reiser4_print_address("block", &h->block); reiser4_print_key("key", h->key); print_coord_content("coord", h->coord); } /* `unlikely' error case */ if (unlikely(IS_CBKERR(h->result))) { /* failure. do cleanup */ hput(h); } else { assert("nikita-1605", WITH_DATA_RET (h->coord->node, 1, ergo((h->result == CBK_COORD_FOUND) && (h->bias == FIND_EXACT) && (!node_is_empty(h->coord->node)), coord_is_existing_item(h->coord)))); } return h->result; }