From 90fb808464599617a028e6c01e59b7b576715f32 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 15 Aug 2024 11:57:38 -0700 Subject: [PATCH] xfs_repair: flag suspect long-format btree blocks 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 --- 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 6faa87f1a..8cbd9eafb 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 221d660e8..2e4453478 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 4da788bec..aeaf9f1a7 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, -- 2.50.1