]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs_scrub: upload clean bills of health
authorDarrick J. Wong <djwong@kernel.org>
Mon, 22 Apr 2024 17:01:17 +0000 (10:01 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 3 Jun 2024 18:37:42 +0000 (11:37 -0700)
If scrub terminates with a clean bill of health, tell the kernel that
the result of the scan is that everything's healthy.

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

index 48ca8313b059ce45c20cda7bc80706dc0c27b8e7..96138e03e71c792626eab8816f17ef9d4891cf51 100644 (file)
@@ -44,6 +44,40 @@ xfs_shutdown_fs(
                str_errno(ctx, ctx->mntpoint);
 }
 
+/*
+ * If we haven't found /any/ problems at all, tell the kernel that we're giving
+ * the filesystem a clean bill of health.
+ */
+static int
+report_to_kernel(
+       struct scrub_ctx        *ctx)
+{
+       struct action_list      alist;
+       int                     ret;
+
+       if (!ctx->scrub_setup_succeeded || ctx->corruptions_found ||
+           ctx->runtime_errors || ctx->unfixable_errors ||
+           ctx->warnings_found)
+               return 0;
+
+       action_list_init(&alist);
+       ret = scrub_clean_health(ctx, &alist);
+       if (ret)
+               return ret;
+
+       /*
+        * Complain if we cannot fail the clean bill of health, unless we're
+        * just testing repairs.
+        */
+       if (action_list_length(&alist) > 0 &&
+           !debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) {
+               str_info(ctx, _("Couldn't upload clean bill of health."), NULL);
+               action_list_discard(&alist);
+       }
+
+       return 0;
+}
+
 /* Clean up the XFS-specific state data. */
 int
 scrub_cleanup(
@@ -51,6 +85,10 @@ scrub_cleanup(
 {
        int                     error;
 
+       error = report_to_kernel(ctx);
+       if (error)
+               return error;
+
        action_lists_free(&ctx->action_lists);
        if (ctx->fshandle)
                free_handle(ctx->fshandle, ctx->fshandle_len);
index 3cb7224f7cc518abf49c0daecc0dd11f8bc75552..9ade805e1b64463f8b03248b500148517455ea77 100644 (file)
@@ -172,6 +172,21 @@ action_lists_alloc(
        return 0;
 }
 
+/* Discard repair list contents. */
+void
+action_list_discard(
+       struct action_list              *alist)
+{
+       struct action_item              *aitem;
+       struct action_item              *n;
+
+       list_for_each_entry_safe(aitem, n, &alist->list, list) {
+               alist->nr--;
+               list_del(&aitem->list);
+               free(aitem);
+       }
+}
+
 /* Free the repair lists. */
 void
 action_lists_free(
index 486617f1ce4a8d840f191f3d2845ba4b4a450ea1..aa3ea13615f2811a02eba0b3a00b862e6ddd382d 100644 (file)
@@ -24,6 +24,7 @@ static inline bool action_list_empty(const struct action_list *alist)
 
 unsigned long long action_list_length(struct action_list *alist);
 void action_list_add(struct action_list *dest, struct action_item *item);
+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,
index cf056779526e1cb0547c45d0428a7460337166db..7cb94af3d15f188ba5dcd934b88284a1cef1c8cb 100644 (file)
@@ -444,6 +444,15 @@ scrub_nlinks(
        return scrub_meta_type(ctx, XFS_SCRUB_TYPE_NLINKS, 0, alist);
 }
 
+/* Update incore health records if we were clean. */
+int
+scrub_clean_health(
+       struct scrub_ctx                *ctx,
+       struct action_list              *alist)
+{
+       return scrub_meta_type(ctx, XFS_SCRUB_TYPE_HEALTHY, 0, alist);
+}
+
 /* How many items do we have to check? */
 unsigned int
 scrub_estimate_ag_work(
index 5e3f40bf1f4171fa4e1870ef390546537b43bcd1..cb33ddb46f35d7c6b633c74bd8ed94fce9a08cf1 100644 (file)
@@ -29,6 +29,7 @@ int scrub_summary_metadata(struct scrub_ctx *ctx, struct action_list *alist);
 int scrub_fs_counters(struct scrub_ctx *ctx, struct action_list *alist);
 int scrub_quotacheck(struct scrub_ctx *ctx, struct action_list *alist);
 int scrub_nlinks(struct scrub_ctx *ctx, struct action_list *alist);
+int scrub_clean_health(struct scrub_ctx *ctx, struct action_list *alist);
 
 bool can_scrub_fs_metadata(struct scrub_ctx *ctx);
 bool can_scrub_inode(struct scrub_ctx *ctx);