From 8fe2cd5d365daa6ad185c70c82376bc7635e1427 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 18 Mar 2008 20:20:26 +0000 Subject: [PATCH] HAMMER 32B/many: Reblocking work. * Fix a bug in the record reblocking code. data_offset's representing data embedded in the record itself must be shifted when the record is shifted. --- sys/vfs/hammer/hammer_reblock.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/sys/vfs/hammer/hammer_reblock.c b/sys/vfs/hammer/hammer_reblock.c index b9703ec02b..48b2c35508 100644 --- a/sys/vfs/hammer/hammer_reblock.c +++ b/sys/vfs/hammer/hammer_reblock.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_reblock.c,v 1.1 2008/03/18 05:19:16 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_reblock.c,v 1.2 2008/03/18 20:20:26 dillon Exp $ */ /* * HAMMER reblocker - This code frees up fragmented physical space @@ -241,8 +241,6 @@ hammer_reblock_data(hammer_mount_t hmp, struct hammer_ioc_reblock *reblock, hammer_blockmap_free(hmp, elm->leaf.data_offset, elm->leaf.data_len); - kprintf("REBLOCK DATA %016llx -> %016llx\n", - elm->leaf.data_offset, ndata_offset); cursor->record->base.data_off = ndata_offset; elm->leaf.data_offset = ndata_offset; @@ -263,8 +261,11 @@ hammer_reblock_record(hammer_mount_t hmp, struct hammer_ioc_reblock *reblock, { struct hammer_buffer *rec_buffer = NULL; hammer_off_t nrec_offset; + hammer_off_t ndata_offset; + hammer_record_ondisk_t orec; hammer_record_ondisk_t nrec; int error; + int inline_data; error = hammer_btree_extract(cursor, HAMMER_CURSOR_GET_RECORD); if (error) @@ -276,21 +277,39 @@ hammer_reblock_record(hammer_mount_t hmp, struct hammer_ioc_reblock *reblock, goto done; /* - * Move the record + * Move the record. Check for an inline data reference and move that + * too if necessary. */ - bcopy(cursor->record, nrec, sizeof(*nrec)); + orec = cursor->record; + bcopy(orec, nrec, sizeof(*nrec)); + + if ((orec->base.data_off & HAMMER_OFF_ZONE_MASK) == HAMMER_ZONE_RECORD) { + ndata_offset = orec->base.data_off - elm->leaf.rec_offset; + KKASSERT(ndata_offset < sizeof(*nrec)); + ndata_offset += nrec_offset; + inline_data = 1; + } else { + ndata_offset = 0; + inline_data = 0; + } - hammer_modify_node(cursor->node, - &elm->leaf.rec_offset, sizeof(hammer_off_t)); hammer_modify_record(cursor->record_buffer, - &cursor->record->base.base.rec_type, - sizeof(cursor->record->base.base.rec_type)); + &orec->base.base.rec_type, sizeof(orec->base.base.rec_type)); + orec->base.base.rec_type |= HAMMER_RECTYPE_MOVED; hammer_blockmap_free(hmp, elm->leaf.rec_offset, sizeof(*nrec)); kprintf("REBLOCK RECD %016llx -> %016llx\n", elm->leaf.rec_offset, nrec_offset); + + hammer_modify_node(cursor->node, + &elm->leaf.rec_offset, sizeof(hammer_off_t)); elm->leaf.rec_offset = nrec_offset; + if (inline_data) { + hammer_modify_node(cursor->node, + &elm->leaf.data_offset, sizeof(hammer_off_t)); + elm->leaf.data_offset = ndata_offset; + } done: if (rec_buffer) -- 2.11.4.GIT