]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: pass runtime errors from xrep_iunlink_mark_ondisk_rec up to callers
authorDarrick J. Wong <djwong@kernel.org>
Mon, 27 Jul 2026 05:25:35 +0000 (22:25 -0700)
committerCarlos Maiolino <cem@kernel.org>
Mon, 3 Aug 2026 08:20:43 +0000 (10:20 +0200)
LOLLM points out that the only error that xrep_iunlink_mark_ondisk_rec
returns is ENOMEM, but we ignore that, and can end up writing a garbage
AGI based on incomplete information.  We shouldn't do that, though here
we must be screen out EFSCORRUPTED/EFSBASDCRC because we haven't
checked the inobt yet.

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 5204eab09c64505d9a43e812ddeeb4f6d683e247..7f19554843038d48ba7574d02bd553bd993c03b8 100644 (file)
@@ -1309,7 +1309,7 @@ xrep_iunlink_mark_ondisk_rec(
  * iunlink_bmp.   We haven't checked the inobt yet, so we don't error out if
  * the btree is corrupt.
  */
-STATIC void
+STATIC int
 xrep_iunlink_mark_ondisk(
        struct xrep_agi         *ragi)
 {
@@ -1321,6 +1321,14 @@ xrep_iunlink_mark_ondisk(
        cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp);
        error = xfs_btree_query_all(cur, xrep_iunlink_mark_ondisk_rec, ragi);
        xfs_btree_del_cursor(cur, error);
+
+       /*
+        * Don't proceed if we couldn't set a bit in the bitmap.  All other
+        * errors we ignore because we haven't actually checked the inobt yet.
+        */
+       if (error == -ENOMEM)
+               return -ENOMEM;
+       return 0;
 }
 
 /*
@@ -1508,7 +1516,9 @@ xrep_iunlink_rebuild_buckets(
         * If there are ondisk inodes that are unlinked and are not been loaded
         * into cache, record them in iunlink_bmp.
         */
-       xrep_iunlink_mark_ondisk(ragi);
+       error = xrep_iunlink_mark_ondisk(ragi);
+       if (error)
+               return error;
 
        /*
         * Walk each iunlink bucket to (re)construct as much of the incore list