]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: don't ignore runtime errors in xrep_iunlink_reload_next
authorDarrick J. Wong <djwong@kernel.org>
Mon, 27 Jul 2026 05:26:52 +0000 (22:26 -0700)
committerCarlos Maiolino <cem@kernel.org>
Mon, 3 Aug 2026 08:20:43 +0000 (10:20 +0200)
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: stable@vger.kernel.org # v6.10
Fixes: ab97f4b1c03075 ("xfs: repair AGI unlinked inode bucket lists")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/scrub/agheader_repair.c

index 4f1f235349c5a311c26e1618dcef730c19e5e858..2104512f1ee19ad900921461e57cdb84dcd5848b 100644 (file)
@@ -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)