]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: try implied cluster allocation when expanding a dir
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 16 Dec 2013 04:54:07 +0000 (23:54 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 16 Dec 2013 04:54:09 +0000 (23:54 -0500)
When we're expanding a directory, check to see if we're doing an
implied cluster allocation; if so, we don't need to allocate a new
block, and we certainly don't need to update the summary counts.

Reported-by: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
e2fsck/pass3.c

index d7a243e4b7692ef07f7a1f2e5c2398f7dd674757..d87bd79f5fbdbbf4282461f6dd6a6a403e5a7604 100644 (file)
@@ -713,12 +713,23 @@ static int expand_dir_proc(ext2_filsys fs,
                last_blk = *blocknr;
                return 0;
        }
-       retval = ext2fs_new_block2(fs, last_blk, ctx->block_found_map,
-                                 &new_blk);
-       if (retval) {
-               es->err = retval;
-               return BLOCK_ABORT;
+
+       if (blockcnt &&
+           (EXT2FS_B2C(fs, last_blk) == EXT2FS_B2C(fs, last_blk + 1)))
+               new_blk = last_blk + 1;
+       else {
+               last_blk &= ~EXT2FS_CLUSTER_MASK(fs);
+               retval = ext2fs_new_block2(fs, last_blk, ctx->block_found_map,
+                                         &new_blk);
+               if (retval) {
+                       es->err = retval;
+                       return BLOCK_ABORT;
+               }
+               es->newblocks++;
+               ext2fs_block_alloc_stats2(fs, new_blk, +1);
        }
+       last_blk = new_blk;
+
        if (blockcnt > 0) {
                retval = ext2fs_new_dir_block(fs, 0, 0, &block);
                if (retval) {
@@ -743,8 +754,6 @@ static int expand_dir_proc(ext2_filsys fs,
        ext2fs_free_mem(&block);
        *blocknr = new_blk;
        ext2fs_mark_block_bitmap2(ctx->block_found_map, new_blk);
-       ext2fs_block_alloc_stats2(fs, new_blk, +1);
-       es->newblocks++;
 
        if (es->num == 0)
                return (BLOCK_CHANGED | BLOCK_ABORT);