]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs_scrub: implement live quotacheck inode scan
authorDarrick J. Wong <djwong@kernel.org>
Mon, 22 Apr 2024 17:01:16 +0000 (10:01 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 3 Jun 2024 18:37:42 +0000 (11:37 -0700)
Teach xfs_scrub to check quota resource usage counters when checking a
filesystem.

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

index 5a5f522a42581681c35f01baec1ba30484d8cbad..53c47bc2b5dc62591319444173d8e40d45a7ede8 100644 (file)
@@ -134,6 +134,11 @@ const struct xfrog_scrub_descr xfrog_scrubbers[XFS_SCRUB_TYPE_NR] = {
                .descr  = "filesystem summary counters",
                .group  = XFROG_SCRUB_GROUP_SUMMARY,
        },
+       [XFS_SCRUB_TYPE_QUOTACHECK] = {
+               .name   = "quotacheck",
+               .descr  = "quota counters",
+               .group  = XFROG_SCRUB_GROUP_ISCAN,
+       },
 };
 
 /* Invoke the scrub ioctl.  Returns zero or negative error code. */
index 5dfc3856b82f34754880611cb7d3d5878a5a4a8d..8807f147aed1e9edcb62c41cbd4842ee0ab91d4b 100644 (file)
@@ -128,6 +128,7 @@ int
 phase4_func(
        struct scrub_ctx        *ctx)
 {
+       struct xfs_fsop_geom    fsgeom;
        int                     ret;
 
        if (!have_action_items(ctx))
@@ -143,6 +144,22 @@ phase4_func(
        if (ret)
                return ret;
 
+       /*
+        * Repair possibly bad quota counts before starting other repairs,
+        * because wildly incorrect quota counts can cause shutdowns.
+        * Quotacheck scans all inodes, so we only want to do it if we know
+        * it's sick.
+        */
+       ret = xfrog_geometry(ctx->mnt.fd, &fsgeom);
+       if (ret)
+               return ret;
+
+       if (fsgeom.sick & XFS_FSOP_GEOM_SICK_QUOTACHECK) {
+               ret = scrub_quotacheck(ctx, &ctx->action_lists[0]);
+               if (ret)
+                       return ret;
+       }
+
        ret = repair_everything(ctx);
        if (ret)
                return ret;
index 65b6dd8953098dbdeab5740e027a7e25c1c30b82..3cb7224f7cc518abf49c0daecc0dd11f8bc75552 100644 (file)
@@ -84,6 +84,9 @@ xfs_action_item_priority(
        case XFS_SCRUB_TYPE_GQUOTA:
        case XFS_SCRUB_TYPE_PQUOTA:
                return PRIO(aitem, XFS_SCRUB_TYPE_UQUOTA);
+       case XFS_SCRUB_TYPE_QUOTACHECK:
+               /* This should always go after [UGP]QUOTA no matter what. */
+               return PRIO(aitem, aitem->type);
        case XFS_SCRUB_TYPE_FSCOUNTERS:
                /* This should always go after AG headers no matter what. */
                return PRIO(aitem, INT_MAX);
index 023cc2c2cd2c79a0932f4996cbfc44b79b7377e6..a22633a8115758c1ebc23eabe85c6fbf549fbb07 100644 (file)
@@ -440,6 +440,15 @@ scrub_fs_counters(
        return scrub_meta_type(ctx, XFS_SCRUB_TYPE_FSCOUNTERS, 0, alist);
 }
 
+/* Scrub /only/ the quota counters. */
+int
+scrub_quotacheck(
+       struct scrub_ctx                *ctx,
+       struct action_list              *alist)
+{
+       return scrub_meta_type(ctx, XFS_SCRUB_TYPE_QUOTACHECK, 0, alist);
+}
+
 /* How many items do we have to check? */
 unsigned int
 scrub_estimate_ag_work(
index 0033fe7ed93145c74ecce8fb5e87942e922769e3..927f86de9ec21f275f5b6168b3295e2294f9317b 100644 (file)
@@ -27,6 +27,7 @@ int scrub_fs_metadata(struct scrub_ctx *ctx, unsigned int scrub_type,
 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);
+int scrub_quotacheck(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);