]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: split up the mustfix repairs and difficulty assessment functions
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:04 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:07 +0000 (17:01 -0700)
Currently, action_list_find_mustfix does two things -- it figures out
which repairs must be tried during phase 2 to enable the inode scan in
phase 3; and it figures out if xfs_scrub should warn about secondary and
primary metadata corruption that might make repair difficult.

Split these into separate functions to make each more coherent.  A long
time from now we'll need this to enable warnings about difficult rt
repairs, but for now this is merely a code cleanup.

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

index ec72bb5b71adedb9edf64b3fbde96b27010431b1..4c0d20a8e2bc291a4bdfb792d1e678b53388b3ba 100644 (file)
@@ -42,9 +42,8 @@ scan_ag_metadata(
        struct scan_ctl                 *sctl = arg;
        struct action_list              alist;
        struct action_list              immediate_alist;
-       unsigned long long              broken_primaries;
-       unsigned long long              broken_secondaries;
        char                            descr[DESCR_BUFSZ];
+       unsigned int                    difficulty;
        int                             ret;
 
        if (sctl->aborted)
@@ -79,12 +78,12 @@ scan_ag_metadata(
         * the inobt from rmapbt data, but if the rmapbt is broken even
         * at this early phase then we are sunk.
         */
-       broken_secondaries = 0;
-       broken_primaries = 0;
-       action_list_find_mustfix(&alist, &immediate_alist,
-                       &broken_primaries, &broken_secondaries);
-       if (broken_secondaries && !debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) {
-               if (broken_primaries)
+       difficulty = action_list_difficulty(&alist);
+       action_list_find_mustfix(&alist, &immediate_alist);
+
+       if ((difficulty & REPAIR_DIFFICULTY_SECONDARY) &&
+           !debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) {
+               if (difficulty & REPAIR_DIFFICULTY_PRIMARY)
                        str_info(ctx, descr,
 _("Corrupt primary and secondary block mapping metadata."));
                else
index 50f168d24fe732c718af0d2ebb0c484a4e951465..8ee9102ab58d3b249ebf31a952239ee7400aedea 100644 (file)
@@ -290,9 +290,7 @@ xfs_action_item_compare(
 void
 action_list_find_mustfix(
        struct action_list              *alist,
-       struct action_list              *immediate_alist,
-       unsigned long long              *broken_primaries,
-       unsigned long long              *broken_secondaries)
+       struct action_list              *immediate_alist)
 {
        struct action_item              *n;
        struct action_item              *aitem;
@@ -301,25 +299,43 @@ action_list_find_mustfix(
                if (!(aitem->flags & XFS_SCRUB_OFLAG_CORRUPT))
                        continue;
                switch (aitem->type) {
-               case XFS_SCRUB_TYPE_RMAPBT:
-                       (*broken_secondaries)++;
-                       break;
                case XFS_SCRUB_TYPE_FINOBT:
                case XFS_SCRUB_TYPE_INOBT:
                        alist->nr--;
                        list_move_tail(&aitem->list, &immediate_alist->list);
                        immediate_alist->nr++;
-                       fallthrough;
+                       break;
+               }
+       }
+}
+
+/* Determine if primary or secondary metadata are inconsistent. */
+unsigned int
+action_list_difficulty(
+       const struct action_list        *alist)
+{
+       struct action_item              *aitem, *n;
+       unsigned int                    ret = 0;
+
+       list_for_each_entry_safe(aitem, n, &alist->list, list) {
+               if (!(aitem->flags & XFS_SCRUB_OFLAG_CORRUPT))
+                       continue;
+
+               switch (aitem->type) {
+               case XFS_SCRUB_TYPE_RMAPBT:
+                       ret |= REPAIR_DIFFICULTY_SECONDARY;
+                       break;
+               case XFS_SCRUB_TYPE_FINOBT:
+               case XFS_SCRUB_TYPE_INOBT:
                case XFS_SCRUB_TYPE_BNOBT:
                case XFS_SCRUB_TYPE_CNTBT:
                case XFS_SCRUB_TYPE_REFCNTBT:
-                       (*broken_primaries)++;
-                       break;
-               default:
-                       abort();
+                       ret |= REPAIR_DIFFICULTY_PRIMARY;
                        break;
                }
        }
+
+       return ret;
 }
 
 /*
index 6b6f64691a36d52bc5dbbfdfa7ac9431ef62af94..b61bd29c860d96b014d6345613241c8fd0cb0292 100644 (file)
@@ -28,9 +28,13 @@ void action_list_discard(struct action_list *alist);
 void action_list_splice(struct action_list *dest, struct action_list *src);
 
 void action_list_find_mustfix(struct action_list *actions,
-               struct action_list *immediate_alist,
-               unsigned long long *broken_primaries,
-               unsigned long long *broken_secondaries);
+               struct action_list *immediate_alist);
+
+/* Primary metadata is corrupt */
+#define REPAIR_DIFFICULTY_PRIMARY      (1U << 0)
+/* Secondary metadata is corrupt */
+#define REPAIR_DIFFICULTY_SECONDARY    (1U << 1)
+unsigned int action_list_difficulty(const struct action_list *actions);
 
 /*
  * Only ask the kernel to repair this object if the kernel directly told us it