/* * Reblock a record's data. Both the B-Tree element and record pointers * to the data must be adjusted. */ static int hammer_reblock_data(struct hammer_ioc_reblock *reblock, hammer_cursor_t cursor, hammer_btree_elm_t elm) { hammer_buffer_t data_buffer = NULL; hammer_off_t odata_offset; hammer_off_t ndata_offset; int error; void *ndata; error = hammer_btree_extract_data(cursor); if (error) return (error); ndata = hammer_alloc_data(cursor->trans, elm->leaf.data_len, elm->leaf.base.rec_type, &ndata_offset, &data_buffer, 0, &error); if (error) goto done; hammer_io_notmeta(data_buffer); /* * Move the data. Note that we must invalidate any cached * data buffer in the cursor before calling blockmap_free. * The blockmap_free may free up the entire big-block and * will not be able to invalidate it if the cursor is holding * a data buffer cached in that big-block. */ hammer_modify_buffer_noundo(cursor->trans, data_buffer); bcopy(cursor->data, ndata, elm->leaf.data_len); hammer_modify_buffer_done(data_buffer); hammer_cursor_invalidate_cache(cursor); hammer_blockmap_free(cursor->trans, elm->leaf.data_offset, elm->leaf.data_len); hammer_modify_node(cursor->trans, cursor->node, &elm->leaf.data_offset, sizeof(hammer_off_t)); odata_offset = elm->leaf.data_offset; elm->leaf.data_offset = ndata_offset; hammer_modify_node_done(cursor->node); if (hammer_debug_general & 0x4000) { hdkprintf("%08x %016jx -> %016jx\n", (elm ? elm->base.localization : -1), (intmax_t)odata_offset, (intmax_t)ndata_offset); } done: if (data_buffer) hammer_rel_buffer(data_buffer, 0); return (error); }
/* * Reblock a record's data. Both the B-Tree element and record pointers * to the data must be adjusted. */ static int hammer_reblock_data(struct hammer_ioc_reblock *reblock, hammer_cursor_t cursor, hammer_btree_elm_t elm) { struct hammer_buffer *data_buffer = NULL; hammer_off_t ndata_offset; int error; void *ndata; error = hammer_btree_extract(cursor, HAMMER_CURSOR_GET_DATA | HAMMER_CURSOR_GET_LEAF); if (error) return (error); ndata = hammer_alloc_data(cursor->trans, elm->leaf.data_len, elm->leaf.base.rec_type, &ndata_offset, &data_buffer, 0, &error); if (error) goto done; hammer_io_notmeta(data_buffer); /* * Move the data. Note that we must invalidate any cached * data buffer in the cursor before calling blockmap_free. * The blockmap_free may free up the entire large-block and * will not be able to invalidate it if the cursor is holding * a data buffer cached in that large block. */ hammer_modify_buffer(cursor->trans, data_buffer, NULL, 0); bcopy(cursor->data, ndata, elm->leaf.data_len); hammer_modify_buffer_done(data_buffer); hammer_cursor_invalidate_cache(cursor); hammer_blockmap_free(cursor->trans, elm->leaf.data_offset, elm->leaf.data_len); hammer_modify_node(cursor->trans, cursor->node, &elm->leaf.data_offset, sizeof(hammer_off_t)); elm->leaf.data_offset = ndata_offset; hammer_modify_node_done(cursor->node); done: if (data_buffer) hammer_rel_buffer(data_buffer, 0); return (error); }