aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2025-09-24 20:54:28 +0000
committerMartin Matuska <mm@FreeBSD.org>2025-09-24 20:54:28 +0000
commit113e60742ef6ba5c069aa737ee57ba3c2f88b248 (patch)
treef42f6a51949e846c92f29a43ce0880a980968ae9
parent275f61111f43507a01eef064efc660f1fa72b6a9 (diff)
parentb2196fbedf5dbfb8593288f5f9ba712e31429a84 (diff)
zfs: merge openzfs/zfs@b2196fbed
Notable upstream pull request merges: #17705 545d66204 Fix a printf format specifier on FreeBSD/i386 #17708 3387d3409 Fix atomic-alignment warnings in libspl on FreeBSD/i386 #17719 f319ff357 vdev_disk_close: take disk write lock before destroying it #17732 1d2d81298 Refactor `zhack label repair` and fix `-c` regression on nonzero TXG #17764 ea37c30fc zdb: Fix asize overflow in verify_livelist_allocs() Obtained from: OpenZFS OpenZFS commit: b2196fbedf5dbfb8593288f5f9ba712e31429a84
-rwxr-xr-xsys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh2
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c2
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_main.c8
-rw-r--r--sys/contrib/openzfs/cmd/zhack.c134
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_main.c10
-rw-r--r--sys/contrib/openzfs/config/Shellcheck.am12
-rw-r--r--sys/contrib/openzfs/config/always-arch.m41
-rw-r--r--sys/contrib/openzfs/config/always-compiler-options.m421
-rw-r--r--sys/contrib/openzfs/config/kernel-dentry-operations.m425
-rw-r--r--sys/contrib/openzfs/config/zfs-build.m41
-rwxr-xr-xsys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in3
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h1
-rw-r--r--sys/contrib/openzfs/include/sys/dmu.h6
-rw-r--r--sys/contrib/openzfs/lib/libspl/Makefile.am3
-rw-r--r--sys/contrib/openzfs/man/Makefile.am17
-rw-r--r--sys/contrib/openzfs/man/man4/zfs.445
-rw-r--r--sys/contrib/openzfs/man/man7/zfsprops.724
-rw-r--r--sys/contrib/openzfs/man/man8/zpool-attach.820
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c85
-rwxr-xr-xsys/contrib/openzfs/scripts/mancheck.sh17
-rwxr-xr-xsys/contrib/openzfs/scripts/zfs-helpers.sh7
-rw-r--r--sys/contrib/openzfs/tests/runfiles/common.run4
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/library.kshlib80
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/zhack_label_repair_001.ksh15
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_001_pos.ksh2
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_002_pos.ksh2
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_on_probe_errors.ksh2
-rw-r--r--sys/modules/zfs/zfs_config.h7
-rw-r--r--sys/modules/zfs/zfs_gitrev.h2
32 files changed, 424 insertions, 148 deletions
diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
index 62e06926e268..8439942c5a41 100755
--- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
+++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
@@ -121,7 +121,7 @@ case "$OS" in
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
;;
freebsd15-0c)
- FreeBSD="15.0-PRERELEASE"
+ FreeBSD="15.0-ALPHA2"
OSNAME="FreeBSD $FreeBSD"
OSv="freebsd14.0"
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index 70096b809656..d655fa715e15 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -385,7 +385,7 @@ verify_livelist_allocs(metaslab_verify_t *mv, uint64_t txg,
sublivelist_verify_block_t svb = {{{0}}};
DVA_SET_VDEV(&svb.svb_dva, mv->mv_vdid);
DVA_SET_OFFSET(&svb.svb_dva, offset);
- DVA_SET_ASIZE(&svb.svb_dva, size);
+ DVA_SET_ASIZE(&svb.svb_dva, 0);
zfs_btree_index_t where;
uint64_t end_offset = offset + size;
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
index f7a627a2fee6..484986bde719 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
@@ -6864,17 +6864,17 @@ print_holds(boolean_t scripted, int nwidth, int tagwidth, nvlist_t *nvl,
if (scripted) {
if (parsable) {
- (void) printf("%s\t%s\t%ld\n", zname,
- tagname, (unsigned long)time);
+ (void) printf("%s\t%s\t%lld\n", zname,
+ tagname, (long long)time);
} else {
(void) printf("%s\t%s\t%s\n", zname,
tagname, tsbuf);
}
} else {
if (parsable) {
- (void) printf("%-*s %-*s %ld\n",
+ (void) printf("%-*s %-*s %lld\n",
nwidth, zname, tagwidth,
- tagname, (unsigned long)time);
+ tagname, (long long)time);
} else {
(void) printf("%-*s %-*s %s\n",
nwidth, zname, tagwidth,
diff --git a/sys/contrib/openzfs/cmd/zhack.c b/sys/contrib/openzfs/cmd/zhack.c
index edf9dfa2cece..8ffbf91ffb30 100644
--- a/sys/contrib/openzfs/cmd/zhack.c
+++ b/sys/contrib/openzfs/cmd/zhack.c
@@ -714,6 +714,23 @@ zhack_repair_read_label(const int fd, vdev_label_t *vl,
return (0);
}
+static int
+zhack_repair_get_byteswap(const zio_eck_t *vdev_eck, const int l, int *byteswap)
+{
+ if (vdev_eck->zec_magic == ZEC_MAGIC) {
+ *byteswap = B_FALSE;
+ } else if (vdev_eck->zec_magic == BSWAP_64((uint64_t)ZEC_MAGIC)) {
+ *byteswap = B_TRUE;
+ } else {
+ (void) fprintf(stderr, "error: label %d: "
+ "Expected the nvlist checksum magic number but instead got "
+ "0x%" PRIx64 "\n",
+ l, vdev_eck->zec_magic);
+ return (1);
+ }
+ return (0);
+}
+
static void
zhack_repair_calc_cksum(const int byteswap, void *data, const uint64_t offset,
const uint64_t abdsize, zio_eck_t *eck, zio_cksum_t *cksum)
@@ -740,33 +757,10 @@ zhack_repair_calc_cksum(const int byteswap, void *data, const uint64_t offset,
}
static int
-zhack_repair_check_label(uberblock_t *ub, const int l, const char **cfg_keys,
- const size_t cfg_keys_len, nvlist_t *cfg, nvlist_t *vdev_tree_cfg,
- uint64_t *ashift)
+zhack_repair_get_ashift(nvlist_t *cfg, const int l, uint64_t *ashift)
{
int err;
-
- if (ub->ub_txg != 0) {
- (void) fprintf(stderr,
- "error: label %d: UB TXG of 0 expected, but got %"
- PRIu64 "\n",
- l, ub->ub_txg);
- (void) fprintf(stderr, "It would appear the device was not "
- "properly removed.\n");
- return (1);
- }
-
- for (int i = 0; i < cfg_keys_len; i++) {
- uint64_t val;
- err = nvlist_lookup_uint64(cfg, cfg_keys[i], &val);
- if (err) {
- (void) fprintf(stderr,
- "error: label %d, %d: "
- "cannot find nvlist key %s\n",
- l, i, cfg_keys[i]);
- return (err);
- }
- }
+ nvlist_t *vdev_tree_cfg;
err = nvlist_lookup_nvlist(cfg,
ZPOOL_CONFIG_VDEV_TREE, &vdev_tree_cfg);
@@ -790,7 +784,7 @@ zhack_repair_check_label(uberblock_t *ub, const int l, const char **cfg_keys,
(void) fprintf(stderr,
"error: label %d: nvlist key %s is zero\n",
l, ZPOOL_CONFIG_ASHIFT);
- return (err);
+ return (1);
}
return (0);
@@ -805,30 +799,35 @@ zhack_repair_undetach(uberblock_t *ub, nvlist_t *cfg, const int l)
*/
if (BP_GET_LOGICAL_BIRTH(&ub->ub_rootbp) != 0) {
const uint64_t txg = BP_GET_LOGICAL_BIRTH(&ub->ub_rootbp);
+ int err;
+
ub->ub_txg = txg;
- if (nvlist_remove_all(cfg, ZPOOL_CONFIG_CREATE_TXG) != 0) {
+ err = nvlist_remove_all(cfg, ZPOOL_CONFIG_CREATE_TXG);
+ if (err) {
(void) fprintf(stderr,
"error: label %d: "
"Failed to remove pool creation TXG\n",
l);
- return (1);
+ return (err);
}
- if (nvlist_remove_all(cfg, ZPOOL_CONFIG_POOL_TXG) != 0) {
+ err = nvlist_remove_all(cfg, ZPOOL_CONFIG_POOL_TXG);
+ if (err) {
(void) fprintf(stderr,
"error: label %d: Failed to remove pool TXG to "
"be replaced.\n",
l);
- return (1);
+ return (err);
}
- if (nvlist_add_uint64(cfg, ZPOOL_CONFIG_POOL_TXG, txg) != 0) {
+ err = nvlist_add_uint64(cfg, ZPOOL_CONFIG_POOL_TXG, txg);
+ if (err) {
(void) fprintf(stderr,
"error: label %d: "
"Failed to add pool TXG of %" PRIu64 "\n",
l, txg);
- return (1);
+ return (err);
}
}
@@ -922,6 +921,7 @@ zhack_repair_test_cksum(const int byteswap, void *vdev_data,
BSWAP_64(ZEC_MAGIC) : ZEC_MAGIC;
const uint64_t actual_magic = vdev_eck->zec_magic;
int err = 0;
+
if (actual_magic != expected_magic) {
(void) fprintf(stderr, "error: label %d: "
"Expected "
@@ -943,6 +943,36 @@ zhack_repair_test_cksum(const int byteswap, void *vdev_data,
return (err);
}
+static int
+zhack_repair_unpack_cfg(vdev_label_t *vl, const int l, nvlist_t **cfg)
+{
+ const char *cfg_keys[] = { ZPOOL_CONFIG_VERSION,
+ ZPOOL_CONFIG_POOL_STATE, ZPOOL_CONFIG_GUID };
+ int err;
+
+ err = nvlist_unpack(vl->vl_vdev_phys.vp_nvlist,
+ VDEV_PHYS_SIZE - sizeof (zio_eck_t), cfg, 0);
+ if (err) {
+ (void) fprintf(stderr,
+ "error: cannot unpack nvlist label %d\n", l);
+ return (err);
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(cfg_keys); i++) {
+ uint64_t val;
+ err = nvlist_lookup_uint64(*cfg, cfg_keys[i], &val);
+ if (err) {
+ (void) fprintf(stderr,
+ "error: label %d, %d: "
+ "cannot find nvlist key %s\n",
+ l, i, cfg_keys[i]);
+ return (err);
+ }
+ }
+
+ return (0);
+}
+
static void
zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
vdev_label_t *vl, const uint64_t label_offset, const int l,
@@ -956,10 +986,7 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
(zio_eck_t *)((char *)(vdev_data) + VDEV_PHYS_SIZE) - 1;
const uint64_t vdev_phys_offset =
label_offset + offsetof(vdev_label_t, vl_vdev_phys);
- const char *cfg_keys[] = { ZPOOL_CONFIG_VERSION,
- ZPOOL_CONFIG_POOL_STATE, ZPOOL_CONFIG_GUID };
nvlist_t *cfg;
- nvlist_t *vdev_tree_cfg = NULL;
uint64_t ashift;
int byteswap;
@@ -967,18 +994,9 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
if (err)
return;
- if (vdev_eck->zec_magic == 0) {
- (void) fprintf(stderr, "error: label %d: "
- "Expected the nvlist checksum magic number to not be zero"
- "\n",
- l);
- (void) fprintf(stderr, "There should already be a checksum "
- "for the label.\n");
+ err = zhack_repair_get_byteswap(vdev_eck, l, &byteswap);
+ if (err)
return;
- }
-
- byteswap =
- (vdev_eck->zec_magic == BSWAP_64((uint64_t)ZEC_MAGIC));
if (byteswap) {
byteswap_uint64_array(&vdev_eck->zec_cksum,
@@ -994,16 +1012,7 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
return;
}
- err = nvlist_unpack(vl->vl_vdev_phys.vp_nvlist,
- VDEV_PHYS_SIZE - sizeof (zio_eck_t), &cfg, 0);
- if (err) {
- (void) fprintf(stderr,
- "error: cannot unpack nvlist label %d\n", l);
- return;
- }
-
- err = zhack_repair_check_label(ub,
- l, cfg_keys, ARRAY_SIZE(cfg_keys), cfg, vdev_tree_cfg, &ashift);
+ err = zhack_repair_unpack_cfg(vl, l, &cfg);
if (err)
return;
@@ -1011,6 +1020,19 @@ zhack_repair_one_label(const zhack_repair_op_t op, const int fd,
char *buf;
size_t buflen;
+ if (ub->ub_txg != 0) {
+ (void) fprintf(stderr,
+ "error: label %d: UB TXG of 0 expected, but got %"
+ PRIu64 "\n", l, ub->ub_txg);
+ (void) fprintf(stderr, "It would appear the device was "
+ "not properly detached.\n");
+ return;
+ }
+
+ err = zhack_repair_get_ashift(cfg, l, &ashift);
+ if (err)
+ return;
+
err = zhack_repair_undetach(ub, cfg, l);
if (err)
return;
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index 237e558da65b..2c46ad0df895 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -456,7 +456,7 @@ get_usage(zpool_help_t idx)
"<pool> <vdev> ...\n"));
case HELP_ATTACH:
return (gettext("\tattach [-fsw] [-o property=value] "
- "<pool> <device> <new-device>\n"));
+ "<pool> <vdev> <new-device>\n"));
case HELP_CLEAR:
return (gettext("\tclear [[--power]|[-nF]] <pool> [device]\n"));
case HELP_CREATE:
@@ -7644,7 +7644,7 @@ zpool_do_replace(int argc, char **argv)
}
/*
- * zpool attach [-fsw] [-o property=value] <pool> <device>|<vdev> <new_device>
+ * zpool attach [-fsw] [-o property=value] <pool> <vdev> <new_device>
*
* -f Force attach, even if <new_device> appears to be in use.
* -s Use sequential instead of healing reconstruction for resilver.
@@ -7652,9 +7652,9 @@ zpool_do_replace(int argc, char **argv)
* -w Wait for resilvering (mirror) or expansion (raidz) to complete
* before returning.
*
- * Attach <new_device> to a <device> or <vdev>, where the vdev can be of type
- * mirror or raidz. If <device> is not part of a mirror, then <device> will
- * be transformed into a mirror of <device> and <new_device>. When a mirror
+ * Attach <new_device> to a <vdev>, where the vdev can be of type
+ * device, mirror or raidz. If <vdev> is not part of a mirror, then <vdev> will
+ * be transformed into a mirror of <vdev> and <new_device>. When a mirror
* is involved, <new_device> will begin life with a DTL of [0, now], and will
* immediately begin to resilver itself. For the raidz case, a expansion will
* commence and reflow the raidz data across all the disks including the
diff --git a/sys/contrib/openzfs/config/Shellcheck.am b/sys/contrib/openzfs/config/Shellcheck.am
index 1ab13516066c..87e6494056cf 100644
--- a/sys/contrib/openzfs/config/Shellcheck.am
+++ b/sys/contrib/openzfs/config/Shellcheck.am
@@ -16,10 +16,14 @@ SHELLCHECK_OPTS = $(call JUST_SHELLCHECK_OPTS,$(1)) $(call JUST_CHECKBAS
PHONY += shellcheck
+shellcheck_verbose = $(shellcheck_verbose_@AM_V@)
+shellcheck_verbose_ = $(shellcheck_verbose_@AM_DEFAULT_V@)
+shellcheck_verbose_0 = @echo SHELLCHECK $(_STGT);
+
_STGT = $(subst ^,/,$(subst shellcheck-here-,,$@))
shellcheck-here-%:
if HAVE_SHELLCHECK
- shellcheck --format=gcc --enable=all --exclude=SC1090,SC1091,SC2039,SC2250,SC2312,SC2317,SC3043 $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") "$$([ -e "$(_STGT)" ] || echo "$(srcdir)/")$(_STGT)"
+ $(shellcheck_verbose)shellcheck --format=gcc --enable=all --exclude=SC1090,SC1091,SC2039,SC2250,SC2312,SC2317,SC3043 $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") "$$([ -e "$(_STGT)" ] || echo "$(srcdir)/")$(_STGT)"
else
@echo "skipping shellcheck of" $(_STGT) "because shellcheck is not installed"
endif
@@ -29,11 +33,15 @@ shellcheck: $(SHELLCHECKSCRIPTS) $(call JUST_SHELLCHECK_OPTS,$(SHELLCHECKSCRIPTS
PHONY += checkbashisms
+checkbashisms_verbose = $(checkbashisms_verbose_@AM_V@)
+checkbashisms_verbose_ = $(checkbashisms_verbose_@AM_DEFAULT_V@)
+checkbashisms_verbose_0 = @echo CHECKBASHISMS $(_BTGT);
+
# command -v *is* specified by POSIX and every shell in existence supports it
_BTGT = $(subst ^,/,$(subst checkbashisms-here-,,$@))
checkbashisms-here-%:
if HAVE_CHECKBASHISMS
- ! { [ -n "$(SHELLCHECK_SHELL)" ] && echo '#!/bin/$(SHELLCHECK_SHELL)'; cat "$$([ -e "$(_BTGT)" ] || echo "$(srcdir)/")$(_BTGT)"; } | \
+ $(checkbashisms_verbose)! { [ -n "$(SHELLCHECK_SHELL)" ] && echo '#!/bin/$(SHELLCHECK_SHELL)'; cat "$$([ -e "$(_BTGT)" ] || echo "$(srcdir)/")$(_BTGT)"; } | \
checkbashisms -npx 2>&1 | grep -vFe "'command' with option other than -p" -e 'command -v' -e 'any possible bashisms' $(CHECKBASHISMS_IGNORE) >&2
else
@echo "skipping checkbashisms of" $(_BTGT) "because checkbashisms is not installed"
diff --git a/sys/contrib/openzfs/config/always-arch.m4 b/sys/contrib/openzfs/config/always-arch.m4
index 1ee6099ca8b2..d73b878916cb 100644
--- a/sys/contrib/openzfs/config/always-arch.m4
+++ b/sys/contrib/openzfs/config/always-arch.m4
@@ -34,6 +34,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_ARCH], [
esac
AM_CONDITIONAL([TARGET_CPU_AARCH64], test $TARGET_CPU = aarch64)
+ AM_CONDITIONAL([TARGET_CPU_I386], test $TARGET_CPU = i386)
AM_CONDITIONAL([TARGET_CPU_X86_64], test $TARGET_CPU = x86_64)
AM_CONDITIONAL([TARGET_CPU_POWERPC], test $TARGET_CPU = powerpc)
AM_CONDITIONAL([TARGET_CPU_SPARC64], test $TARGET_CPU = sparc64)
diff --git a/sys/contrib/openzfs/config/always-compiler-options.m4 b/sys/contrib/openzfs/config/always-compiler-options.m4
index 37fa079e0f4c..0e96435e3713 100644
--- a/sys/contrib/openzfs/config/always-compiler-options.m4
+++ b/sys/contrib/openzfs/config/always-compiler-options.m4
@@ -210,6 +210,27 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED], [
])
dnl #
+dnl # Check if cc supports -Wno-atomic-alignment option.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_ATOMIC_ALIGNMENT], [
+ AC_MSG_CHECKING([whether $CC supports -Wno-atomic-alignment])
+
+ saved_flags="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror -Wno-atomic-alignment"
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [
+ NO_ATOMIC_ALIGNMENT=-Wno-atomic-alignment
+ AC_MSG_RESULT([yes])
+ ], [
+ NO_ATOMIC_ALIGNMENT=
+ AC_MSG_RESULT([no])
+ ])
+
+ CFLAGS="$saved_flags"
+ AC_SUBST([NO_ATOMIC_ALIGNMENT])
+])
+
+dnl #
dnl # Check if cc supports -Wimplicit-fallthrough option.
dnl #
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH], [
diff --git a/sys/contrib/openzfs/config/kernel-dentry-operations.m4 b/sys/contrib/openzfs/config/kernel-dentry-operations.m4
index 6d87ad0e0710..ce0e6e5be959 100644
--- a/sys/contrib/openzfs/config/kernel-dentry-operations.m4
+++ b/sys/contrib/openzfs/config/kernel-dentry-operations.m4
@@ -46,12 +46,37 @@ AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [
])
])
+dnl #
+dnl # 6.17 API change
+dnl # sb->s_d_op removed; set_default_d_op(sb, dop) added
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_DEFAULT_D_OP], [
+ ZFS_LINUX_TEST_SRC([set_default_d_op], [
+ #include <linux/dcache.h>
+ ], [
+ set_default_d_op(NULL, NULL);
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_SET_DEFAULT_D_OP], [
+ AC_MSG_CHECKING([whether set_default_d_op() is available])
+ ZFS_LINUX_TEST_RESULT([set_default_d_op], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SET_DEFAULT_D_OP, 1,
+ [Define if set_default_d_op() is available])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+])
+
AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY], [
ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS
ZFS_AC_KERNEL_SRC_D_SET_D_OP
+ ZFS_AC_KERNEL_SRC_SET_DEFAULT_D_OP
])
AC_DEFUN([ZFS_AC_KERNEL_DENTRY], [
ZFS_AC_KERNEL_D_OBTAIN_ALIAS
ZFS_AC_KERNEL_D_SET_D_OP
+ ZFS_AC_KERNEL_SET_DEFAULT_D_OP
])
diff --git a/sys/contrib/openzfs/config/zfs-build.m4 b/sys/contrib/openzfs/config/zfs-build.m4
index adf6576f3193..161d390466db 100644
--- a/sys/contrib/openzfs/config/zfs-build.m4
+++ b/sys/contrib/openzfs/config/zfs-build.m4
@@ -252,6 +252,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
ZFS_AC_CONFIG_ALWAYS_CC_NO_CLOBBERED
ZFS_AC_CONFIG_ALWAYS_CC_INFINITE_RECURSION
ZFS_AC_CONFIG_ALWAYS_KERNEL_CC_INFINITE_RECURSION
+ ZFS_AC_CONFIG_ALWAYS_CC_NO_ATOMIC_ALIGNMENT
ZFS_AC_CONFIG_ALWAYS_CC_IMPLICIT_FALLTHROUGH
ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN
ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION
diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in
index acad468edfd1..130d94c70707 100755
--- a/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in
+++ b/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in
@@ -16,7 +16,8 @@ depends() {
}
installkernel() {
- instmods -c zfs
+ hostonly='' instmods -c zfs
+ instmods mpt3sas virtio_blk
}
install() {
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h
index f5a9105cd885..8994aab889fe 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h
@@ -55,6 +55,7 @@ extern const struct file_operations zpl_dir_file_operations;
extern void zpl_prune_sb(uint64_t nr_to_scan, void *arg);
extern const struct super_operations zpl_super_operations;
+extern const struct dentry_operations zpl_dentry_operations;
extern const struct export_operations zpl_export_operations;
extern struct file_system_type zpl_fs_type;
diff --git a/sys/contrib/openzfs/include/sys/dmu.h b/sys/contrib/openzfs/include/sys/dmu.h
index b18961be1282..aa5035862def 100644
--- a/sys/contrib/openzfs/include/sys/dmu.h
+++ b/sys/contrib/openzfs/include/sys/dmu.h
@@ -414,9 +414,9 @@ typedef struct dmu_buf {
#define DMU_POOL_ZPOOL_CHECKPOINT "com.delphix:zpool_checkpoint"
#define DMU_POOL_LOG_SPACEMAP_ZAP "com.delphix:log_spacemap_zap"
#define DMU_POOL_DELETED_CLONES "com.delphix:deleted_clones"
-#define DMU_POOL_TXG_LOG_TIME_MINUTES "com.klaraystems:txg_log_time:minutes"
-#define DMU_POOL_TXG_LOG_TIME_DAYS "com.klaraystems:txg_log_time:days"
-#define DMU_POOL_TXG_LOG_TIME_MONTHS "com.klaraystems:txg_log_time:months"
+#define DMU_POOL_TXG_LOG_TIME_MINUTES "com.klarasystems:txg_log_time:minutes"
+#define DMU_POOL_TXG_LOG_TIME_DAYS "com.klarasystems:txg_log_time:days"
+#define DMU_POOL_TXG_LOG_TIME_MONTHS "com.klarasystems:txg_log_time:months"
/*
* Allocate an object from this objset. The range of object numbers
diff --git a/sys/contrib/openzfs/lib/libspl/Makefile.am b/sys/contrib/openzfs/lib/libspl/Makefile.am
index 6640ecd582a7..0fd907d3011e 100644
--- a/sys/contrib/openzfs/lib/libspl/Makefile.am
+++ b/sys/contrib/openzfs/lib/libspl/Makefile.am
@@ -2,6 +2,9 @@ include $(srcdir)/%D%/include/Makefile.am
libspl_assert_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS) $(LIBUNWIND_CFLAGS)
libspl_la_CFLAGS = $(libspl_assert_la_CFLAGS)
+if TARGET_CPU_I386
+libspl_la_CFLAGS += $(NO_ATOMIC_ALIGNMENT)
+endif
noinst_LTLIBRARIES += libspl_assert.la libspl.la
CPPCHECKTARGETS += libspl_assert.la libspl.la
diff --git a/sys/contrib/openzfs/man/Makefile.am b/sys/contrib/openzfs/man/Makefile.am
index 9fb8fdb175b0..7a63641c1c39 100644
--- a/sys/contrib/openzfs/man/Makefile.am
+++ b/sys/contrib/openzfs/man/Makefile.am
@@ -124,10 +124,21 @@ dist_noinst_DATA += $(dist_noinst_man_MANS) $(dist_man_MANS)
SUBSTFILES += $(nodist_man_MANS)
-CHECKS += mancheck
-mancheck:
- $(top_srcdir)/scripts/mancheck.sh $(srcdir)/%D%
+MANFILES = $(dist_noinst_man_MANS) $(dist_man_MANS) $(nodist_man_MANS)
+
+PHONY += mancheck
+
+mancheck_verbose = $(mancheck_verbose_@AM_V@)
+mancheck_verbose_ = $(mancheck_verbose_@AM_DEFAULT_V@)
+mancheck_verbose_0 = @echo MANCHECK $(_MTGT);
+_MTGT = $(subst ^,/,$(subst mancheck-,,$@))
+mancheck-%:
+ $(mancheck_verbose)scripts/mancheck.sh $(_MTGT)
+
+mancheck: $(foreach manfile, $(MANFILES), $(addprefix mancheck-,$(subst /,^,$(manfile))))
+
+CHECKS += mancheck
if BUILD_LINUX
# The manual pager in most Linux distros defaults to "BSD" when .Os is blank,
diff --git a/sys/contrib/openzfs/man/man4/zfs.4 b/sys/contrib/openzfs/man/man4/zfs.4
index 7f1adaceb408..11bcbf430210 100644
--- a/sys/contrib/openzfs/man/man4/zfs.4
+++ b/sys/contrib/openzfs/man/man4/zfs.4
@@ -18,7 +18,7 @@
.\" own identifying information:
.\" Portions Copyright [yyyy] [name of copyright owner]
.\"
-.Dd August 14, 2025
+.Dd September 15, 2025
.Dt ZFS 4
.Os
.
@@ -2583,6 +2583,49 @@ the xattr so as to not accumulate duplicates.
.It Sy zio_requeue_io_start_cut_in_line Ns = Ns Sy 0 Ns | Ns 1 Pq int
Prioritize requeued I/O.
.
+.It Sy zfs_delete_inode Ns = Ns Sy 0 Ns | Ns 1 Pq int
+Sets whether the kernel should free an inode structure when the last reference
+is released, or cache it in memory.
+Intended for testing/debugging.
+.Pp
+A live inode structure "pins" versious internal OpenZFS structures in memory,
+which can result in large amounts of "unusable" memory on systems with lots of
+infrequently-accessed files, until the kernel's memory pressure mechanism
+asks OpenZFS to release them.
+.Pp
+The default value of
+.Sy 0
+always caches inodes that appear to still exist on disk.
+Setting it to
+.Sy 1
+will immediately release unused inodes and their associated memory back to the
+dbuf cache or the ARC for reuse, but may reduce performance if inodes are
+frequently evicted and reloaded.
+.Pp
+This parameter is only available on Linux.
+.
+.It Sy zfs_delete_dentry Ns = Ns Sy 0 Ns | Ns 1 Pq int
+Sets whether the kernel should free a dentry structure when it is no longer
+required, or hold it in the dentry cache.
+Intended for testing/debugging.
+.
+Since a dentry structure holds an inode reference, a cached dentry can "pin"
+an inode in memory indefinitely, along with associated OpenZFS structures (See
+.Sy zfs_delete_inode ) .
+.Pp
+The default value of
+.Sy 0
+instructs the kernel to cache entries and their associated inodes when they
+are no longer directly referenced.
+They will be reclaimed as part of the kernel's normal cache management
+processes.
+Setting it to
+.Sy 1
+will instruct the kernel to release directory entries and their inodes as soon
+as they are no longer referenced by the filesystem.
+.Pp
+This parameter is only available on Linux.
+.
.It Sy zio_taskq_batch_pct Ns = Ns Sy 80 Ns % Pq uint
Percentage of online CPUs which will run a worker thread for I/O.
These workers are responsible for I/O work such as compression, encryption,
diff --git a/sys/contrib/openzfs/man/man7/zfsprops.7 b/sys/contrib/openzfs/man/man7/zfsprops.7
index 0930771c9fce..77e994b912b6 100644
--- a/sys/contrib/openzfs/man/man7/zfsprops.7
+++ b/sys/contrib/openzfs/man/man7/zfsprops.7
@@ -39,7 +39,7 @@
.\" Copyright (c) 2019, Kjeld Schouten-Lebbing
.\" Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
.\"
-.Dd August 6, 2025
+.Dd September 13, 2025
.Dt ZFSPROPS 7
.Os
.
@@ -1192,18 +1192,26 @@ keylocation can be with either
.Nm zfs Cm set
or
.Nm zfs Cm change-key .
+.Pp
If
.Sy prompt
-is selected ZFS will ask for the key at the command prompt when it is required
-to access the encrypted data (see
+is selected, ZFS will expect the key to be provided when it is required to
+access the encrypted data (see
.Nm zfs Cm load-key
for details).
-This setting will also allow the key to be passed in via the standard input
-stream,
-but users should be careful not to place keys which should be kept secret on
-the command line.
-If a file URI is selected, the key will be loaded from the
+If stdin is a TTY, then ZFS will ask for the key to be provided.
+Otherwise, stdin is expected to be the key to use and will be processed as such.
+Users should be careful not to place keys which should be kept secret on the
+command line, as most operating systems may expose command line arguments to
+other processes.
+If the
+.Dq raw
+.Sy keyformat
+was used, then the key must be provided via stdin.
+.Pp
+If a file URL is selected, the key will be loaded from the
specified absolute file path.
+.Pp
If an HTTPS or HTTP URL is selected, it will be GETted using
.Xr fetch 3 ,
libcurl, or nothing, depending on compile-time configuration and run-time
diff --git a/sys/contrib/openzfs/man/man8/zpool-attach.8 b/sys/contrib/openzfs/man/man8/zpool-attach.8
index f120350a5190..04996ed4fa11 100644
--- a/sys/contrib/openzfs/man/man8/zpool-attach.8
+++ b/sys/contrib/openzfs/man/man8/zpool-attach.8
@@ -39,24 +39,24 @@
.Cm attach
.Op Fl fsw
.Oo Fl o Ar property Ns = Ns Ar value Oc
-.Ar pool device new_device
+.Ar pool vdev new_device
.
.Sh DESCRIPTION
Attaches
.Ar new_device
to the existing
-.Ar device .
+.Ar vdev .
The behavior differs depending on if the existing
-.Ar device
+.Ar vdev
is a RAID-Z device, or a mirror/plain device.
.Pp
-If the existing device is a mirror or plain device
+If the existing vdev is a mirror or plain device
.Pq e.g. specified as Qo Li sda Qc or Qq Li mirror-7 ,
-the new device will be mirrored with the existing device, a resilver will be
+the new device will be mirrored with the existing vdev, a resilver will be
initiated, and the new device will contribute to additional redundancy once the
resilver completes.
If
-.Ar device
+.Ar vdev
is not currently part of a mirrored configuration,
.Ar device
automatically transforms into a two-way mirror of
@@ -64,7 +64,7 @@ automatically transforms into a two-way mirror of
and
.Ar new_device .
If
-.Ar device
+.Ar vdev
is part of a two-way mirror, attaching
.Ar new_device
creates a three-way mirror, and so on.
@@ -72,7 +72,7 @@ In either case,
.Ar new_device
begins to resilver immediately and any running scrub is canceled.
.Pp
-If the existing device is a RAID-Z device
+If the existing vdev is a RAID-Z device
.Pq e.g. specified as Qq Ar raidz2-0 ,
the new device will become part of that RAID-Z group.
A "raidz expansion" will be initiated, and once the expansion completes,
@@ -112,7 +112,7 @@ the checksums of all blocks which have been copied during the expansion.
Forces use of
.Ar new_device ,
even if it appears to be in use.
-Not all devices can be overridden in this manner.
+Not all vdevs can be overridden in this manner.
.It Fl o Ar property Ns = Ns Ar value
Sets the given pool properties.
See the
@@ -121,7 +121,7 @@ manual page for a list of valid properties that can be set.
The only property supported at the moment is
.Sy ashift .
.It Fl s
-When attaching to a mirror or plain device, the
+When attaching to a mirror or plain vdev, the
.Ar new_device
is reconstructed sequentially to restore redundancy as quickly as possible.
Checksums are not verified during sequential reconstruction so a scrub is
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
index 830fad7fe793..1bd3500e9f66 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
@@ -471,13 +471,17 @@ vdev_disk_close(vdev_t *v)
if (v->vdev_reopening || vd == NULL)
return;
+ rw_enter(&vd->vd_lock, RW_WRITER);
+
if (vd->vd_bdh != NULL)
vdev_blkdev_put(vd->vd_bdh, spa_mode(v->vdev_spa),
zfs_vdev_holder);
+ v->vdev_tsd = NULL;
+
+ rw_exit(&vd->vd_lock);
rw_destroy(&vd->vd_lock);
kmem_free(vd, sizeof (vdev_disk_t));
- v->vdev_tsd = NULL;
}
/*
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
index cd606e667bff..8a7d14ab6119 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
@@ -1556,6 +1556,12 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
sb->s_xattr = zpl_xattr_handlers;
sb->s_export_op = &zpl_export_operations;
+#ifdef HAVE_SET_DEFAULT_D_OP
+ set_default_d_op(sb, &zpl_dentry_operations);
+#else
+ sb->s_d_op = &zpl_dentry_operations;
+#endif
+
/* Set features for file system. */
zfs_set_fuid_feature(zfsvfs);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
index 53819628627d..444948d03cb3 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2011, Lawrence Livermore National Security, LLC.
* Copyright (c) 2023, Datto Inc. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
*/
@@ -33,6 +34,20 @@
#include <linux/iversion.h>
#include <linux/version.h>
+/*
+ * What to do when the last reference to an inode is released. If 0, the kernel
+ * will cache it on the superblock. If 1, the inode will be freed immediately.
+ * See zpl_drop_inode().
+ */
+int zfs_delete_inode = 0;
+
+/*
+ * What to do when the last reference to a dentry is released. If 0, the kernel
+ * will cache it until the entry (file) is destroyed. If 1, the dentry will be
+ * marked for cleanup, at which time its inode reference will be released. See
+ * zpl_dentry_delete().
+ */
+int zfs_delete_dentry = 0;
static struct inode *
zpl_inode_alloc(struct super_block *sb)
@@ -77,11 +92,36 @@ zpl_dirty_inode(struct inode *ip, int flags)
}
/*
- * When ->drop_inode() is called its return value indicates if the
- * inode should be evicted from the inode cache. If the inode is
- * unhashed and has no links the default policy is to evict it
- * immediately.
+ * ->drop_inode() is called when the last reference to an inode is released.
+ * Its return value indicates if the inode should be destroyed immediately, or
+ * cached on the superblock structure.
+ *
+ * By default (zfs_delete_inode=0), we call generic_drop_inode(), which returns
+ * "destroy immediately" if the inode is unhashed and has no links (roughly: no
+ * longer exists on disk). On datasets with millions of rarely-accessed files,
+ * this can cause a large amount of memory to be "pinned" by cached inodes,
+ * which in turn pin their associated dnodes and dbufs, until the kernel starts
+ * reporting memory pressure and requests OpenZFS release some memory (see
+ * zfs_prune()).
+ *
+ * When set to 1, we call generic_delete_node(), which always returns "destroy
+ * immediately", resulting in inodes being destroyed immediately, releasing
+ * their associated dnodes and dbufs to the dbuf cached and the ARC to be
+ * evicted as normal.
*
+ * Note that the "last reference" doesn't always mean the last _userspace_
+ * reference; the dentry cache also holds a reference, so "busy" inodes will
+ * still be kept alive that way (subject to dcache tuning).
+ */
+static int
+zpl_drop_inode(struct inode *ip)
+{
+ if (zfs_delete_inode)
+ return (generic_delete_inode(ip));
+ return (generic_drop_inode(ip));
+}
+
+/*
* The ->evict_inode() callback must minimally truncate the inode pages,
* and call clear_inode(). For 2.6.35 and later kernels this will
* simply update the inode state, with the sync occurring before the
@@ -470,6 +510,7 @@ const struct super_operations zpl_super_operations = {
.destroy_inode = zpl_inode_destroy,
.dirty_inode = zpl_dirty_inode,
.write_inode = NULL,
+ .drop_inode = zpl_drop_inode,
.evict_inode = zpl_evict_inode,
.put_super = zpl_put_super,
.sync_fs = zpl_sync_fs,
@@ -480,6 +521,35 @@ const struct super_operations zpl_super_operations = {
.show_stats = NULL,
};
+/*
+ * ->d_delete() is called when the last reference to a dentry is released. Its
+ * return value indicates if the dentry should be destroyed immediately, or
+ * retained in the dentry cache.
+ *
+ * By default (zfs_delete_dentry=0) the kernel will always cache unused
+ * entries. Each dentry holds an inode reference, so cached dentries can hold
+ * the final inode reference indefinitely, leading to the inode and its related
+ * data being pinned (see zpl_drop_inode()).
+ *
+ * When set to 1, we signal that the dentry should be destroyed immediately and
+ * never cached. This reduces memory usage, at the cost of higher overheads to
+ * lookup a file, as the inode and its underlying data (dnode/dbuf) need to be
+ * reloaded and reinflated.
+ *
+ * Note that userspace does not have direct control over dentry references and
+ * reclaim; rather, this is part of the kernel's caching and reclaim subsystems
+ * (eg vm.vfs_cache_pressure).
+ */
+static int
+zpl_dentry_delete(const struct dentry *dentry)
+{
+ return (zfs_delete_dentry ? 1 : 0);
+}
+
+const struct dentry_operations zpl_dentry_operations = {
+ .d_delete = zpl_dentry_delete,
+};
+
struct file_system_type zpl_fs_type = {
.owner = THIS_MODULE,
.name = ZFS_DRIVER,
@@ -491,3 +561,10 @@ struct file_system_type zpl_fs_type = {
.mount = zpl_mount,
.kill_sb = zpl_kill_sb,
};
+
+ZFS_MODULE_PARAM(zfs, zfs_, delete_inode, INT, ZMOD_RW,
+ "Delete inodes as soon as the last reference is released.");
+
+ZFS_MODULE_PARAM(zfs, zfs_, delete_dentry, INT, ZMOD_RW,
+ "Delete dentries from dentry cache as soon as the last reference is "
+ "released.");
diff --git a/sys/contrib/openzfs/scripts/mancheck.sh b/sys/contrib/openzfs/scripts/mancheck.sh
index 364ad1b76286..33d7d3c7155f 100755
--- a/sys/contrib/openzfs/scripts/mancheck.sh
+++ b/sys/contrib/openzfs/scripts/mancheck.sh
@@ -11,12 +11,12 @@
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# shellcheck disable=SC2086
+# shellcheck disable=SC2068,SC2086
trap 'rm -f "$stdout_file" "$stderr_file" "$result_file"' EXIT
if [ "$#" -eq 0 ]; then
- echo "Usage: $0 manpage-directory..."
+ echo "Usage: $0 <manpage-directory|manpage-file>..."
exit 1
fi
@@ -27,7 +27,16 @@ fi
IFS="
"
-files="$(find "$@" -type f -name '*[1-9]*' -not -name '.*')" || exit 1
+files="$(
+ for path in $@ ; do
+ find -L $path -type f -name '*[1-9]*' -not -name '.*'
+ done | sort | uniq
+)"
+
+if [ "$files" = "" ] ; then
+ echo no files to process! 1>&2
+ exit 1
+fi
add_excl="$(awk '
/^.\\" lint-ok:/ {
@@ -48,6 +57,4 @@ grep -vhE -e 'mandoc: outdated mandoc.db' -e 'STYLE: referenced manual not found
if [ -s "$result_file" ]; then
cat "$result_file"
exit 1
-else
- echo "no errors found"
fi
diff --git a/sys/contrib/openzfs/scripts/zfs-helpers.sh b/sys/contrib/openzfs/scripts/zfs-helpers.sh
index b45384a9aa52..2e97d40db1c1 100755
--- a/sys/contrib/openzfs/scripts/zfs-helpers.sh
+++ b/sys/contrib/openzfs/scripts/zfs-helpers.sh
@@ -122,6 +122,13 @@ install() {
src=$1
dst=$2
+ # We may have an old symlink pointing to different ZFS workspace.
+ # Remove the old symlink if it doesn't point to our workspace.
+ if [ -h "$dst" ] && [ "$(readlink -f """$dst""")" != "$src" ] ; then
+ echo "Removing old symlink: $dst -> $(readlink """$dst""")"
+ rm "$dst"
+ fi
+
if [ -h "$dst" ]; then
echo "Symlink exists: $dst"
elif [ -e "$dst" ]; then
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index 4dd700ef361c..2b002830c82f 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -641,9 +641,9 @@ tests = ['zfs_list_001_pos', 'zfs_list_002_pos', 'zfs_list_003_pos',
user =
tags = ['functional', 'cli_user', 'zfs_list']
-[tests/functional/cli_root/zfs_send_delegation_user]
+[tests/functional/cli_user/zfs_send_delegation_user]
tests = ['zfs_send_usertest']
-tags = ['functional', 'cli_root', 'zfs_send_delegation_user']
+tags = ['functional', 'cli_user', 'zfs_send_delegation_user']
[tests/functional/cli_user/zpool_iostat]
tests = ['zpool_iostat_001_neg', 'zpool_iostat_002_pos',
diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib b/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib
index 6b0f8b18c4b6..8b30b9b91641 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib
+++ b/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib
@@ -1085,7 +1085,7 @@ function fill_fs # destdir dirnum filenum bytes num_writes data
typeset -i filenum=${3:-50}
typeset -i bytes=${4:-8192}
typeset -i num_writes=${5:-10240}
- typeset data=${6:-0}
+ typeset data=${6:-"R"}
mkdir -p $destdir/{1..$dirnum}
for f in $destdir/{1..$dirnum}/$TESTFILE{1..$filenum}; do
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/library.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/library.kshlib
index 0f5f6198daf2..0d07b1fd1952 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/library.kshlib
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/library.kshlib
@@ -33,13 +33,16 @@
# Test one:
#
# 1. Create pool on a loopback device with some test data
-# 2. Export the pool.
-# 3. Corrupt all label checksums in the pool
-# 4. Check that pool cannot be imported
-# 5. Verify that it cannot be imported after using zhack label repair -u
+# 2. Checksum repair should work with a valid TXG. Repeatedly write and
+# sync the pool so there are enough transactions for every uberblock
+# to have a TXG
+# 3. Export the pool.
+# 4. Corrupt all label checksums in the pool
+# 5. Check that pool cannot be imported
+# 6. Verify that it cannot be imported after using zhack label repair -u
# to ensure that the -u option will quit on corrupted checksums.
-# 6. Use zhack label repair -c on device
-# 7. Check that pool can be imported and that data is intact
+# 7. Use zhack label repair -c on device
+# 8. Check that pool can be imported and that data is intact
#
# Test two:
#
@@ -97,7 +100,7 @@ VIRTUAL_MIRROR_DEVICE=
function cleanup_lo
{
- L_DEVICE="$1"
+ typeset L_DEVICE="$1"
if [[ -e $L_DEVICE ]]; then
if is_linux; then
@@ -133,9 +136,9 @@ function get_devsize
function pick_logop
{
- L_SHOULD_SUCCEED="$1"
+ typeset L_SHOULD_SUCCEED="$1"
- l_logop="log_mustnot"
+ typeset l_logop="log_mustnot"
if [ "$L_SHOULD_SUCCEED" == true ]; then
l_logop="log_must"
fi
@@ -145,7 +148,9 @@ function pick_logop
function check_dataset
{
- L_SHOULD_SUCCEED="$1"
+ typeset L_SHOULD_SUCCEED="$1"
+
+ typeset L_LOGOP=
L_LOGOP="$(pick_logop "$L_SHOULD_SUCCEED")"
"$L_LOGOP" mounted "$TESTPOOL"/"$TESTFS"
@@ -170,9 +175,21 @@ function setup_dataset
check_dataset true
}
+function force_transactions
+{
+ typeset L_TIMES="$1"
+ typeset i=
+ for ((i=0; i < L_TIMES; i++))
+ do
+ touch "$TESTDIR"/"test" || return $?
+ zpool sync -f "$TESTPOOL" || return $?
+ done
+ return 0
+}
+
function get_practical_size
{
- L_SIZE="$1"
+ typeset L_SIZE="$1"
if [ "$((L_SIZE % LABEL_SIZE))" -ne 0 ]; then
echo "$(((L_SIZE / LABEL_SIZE) * LABEL_SIZE))"
@@ -183,10 +200,11 @@ function get_practical_size
function corrupt_sized_label_checksum
{
- L_SIZE="$1"
- L_LABEL="$2"
- L_DEVICE="$3"
+ typeset L_SIZE="$1"
+ typeset L_LABEL="$2"
+ typeset L_DEVICE="$3"
+ typeset L_PRACTICAL_SIZE=
L_PRACTICAL_SIZE="$(get_practical_size "$L_SIZE")"
typeset -a L_OFFSETS=("$LABEL_CKSUM_START" \
@@ -201,8 +219,8 @@ function corrupt_sized_label_checksum
function corrupt_labels
{
- L_SIZE="$1"
- L_DISK="$2"
+ typeset L_SIZE="$1"
+ typeset L_DISK="$2"
corrupt_sized_label_checksum "$L_SIZE" 0 "$L_DISK"
corrupt_sized_label_checksum "$L_SIZE" 1 "$L_DISK"
@@ -212,11 +230,14 @@ function corrupt_labels
function try_import_and_repair
{
- L_REPAIR_SHOULD_SUCCEED="$1"
- L_IMPORT_SHOULD_SUCCEED="$2"
- L_OP="$3"
- L_POOLDISK="$4"
+ typeset L_REPAIR_SHOULD_SUCCEED="$1"
+ typeset L_IMPORT_SHOULD_SUCCEED="$2"
+ typeset L_OP="$3"
+ typeset L_POOLDISK="$4"
+
+ typeset L_REPAIR_LOGOP=
L_REPAIR_LOGOP="$(pick_logop "$L_REPAIR_SHOULD_SUCCEED")"
+ typeset L_IMPORT_LOGOP=
L_IMPORT_LOGOP="$(pick_logop "$L_IMPORT_SHOULD_SUCCEED")"
log_mustnot zpool import "$TESTPOOL" -d "$L_POOLDISK"
@@ -230,10 +251,10 @@ function try_import_and_repair
function prepare_vdev
{
- L_SIZE="$1"
- L_BACKFILE="$2"
+ typeset L_SIZE="$1"
+ typeset L_BACKFILE="$2"
- l_devname=
+ typeset l_devname=
if truncate -s "$L_SIZE" "$L_BACKFILE"; then
if is_linux; then
l_devname="$(losetup -f "$L_BACKFILE" --show)"
@@ -248,7 +269,7 @@ function prepare_vdev
function run_test_one
{
- L_SIZE="$1"
+ typeset L_SIZE="$1"
VIRTUAL_DEVICE="$(prepare_vdev "$L_SIZE" "$VIRTUAL_DISK")"
log_must test -e "$VIRTUAL_DEVICE"
@@ -257,6 +278,9 @@ function run_test_one
setup_dataset
+ # Force 256 extra transactions to ensure all uberblocks are assigned a TXG
+ log_must force_transactions 256
+
log_must zpool export "$TESTPOOL"
corrupt_labels "$L_SIZE" "$VIRTUAL_DISK"
@@ -272,7 +296,7 @@ function run_test_one
function make_mirrored_pool
{
- L_SIZE="$1"
+ typeset L_SIZE="$1"
VIRTUAL_DEVICE="$(prepare_vdev "$L_SIZE" "$VIRTUAL_DISK")"
log_must test -e "$VIRTUAL_DEVICE"
@@ -296,7 +320,7 @@ function export_and_cleanup_vdisk
function run_test_two
{
- L_SIZE="$1"
+ typeset L_SIZE="$1"
make_mirrored_pool "$L_SIZE"
@@ -317,7 +341,7 @@ function run_test_two
function run_test_three
{
- L_SIZE="$1"
+ typeset L_SIZE="$1"
make_mirrored_pool "$L_SIZE"
@@ -342,7 +366,7 @@ function run_test_three
function run_test_four
{
- L_SIZE="$1"
+ typeset L_SIZE="$1"
make_mirrored_pool "$L_SIZE"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/zhack_label_repair_001.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/zhack_label_repair_001.ksh
index ce159b555d20..b5b24322f882 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/zhack_label_repair_001.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zhack/zhack_label_repair_001.ksh
@@ -18,13 +18,16 @@
# Strategy:
#
# 1. Create pool on a loopback device with some test data
-# 2. Export the pool.
-# 3. Corrupt all label checksums in the pool
-# 4. Check that pool cannot be imported
-# 5. Verify that it cannot be imported after using zhack label repair -u
+# 2. Checksum repair should work with a valid TXG. Repeatedly write and
+# sync the pool so there are enough transactions for every uberblock
+# to have a TXG
+# 3. Export the pool.
+# 4. Corrupt all label checksums in the pool
+# 5. Check that pool cannot be imported
+# 6. Verify that it cannot be imported after using zhack label repair -u
# to ensure that the -u option will quit on corrupted checksums.
-# 6. Use zhack label repair -c on device
-# 7. Check that pool can be imported and that data is intact
+# 7. Use zhack label repair -c on device
+# 8. Check that pool can be imported and that data is intact
. "$STF_SUITE"/tests/functional/cli_root/zhack/library.kshlib
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_001_pos.ksh
index ef49a5d50f6c..45848bec1f5a 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_001_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_001_pos.ksh
@@ -86,7 +86,7 @@ log_must zpool set autoreplace=on $TESTPOOL
# Add some data to the pool
log_must zfs create $TESTPOOL/fs
-log_must fill_fs /$TESTPOOL/fs 4 100 4096 512 Z
+log_must fill_fs /$TESTPOOL/fs 4 100 4096 512 R
log_must zpool export $TESTPOOL
# Record the partition UUID for later comparison
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_002_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_002_pos.ksh
index a77957f32255..878b4e450340 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_002_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_replace_002_pos.ksh
@@ -119,7 +119,7 @@ log_must zpool set autoreplace=on $TESTPOOL
# Add some data to the pool
log_must zfs create $TESTPOOL/fs
-log_must fill_fs /$TESTPOOL/fs 4 100 4096 512 Z
+log_must fill_fs /$TESTPOOL/fs 4 100 4096 512 R
log_must zpool export $TESTPOOL
# Record the partition UUID for later comparison
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_on_probe_errors.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_on_probe_errors.ksh
index 340994bb60c5..b5df1c7e37f8 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_on_probe_errors.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_on_probe_errors.ksh
@@ -101,7 +101,7 @@ sync_pool $TESTPOOL
log_must zfs create $TESTPOOL/fs
MNTPOINT="$(get_prop mountpoint $TESTPOOL/fs)"
SECONDS=0
-log_must fill_fs $MNTPOINT 1 200 4096 10 Z
+log_must fill_fs $MNTPOINT 1 200 4096 10 R
log_note "fill_fs took $SECONDS seconds"
sync_pool $TESTPOOL
diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h
index 77d08862dcd5..c595030ed4a0 100644
--- a/sys/modules/zfs/zfs_config.h
+++ b/sys/modules/zfs/zfs_config.h
@@ -582,6 +582,9 @@
/* iops->set_acl() takes 4 args, arg2 is struct dentry * */
/* #undef HAVE_SET_ACL_USERNS_DENTRY_ARG2 */
+/* Define if set_default_d_op() is available */
+/* #undef HAVE_SET_DEFAULT_D_OP */
+
/* shrinker_register exists */
/* #undef HAVE_SHRINKER_REGISTER */
@@ -840,7 +843,7 @@
/* #undef ZFS_DEVICE_MINOR */
/* Define the project alias string. */
-#define ZFS_META_ALIAS "zfs-2.4.99-52-FreeBSD_g3f4312a0a"
+#define ZFS_META_ALIAS "zfs-2.4.99-72-FreeBSD_gb2196fbed"
/* Define the project author. */
#define ZFS_META_AUTHOR "OpenZFS"
@@ -870,7 +873,7 @@
#define ZFS_META_NAME "zfs"
/* Define the project release. */
-#define ZFS_META_RELEASE "52-FreeBSD_g3f4312a0a"
+#define ZFS_META_RELEASE "72-FreeBSD_gb2196fbed"
/* Define the project version. */
#define ZFS_META_VERSION "2.4.99"
diff --git a/sys/modules/zfs/zfs_gitrev.h b/sys/modules/zfs/zfs_gitrev.h
index 585e308e72d5..9eae1e8573c0 100644
--- a/sys/modules/zfs/zfs_gitrev.h
+++ b/sys/modules/zfs/zfs_gitrev.h
@@ -1 +1 @@
-#define ZFS_META_GITREV "zfs-2.4.99-52-g3f4312a0a"
+#define ZFS_META_GITREV "zfs-2.4.99-72-gb2196fbed"