/* find delimiting keys of child Determine left and right delimiting keys for child pointed to by @parent_coord. */ static void find_child_delimiting_keys(znode * parent /* parent znode, passed * locked */ , const coord_t *parent_coord /* coord where pointer * to child is stored */ , reiser4_key * ld /* where to store left * delimiting key */ , reiser4_key * rd /* where to store right * delimiting key */ ) { coord_t neighbor; assert("nikita-1484", parent != NULL); assert_rw_locked(&(znode_get_tree(parent)->dk_lock)); coord_dup(&neighbor, parent_coord); if (neighbor.between == AT_UNIT) /* imitate item ->lookup() behavior. */ neighbor.between = AFTER_UNIT; if (coord_set_to_left(&neighbor) == 0) unit_key_by_coord(&neighbor, ld); else { assert("nikita-14851", 0); *ld = *znode_get_ld_key(parent); } coord_dup(&neighbor, parent_coord); if (neighbor.between == AT_UNIT) neighbor.between = AFTER_UNIT; if (coord_set_to_right(&neighbor) == 0) unit_key_by_coord(&neighbor, rd); else *rd = *znode_get_rd_key(parent); }
/* cde_check ->check() method for compressed directory items used for debugging, every item should have here the most complete possible check of the consistency of the item that the inventor can construct */ int reiser4_check_cde(const coord_t * coord /* coord of item to check */, const char **error /* where to store error message */) { int i; int result; char *item_start; char *item_end; reiser4_key key; coord_t c; assert("nikita-1357", coord != NULL); assert("nikita-1358", error != NULL); if (!ergo(coord->item_pos != 0, is_dot_key(item_key_by_coord(coord, &key)))) { *error = "CDE doesn't start with dot"; return -1; } item_start = item_body_by_coord(coord); item_end = item_start + item_length_by_coord(coord); coord_dup(&c, coord); result = 0; for (i = 0; i < units(coord); ++i) { directory_entry_format *entry; if ((char *)(header_at(coord, i) + 1) > item_end - units(coord) * sizeof *entry) { *error = "CDE header is out of bounds"; result = -1; break; } entry = entry_at(coord, i); if ((char *)entry < item_start + sizeof(cde_item_format)) { *error = "CDE header is too low"; result = -1; break; } if ((char *)(entry + 1) > item_end) { *error = "CDE header is too high"; result = -1; break; } } return result; }
/* this returns max key in the item */ reiser4_key *max_item_key_by_coord(const coord_t * coord /* coord to query */ , reiser4_key * key /* result */ ) { coord_t last; assert("nikita-338", coord != NULL); assert("nikita-339", coord->node != NULL); assert("nikita-340", znode_is_loaded(coord->node)); /* make coord pointing to last item's unit */ coord_dup(&last, coord); last.unit_pos = coord_num_units(&last) - 1; assert("vs-1560", coord_is_existing_unit(&last)); max_unit_key_by_coord(&last, key); return key; }
/** * reiser4_replace_extent - replace extent and paste 1 or 2 after it * @un_extent: coordinate of extent to be overwritten * @lh: need better comment * @key: need better comment * @exts_to_add: data prepared for insertion into tree * @replace: need better comment * @flags: need better comment * @return_insert_position: need better comment * * Overwrites one extent, pastes 1 or 2 more ones after overwritten one. If * @return_inserted_position is 1 - @un_extent and @lh are returned set to * first of newly inserted units, if it is 0 - @un_extent and @lh are returned * set to extent which was overwritten. */ int reiser4_replace_extent(struct replace_handle *h, int return_inserted_position) { int result; znode *orig_znode; /*ON_DEBUG(reiser4_extent orig_ext);*/ /* this is for debugging */ assert("vs-990", coord_is_existing_unit(h->coord)); assert("vs-1375", znode_is_write_locked(h->coord->node)); assert("vs-1426", extent_get_width(&h->overwrite) != 0); assert("vs-1427", extent_get_width(&h->new_extents[0]) != 0); assert("vs-1427", ergo(h->nr_new_extents == 2, extent_get_width(&h->new_extents[1]) != 0)); /* compose structure for paste */ init_new_extent(&h->item, &h->new_extents[0], h->nr_new_extents); coord_dup(&h->coord_after, h->coord); init_lh(&h->lh_after); copy_lh(&h->lh_after, h->lh); reiser4_tap_init(&h->watch, &h->coord_after, &h->lh_after, ZNODE_WRITE_LOCK); reiser4_tap_monitor(&h->watch); ON_DEBUG(h->orig_ext = *extent_by_coord(h->coord)); orig_znode = h->coord->node; #if REISER4_DEBUG /* make sure that key is set properly */ unit_key_by_coord(h->coord, &h->tmp); set_key_offset(&h->tmp, get_key_offset(&h->tmp) + extent_get_width(&h->overwrite) * current_blocksize); assert("vs-1080", keyeq(&h->tmp, &h->paste_key)); #endif /* set insert point after unit to be replaced */ h->coord->between = AFTER_UNIT; result = insert_into_item(h->coord, return_inserted_position ? h->lh : NULL, &h->paste_key, &h->item, h->flags); if (!result) { /* now we have to replace the unit after which new units were inserted. Its position is tracked by @watch */ reiser4_extent *ext; znode *node; node = h->coord_after.node; if (node != orig_znode) { coord_clear_iplug(&h->coord_after); result = zload(node); } if (likely(!result)) { ext = extent_by_coord(&h->coord_after); assert("vs-987", znode_is_loaded(node)); assert("vs-988", !memcmp(ext, &h->orig_ext, sizeof(*ext))); /* overwrite extent unit */ memcpy(ext, &h->overwrite, sizeof(reiser4_extent)); znode_make_dirty(node); if (node != orig_znode) zrelse(node); if (return_inserted_position == 0) { /* coord and lh are to be set to overwritten extent */ assert("vs-1662", WITH_DATA(node, !memcmp(&h->overwrite, extent_by_coord( &h->coord_after), sizeof(reiser4_extent)))); *h->coord = h->coord_after; done_lh(h->lh); copy_lh(h->lh, &h->lh_after); } else { /* h->coord and h->lh are to be set to first of inserted units */ assert("vs-1663", WITH_DATA(h->coord->node, !memcmp(&h->new_extents[0], extent_by_coord(h->coord), sizeof(reiser4_extent)))); assert("vs-1664", h->lh->node == h->coord->node); } } } reiser4_tap_done(&h->watch); return result; }