]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: call GETFSMAP for each rt group in parallel
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:24:40 +0000 (16:24 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:35 +0000 (18:01 -0800)
If realtime groups are enabled, we should take advantage of the sharding
to speed up the spacemap scans.  Do so by issuing per-rtgroup GETFSMAP
calls.

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

index 4b7fae252d86ca621ac4357eec61870dd3b1912e..c293ab44a5286c213a8200748a8eb6cc93dd547e 100644 (file)
@@ -127,6 +127,43 @@ scan_ag_rmaps(
        }
 }
 
+/* Iterate all the reverse mappings of a realtime group. */
+static void
+scan_rtg_rmaps(
+       struct workqueue        *wq,
+       xfs_agnumber_t          rgno,
+       void                    *arg)
+{
+       struct scrub_ctx        *ctx = (struct scrub_ctx *)wq->wq_ctx;
+       struct scan_blocks      *sbx = arg;
+       struct fsmap            keys[2] = { };
+       off_t                   bperrg = bytes_per_rtgroup(&ctx->mnt.fsgeom);
+       int                     ret;
+
+       keys[0].fmr_device = ctx->fsinfo.fs_rtdev;
+       keys[0].fmr_physical = (xfs_rtblock_t)rgno * bperrg;
+       keys[1].fmr_device = ctx->fsinfo.fs_rtdev;
+       keys[1].fmr_physical = ((rgno + 1) * bperrg) - 1;
+       keys[1].fmr_owner = ULLONG_MAX;
+       keys[1].fmr_offset = ULLONG_MAX;
+       keys[1].fmr_flags = UINT_MAX;
+
+       if (sbx->aborted)
+               return;
+
+       ret = scrub_iterate_fsmap(ctx, keys, sbx->fn, sbx->arg);
+       if (ret) {
+               char            descr[DESCR_BUFSZ];
+
+               snprintf(descr, DESCR_BUFSZ, _("dev %d:%d rtgroup %u fsmap"),
+                                       major(ctx->fsinfo.fs_datadev),
+                                       minor(ctx->fsinfo.fs_datadev),
+                                       rgno);
+               str_liberror(ctx, ret, descr);
+               sbx->aborted = true;
+       }
+}
+
 /* Iterate all the reverse mappings of a standalone device. */
 static void
 scan_dev_rmaps(
@@ -206,14 +243,6 @@ scrub_scan_all_spacemaps(
                str_liberror(ctx, ret, _("creating fsmap workqueue"));
                return ret;
        }
-       if (ctx->fsinfo.fs_rt) {
-               ret = -workqueue_add(&wq, scan_rt_rmaps, 0, &sbx);
-               if (ret) {
-                       sbx.aborted = true;
-                       str_liberror(ctx, ret, _("queueing rtdev fsmap work"));
-                       goto out;
-               }
-       }
        if (ctx->fsinfo.fs_log) {
                ret = -workqueue_add(&wq, scan_log_rmaps, 0, &sbx);
                if (ret) {
@@ -230,6 +259,31 @@ scrub_scan_all_spacemaps(
                        break;
                }
        }
+       if (ctx->fsinfo.fs_rt) {
+               for (agno = 0; agno < ctx->mnt.fsgeom.rgcount; agno++) {
+                       ret = -workqueue_add(&wq, scan_rtg_rmaps, agno, &sbx);
+                       if (ret) {
+                               sbx.aborted = true;
+                               str_liberror(ctx, ret,
+                                               _("queueing rtgroup fsmap work"));
+                               break;
+                       }
+               }
+
+               /*
+                * If the fs doesn't have any realtime groups, scan the entire
+                * volume all at once, since the above loop did nothing.
+                */
+               if (ctx->mnt.fsgeom.rgcount == 0) {
+                       ret = -workqueue_add(&wq, scan_rt_rmaps, 0, &sbx);
+                       if (ret) {
+                               sbx.aborted = true;
+                               str_liberror(ctx, ret,
+                                               _("queueing rtdev fsmap work"));
+                               goto out;
+                       }
+               }
+       }
 out:
        ret = -workqueue_terminate(&wq);
        if (ret) {