From a68eb7c7fde165d06e78d2ebd2bdf960b16ffd73 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 20 Nov 2024 16:24:40 -0800 Subject: [PATCH] xfs_scrub: call GETFSMAP for each rt group in parallel 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" Reviewed-by: Christoph Hellwig --- scrub/spacemap.c | 70 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/scrub/spacemap.c b/scrub/spacemap.c index 4b7fae25..c293ab44 100644 --- a/scrub/spacemap.c +++ b/scrub/spacemap.c @@ -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) { -- 2.47.3