[PATCH 10/10] xfs: don't ignore runtime errors in xrep_iunlink_reload_next
"Darrick J. Wong" <[email protected]> Sun, 26 Jul 2026 22:26:52 -0700
| Newsgroups | org.kernel.vger.linux-xfs,org.kernel.vger.stable |
|---|---|
| Message-ID | <178512389808.1495075.18295643958709747985.stgit@frogsfrogsfrogs> |
From: Darrick J. Wong <[email protected]> LOLLM complained that this function ignores runtime errors being returned by xrep_iunlink_store_*. Rework the function signature so that we can return runtime errors to abort the repair. Cc: <[email protected]> # v6.10 Fixes: ab97f4b1c03075 ("xfs: repair AGI unlinked inode bucket lists") Signed-off-by: "Darrick J. Wong" <[email protected]> Assisted-by: LOLLM # finding obvious bugs --- fs/xfs/scrub/agheader_repair.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 4f1f235349c5a3..2104512f1ee19a 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -1041,31 +1041,40 @@ xrep_iunlink_next( * the chain or if we should stop walking the chain due to corruption; or a * per-AG inode number. */ -STATIC xfs_agino_t +STATIC int xrep_iunlink_reload_next( struct xrep_agi *ragi, xfs_agino_t prev_agino, - xfs_agino_t agino) + xfs_agino_t agino, + xfs_agino_t *next_agino) { struct xfs_scrub *sc = ragi->sc; struct xfs_inode *ip; - xfs_agino_t ret = NULLAGINO; int error; + *next_agino = NULLAGINO; + error = xchk_iget(ragi->sc, xfs_agino_to_ino(sc->sa.pag, agino), &ip); if (error) - return ret; + return 0; trace_xrep_iunlink_reload_next(ip, prev_agino); /* If this is a linked inode, stop processing the chain. */ if (VFS_I(ip)->i_nlink != 0) { - xrep_iunlink_store_next(ragi, agino, NULLAGINO); + error = xrep_iunlink_store_next(ragi, agino, NULLAGINO); + if (error) + return error; + + error = xrep_iunlink_store_prev(ragi, agino, LINKED_AGINO); + if (error) + return error; + goto rele; } ip->i_prev_unlinked = prev_agino; - ret = ip->i_next_unlinked; + *next_agino = ip->i_next_unlinked; /* * Drop the inode reference that we just took. We hold the AGI, so @@ -1074,7 +1083,7 @@ xrep_iunlink_reload_next( */ rele: xchk_irele(sc, ip); - return ret; + return 0; } /* @@ -1114,9 +1123,12 @@ xrep_iunlink_walk_ondisk_bucket( break; next_agino = xrep_iunlink_next(sc, agino); - if (!next_agino) - next_agino = xrep_iunlink_reload_next(ragi, prev_agino, - agino); + if (!next_agino) { + error = xrep_iunlink_reload_next(ragi, prev_agino, + agino, &next_agino); + if (error) + break; + } error = xagino_bitmap_set(&seen, agino, 1); if (error)