Whamcloud - gitweb
libext2fs: optimize ext2fs_convert_subcluster_bitmap()
authorLi Dongyang <dongyangli@ddn.com>
Mon, 27 Jan 2020 02:52:02 +0000 (21:52 -0500)
committerLi Dongyang <dongyangli@ddn.com>
Wed, 27 May 2020 01:20:24 +0000 (11:20 +1000)
For a bigalloc filesystem, converting the block bitmap from blocks
to chunks in ext2fs_convert_subcluster_bitmap() can take a long time
when the device is huge, because we test the bitmap
bit-by-bit using ext2fs_test_block_bitmap2().
Use ext2fs_find_first_set_block_bitmap2() which is more efficient
for mke2fs when the fs is mostly empty.

e2fsck can also benefit from this during pass1 block scanning.

Time taken for "mke2fs -O bigalloc,extent -C 131072 -b 4096" on a 1PB
device:

without patch:
real    27m49.457s
user    21m36.474s
sys     6m9.514s

with patch:
real    6m31.908s
user    0m1.806s
sys    6m29.697s

Signed-off-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/gen_bitmap64.c

index 6e4d8b7..f1dd189 100644 (file)
@@ -799,8 +799,7 @@ errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
        ext2fs_generic_bitmap_64 bmap, cmap;
        ext2fs_block_bitmap     gen_bmap = *bitmap, gen_cmap;
        errcode_t               retval;
-       blk64_t                 i, b_end, c_end;
-       int                     n, ratio;
+       blk64_t                 i, next, b_end, c_end;
 
        bmap = (ext2fs_generic_bitmap_64) gen_bmap;
        if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(gen_bmap))
@@ -817,18 +816,13 @@ errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
        bmap->end = bmap->real_end;
        c_end = cmap->end;
        cmap->end = cmap->real_end;
-       n = 0;
-       ratio = 1 << fs->cluster_ratio_bits;
        while (i < bmap->real_end) {
-               if (ext2fs_test_block_bitmap2(gen_bmap, i)) {
-                       ext2fs_mark_block_bitmap2(gen_cmap, i);
-                       i += ratio - n;
-                       n = 0;
-                       continue;
-               }
-               i++; n++;
-               if (n >= ratio)
-                       n = 0;
+               retval = ext2fs_find_first_set_block_bitmap2(gen_bmap,
+                                               i, bmap->real_end, &next);
+               if (retval)
+                       break;
+               ext2fs_mark_block_bitmap2(gen_cmap, next);
+               i = EXT2FS_C2B(fs, EXT2FS_B2C(fs, next) + 1);
        }
        bmap->end = b_end;
        cmap->end = c_end;