From 042505d78e02ba5179ed11b7b1ae4de14cc0a2f6 Mon Sep 17 00:00:00 2001 From: Tomohiro Kusumi Date: Fri, 17 Jul 2015 00:50:05 +0900 Subject: [PATCH] sbin/hammer: Fix wrong free big-blocks counter - newfs_hammer needs to decrement extra 2 big-blocks from vol0_stat_freebigblocks for zone 8 and 9. - newfs_hammer has following three lines that allocate the root inode, root btree node, and pfs0 metadata for zone 8 and 9, however because alloc_blockmap() doesn't decrement vol0_stat _freebigblocks when a blockmap first meets a new layer2, the volume header shows vol0_stat_freebigblocks 2 more than it actually is. bnode = alloc_btree_element(&btree_off, &data_buffer0); idata = alloc_meta_element(&data_off, sizeof(*idata), &data_buffer1); pfsd = alloc_meta_element(&pfsd_off, sizeof(*pfsd), &data_buffer2); - This also means vol0_stat_bigblocks and vol0_stat_freebigblocks are not equal initially. This commit makes vol0_stat_bigblocks equal (vol0_stat_freebigblocks + 2), while these two were equal until this commit. This should make sense than decrementing vol0_stat_bigblocks by 2 to make these two look the same, because inodes and btree nodes allocated by regular filesystem operations do decrement vol0_stat_freebigblocks whenever a new big-block is allocated and those are counted as used big-blocks. The initial inode, btree node and pfs shouldn't be an exception. The diff of hammer info command right after newfs_hammer would look like this. ========== # diff -aNur ./before ./after --- ./before 2015-07-17 03:17:10.999193000 +0900 +++ ./after 2015-07-17 03:17:14.649193000 +0900 @@ -1,17 +1,17 @@ Big-block information Total 178376 - Used 0 (0.00%) + Used 2 (0.00%) /* inode/btree/pfs0 */ Reserved 45 (0.03%) - Free 178331 (99.97%) + Free 178329 (99.97%) /* 2 less than before */ Space information No. Inodes 1 Total size 1.4T (1496326340608 bytes) - Used 0B (0.00%) + Used 16M (0.00%) /* 2x8[MB] more than before */ Reserved 360M (0.03%) Free 1.4T (99.97%) PFS information ========== --- sbin/hammer/ondisk.c | 1 + sbin/newfs_hammer/newfs_hammer.c | 18 +++++++++++++++++- sys/vfs/hammer/hammer_disk.h | 4 +++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/sbin/hammer/ondisk.c b/sbin/hammer/ondisk.c index 91bf9f28e4..a5dfa9b681 100644 --- a/sbin/hammer/ondisk.c +++ b/sbin/hammer/ondisk.c @@ -907,6 +907,7 @@ again: --layer1->blocks_free; layer1->layer1_crc = crc32(layer1, HAMMER_LAYER1_CRCSIZE); layer2->zone = zone; + --volume->ondisk->vol0_stat_freebigblocks; assert(layer2->bytes_free == HAMMER_BIGBLOCK_SIZE); assert(layer2->append_off == 0); } diff --git a/sbin/newfs_hammer/newfs_hammer.c b/sbin/newfs_hammer/newfs_hammer.c index dd363af362..4489ad2eb4 100644 --- a/sbin/newfs_hammer/newfs_hammer.c +++ b/sbin/newfs_hammer/newfs_hammer.c @@ -258,7 +258,6 @@ main(int ac, char **av) * having to fallback to an extremely inefficient algorithm. */ vol = get_volume(RootVolNo); - vol->ondisk->vol0_stat_bigblocks = vol->ondisk->vol0_stat_freebigblocks; vol->cache.modified = 1; uuid_to_string(&Hammer_FSId, &fsidstr, &status); @@ -576,6 +575,11 @@ format_volume(struct volume_info *vol, int nvols, const char *label, */ ondisk->vol0_next_tid = createtid(); + /* + * Format freemap. vol0_stat_freebigblocks is + * the number of big-blocks available for anything + * other than freemap zone at this point. + */ format_freemap(vol); ondisk->vol0_stat_freebigblocks = initialize_freemap(vol); @@ -585,8 +589,20 @@ format_volume(struct volume_info *vol, int nvols, const char *label, for (i = HAMMER_ZONE2_MAPPED_INDEX; i < HAMMER_MAX_ZONES; ++i) { format_blockmap(&ondisk->vol0_blockmap[i], i, 0); } + + /* + * Format undo zone. Formatting decrements + * vol0_stat_freebigblocks whenever a new big-block + * is allocated for undo zone. + */ format_undomap(vol); + ondisk->vol0_stat_bigblocks = ondisk->vol0_stat_freebigblocks; + /* + * Format the root directory. Formatting decrements + * vol0_stat_freebigblocks whenever a new big-block + * is allocated for required zones. + */ ondisk->vol0_btree_root = format_root(label); ++ondisk->vol0_stat_inodes; /* root inode */ } else { diff --git a/sys/vfs/hammer/hammer_disk.h b/sys/vfs/hammer/hammer_disk.h index 01a0689ffa..3ef6309dfc 100644 --- a/sys/vfs/hammer/hammer_disk.h +++ b/sys/vfs/hammer/hammer_disk.h @@ -610,7 +610,9 @@ struct hammer_volume_ondisk { /* * These fields are initialized and space is reserved in every * volume making up a HAMMER filesytem, but only the master volume - * contains valid data. + * contains valid data. Note that vol0_stat_bigblocks does not + * include big-blocks for freemap and undomap initially allocated + * by newfs_hammer. */ int64_t vol0_stat_bigblocks; /* total big-blocks when fs is empty */ int64_t vol0_stat_freebigblocks;/* number of free big-blocks */ -- 2.41.0