From: Darrick J. Wong Date: Thu, 21 Nov 2024 00:24:40 +0000 (-0800) Subject: xfs_scrub: call GETFSMAP for each rt group in parallel X-Git-Tag: v6.13.0~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a68eb7c7fde165d06e78d2ebd2bdf960b16ffd73;p=thirdparty%2Fxfsprogs-dev.git 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 --- 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) {