From: Darrick J. Wong <djwong@xxxxxxxxxx> Pass a "suspect" counter through scan_lbtree just like we do for short-format btree blocks, and increment its value when we encounter blocks with bad CRCs or outright corruption. This makes it so that repair actually catches bmbt blocks with bad crcs or other verifier errors. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- repair/dinode.c | 2 +- repair/scan.c | 15 ++++++++++++--- repair/scan.h | 3 +++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index 31b3cd74139..a0071d5de88 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -872,7 +872,7 @@ _("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"), if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, type, whichfork, lino, tot, nex, blkmapp, - &cursor, 1, check_dups, magic, + &cursor, 0, 1, check_dups, magic, (void *)zap_metadata, &xfs_bmbt_buf_ops)) return(1); /* diff --git a/repair/scan.c b/repair/scan.c index 1cd4d0ad2e1..2f8a3348ae1 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -136,6 +136,7 @@ scan_lbtree( xfs_extnum_t *nex, blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, + int suspect, int isroot, int check_dups, int *dirty, @@ -148,6 +149,7 @@ scan_lbtree( xfs_extnum_t *nex, blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, + int suspect, int isroot, int check_dups, uint64_t magic, @@ -167,6 +169,12 @@ scan_lbtree( XFS_FSB_TO_AGBNO(mp, root)); return(1); } + if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) { + do_warn(_("btree block %d/%d is suspect, error %d\n"), + XFS_FSB_TO_AGNO(mp, root), + XFS_FSB_TO_AGBNO(mp, root), bp->b_error); + suspect++; + } /* * only check for bad CRC here - caller will determine if there @@ -182,7 +190,7 @@ scan_lbtree( err = (*func)(XFS_BUF_TO_BLOCK(bp), nlevels - 1, type, whichfork, root, ino, tot, nex, blkmapp, - bm_cursor, isroot, check_dups, &dirty, + bm_cursor, suspect, isroot, check_dups, &dirty, magic, priv); ASSERT(dirty == 0 || (dirty && !no_modify)); @@ -209,6 +217,7 @@ scan_bmapbt( xfs_extnum_t *nex, blkmap_t **blkmapp, bmap_cursor_t *bm_cursor, + int suspect, int isroot, int check_dups, int *dirty, @@ -516,7 +525,7 @@ _("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), err = scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, whichfork, ino, tot, nex, blkmapp, - bm_cursor, 0, check_dups, magic, priv, + bm_cursor, suspect, 0, check_dups, magic, priv, &xfs_bmbt_buf_ops); if (err) return(1); @@ -584,7 +593,7 @@ _("bad fwd (right) sibling pointer (saw %" PRIu64 " should be NULLFSBLOCK)\n" be64_to_cpu(pkey[numrecs - 1].br_startoff); } - return(0); + return suspect > 0 ? 1 : 0; } static void diff --git a/repair/scan.h b/repair/scan.h index 4da788becbe..aeaf9f1a7f4 100644 --- a/repair/scan.h +++ b/repair/scan.h @@ -23,6 +23,7 @@ int scan_lbtree( xfs_extnum_t *nex, struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, + int suspect, int isroot, int check_dups, int *dirty, @@ -35,6 +36,7 @@ int scan_lbtree( xfs_extnum_t *nex, struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, + int suspect, int isroot, int check_dups, uint64_t magic, @@ -52,6 +54,7 @@ int scan_bmapbt( xfs_extnum_t *nex, struct blkmap **blkmapp, bmap_cursor_t *bm_cursor, + int suspect, int isroot, int check_dups, int *dirty,