From cd423df181fba2de46dc632fcebda754a1a4f683 Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Fri, 19 Jul 2024 16:09:16 +1000 Subject: [PATCH] LU-15985 e2fsck: skip block scanning if the inode is too bad 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 Reviewed-on: https://review.whamcloud.com/c/tools/e2fsprogs/+/55802 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Li Xi Reviewed-by: Andreas Dilger --- e2fsck/pass1.c | 20 ++++++++++++ tests/f_ibadness_meta_collision/expect.1 | 51 +++++++++++++++++++++++++++++++ tests/f_ibadness_meta_collision/expect.2 | 7 +++++ tests/f_ibadness_meta_collision/image.gz | Bin 0 -> 21971 bytes tests/f_ibadness_meta_collision/name | 1 + tests/f_ibadness_meta_collision/script | 4 +++ 6 files changed, 83 insertions(+) create mode 100644 tests/f_ibadness_meta_collision/expect.1 create mode 100644 tests/f_ibadness_meta_collision/expect.2 create mode 100644 tests/f_ibadness_meta_collision/image.gz create mode 100644 tests/f_ibadness_meta_collision/name create mode 100644 tests/f_ibadness_meta_collision/script diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 7399fe7..412a756 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -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 index 0000000..6012071 --- /dev/null +++ b/tests/f_ibadness_meta_collision/expect.1 @@ -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 index 0000000..1f4c8aa --- /dev/null +++ b/tests/f_ibadness_meta_collision/expect.2 @@ -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 index 0000000000000000000000000000000000000000..685923a1a9a6841ed64bc3c204df3e66a1597b65 GIT binary patch literal 21971 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 literal 0 HcmV?d00001 diff --git a/tests/f_ibadness_meta_collision/name b/tests/f_ibadness_meta_collision/name new file mode 100644 index 0000000..a3b38c5 --- /dev/null +++ b/tests/f_ibadness_meta_collision/name @@ -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 index 0000000..324a3e4 --- /dev/null +++ b/tests/f_ibadness_meta_collision/script @@ -0,0 +1,4 @@ +FSCK_OPT="-fyd" +SECOND_FSCK_OPT=-yf + +. $cmd_dir/run_e2fsck -- 1.8.3.1