[PATCH 2/8] xfs: make cow repair somewhat flaky when debugging knob enabled

"Darrick J. Wong" <[email protected]>
Newsgroups org.kernel.vger.linux-xfs
Message-ID <178400716411.267810.15891272511669595385.stgit@frogsfrogsfrogs>
From: Darrick J. Wong <[email protected]>

Introduce a new behavior for the cow fork repair code: if the debugging
knob is enabled, we'll pick a random subrange of each cow fork mapping
to mark as bad.  This will exercise the xrep_cow_replace_mapping more
thoroughly.

Signed-off-by: "Darrick J. Wong" <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
---
 fs/xfs/scrub/cow_repair.c |   33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)


diff --git a/fs/xfs/scrub/cow_repair.c b/fs/xfs/scrub/cow_repair.c
index ca3405a26b641c..511a761dca9fe3 100644
--- a/fs/xfs/scrub/cow_repair.c
+++ b/fs/xfs/scrub/cow_repair.c
@@ -224,6 +224,29 @@ xrep_cow_mark_missing_staging_rmap(
 			xfs_gbno_to_fsb(cur->bc_group, rec_bno), rec_len);
 }
 
+/*
+ * Trim the start and end of the current mapping by up to 1/4 of the length
+ * and mark that as "bad" to test the cow fork repair mechanism.
+ */
+static inline int
+xrep_cow_debug_replacement(
+	struct xrep_cow		*xc)
+{
+	xfs_fsblock_t		fsbno = xc->irec.br_startblock;
+	xfs_extlen_t		len = xc->irec.br_blockcount;
+	uint32_t		trim;
+
+	/* get_random_u32_below requires a nonzero argument */
+	trim = len > 4 ? get_random_u32_below(len / 4) : 0;
+	len -= trim;
+
+	trim = len > 4 ? get_random_u32_below(len / 4) : 0;
+	fsbno += trim;
+	len -= trim;
+
+	return xrep_cow_mark_file_range(xc, fsbno, len);
+}
+
 /*
  * Find any part of the CoW fork mapping that isn't a single-owner CoW staging
  * extent and mark the corresponding part of the file range in the bitmap.
@@ -293,8 +316,9 @@ xrep_cow_find_bad(
 	 * If userspace is forcing us to rebuild the CoW fork or someone turned
 	 * on the debugging knob, replace everything in the CoW fork.
 	 */
-	if ((sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) ||
-	    XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR))
+	if (XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR))
+		error = xrep_cow_debug_replacement(xc);
+	else if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD)
 		error = xrep_cow_mark_file_range(xc, xc->irec.br_startblock,
 				xc->irec.br_blockcount);
 
@@ -375,8 +399,9 @@ xrep_cow_find_bad_rt(
 	 * turned on the debugging knob, replace everything in the
 	 * CoW fork and then scan for staging extents in the refcountbt.
 	 */
-	if ((sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) ||
-	    XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR))
+	if (XFS_TEST_ERROR(sc->mp, XFS_ERRTAG_FORCE_SCRUB_REPAIR))
+		error = xrep_cow_debug_replacement(xc);
+	else if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD)
 		error = xrep_cow_mark_file_range(xc, xc->irec.br_startblock,
 				xc->irec.br_blockcount);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.