aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/cddl/boot/zfs/zfsimpl.h10
-rw-r--r--usr.sbin/makefs/makefs.811
-rw-r--r--usr.sbin/makefs/tests/makefs_zfs_tests.sh59
-rw-r--r--usr.sbin/makefs/zfs.c17
-rw-r--r--usr.sbin/makefs/zfs/zfs.h2
5 files changed, 98 insertions, 1 deletions
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index d3ae3c32635d..b14a829025d1 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -905,6 +905,16 @@ typedef enum pool_state {
} pool_state_t;
/*
+ * Send TRIM commands in-line during normal pool operation while deleting.
+ * OFF: no
+ * ON: yes
+ */
+typedef enum {
+ SPA_AUTOTRIM_OFF = 0,
+ SPA_AUTOTRIM_ON,
+} spa_autotrim_t;
+
+/*
* The uberblock version is incremented whenever an incompatible on-disk
* format change is made to the SPA, DMU, or ZAP.
*
diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8
index 56e2ffda956f..2ce33cbc8d7f 100644
--- a/usr.sbin/makefs/makefs.8
+++ b/usr.sbin/makefs/makefs.8
@@ -33,7 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd August 12, 2026
+.Dd October 7, 2026
.Dt MAKEFS 8
.Os
.Sh NAME
@@ -536,6 +536,15 @@ The following keywords are supported:
The base-2 logarithm of the minimum block size.
Typical values are 9 (512B blocks) and 12 (4KB blocks).
The default value is 12.
+.It Cm autotrim
+The value of the
+.Ql autotrim
+pool property, either
+.Ql on
+or
+.Ql off .
+The default is
+.Ql off .
.It Cm bootfs
The name of the bootable dataset for the pool.
Specifying this option causes the
diff --git a/usr.sbin/makefs/tests/makefs_zfs_tests.sh b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
index 940461fe2565..b8595a98a2ab 100644
--- a/usr.sbin/makefs/tests/makefs_zfs_tests.sh
+++ b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
@@ -108,6 +108,64 @@ autoexpand_cleanup()
}
#
+# Test setting the autotrim pool property.
+#
+atf_test_case autotrim cleanup
+autotrim_body()
+{
+ local src val
+
+ create_test_inputs
+
+ atf_check -s exit:1 -e match:"invalid value .foo. for autotrim" \
+ $MAKEFS -s 1g -o rootpath=/ -o poolname=$ZFS_POOL_NAME \
+ -o autotrim=foo $TEST_IMAGE $TEST_INPUTS_DIR
+
+ for val in on off; do
+ atf_check $MAKEFS -s 1g -o rootpath=/ \
+ -o poolname=$ZFS_POOL_NAME \
+ -o autotrim=$val \
+ $TEST_IMAGE $TEST_INPUTS_DIR
+
+ import_image
+
+ check_image_contents
+
+ # OpenZFS reports a pool property whose value equals the
+ # default as coming from the default, even if it was set.
+ if [ $val = off ]; then
+ src=default
+ else
+ src=local
+ fi
+ atf_check -o inline:$val\\n \
+ zpool get -H -o value autotrim $ZFS_POOL_NAME
+ atf_check -o inline:$src\\n \
+ zpool get -H -o source autotrim $ZFS_POOL_NAME
+
+ atf_check zpool destroy ${ZFS_POOL_NAME}
+ atf_check rm -f ${TEST_ZFS_POOL_NAME}
+ atf_check mdconfig -d -u $(cat ${TEST_MD_DEVICE_FILE})
+ atf_check rm -f ${TEST_MD_DEVICE_FILE}
+ done
+
+ # Without the option the property keeps its default value.
+ atf_check $MAKEFS -s 1g -o rootpath=/ -o poolname=$ZFS_POOL_NAME \
+ $TEST_IMAGE $TEST_INPUTS_DIR
+
+ import_image
+
+ atf_check -o inline:off\\n \
+ zpool get -H -o value autotrim $ZFS_POOL_NAME
+ atf_check -o inline:default\\n \
+ zpool get -H -o source autotrim $ZFS_POOL_NAME
+}
+autotrim_cleanup()
+{
+ common_cleanup
+}
+
+#
# Test with some default layout defined by the common code.
#
atf_test_case basic cleanup
@@ -1163,6 +1221,7 @@ T_flag_mtree_cleanup()
atf_init_test_cases()
{
atf_add_test_case autoexpand
+ atf_add_test_case autotrim
atf_add_test_case basic
atf_add_test_case compression
atf_add_test_case dataset_link_counts
diff --git a/usr.sbin/makefs/zfs.c b/usr.sbin/makefs/zfs.c
index 1288c52141ab..9e304202fb4f 100644
--- a/usr.sbin/makefs/zfs.c
+++ b/usr.sbin/makefs/zfs.c
@@ -82,6 +82,8 @@ zfs_prep_opts(fsinfo_t *fsopts)
memset(zfs, 0, sizeof(*zfs));
const option_t zfs_options[] = {
+ { '\0', "autotrim", &zfs->autotrim, OPT_STRPTR,
+ 0, 0, "Automatic TRIM (on or off)" },
{ '\0', "bootfs", &zfs->bootfs, OPT_STRPTR,
0, 0, "Bootable dataset" },
{ '\0', "mssize", &zfs->mssize, OPT_INT64,
@@ -247,6 +249,17 @@ zfs_check_opts(fsinfo_t *fsopts)
if (zfs->vdevpath[0] != '/')
errx(1, "path `%s' must be absolute", zfs->vdevpath);
+ zfs->autotrimval = SPA_AUTOTRIM_OFF;
+ if (zfs->autotrim != NULL) {
+ if (strcmp(zfs->autotrim, "on") == 0)
+ zfs->autotrimval = SPA_AUTOTRIM_ON;
+ else if (strcmp(zfs->autotrim, "off") == 0)
+ zfs->autotrimval = SPA_AUTOTRIM_OFF;
+ else
+ errx(1, "invalid value `%s' for autotrim",
+ zfs->autotrim);
+ }
+
if (zfs->ashift == 0)
zfs->ashift = 12;
@@ -262,6 +275,7 @@ zfs_cleanup_opts(fsinfo_t *fsopts)
zfs = fsopts->fs_specific;
free(zfs->rootpath);
free(zfs->vdevpath);
+ free(zfs->autotrim);
free(zfs->bootfs);
free(__DECONST(void *, zfs->poolname));
STAILQ_FOREACH_SAFE(d, &zfs->datasetdescs, next, tmp) {
@@ -474,6 +488,9 @@ pool_init_objdir_poolprops(zfs_opt_t *zfs, zfs_zap_t *objdir)
zap_add_uint64(objdir, DMU_POOL_PROPS, id);
zfs->poolprops = zap_alloc(zfs->mos, dnode);
+
+ if (zfs->autotrim != NULL)
+ zap_add_uint64(zfs->poolprops, "autotrim", zfs->autotrimval);
}
/*
diff --git a/usr.sbin/makefs/zfs/zfs.h b/usr.sbin/makefs/zfs/zfs.h
index 13f2ece43c69..ebc54caad8e9 100644
--- a/usr.sbin/makefs/zfs/zfs.h
+++ b/usr.sbin/makefs/zfs/zfs.h
@@ -80,6 +80,8 @@ typedef struct {
const char *poolname;
char *rootpath; /* implicit mount point prefix */
char *vdevpath; /* vdev path, pool property */
+ char *autotrim; /* "on" or "off", pool property */
+ spa_autotrim_t autotrimval; /* parsed autotrim value */
char *bootfs; /* bootable dataset, pool property */
int ashift; /* vdev block size */
uint64_t mssize; /* metaslab size */