]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs_healer: run a full xfs_scrub repair if we don't know how to do a spot repair
authorDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jun 2026 04:59:06 +0000 (21:59 -0700)
committerAndrey Albershteyn <aalbersh@kernel.org>
Wed, 3 Jun 2026 08:45:24 +0000 (10:45 +0200)
Codex noticed that there are a few sickness event flags that we don't
explicitly handle in fsrepair.c.  These three codes
(XFS_FSOP_GEOM_SICK_METADIR, XFS_FSOP_GEOM_SICK_METAPATH, and
XFS_AG_GEOM_SICK_INODES) can't be handled from within xfs_healer, so we
should trigger a full xfs_scrub run to try to fix those problems.

Cc: linux-xfs@vger.kernel.org # v7.0.0
Fixes: a162dc462186a6 ("xfs_healer: run full scrub after lost corruption events or targeted repair failure")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
healer/fsrepair.c

index 7ad513b2d69b9384b7f4871b21572c044b37381f..7da9e562d68734ad95112af2f1e8b0795243417b 100644 (file)
@@ -88,6 +88,7 @@ try_repair_wholefs(
        };
 #undef X
        const struct u32_scrub  *f;
+       uint32_t                needrepair = hme->e.fs.mask;
 
        foreach_scrub_type(f, hme->e.fs.mask, FS_STRUCTURES) {
                enum repair_outcome     outcome =
@@ -99,7 +100,11 @@ try_repair_wholefs(
 
                if (outcome == REPAIR_FAILED)
                        return NEED_FULL_REPAIR;
+
+               needrepair &= ~f->event_mask;
        }
+       if (needrepair)
+               return NEED_FULL_REPAIR;
 
        return REPAIR_DONE;
 }
@@ -127,7 +132,8 @@ try_repair_ag(
                {0,             0},
        };
 #undef X
-       const struct u32_scrub *f;
+       const struct u32_scrub  *f;
+       uint32_t                needrepair = hme->e.group.mask;
 
        foreach_scrub_type(f, hme->e.group.mask, AG_STRUCTURES) {
                enum repair_outcome     outcome =
@@ -140,7 +146,11 @@ try_repair_ag(
 
                if (outcome == REPAIR_FAILED)
                        return NEED_FULL_REPAIR;
+
+               needrepair &= ~f->event_mask;
        }
+       if (needrepair)
+               return NEED_FULL_REPAIR;
 
        return REPAIR_DONE;
 }
@@ -163,7 +173,8 @@ try_repair_rtgroup(
                {0,             0},
        };
 #undef X
-       const struct u32_scrub *f;
+       const struct u32_scrub  *f;
+       uint32_t                needrepair = hme->e.group.mask;
 
        foreach_scrub_type(f, hme->e.group.mask, RTG_STRUCTURES) {
                enum repair_outcome     outcome =
@@ -176,7 +187,11 @@ try_repair_rtgroup(
 
                if (outcome == REPAIR_FAILED)
                        return NEED_FULL_REPAIR;
+
+               needrepair &= ~f->event_mask;
        }
+       if (needrepair)
+               return NEED_FULL_REPAIR;
 
        return REPAIR_DONE;
 }
@@ -206,6 +221,7 @@ try_repair_inode(
        struct hme_prefix       new_pfx = { };
        const struct hme_prefix *pfx = orig_pfx;
        const struct u32_scrub  *f;
+       uint32_t                needrepair = hme->e.inode.mask;
 
        foreach_scrub_type(f, hme->e.inode.mask, INODE_STRUCTURES) {
                enum repair_outcome     outcome =
@@ -228,7 +244,11 @@ try_repair_inode(
 
                if (outcome == REPAIR_FAILED)
                        return NEED_FULL_REPAIR;
+
+               needrepair &= ~f->event_mask;
        }
+       if (needrepair)
+               return NEED_FULL_REPAIR;
 
        return REPAIR_DONE;
 }