[PATCH 7/8] xfs_scrub: warn about difficult repairs to rt and quota metadata

Darrick J. Wong
2023-12-31T22:40:06Z

Warn the user if there are problems with the rt or quota metadata that
might make repairs difficult. For now there aren't any corruption
conditions that would trigger this, but we don't want to leave a gap.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
scrub/phase2.c | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/scrub/phase2.c b/scrub/phase2.c
index 4c0d20a8e2b..3e88c969b43 100644
--- a/scrub/phase2.c
+++ b/scrub/phase2.c
@@ -31,6 +31,25 @@ struct scan_ctl {
bool aborted;
};

+/* Warn about the types of mutual inconsistencies that may make repairs hard. */
+static inline void
+warn_repair_difficulties(
+ struct scrub_ctx *ctx,
+ unsigned int difficulty,
+ const char *descr)
+{
+ if (!(difficulty & REPAIR_DIFFICULTY_SECONDARY))
+ return;
+ if (debug_tweak_on("XFS_SCRUB_FORCE_REPAIR"))
+ return;
+
+ if (difficulty & REPAIR_DIFFICULTY_PRIMARY)
+ str_info(ctx, descr, _("Corrupt primary and secondary metadata."));
+ else
+ str_info(ctx, descr, _("Corrupt secondary metadata."));
+ str_info(ctx, descr, _("Filesystem might not be repairable."));
+}
+
/* Scrub each AG's metadata btrees. */
static void
scan_ag_metadata(
@@ -80,18 +99,7 @@ scan_ag_metadata(
*/
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
- str_info(ctx, descr,
-_("Corrupt secondary block mapping metadata."));
- str_info(ctx, descr,
-_("Filesystem might not be repairable."));
- }
+ warn_repair_difficulties(ctx, difficulty, descr);

/* Repair (inode) btree damage. */
ret = action_list_process_or_defer(ctx, agno, &immediate_alist);
@@ -115,6 +123,7 @@ scan_fs_metadata(
struct action_list alist;
struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
struct scan_ctl *sctl = arg;
+ unsigned int difficulty;
int ret;

if (sctl->aborted)
@@ -127,6 +136,10 @@ scan_fs_metadata(
goto out;
}

+ /* Complain about metadata corruptions that might not be fixable. */
+ difficulty = action_list_difficulty(&alist);
+ warn_repair_difficulties(ctx, difficulty, xfrog_scrubbers[type].descr);
+
action_list_defer(ctx, 0, &alist);