Whamcloud - gitweb
e2fsck: eliminate per-block cluster alignment check
authorTahsin Erdogan <tahsin@google.com>
Sat, 15 Apr 2017 06:24:36 +0000 (23:24 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 27 Apr 2017 15:08:04 +0000 (11:08 -0400)
scan_extent_node() did cluster alignment check for every block in an
extent. This is unnecessary and significantly slows down the runtime
when hugefile is used with bigalloc.

Do cluster alignment check once for each extent.

Google-Bug-Id: 36886699

Signed-off-by: Tahsin Erdogan <tahsin@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/pass5.c
tests/f_badcluster/expect

index 1b6c506..fd12024 100644 (file)
@@ -648,4 +648,7 @@ unsigned long long get_memory_size(void);
 extern void e2fsck_clear_progbar(e2fsck_t ctx);
 extern int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
                                  float percent, unsigned int dpynum);
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
 #endif /* _E2FSCK_H */
index 40ffd8d..422a3d6 100644 (file)
@@ -2155,14 +2155,20 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
        }
 }
 
+/*
+ * When cluster size is greater than one block, it is caller's responsibility
+ * to make sure block parameter starts at a cluster boundary.
+ */
 static _INLINE_ void mark_blocks_used(e2fsck_t ctx, blk64_t block,
                                      unsigned int num)
 {
        if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num))
                ext2fs_mark_block_bitmap_range2(ctx->block_found_map, block, num);
-       else
-               while (num--)
-                       mark_block_used(ctx, block++);
+       else {
+               int i;
+               for (i = 0; i < num; i += EXT2FS_CLUSTER_RATIO(ctx->fs))
+                       mark_block_used(ctx, block + i);
+       }
 }
 
 /*
@@ -2562,8 +2568,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 {
        struct ext2fs_extent    extent;
        blk64_t                 blk, last_lblk;
-       e2_blkcnt_t             blockcnt;
-       unsigned int            i;
+       unsigned int            i, n;
        int                     is_dir, is_leaf;
        problem_t               problem;
        struct ext2_extent_info info;
@@ -2828,50 +2833,29 @@ report_problem:
                        }
                }
 alloc_later:
-               while (is_dir && (++pb->last_db_block <
-                                 (e2_blkcnt_t) extent.e_lblk)) {
-                       pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
-                                                             pb->ino, 0,
-                                                             pb->last_db_block);
-                       if (pctx->errcode) {
-                               pctx->blk = 0;
-                               pctx->num = pb->last_db_block;
-                               goto failed_add_dir_block;
-                       }
-               }
-               if (!ctx->fs->cluster_ratio_bits) {
-                       mark_blocks_used(ctx, extent.e_pblk, extent.e_len);
-                       pb->num_blocks += extent.e_len;
-               }
-               for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
-                    i < extent.e_len;
-                    blk++, blockcnt++, i++) {
-                       if (ctx->fs->cluster_ratio_bits &&
-                           !(pb->previous_block &&
-                             (EXT2FS_B2C(ctx->fs, blk) ==
-                              EXT2FS_B2C(ctx->fs, pb->previous_block)) &&
-                             (blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
-                             ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
-                               mark_block_used(ctx, blk);
-                               pb->num_blocks++;
-                       }
-                       if (has_unaligned_cluster_map(ctx, pb->previous_block,
-                                                     pb->last_block, blk,
-                                                     blockcnt)) {
-                               pctx->blk = blockcnt;
-                               pctx->blk2 = blk;
-                               fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
-                               mark_block_used(ctx, blk);
-                               mark_block_used(ctx, blk);
+               if (is_dir) {
+                       while (++pb->last_db_block <
+                              (e2_blkcnt_t) extent.e_lblk) {
+                               pctx->errcode = ext2fs_add_dir_block2(
+                                                       ctx->fs->dblist,
+                                                       pb->ino, 0,
+                                                       pb->last_db_block);
+                               if (pctx->errcode) {
+                                       pctx->blk = 0;
+                                       pctx->num = pb->last_db_block;
+                                       goto failed_add_dir_block;
+                               }
                        }
-                       pb->last_block = blockcnt;
-                       pb->previous_block = blk;
 
-                       if (is_dir) {
-                               pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
+                       for (i = 0; i < extent.e_len; i++) {
+                               pctx->errcode = ext2fs_add_dir_block2(
+                                                       ctx->fs->dblist,
+                                                       pctx->ino,
+                                                       extent.e_pblk + i,
+                                                       extent.e_lblk + i);
                                if (pctx->errcode) {
-                                       pctx->blk = blk;
-                                       pctx->num = blockcnt;
+                                       pctx->blk = extent.e_pblk + i;
+                                       pctx->num = extent.e_lblk + i;
                                failed_add_dir_block:
                                        fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
                                        /* Should never get here */
@@ -2879,9 +2863,46 @@ alloc_later:
                                        return;
                                }
                        }
+                       if (extent.e_len > 0)
+                               pb->last_db_block = extent.e_lblk + extent.e_len - 1;
+               }
+               if (has_unaligned_cluster_map(ctx, pb->previous_block,
+                                             pb->last_block,
+                                             extent.e_pblk,
+                                             extent.e_lblk)) {
+                       for (i = 0; i < extent.e_len; i++) {
+                               pctx->blk = extent.e_lblk + i;
+                               pctx->blk2 = extent.e_pblk + i;
+                               fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
+                               mark_block_used(ctx, extent.e_pblk + i);
+                               mark_block_used(ctx, extent.e_pblk + i);
+                       }
+               }
+
+               /*
+                * Check whether first cluster got marked in previous iteration.
+                */
+               if (ctx->fs->cluster_ratio_bits &&
+                   pb->previous_block &&
+                   (EXT2FS_B2C(ctx->fs, extent.e_pblk) ==
+                    EXT2FS_B2C(ctx->fs, pb->previous_block)))
+                       /* Set blk to the beginning of next cluster. */
+                       blk = EXT2FS_C2B(
+                               ctx->fs,
+                               EXT2FS_B2C(ctx->fs, extent.e_pblk) + 1);
+               else
+                       /* Set blk to the beginning of current cluster. */
+                       blk = EXT2FS_C2B(ctx->fs,
+                                        EXT2FS_B2C(ctx->fs, extent.e_pblk));
+
+               if (blk < extent.e_pblk + extent.e_len) {
+                       mark_blocks_used(ctx, blk,
+                                        extent.e_pblk + extent.e_len - blk);
+                       n = DIV_ROUND_UP(extent.e_pblk + extent.e_len - blk,
+                                        EXT2FS_CLUSTER_RATIO(ctx->fs));
+                       pb->num_blocks += n;
                }
-               if (is_dir && extent.e_len > 0)
-                       pb->last_db_block = blockcnt - 1;
+               pb->last_block = extent.e_lblk + extent.e_len - 1;
                pb->previous_block = extent.e_pblk + extent.e_len - 1;
                start_block = pb->last_block = last_lblk;
                if (is_leaf && !is_dir &&
index fb55b7e..ab73649 100644 (file)
@@ -21,8 +21,6 @@
 #include "e2fsck.h"
 #include "problem.h"
 
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
 static void check_block_bitmaps(e2fsck_t ctx);
 static void check_inode_bitmaps(e2fsck_t ctx);
 static void check_inode_end(e2fsck_t ctx);
index 75a3820..b44e65d 100644 (file)
@@ -13,8 +13,6 @@ Inode 17 logical block 0 (physical block 1186) violates cluster allocation rules
 Will fix in pass 1B.
 Inode 17 logical block 2 (physical block 1184) violates cluster allocation rules.
 Will fix in pass 1B.
-Inode 17, i_blocks is 32, should be 64.  Fix? yes
-
 Inode 18 logical block 3 (physical block 1201) violates cluster allocation rules.
 Will fix in pass 1B.
 Inode 18, i_blocks is 32, should be 64.  Fix? yes
@@ -86,8 +84,6 @@ Inode 12, i_blocks is 64, should be 32.  Fix? yes
 
 Inode 16, i_blocks is 64, should be 32.  Fix? yes
 
-Inode 17, i_blocks is 64, should be 32.  Fix? yes
-
 Inode 18, i_blocks is 64, should be 32.  Fix? yes
 
 Pass 2: Checking directory structure