Whamcloud - gitweb
LU-15985 e2fsck: skip block scanning if the inode is too bad 02/55802/4 master-lustre
authorLi Dongyang <dongyangli@ddn.com>
Fri, 19 Jul 2024 06:09:16 +0000 (16:09 +1000)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 1 Aug 2024 14:44:19 +0000 (14:44 +0000)
If the inode is badly corrupted, scanning the extent tree/blocks could
get stuck repeating the error with:
Inode %i block %b conflicts with critical metadata, skipping block checks.

This error PR_1_CRITICAL_METADATA_COLLISION bumps up inode badness by 2
already, we could skip the block/extent scanning if the inode badness is
above the threshold.

Add test case f_ibadness_meta_collision to verify this.

Change-Id: Ifd7246ee8cceb4ea11d2c255310c5af0176bfb1c
Signed-off-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-on: https://review.whamcloud.com/c/tools/e2fsprogs/+/55802
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
e2fsck/pass1.c
tests/f_ibadness_meta_collision/expect.1 [new file with mode: 0644]
tests/f_ibadness_meta_collision/expect.2 [new file with mode: 0644]
tests/f_ibadness_meta_collision/image.gz [new file with mode: 0644]
tests/f_ibadness_meta_collision/name [new file with mode: 0644]
tests/f_ibadness_meta_collision/script [new file with mode: 0644]

index 7399fe7..412a756 100644 (file)
@@ -4745,6 +4745,17 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
        while ((pctx->errcode == 0 ||
                pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID) &&
               info.num_entries-- > 0) {
+               __u16 badness;
+
+               if (ctx->inode_badness &&
+                   !ext2fs_icount_fetch(ctx->inode_badness,
+                                       pb->ino, &badness) &&
+                   badness > ctx->inode_badness_threshold) {
+                       log_out(ctx, "Inode %lu is badly corrupt, skipping block check\n",
+                               pb->ino);
+                       return;
+               }
+
                is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
                is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
                last_lblk = extent.e_lblk + extent.e_len - 1;
@@ -5588,6 +5599,7 @@ static int process_block(ext2_filsys fs,
        int     ret_code = 0;
        problem_t       problem = 0;
        e2fsck_t        ctx;
+       __u16           badness;
 
        p = (struct process_block_struct *) priv_data;
        pctx = p->pctx;
@@ -5611,6 +5623,14 @@ static int process_block(ext2_filsys fs,
        if (blk == 0)
                return 0;
 
+       if (ctx->inode_badness &&
+           !ext2fs_icount_fetch(ctx->inode_badness, p->ino, &badness) &&
+           badness > ctx->inode_badness_threshold) {
+               log_out(ctx, "Inode %lu is badly corrupt, skipping block check\n",
+                       p->ino);
+               return BLOCK_ABORT;
+       }
+
 #if 0
        printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
               blockcnt);
diff --git a/tests/f_ibadness_meta_collision/expect.1 b/tests/f_ibadness_meta_collision/expect.1
new file mode 100644 (file)
index 0000000..6012071
--- /dev/null
@@ -0,0 +1,51 @@
+Pass 1: Checking inodes, blocks, and sizes
+process_block: increase inode 12 badness 0 to 2 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+process_block: increase inode 12 badness 2 to 4 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+process_block: increase inode 12 badness 4 to 6 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+process_block: increase inode 12 badness 6 to 8 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+process_block: increase inode 12 badness 8 to 10 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+process_block: increase inode 12 badness 10 to 12 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+process_block: increase inode 12 badness 12 to 14 for 10071
+Inode 12 block 104 conflicts with critical metadata, skipping block checks.
+Inode 12 is badly corrupt, skipping block check
+check_blocks: increase inode 12 badness 14 to 15 for 1000d
+Inode 12, i_blocks is 2, should be 16.  Fix? yes
+
+Inode 12 is badly corrupt (badness value = 15).  Clear? yes
+
+Restarting e2fsck from the beginning...
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Entry 'testfile' in / (2) has deleted/unused inode 12.  Clear? yes
+
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Block bitmap differences:  -2651
+Fix? yes
+
+Free blocks count wrong for group #0 (5541, counted=5542).
+Fix? yes
+
+Free blocks count wrong (13153, counted=13154).
+Fix? yes
+
+Inode bitmap differences:  -12
+Fix? yes
+
+Free inodes count wrong for group #0 (2036, counted=2037).
+Fix? yes
+
+Free inodes count wrong (4084, counted=4085).
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/4096 files (0.0% non-contiguous), 3230/16384 blocks
+Exit status is 1
diff --git a/tests/f_ibadness_meta_collision/expect.2 b/tests/f_ibadness_meta_collision/expect.2
new file mode 100644 (file)
index 0000000..1f4c8aa
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/4096 files (0.0% non-contiguous), 3230/16384 blocks
+Exit status is 0
diff --git a/tests/f_ibadness_meta_collision/image.gz b/tests/f_ibadness_meta_collision/image.gz
new file mode 100644 (file)
index 0000000..685923a
Binary files /dev/null and b/tests/f_ibadness_meta_collision/image.gz differ
diff --git a/tests/f_ibadness_meta_collision/name b/tests/f_ibadness_meta_collision/name
new file mode 100644 (file)
index 0000000..a3b38c5
--- /dev/null
@@ -0,0 +1 @@
+Bad inode has many blocks colliding with metadata
diff --git a/tests/f_ibadness_meta_collision/script b/tests/f_ibadness_meta_collision/script
new file mode 100644 (file)
index 0000000..324a3e4
--- /dev/null
@@ -0,0 +1,4 @@
+FSCK_OPT="-fyd"
+SECOND_FSCK_OPT=-yf
+
+. $cmd_dir/run_e2fsck