Blame SOURCES/bz1487726-7-fsck_gfs2_Clear_bad_indirect_block_pointers_when_bitmap_meets_expectations.patch

9257a6
commit 4707be4ee1e214cc420679650e1897b3b0817638
9257a6
Author: Andrew Price <anprice@redhat.com>
9257a6
Date:   Fri Oct 18 19:43:48 2019 +0100
9257a6
9257a6
    fsck.gfs2: Clear bad indirect block pointers when bitmap meets expectations
9257a6
    
9257a6
    This issue only occurs when an indirect pointer of a 'system' directory
9257a6
    points to an invalid block but the block's bitmap state is as expected.
9257a6
    If the block's state is not as expected, the corruption is fixed by an
9257a6
    earlier check.
9257a6
    
9257a6
    In this scenario, pass1_check_metalist() checks the type of a block and
9257a6
    compares it with what it expected the indirect pointer to point to. If
9257a6
    there is a metadata mismatch a bad indirect pointer is reported but the
9257a6
    entire inode is considered invalid, causing it to be removed later, or
9257a6
    rebuilt in the case of protected structures such as the root inode.
9257a6
    This is heavy-handed and the right thing to do is to zero the indirect
9257a6
    block pointer.
9257a6
    
9257a6
    Previously we had no access to the pointer block itself to update it in
9257a6
    pass1_check_metalist() but now that an iptr is passed in, it's just a
9257a6
    case of zeroing the pointer at the correct offset and marking the bh as
9257a6
    modified. This means that fsck.gfs2 can now fix bad indirect pointers of
9257a6
    the root directory without throwing away the entire directory tree.
9257a6
    
9257a6
    Resolves: rhbz#1487726
9257a6
    
9257a6
    Signed-off-by: Andrew Price <anprice@redhat.com>
9257a6
9257a6
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
9257a6
index 66cf6dc6..deef1425 100644
9257a6
--- a/gfs2/fsck/pass1.c
9257a6
+++ b/gfs2/fsck/pass1.c
9257a6
@@ -401,8 +401,15 @@ static int pass1_check_metalist(struct iptr iptr, struct gfs2_buffer_head **bh,
9257a6
 			 (unsigned long long)ip->i_di.di_num.no_addr,
9257a6
 			 (unsigned long long)block,
9257a6
 			 (unsigned long long)block, blktypedesc);
9257a6
-		brelse(nbh);
9257a6
-		return meta_skip_further;
9257a6
+		if (query(_("Zero the indirect block pointer? (y/n) "))){
9257a6
+			*iptr_ptr(iptr) = 0;
9257a6
+			bmodified(iptr.ipt_bh);
9257a6
+			*is_valid = 1;
9257a6
+			return meta_skip_one;
9257a6
+		} else {
9257a6
+			brelse(nbh);
9257a6
+			return meta_skip_further;
9257a6
+		}
9257a6
 	}
9257a6
 
9257a6
 	bc->indir_count++;