]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: hoist per-bucket unlinked list check to helper
authorDarrick J. Wong <djwong@kernel.org>
Mon, 27 Jul 2026 05:24:33 +0000 (22:24 -0700)
committerCarlos Maiolino <cem@kernel.org>
Mon, 3 Aug 2026 08:20:42 +0000 (10:20 +0200)
In the next patch we're going to make this loop more exciting, so hoist
the code to a helper function to reduce clutter in the resulting code.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/scrub/agheader.c

index 62ed5eaf08fbc189cdbfeb048b64b3b09437193d..cecf034ef989c7a5623f9d2fad5b030d78d3e0fb 100644 (file)
@@ -932,6 +932,42 @@ xchk_agi_xref(
        /* scrub teardown will take care of sc->sa for us */
 }
 
+/*
+ * Walk the incore unlinked list for a particular AGI bucket to construct
+ * the unlinked inode bitmap for later reconstruction of the unlinked list.
+ * Returns 1 if we should keep checking, or 0 to stop checking.
+ */
+static int
+xchk_iunlink_bucket(
+       struct xfs_scrub                *sc,
+       unsigned int                    bucket,
+       xfs_agino_t                     agino)
+{
+       while (agino != NULLAGINO) {
+               struct xfs_inode        *ip;
+
+               if (agino % XFS_AGI_UNLINKED_BUCKETS != bucket) {
+                       xchk_block_set_corrupt(sc, sc->sa.agi_bp);
+                       return 0;
+               }
+
+               ip = xfs_iunlink_lookup(sc->sa.pag, agino);
+               if (!ip) {
+                       xchk_block_set_corrupt(sc, sc->sa.agi_bp);
+                       return 0;
+               }
+
+               if (!xfs_inode_on_unlinked_list(ip)) {
+                       xchk_block_set_corrupt(sc, sc->sa.agi_bp);
+                       return 0;
+               }
+
+               agino = ip->i_next_unlinked;
+       }
+
+       return 1;
+}
+
 /*
  * Check the unlinked buckets for links to bad inodes.  We hold the AGI, so
  * there cannot be any threads updating unlinked list pointers in this AG.
@@ -942,30 +978,14 @@ xchk_iunlink(
        struct xfs_agi          *agi)
 {
        unsigned int            i;
-       struct xfs_inode        *ip;
 
        for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
-               xfs_agino_t     agino = be32_to_cpu(agi->agi_unlinked[i]);
-
-               while (agino != NULLAGINO) {
-                       if (agino % XFS_AGI_UNLINKED_BUCKETS != i) {
-                               xchk_block_set_corrupt(sc, sc->sa.agi_bp);
-                               return;
-                       }
-
-                       ip = xfs_iunlink_lookup(sc->sa.pag, agino);
-                       if (!ip) {
-                               xchk_block_set_corrupt(sc, sc->sa.agi_bp);
-                               return;
-                       }
-
-                       if (!xfs_inode_on_unlinked_list(ip)) {
-                               xchk_block_set_corrupt(sc, sc->sa.agi_bp);
-                               return;
-                       }
-
-                       agino = ip->i_next_unlinked;
-               }
+               int             ret;
+
+               ret = xchk_iunlink_bucket(sc, i,
+                               be32_to_cpu(agi->agi_unlinked[i]));
+               if (ret < 1)
+                       return;
        }
 }