]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libfrog: create a new scrub group for things requiring full inode scans
authorDarrick J. Wong <djwong@kernel.org>
Mon, 22 Apr 2024 17:00:50 +0000 (10:00 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 3 Jun 2024 18:37:35 +0000 (11:37 -0700)
Subsequent patches will add online fsck types (quotacheck, link counts)
that require us to walk every inode in the entire filesystem.  This
requires the AG metadata and the inodes to be in good enough shape to
complete the scan without hitting corruption errors.  As such, they
ought to run after phases 2-4 and before phase 7, which summarizes what
we've found.

Phase 5 seems like a reasonable place to do this, since it already walks
every xattr and directory entry in the filesystem to look for suspicious
looking names.  Add a new XFROG_SCRUB_GROUP, and add it to phase 5.

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

index 70301c0676c4b27939b4f7899b0209d349f80362..a77cd872fede72ac09416b852574350e62174026 100644 (file)
@@ -184,6 +184,7 @@ parse_args(
        case XFROG_SCRUB_GROUP_FS:
        case XFROG_SCRUB_GROUP_NONE:
        case XFROG_SCRUB_GROUP_SUMMARY:
+       case XFROG_SCRUB_GROUP_ISCAN:
                if (!parse_none(argc, optind)) {
                        exitcode = 1;
                        return command_usage(cmdinfo);
index 68f1a968103eb2783860e12666adc84df7897a75..27230c62f71aed3ee7ab3c10fa7e45c492d95b3f 100644 (file)
@@ -13,6 +13,7 @@ enum xfrog_scrub_group {
        XFROG_SCRUB_GROUP_PERAG,        /* per-AG metadata */
        XFROG_SCRUB_GROUP_FS,           /* per-FS metadata */
        XFROG_SCRUB_GROUP_INODE,        /* per-inode metadata */
+       XFROG_SCRUB_GROUP_ISCAN,        /* metadata requiring full inode scan */
        XFROG_SCRUB_GROUP_SUMMARY,      /* summary metadata */
 };
 
index 7e0eaca90422694b49b292cadf977cb59cc5b8b6..0a91e4f0640b3980b39cdc7a7432a20111dde898 100644 (file)
@@ -16,6 +16,8 @@
 #include "list.h"
 #include "libfrog/paths.h"
 #include "libfrog/workqueue.h"
+#include "libfrog/fsgeom.h"
+#include "libfrog/scrub.h"
 #include "xfs_scrub.h"
 #include "common.h"
 #include "inodes.h"
@@ -23,8 +25,9 @@
 #include "scrub.h"
 #include "descr.h"
 #include "unicrash.h"
+#include "repair.h"
 
-/* Phase 5: Check directory connectivity. */
+/* Phase 5: Full inode scans and check directory connectivity. */
 
 /*
  * Warn about problematic bytes in a directory/attribute name.  That means
@@ -386,9 +389,24 @@ int
 phase5_func(
        struct scrub_ctx        *ctx)
 {
+       struct action_list      alist;
        bool                    aborted = false;
        int                     ret;
 
+       /*
+        * Check and fix anything that requires a full inode scan.  We do this
+        * after we've checked all inodes and repaired anything that could get
+        * in the way of a scan.
+        */
+       action_list_init(&alist);
+       ret = scrub_iscan_metadata(ctx, &alist);
+       if (ret)
+               return ret;
+       ret = action_list_process(ctx, ctx->mnt.fd, &alist,
+                       ALP_COMPLAIN_IF_UNFIXED | ALP_NOPROGRESS);
+       if (ret)
+               return ret;
+
        if (ctx->corruptions_found || ctx->unfixable_errors) {
                str_info(ctx, ctx->mntpoint,
 _("Filesystem has errors, skipping connectivity checks."));
@@ -417,7 +435,7 @@ phase5_estimate(
        unsigned int            *nr_threads,
        int                     *rshift)
 {
-       *items = ctx->mnt_sv.f_files - ctx->mnt_sv.f_ffree;
+       *items = scrub_estimate_iscan_work(ctx);
        *nr_threads = scrub_nproc(ctx);
        *rshift = 0;
        return 0;
index 1c53260cc26cd7b1e0fd211bdcca3dff30b6cc25..023cc2c2cd2c79a0932f4996cbfc44b79b7377e6 100644 (file)
@@ -47,6 +47,7 @@ format_scrub_descr(
                break;
        case XFROG_SCRUB_GROUP_FS:
        case XFROG_SCRUB_GROUP_SUMMARY:
+       case XFROG_SCRUB_GROUP_ISCAN:
                return snprintf(buf, buflen, _("%s"), _(sc->descr));
                break;
        case XFROG_SCRUB_GROUP_NONE:
@@ -421,6 +422,15 @@ scrub_summary_metadata(
        return scrub_group(ctx, XFROG_SCRUB_GROUP_SUMMARY, 0, alist);
 }
 
+/* Scrub all metadata requiring a full inode scan. */
+int
+scrub_iscan_metadata(
+       struct scrub_ctx                *ctx,
+       struct action_list              *alist)
+{
+       return scrub_group(ctx, XFROG_SCRUB_GROUP_ISCAN, 0, alist);
+}
+
 /* Scrub /only/ the superblock summary counters. */
 int
 scrub_fs_counters(
@@ -456,6 +466,29 @@ scrub_estimate_ag_work(
        return estimate;
 }
 
+/*
+ * How many kernel calls will we make to scrub everything requiring a full
+ * inode scan?
+ */
+unsigned int
+scrub_estimate_iscan_work(
+       struct scrub_ctx                *ctx)
+{
+       const struct xfrog_scrub_descr  *sc;
+       int                             type;
+       unsigned int                    estimate;
+
+       estimate = ctx->mnt_sv.f_files - ctx->mnt_sv.f_ffree;
+
+       sc = xfrog_scrubbers;
+       for (type = 0; type < XFS_SCRUB_TYPE_NR; type++, sc++) {
+               if (sc->group == XFROG_SCRUB_GROUP_ISCAN)
+                       estimate++;
+       }
+
+       return estimate;
+}
+
 /*
  * Scrub file metadata of some sort.  If errors occur, this function will log
  * them and return nonzero.
index 8a999da6a965235f259d321fd2f8dd82aa7ca5f9..0033fe7ed93145c74ecce8fb5e87942e922769e3 100644 (file)
@@ -24,6 +24,7 @@ int scrub_ag_metadata(struct scrub_ctx *ctx, xfs_agnumber_t agno,
                struct action_list *alist);
 int scrub_fs_metadata(struct scrub_ctx *ctx, unsigned int scrub_type,
                struct action_list *alist);
+int scrub_iscan_metadata(struct scrub_ctx *ctx, struct action_list *alist);
 int scrub_summary_metadata(struct scrub_ctx *ctx, struct action_list *alist);
 int scrub_fs_counters(struct scrub_ctx *ctx, struct action_list *alist);
 
index 7aea79d9555e3bdd2a9993635365e5a5560e0d61..34d850d8db36705c4148a798835f2e42d57b3621 100644 (file)
@@ -99,6 +99,7 @@ int phase7_func(struct scrub_ctx *ctx);
 
 /* Progress estimator functions */
 unsigned int scrub_estimate_ag_work(struct scrub_ctx *ctx);
+unsigned int scrub_estimate_iscan_work(struct scrub_ctx *ctx);
 int phase2_estimate(struct scrub_ctx *ctx, uint64_t *items,
                    unsigned int *nr_threads, int *rshift);
 int phase3_estimate(struct scrub_ctx *ctx, uint64_t *items,