git: 7d3f9eb16890 - stable/14 - makefs: Record a larger TXG number in the uberblock

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 28 Oct 2024 16:59:44 UTC
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=7d3f9eb168904b0f201c6bb377818d238060075a

commit 7d3f9eb168904b0f201c6bb377818d238060075a
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-10-14 13:08:09 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-10-28 16:39:50 +0000

    makefs: Record a larger TXG number in the uberblock
    
    By default, OpenZFS will perform metadata verification of the most
    recent TXGs, but this can be very slow since all data in a pool
    generated by makefs was logically written in a single transaction.
    
    Avoid triggering this verification by default, but add an option to
    restore the previous behaviour and enable it in regression test cases.
    
    Reported by:    cperciva
    Tested by:      cperciva (previous version)
    MFC after:      2 weeks
    
    (cherry picked from commit 4e15366c6a6907bcd0e2c28885ba5878ed4280d2)
---
 usr.sbin/makefs/makefs.8                  |  3 +++
 usr.sbin/makefs/tests/makefs_zfs_tests.sh |  2 +-
 usr.sbin/makefs/zfs.c                     | 13 +++++++++++++
 usr.sbin/makefs/zfs/zfs.h                 |  2 ++
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8
index c6aeae961196..0cc2619e6c89 100644
--- a/usr.sbin/makefs/makefs.8
+++ b/usr.sbin/makefs/makefs.8
@@ -536,6 +536,9 @@ By default,
 allocates large (up to 512MB) metaslabs with the expectation that
 the image will be auto-expanded upon first use.
 This option allows the default heuristic to be overridden.
+.It verify-txgs
+Prompt OpenZFS to verify pool metadata during import.
+This is disabled by default as it may significantly increase import times.
 .It poolname
 The name of the ZFS pool.
 This option must be specified.
diff --git a/usr.sbin/makefs/tests/makefs_zfs_tests.sh b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
index 6e20ae33b354..9196232ed3b3 100644
--- a/usr.sbin/makefs/tests/makefs_zfs_tests.sh
+++ b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
@@ -28,7 +28,7 @@
 # SUCH DAMAGE.
 #
 
-MAKEFS="makefs -t zfs -o nowarn=true"
+MAKEFS="makefs -t zfs -o verify-txgs=true -o nowarn=true"
 ZFS_POOL_NAME="makefstest$$"
 TEST_ZFS_POOL_NAME="$TMPDIR/poolname"
 
diff --git a/usr.sbin/makefs/zfs.c b/usr.sbin/makefs/zfs.c
index b16a48564f04..43469c2358be 100644
--- a/usr.sbin/makefs/zfs.c
+++ b/usr.sbin/makefs/zfs.c
@@ -91,6 +91,8 @@ zfs_prep_opts(fsinfo_t *fsopts)
 		  0, 0, "Prefix for all dataset mount points" },
 		{ '\0', "ashift", &zfs->ashift, OPT_INT32,
 		  MINBLOCKSHIFT, MAXBLOCKSHIFT, "ZFS pool ashift" },
+		{ '\0', "verify-txgs", &zfs->verify_txgs, OPT_BOOL,
+		  0, 0, "Make OpenZFS verify data upon import" },
 		{ '\0', "nowarn", &zfs->nowarn, OPT_BOOL,
 		  0, 0, "Suppress warning about experimental ZFS support" },
 		{ .name = NULL }
@@ -594,7 +596,18 @@ pool_labels_write(zfs_opt_t *zfs)
 		ub = (uberblock_t *)(&label->vl_uberblock[0] + uoff);
 		ub->ub_magic = UBERBLOCK_MAGIC;
 		ub->ub_version = SPA_VERSION;
+
+		/*
+		 * Upon import, OpenZFS will perform metadata verification of
+		 * the last TXG by default.  If all data is written in the same
+		 * TXG, it'll all get verified, which can be painfully slow in
+		 * some cases, e.g., initial boot in a cloud environment with
+		 * slow storage.  So, fabricate additional TXGs to avoid this
+		 * overhead, unless the user requests otherwise.
+		 */
 		ub->ub_txg = TXG;
+		if (!zfs->verify_txgs)
+			ub->ub_txg += TXG_SIZE;
 		ub->ub_guid_sum = zfs->poolguid + zfs->vdevguid;
 		ub->ub_timestamp = 0;
 
diff --git a/usr.sbin/makefs/zfs/zfs.h b/usr.sbin/makefs/zfs/zfs.h
index ff94c270bbf6..924fad83f63e 100644
--- a/usr.sbin/makefs/zfs/zfs.h
+++ b/usr.sbin/makefs/zfs/zfs.h
@@ -55,6 +55,7 @@ _Static_assert(MINBLOCKSIZE == SPA_MINBLOCKSIZE, "");
 
 /* All data was written in this transaction group. */
 #define	TXG			4
+#define	TXG_SIZE		4
 
 typedef struct zfs_dsl_dataset zfs_dsl_dataset_t;
 typedef struct zfs_dsl_dir zfs_dsl_dir_t;
@@ -82,6 +83,7 @@ typedef struct {
 	int		ashift;		/* vdev block size */
 	uint64_t	mssize;		/* metaslab size */
 	STAILQ_HEAD(, dataset_desc) datasetdescs; /* non-root dataset descrs  */
+	bool		verify_txgs;	/* verify data upon import */
 
 	/* Pool state. */
 	uint64_t	poolguid;	/* pool and root vdev GUID */