]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: check dependencies of a scrub type before repairing
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:06 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:07 +0000 (17:01 -0700)
Now that we have a map of a scrub type to its dependent scrub types, use
this information to avoid trying to fix higher level metadata before the
lower levels have passed.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
scrub/repair.c
scrub/scrub.h

index d4521f50c6872908ad7c0b0a73e3c83c108adffd..9b4b5d01626ed253db835902fb77f1a36d33cedf 100644 (file)
@@ -497,6 +497,29 @@ action_list_process(
        return ret;
 }
 
+/* Decide if the dependent scrub types of the given scrub type are ok. */
+static bool
+repair_item_dependencies_ok(
+       const struct scrub_item *sri,
+       unsigned int            scrub_type)
+{
+       unsigned int            dep_mask = repair_deps[scrub_type];
+       unsigned int            b;
+
+       for (b = 0; dep_mask && b < XFS_SCRUB_TYPE_NR; b++, dep_mask >>= 1) {
+               if (!(dep_mask & 1))
+                       continue;
+               /*
+                * If this lower level object also needs repair, we can't fix
+                * the higher level item.
+                */
+               if (sri->sri_state[b] & SCRUB_ITEM_NEEDSREPAIR)
+                       return false;
+       }
+
+       return true;
+}
+
 /*
  * For a given filesystem object, perform all repairs of a given class
  * (corrupt, xcorrupt, xfail, preen) if the repair item says it's needed.
@@ -536,6 +559,15 @@ repair_item_class(
                if (!(sri->sri_state[scrub_type] & repair_mask))
                        continue;
 
+               /*
+                * Don't try to repair higher level items if their lower-level
+                * dependencies haven't been verified, unless this is our last
+                * chance to fix things without complaint.
+                */
+               if (!(flags & XRM_FINAL_WARNING) &&
+                   !repair_item_dependencies_ok(sri, scrub_type))
+                       continue;
+
                fix = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, flags);
                switch (fix) {
                case CHECK_DONE:
index f22a952629e1eed660dc1a0a8115c3745bbbc28a..3ae0bfd29523577ef038d2cc74e8f92c342f0a73 100644 (file)
@@ -43,6 +43,11 @@ enum check_outcome {
 #define SCRUB_ITEM_REPAIR_XREF (SCRUB_ITEM_XFAIL | \
                                 SCRUB_ITEM_XCORRUPT)
 
+/* Mask of bits signalling that a piece of metadata requires attention. */
+#define SCRUB_ITEM_NEEDSREPAIR (SCRUB_ITEM_CORRUPT | \
+                                SCRUB_ITEM_XFAIL | \
+                                SCRUB_ITEM_XCORRUPT)
+
 struct scrub_item {
        /*
         * Information we need to call the scrub and repair ioctls.  Per-AG