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 9ab193bc5fe973..4eafb2324909e1 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -923,7 +923,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 88fbda6b83f61a..cd44a9b14f3a1c 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, @@ -505,7 +514,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); @@ -573,7 +582,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 4da788becbef66..aeaf9f1a7f4ba9 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,