[PATCH 41/43] xfs_scrub: use histograms to speed up phase 8 on the realtime volume

Darrick J. Wong
2024-10-11T01:35:15Z

Use the same statistical methods that we use on the data volume to
compute the minimum threshold size for fstrims on the realtime volume.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
scrub/phase7.c | 7 +++++++
scrub/phase8.c | 6 +++++-
scrub/xfs_scrub.c | 2 ++
scrub/xfs_scrub.h | 1 +
4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/scrub/phase7.c b/scrub/phase7.c
index 475d8f157eecca..01097b67879878 100644
--- a/scrub/phase7.c
+++ b/scrub/phase7.c
@@ -31,6 +31,7 @@ struct summary_counts {

/* Free space histogram, in fsb */
struct histogram datadev_hist;
+ struct histogram rtdev_hist;
};

/*
@@ -56,6 +57,7 @@ summary_count_init(
struct summary_counts *counts = data;

init_freesp_hist(&counts->datadev_hist);
+ init_freesp_hist(&counts->rtdev_hist);
}

/* Record block usage. */
@@ -83,6 +85,8 @@ count_block_summary(
blocks = cvt_b_to_off_fsbt(&ctx->mnt, fsmap->fmr_length);
if (fsmap->fmr_device == ctx->fsinfo.fs_datadev)
hist_add(&counts->datadev_hist, blocks);
+ else if (fsmap->fmr_device == ctx->fsinfo.fs_rtdev)
+ hist_add(&counts->rtdev_hist, blocks);
return 0;
}

@@ -124,7 +128,9 @@ add_summaries(
total->agbytes += item->agbytes;

hist_import(&total->datadev_hist, &item->datadev_hist);
+ hist_import(&total->rtdev_hist, &item->rtdev_hist);
hist_free(&item->datadev_hist);
+ hist_free(&item->rtdev_hist);
return 0;
}

@@ -195,6 +201,7 @@ phase7_func(

/* Preserve free space histograms for phase 8. */
hist_move(&ctx->datadev_hist, &totalcount.datadev_hist);
+ hist_move(&ctx->rtdev_hist, &totalcount.rtdev_hist);

/* Scan the whole fs. */
error = scrub_count_all_inodes(ctx, &counted_inodes);
diff --git a/scrub/phase8.c b/scrub/phase8.c
index adb177ecdafbeb..e8c72d8eb851af 100644
--- a/scrub/phase8.c
+++ b/scrub/phase8.c
@@ -211,13 +211,17 @@ fstrim_rtdev(
struct scrub_ctx *ctx)
{
struct xfs_fsop_geom *geo = &ctx->mnt.fsgeom;
+ uint64_t minlen_fsb;
+
+ minlen_fsb = fstrim_compute_minlen(ctx, &ctx->rtdev_hist);

/*
* The fstrim ioctl pretends that the realtime volume is in the address
* space immediately after the data volume. Ignore EINVAL if someone
* tries to run us on an older kernel.
*/
- return fstrim_fsblocks(ctx, geo->datablocks, geo->rtblocks, 0, true);
+ return fstrim_fsblocks(ctx, geo->datablocks, geo->rtblocks,
+ minlen_fsb, true);
}

/* Trim the filesystem, if desired. */
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
index 3e7d9138f97ec2..90897cc26cd71d 100644
--- a/scrub/xfs_scrub.c
+++ b/scrub/xfs_scrub.c
@@ -728,6 +728,7 @@ main(
int error;

hist_init(&ctx.datadev_hist);
+ hist_init(&ctx.rtdev_hist);

fprintf(stdout, "EXPERIMENTAL xfs_scrub program in use! Use at your own risk!\n");
fflush(stdout);
@@ -960,6 +961,7 @@ main(
unicrash_unload();

hist_free(&ctx.datadev_hist);
+ hist_free(&ctx.rtdev_hist);

/*
* If we're being run as a service, the return code must fit the LSB
diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
index 5d336cb55c7422..6ee359f4cebd47 100644
--- a/scrub/xfs_scrub.h
+++ b/scrub/xfs_scrub.h
@@ -101,6 +101,7 @@ struct scrub_ctx {

/* Free space histograms, in fsb */
struct histogram datadev_hist;
+ struct histogram rtdev_hist;

/*
* Pick the largest value for fstrim minlen such that we trim at least