diff mbox series

[42/45] xfs_scrub: fstrim each rtgroup in parallel

Message ID 167243878911.731133.1130139562119311184.stgit@magnolia (mailing list archive)
State New, archived
Headers show
Series libxfs: shard the realtime section | expand

Commit Message

Darrick J. Wong Dec. 30, 2022, 10:19 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libfrog/fsgeom.h |   21 +++++++++++++++++++++
 scrub/phase8.c   |   46 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/libfrog/fsgeom.h b/libfrog/fsgeom.h
index 8c21b240bb2..6c6d6bb815a 100644
--- a/libfrog/fsgeom.h
+++ b/libfrog/fsgeom.h
@@ -203,4 +203,25 @@  cvt_b_to_agbno(
 	return cvt_daddr_to_agbno(xfd, cvt_btobbt(byteno));
 }
 
+/* Convert rtgroup number and rtgroup block to fs block number */
+static inline uint64_t
+cvt_rgbno_to_daddr(
+	struct xfs_fd		*xfd,
+	uint32_t		rgno,
+	uint32_t		rgbno)
+{
+	return cvt_off_fsb_to_bb(xfd,
+			(uint64_t)rgno * xfd->fsgeom.rgblocks + rgbno);
+}
+
+/* Convert rtgroup number and rtgroup block to a byte location on disk. */
+static inline uint64_t
+cvt_rgbno_to_b(
+	struct xfs_fd		*xfd,
+	xfs_rgnumber_t		rgno,
+	xfs_rgblock_t		rgbno)
+{
+	return cvt_bbtob(cvt_rgbno_to_daddr(xfd, rgno, rgbno));
+}
+
 #endif /* __LIBFROG_FSGEOM_H__ */
diff --git a/scrub/phase8.c b/scrub/phase8.c
index a8ea8db706b..cc4901f8614 100644
--- a/scrub/phase8.c
+++ b/scrub/phase8.c
@@ -48,6 +48,7 @@  fstrim_ok(
 
 struct trim_ctl {
 	uint64_t	datadev_end_pos;
+	uint64_t	rtdev_end_pos;
 	bool		aborted;
 };
 
@@ -80,6 +81,35 @@  trim_ag(
 	progress_add(1);
 }
 
+/* Trim each rt group. */
+static void
+trim_rtgroup(
+	struct workqueue	*wq,
+	xfs_agnumber_t		rgno,
+	void			*arg)
+{
+	struct scrub_ctx	*ctx = (struct scrub_ctx *)wq->wq_ctx;
+	struct trim_ctl		*tctl = arg;
+	uint64_t		pos, len, eortg_pos;
+	int			error;
+
+	pos = cvt_rgbno_to_b(&ctx->mnt, rgno, 0);
+	eortg_pos = cvt_rgbno_to_b(&ctx->mnt, rgno, ctx->mnt.fsgeom.rgblocks);
+	len = min(tctl->rtdev_end_pos, eortg_pos) - pos;
+
+	error = fstrim(ctx, pos + tctl->datadev_end_pos, len);
+	if (error) {
+		char		descr[DESCR_BUFSZ];
+
+		snprintf(descr, sizeof(descr) - 1, _("fstrim rgno %u"), rgno);
+		str_liberror(ctx, error, descr);
+		tctl->aborted = true;
+		return;
+	}
+
+	progress_add(1);
+}
+
 /* Trim the filesystem, if desired. */
 int
 phase8_func(
@@ -97,6 +127,8 @@  phase8_func(
 
 	tctl.datadev_end_pos = cvt_off_fsb_to_b(&ctx->mnt,
 			ctx->mnt.fsgeom.datablocks);
+	tctl.rtdev_end_pos = cvt_off_fsb_to_b(&ctx->mnt,
+			ctx->mnt.fsgeom.rtblocks);
 
 	error = -workqueue_create(&wq, (struct xfs_mount *)ctx,
 			disk_heads(ctx->datadev));
@@ -117,6 +149,18 @@  phase8_func(
 		}
 	}
 
+	/* Trim each rtgroup in parallel. */
+	for (agno = 0;
+	     agno < ctx->mnt.fsgeom.rgcount && !tctl.aborted;
+	     agno++) {
+		error = -workqueue_add(&wq, trim_rtgroup, agno, &tctl);
+		if (error) {
+			str_liberror(ctx, error,
+					_("queueing per-rtgroup fstrim work"));
+			goto out_wq;
+		}
+	}
+
 out_wq:
 	err2 = -workqueue_terminate(&wq);
 	if (err2) {
@@ -142,7 +186,7 @@  phase8_estimate(
 	*items = 0;
 
 	if (fstrim_ok(ctx))
-		*items = ctx->mnt.fsgeom.agcount;
+		*items = ctx->mnt.fsgeom.agcount + ctx->mnt.fsgeom.rgcount;
 
 	*nr_threads = disk_heads(ctx->datadev);
 	*rshift = 0;