aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.inc14
-rw-r--r--README.md1
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.14
-rw-r--r--lib/libpfctl/libpfctl.c6
-rw-r--r--lib/libpfctl/libpfctl.h2
-rw-r--r--lib/libsys/intro.25
-rw-r--r--lib/libusb/libusb.h7
-rw-r--r--lib/libusb/libusb10.c4
-rwxr-xr-xlibexec/nuageinit/nuageinit2
-rw-r--r--libexec/nuageinit/tests/nuageinit.sh8
-rw-r--r--release/Makefile.vm7
-rw-r--r--sbin/devd/devd.cc2
-rw-r--r--sbin/devmatch/devmatch.c37
-rw-r--r--sbin/init/init.810
-rw-r--r--sbin/init/init.c18
-rw-r--r--sbin/md5/tests/md5_test.sh12
-rw-r--r--sbin/pfctl/parse.y2
-rw-r--r--sbin/pfctl/pf_print_state.c4
-rw-r--r--sbin/pfctl/pfctl.c8
-rw-r--r--sbin/sysctl/sysctl.83
-rw-r--r--share/man/man4/Makefile2
-rw-r--r--share/man/man4/dtrace_cam.46
-rw-r--r--share/man/man4/dtrace_ip.43
-rw-r--r--share/man/man4/dtrace_mib.4123
-rw-r--r--share/man/man4/dtrace_syscall.487
-rw-r--r--share/man/man4/dtrace_tcp.43
-rw-r--r--share/man/man4/icmp.43
-rw-r--r--share/man/man4/icmp6.43
-rw-r--r--share/man/man4/ifmib.43
-rw-r--r--share/man/man4/ip.43
-rw-r--r--share/man/man4/ipsec.43
-rw-r--r--share/man/man4/linux.43
-rw-r--r--share/man/man4/scsi.44
-rw-r--r--share/man/man4/smartpqi.432
-rw-r--r--share/man/man4/tcp.43
-rw-r--r--share/man/man4/udp.43
-rw-r--r--share/man/man7/d.746
-rw-r--r--share/man/man7/freebsd-base.728
-rw-r--r--share/man/man7/stats.75
-rw-r--r--share/man/man9/Makefile1
-rw-r--r--share/man/man9/cdefs.96
-rw-r--r--share/man/man9/uio.945
-rw-r--r--stand/libsa/zfs/Makefile.inc6
-rw-r--r--sys/compat/linuxkpi/common/include/linux/compiler_attributes.h1
-rw-r--r--sys/conf/kern.pre.mk6
-rwxr-xr-xsys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh16
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml2
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-qemu.yml10
-rw-r--r--sys/contrib/openzfs/cmd/zed/zed_event.c2
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_main.c3
-rw-r--r--sys/contrib/openzfs/config/kernel-dentry-alias.m432
-rw-r--r--sys/contrib/openzfs/config/kernel.m42
-rw-r--r--sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c5
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h2
-rw-r--r--sys/contrib/openzfs/include/sys/vdev_rebuild.h1
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c18
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_diff.c4
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_impl.h1
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_mnttab.c70
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_pool.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c2
-rw-r--r--sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c16
-rw-r--r--sys/contrib/openzfs/man/man4/spl.413
-rw-r--r--sys/contrib/openzfs/man/man7/vdevprops.76
-rw-r--r--sys/contrib/openzfs/man/man7/zfsprops.715
-rw-r--r--sys/contrib/openzfs/module/nvpair/nvpair.c5
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c19
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c5
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c16
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu.c10
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_objset.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_send.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_bookmark.c18
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_dir.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_rebuild.c12
-rw-r--r--sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h2
-rw-r--r--sys/contrib/openzfs/module/zstd/lib/common/zstd_common.c8
-rw-r--r--sys/contrib/openzfs/tests/runfiles/common.run5
-rw-r--r--sys/contrib/openzfs/tests/runfiles/sanity.run2
-rwxr-xr-xsys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am4
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_mnttab_cache_check.c107
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/threadsappend.c8
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am2
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/fadvise/fadvise_dontneed.ksh13
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/libzfs/libzfs_mnttab_cache.ksh26
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/redacted_send/redacted_max_blkid.ksh118
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib9
-rw-r--r--sys/dev/acpi_support/acpi_panasonic.c2
-rw-r--r--sys/dev/ichsmb/ichsmb_pci.c9
-rw-r--r--sys/dev/mii/miidevs8
-rw-r--r--sys/dev/mii/smscphy.c4
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c15
-rw-r--r--sys/dev/smartpqi/smartpqi_cam.c4
-rw-r--r--sys/dev/smartpqi/smartpqi_defines.h8
-rw-r--r--sys/dev/smartpqi/smartpqi_discovery.c21
-rw-r--r--sys/dev/smartpqi/smartpqi_event.c17
-rw-r--r--sys/dev/smartpqi/smartpqi_main.c12
-rw-r--r--sys/dev/smartpqi/smartpqi_misc.c4
-rw-r--r--sys/dev/smartpqi/smartpqi_queue.c4
-rw-r--r--sys/dev/smartpqi/smartpqi_request.c4
-rw-r--r--sys/dev/smartpqi/smartpqi_response.c4
-rw-r--r--sys/dev/smartpqi/smartpqi_sis.c6
-rw-r--r--sys/dev/smartpqi/smartpqi_structures.h4
-rw-r--r--sys/dev/usb/net/if_smsc.c2
-rw-r--r--sys/dev/virtio/network/if_vtnet.c611
-rw-r--r--sys/dev/virtio/network/if_vtnetvar.h16
-rw-r--r--sys/dev/virtio/p9fs/virtio_p9fs.c11
-rw-r--r--sys/fs/nfsclient/nfs_clsubs.c10
-rw-r--r--sys/fs/nfsclient/nfsnode.h2
-rw-r--r--sys/fs/p9fs/p9fs.h1
-rw-r--r--sys/fs/p9fs/p9fs_subr.c14
-rw-r--r--sys/fs/p9fs/p9fs_vfsops.c4
-rw-r--r--sys/fs/p9fs/p9fs_vnops.c97
-rw-r--r--sys/kern/subr_eventhandler.c22
-rw-r--r--sys/kern/subr_kobj.c4
-rw-r--r--sys/kern/sys_process.c46
-rw-r--r--sys/kern/uipc_usrreq.c21
-rw-r--r--sys/kern/vfs_bio.c3
-rw-r--r--sys/modules/ath10k/Makefile2
-rw-r--r--sys/modules/ath11k/Makefile2
-rw-r--r--sys/modules/ath12k/Makefile2
-rw-r--r--sys/modules/zfs/zfs_config.h7
-rw-r--r--sys/modules/zfs/zfs_gitrev.h2
-rw-r--r--sys/net/if_vlan.c126
-rw-r--r--sys/netpfil/pf/if_pfsync.c7
-rw-r--r--sys/netpfil/pf/pf_ioctl.c24
-rw-r--r--sys/netpfil/pf/pf_nl.c189
-rw-r--r--sys/netpfil/pf/pf_nl.h2
-rw-r--r--sys/sys/cdefs.h1
-rw-r--r--sys/sys/eventhandler.h4
-rw-r--r--sys/sys/priority.h8
-rw-r--r--sys/sys/rtprio.h9
-rw-r--r--sys/sys/ucred.h11
-rw-r--r--sys/vm/vm_map.c34
-rwxr-xr-xtests/sys/netinet6/frag6/frag6_19.sh3
-rw-r--r--tests/sys/netpfil/pf/get_state.sh44
-rw-r--r--tests/sys/netpfil/pf/killstate.sh2
-rw-r--r--tests/sys/netpfil/pf/match.sh36
-rw-r--r--tests/sys/netpfil/pf/names.sh40
-rw-r--r--tools/build/test-includes/badfiles.inc2
-rwxr-xr-xtools/tools/git/git-arc.sh2
-rwxr-xr-xusr.bin/stat/tests/stat_test.sh6
-rw-r--r--usr.sbin/bhyve/pci_virtio_scsi.c6
-rw-r--r--usr.sbin/certctl/certctl.815
-rw-r--r--usr.sbin/certctl/certctl.c81
-rw-r--r--usr.sbin/certctl/tests/certctl_test.sh3
-rw-r--r--usr.sbin/jail/config.c7
-rw-r--r--usr.sbin/rtadvd/config.c22
151 files changed, 1850 insertions, 1033 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index b07b5f9c1a65..2927054c2e83 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -2128,7 +2128,7 @@ real-packages: stage-packages create-packages sign-packages .PHONY
real-update-packages: stage-packages .PHONY
${_+_}${MAKE} -C ${.CURDIR} PKG_VERSION=${PKG_VERSION} create-packages
-.if defined(PKG_VERSION_FROM_DIR)
+.if defined(PKG_VERSION_FROM_DIR) && ${PKG_VERSION} != ${PKG_VERSION_FROM}
@echo "==> Checking for new packages (comparing ${PKG_VERSION} to ${PKG_VERSION_FROM})"
@for pkg in ${PKG_VERSION_FROM_DIR}/${PKG_NAME_PREFIX}-*; do \
pkgname=$$(${PKG_CMD} query -F $${pkg} '%n' | sed 's/${PKG_NAME_PREFIX}-\(.*\)/\1/') ; \
@@ -2146,6 +2146,8 @@ real-update-packages: stage-packages .PHONY
echo "==> New package $${newpkgname}" ; \
fi ; \
done
+.elif defined(PKG_VERSION_FROM_DIR)
+ @echo "==> Package version ${PKG_VERSION} unchanged, keeping old package set"
.else
@echo "==> Bootstrapping repository, not checking for new packages"
.endif
diff --git a/README.md b/README.md
index 737afe1566ec..160c91b387e6 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,7 @@ Source Roadmap:
| krb5 | Build system for Kerberos 5 (MIT). |
| lib | System libraries. |
| libexec | System commands intended to be executed by other commands or daemons. |
+| packages | Base system packages. |
| release | Makefiles and scripts used for building releases and VM images. |
| rescue | Build system for statically linked /rescue commands. |
| sbin | System commands. |
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
index 5173074ee63e..e78b6e1875ae 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
@@ -20,7 +20,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 20, 2026
+.Dd May 7, 2026
.Dt DTRACE 1
.Os
.Sh NAME
@@ -1304,12 +1304,14 @@ in
.Xr dtrace_ip 4 ,
.Xr dtrace_kinst 4 ,
.Xr dtrace_lockstat 4 ,
+.Xr dtrace_mib 4 ,
.Xr dtrace_pid 4 ,
.Xr dtrace_proc 4 ,
.Xr dtrace_priv 4 ,
.Xr dtrace_profile 4 ,
.Xr dtrace_sched 4 ,
.Xr dtrace_sctp 4 ,
+.Xr dtrace_syscall 4 ,
.Xr dtrace_tcp 4 ,
.Xr dtrace_udp 4 ,
.Xr dtrace_udplite 4 ,
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 59783592a370..4e51167b401a 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1929,6 +1929,8 @@ static const struct snl_attr_parser nla_p_skey[] = {
SNL_DECLARE_ATTR_PARSER(skey_parser, nla_p_skey);
#undef _OUT
+SNL_DECLARE_ATTR_PARSER(rule_parser, ap_getrule);
+
#define _IN(_field) offsetof(struct genlmsghdr, _field)
#define _OUT(_field) offsetof(struct pfctl_state, _field)
static struct snl_attr_parser ap_state[] = {
@@ -1963,6 +1965,7 @@ static struct snl_attr_parser ap_state[] = {
{ .type = PF_ST_RT_IFNAME, .off = _OUT(rt_ifname), .cb = snl_attr_store_ifname },
{ .type = PF_ST_SRC_NODE_FLAGS, .off = _OUT(src_node_flags), .cb = snl_attr_get_uint8 },
{ .type = PF_ST_RT_AF, .off = _OUT(rt_af), .cb = snl_attr_get_uint8 },
+ { .type = PF_ST_CREATED_BY_RULE, .off = _OUT(created_by_rule), .arg = &rule_parser, .cb = snl_attr_get_nested },
};
#undef _IN
#undef _OUT
@@ -1988,6 +1991,7 @@ pfctl_get_states_h(struct pfctl_handle *h, struct pfctl_state_filter *filter, pf
snl_add_msg_attr_u8(&nw, PF_ST_AF, filter->af);
snl_add_msg_attr_ip6(&nw, PF_ST_FILTER_ADDR, &filter->addr.v6);
snl_add_msg_attr_ip6(&nw, PF_ST_FILTER_MASK, &filter->mask.v6);
+ snl_add_msg_attr_bool(&nw, PF_ST_INCLUDE_RULE, filter->include_rule);
hdr = snl_finalize_msg(&nw);
if (hdr == NULL)
@@ -2009,7 +2013,7 @@ pfctl_get_states_h(struct pfctl_handle *h, struct pfctl_state_filter *filter, pf
return (ret);
}
- return (0);
+ return (e.error);
}
int
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 1012be53db65..3080209ec7a0 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -406,6 +406,7 @@ struct pfctl_state {
char rt_ifname[IFNAMSIZ];
sa_family_t rt_af;
uint8_t src_node_flags;
+ struct pfctl_rule created_by_rule;
};
TAILQ_HEAD(pfctl_statelist, pfctl_state);
@@ -504,6 +505,7 @@ struct pfctl_state_filter {
sa_family_t af;
struct pf_addr addr;
struct pf_addr mask;
+ bool include_rule;
};
typedef int (*pfctl_get_state_fn)(struct pfctl_state *, void *);
int pfctl_get_states_iter(pfctl_get_state_fn f, void *arg);
diff --git a/lib/libsys/intro.2 b/lib/libsys/intro.2
index 008936b278ae..33dfecf648c5 100644
--- a/lib/libsys/intro.2
+++ b/lib/libsys/intro.2
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 19, 2024
+.Dd May 7, 2026
.Dt INTRO 2
.Os
.Sh NAME
@@ -756,7 +756,8 @@ during a system boot.
.El
.Sh SEE ALSO
.Xr intro 3 ,
-.Xr perror 3
+.Xr perror 3 ,
+.Xr dtrace_syscall 4
.Sh HISTORY
The
.Nm Ns Pq 2
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index 623b56fb273b..46a2ed5eb8a6 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -119,6 +119,13 @@ enum libusb_endpoint_direction {
#define LIBUSB_TRANSFER_TYPE_MASK 0x03
+enum libusb_endpoint_transfer_type {
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_CONTROL = 0,
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_ISOCHRONOUS = 1,
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK = 2,
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT = 3,
+};
+
enum libusb_transfer_type {
LIBUSB_TRANSFER_TYPE_CONTROL = 0,
LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1,
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index b3af017ab980..56c9caedab16 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -1769,14 +1769,14 @@ libusb10_cancel_all_transfer_locked(struct libusb20_device *pdev, struct libusb_
if (sxfer == NULL)
continue;
/* complete pending transfer */
- libusb10_complete_transfer(xfer, sxfer, LIBUSB_TRANSFER_ERROR);
+ libusb10_complete_transfer(xfer, sxfer, LIBUSB_TRANSFER_CANCELLED);
}
while ((sxfer = TAILQ_FIRST(&dev->tr_head))) {
TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
/* complete pending transfer */
- libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_ERROR);
+ libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_CANCELLED);
}
}
diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit
index f7700f7d8e70..a1ebd3f52b25 100755
--- a/libexec/nuageinit/nuageinit
+++ b/libexec/nuageinit/nuageinit
@@ -727,7 +727,7 @@ local function load_userdata()
f:close()
local obj = nil
- if ud then
+ if ud and line == "#cloud-config" then
f = io.open(ni_path .. "/" .. ud)
obj = yaml.load(f:read("*a"))
f:close()
diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh
index 3a01413f8487..1fd68d5a178e 100644
--- a/libexec/nuageinit/tests/nuageinit.sh
+++ b/libexec/nuageinit/tests/nuageinit.sh
@@ -76,10 +76,12 @@ nocloud_userdata_script_body()
{
mkdir -p media/nuageinit
printf "instance-id: iid-local01\n" > "${PWD}"/media/nuageinit/meta-data
- printf "#!/bin/sh\necho yeah\n" > "${PWD}"/media/nuageinit/user-data
- chmod 755 "${PWD}"/media/nuageinit/user-data
+ # ensure this is an invalid when parsed with the yaml parser
+ printf "#!/bin/sh\n: ${test:-yes}\necho $test\n" > "${PWD}"/media/nuageinit/user-data
+ chmod 644 "${PWD}"/media/nuageinit/user-data
atf_check -s exit:0 /usr/libexec/nuageinit "${PWD}"/media/nuageinit nocloud
- atf_check -o inline:"#!/bin/sh\necho yeah\n" cat var/cache/nuageinit/user_data
+ atf_check test -x var/cache/nuageinit/user_data
+ atf_check -o inline:"#!/bin/sh\n: ${test:-yes}\necho $test\n" cat var/cache/nuageinit/user_data
}
nocloud_user_data_script_body()
diff --git a/release/Makefile.vm b/release/Makefile.vm
index d937783f02fe..8296fc47a477 100644
--- a/release/Makefile.vm
+++ b/release/Makefile.vm
@@ -99,9 +99,10 @@ QEMUTGT?=
.if (defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE)) || \
(defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES))
-.if (defined(WITHOUT_QEMU) && !defined(NO_ROOT)) || \
- (!defined(WITHOUT_QEMU) && defined(NO_ROOT))
-.error WITHOUT_QEMU requires NO_ROOT (and vice versa)
+.if (defined(WITHOUT_QEMU) && !defined(NO_ROOT))
+.error WITHOUT_QEMU requires NO_ROOT
+.elif (!defined(WITHOUT_QEMU) && defined(NO_ROOT))
+.error NO_ROOT requires WITHOUT_QEMU
.endif
.endif
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index ee38fbb2ccee..cff50d2f8d80 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -369,7 +369,7 @@ media::do_match(config &c)
retval = false;
- s = socket(PF_INET, SOCK_DGRAM, 0);
+ s = socket(PF_LOCAL, SOCK_DGRAM, 0);
if (s >= 0) {
memset(&ifmr, 0, sizeof(ifmr));
strlcpy(ifmr.ifm_name, value.c_str(), sizeof(ifmr.ifm_name));
diff --git a/sbin/devmatch/devmatch.c b/sbin/devmatch/devmatch.c
index 62bfc2c521ed..6c6c5f3bcf79 100644
--- a/sbin/devmatch/devmatch.c
+++ b/sbin/devmatch/devmatch.c
@@ -102,6 +102,9 @@ read_linker_hints(void)
size_t buflen, len;
if (linker_hints == NULL) {
+ void *all_hints = NULL;
+ size_t all_len = 0;
+
if (sysctlbyname("kern.module_path", NULL, &buflen, NULL, 0) < 0)
errx(1, "Can't find kernel module path.");
modpath = malloc(buflen);
@@ -111,13 +114,39 @@ read_linker_hints(void)
errx(1, "Can't find kernel module path.");
p = modpath;
while ((q = strsep(&p, ";")) != NULL) {
+ void *h;
+
snprintf(fn, sizeof(fn), "%s/linker.hints", q);
- hints = read_hints(fn, &len);
- if (hints == NULL)
+ h = read_hints(fn, &len);
+ if (h == NULL)
continue;
- break;
+ if (len < sizeof(int) ||
+ *(int *)(intptr_t)h != LINKER_HINTS_VERSION) {
+ free(h);
+ continue;
+ }
+ if (all_hints == NULL) {
+ all_hints = h;
+ all_len = len;
+ } else {
+ void *merged;
+
+ merged = realloc(all_hints, all_len + len - sizeof(int));
+ if (merged == NULL) {
+ free(h);
+ continue;
+ }
+ all_hints = merged;
+ memcpy((char *)all_hints + all_len,
+ (char *)h + sizeof(int),
+ len - sizeof(int));
+ all_len += len - sizeof(int);
+ free(h);
+ }
}
- if (q == NULL) {
+ hints = all_hints;
+ len = all_len;
+ if (hints == NULL) {
if (quiet_flag)
exit(EX_UNAVAILABLE);
else
diff --git a/sbin/init/init.8 b/sbin/init/init.8
index 85b1db2ddf06..f562efde0b51 100644
--- a/sbin/init/init.8
+++ b/sbin/init/init.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 22, 2021
+.Dd May 5, 2026
.Dt INIT 8
.Os
.Sh NAME
@@ -396,6 +396,14 @@ back to the default, so that the
.Pa /etc/rc
script is executed with the standard shell
.Pa /bin/sh .
+.It Va init_rc
+If set to a valid file name in the root file system,
+overrides the default path to
+.Xr rc 8
+.Pq Pa /etc/rc .
+This is useful for testing alternative service managers
+without modifying the default
+.Pa /etc/rc .
.It Va init_path
Specifies the path used to search for the init binary.
More than one binary can be listed in the string,
diff --git a/sbin/init/init.c b/sbin/init/init.c
index d28501053c7f..db680c7f73bd 100644
--- a/sbin/init/init.c
+++ b/sbin/init/init.c
@@ -1025,11 +1025,23 @@ static state_func_t
runcom(void)
{
state_func_t next_transition;
+ char runcom_path[PATH_MAX];
+ const char *rc_script;
- BOOTTRACE("/etc/rc starting...");
- if ((next_transition = run_script(_PATH_RUNCOM)) != NULL)
+ /*
+ * Allow overriding /etc/rc via the init_rc kenv variable.
+ * This is useful for testing alternative service managers
+ * without modifying /etc/rc.
+ */
+ if (kenv(KENV_GET, "init_rc", runcom_path, sizeof(runcom_path)) > 0)
+ rc_script = runcom_path;
+ else
+ rc_script = _PATH_RUNCOM;
+
+ BOOTTRACE("%s starting...", rc_script);
+ if ((next_transition = run_script(rc_script)) != NULL)
return next_transition;
- BOOTTRACE("/etc/rc finished");
+ BOOTTRACE("%s finished", rc_script);
runcom_mode = AUTOBOOT; /* the default */
return (state_func_t) read_ttys;
diff --git a/sbin/md5/tests/md5_test.sh b/sbin/md5/tests/md5_test.sh
index 34bdf43f13ea..a7632664c7aa 100644
--- a/sbin/md5/tests/md5_test.sh
+++ b/sbin/md5/tests/md5_test.sh
@@ -176,6 +176,7 @@ out_7_skein1024="cf21a613620e6c119eca31fdfaad449a8e02f95ca256c21d2a105f8e4157048
out_8_skein1024="e6799b78db54085a2be7ff4c8007f147fa88d326abab30be0560b953396d8802feee9a15419b48a467574e9283be15685ca8a079ee52b27166b64dd70b124b1d4e4f6aca37224c3f2685e67e67baef9f94b905698adc794a09672aba977a61b20966912acdb08c21a2c37001785355dc884751a21f848ab36e590331ff938138"
for alg in $algorithms ; do
+ eval "perl=\$name_perl_${alg}" # supported in Perl mode?
eval "
atf_test_case self_test_${alg}
self_test_${alg}_head() {
@@ -228,14 +229,13 @@ gnu_${alg}_vec${i}_body() {
atf_check -o inline:\"\$out_${i}_${alg} -\0\" ${alg}sum -z - <in
}
"
- eval "
+ [ -n "$perl" ] && eval "
atf_test_case perl_${alg}_vec${i}
perl_${alg}_vec${i}_head() {
atf_set descr \"Perl mode \$name_bsd_${alg} test vector ${i}\"
atf_set require.progs \"shasum\"
}
perl_${alg}_vec${i}_body() {
- [ -n \"\$name_perl_${alg}\" ] || atf_skip \"shasum does not support ${alg}\"
printf '%s' \"\$inp_${i}\" >in
atf_check -o inline:\"\$out_${i}_${alg} -\n\" shasum \$alg_perl_${alg} <in
atf_check -o inline:\"\$out_${i}_${alg} *-\n\" shasum \$alg_perl_${alg} -b <in
@@ -281,14 +281,13 @@ gnu_check_${alg}_body() {
atf_check -s exit:$rv ${alg}sum --check --status digests
}
"
- eval "
+ [ -n "$perl" ] && eval "
atf_test_case perl_check_${alg}
perl_check_${alg}_head() {
atf_set descr \"Perl mode check test for \$name_bsd_${alg}\"
atf_set require.progs \"shasum\"
}
perl_check_${alg}_body() {
- [ -n \"\$name_perl_${alg}\" ] || atf_skip \"shasum does not support ${alg}\"
:>digests
:>stdout
:>stderr
@@ -394,14 +393,15 @@ EOF
atf_init_test_cases()
{
for alg in $algorithms ; do
+ eval "perl=\$name_perl_${alg}" # supported in Perl mode?
atf_add_test_case self_test_${alg}
for i in $(seq $n) ; do
atf_add_test_case bsd_${alg}_vec${i}
atf_add_test_case gnu_${alg}_vec${i}
- atf_add_test_case perl_${alg}_vec${i}
+ [ -n "$perl" ] && atf_add_test_case perl_${alg}_vec${i}
done
atf_add_test_case gnu_check_${alg}
- atf_add_test_case perl_check_${alg}
+ [ -n "$perl" ] && atf_add_test_case perl_check_${alg}
done
atf_add_test_case gnu_bflag
atf_add_test_case gnu_cflag
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 57a5140ffeb7..7e9d81da6ed9 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -4242,7 +4242,7 @@ dynaddr : '(' STRING ')' {
char *p, *op;
op = $2;
- if (!isalpha(op[0])) {
+ if (op[0] == '\0') {
yyerror("invalid interface name '%s'", op);
free(op);
YYERROR;
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
index 1c5a46f86b35..9b0c57fd73d3 100644
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -434,6 +434,10 @@ print_state(struct pfctl_state *s, int opts)
if (strcmp(s->ifname, s->orig_ifname) != 0)
printf(" origif: %s\n", s->orig_ifname);
+
+ printf(" rule: ");
+ print_rule(&s->created_by_rule, "", 0, 0);
+ printf("\n");
}
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index e84e7f9272d4..c349487ed9d2 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1991,16 +1991,20 @@ pfctl_show_states(int dev, const char *iface, int opts)
{
struct pfctl_show_state_arg arg;
struct pfctl_state_filter filter = {};
+ int ret;
if (iface != NULL)
strlcpy(filter.ifname, iface, IFNAMSIZ);
+ if (opts & PF_OPT_VERBOSE2)
+ filter.include_rule = true;
+
arg.opts = opts;
arg.dotitle = opts & PF_OPT_SHOWALL;
arg.iface = iface;
- if (pfctl_get_states_h(pfh, &filter, pfctl_show_state, &arg))
- return (-1);
+ if ((ret = pfctl_get_states_h(pfh, &filter, pfctl_show_state, &arg)) != 0)
+ errc(1, ret, "pfctl_get_states");
return (0);
}
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8
index e0e35f075a78..b97bce320898 100644
--- a/sbin/sysctl/sysctl.8
+++ b/sbin/sysctl/sysctl.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 31, 2025
+.Dd May 7, 2026
.Dt SYSCTL 8
.Os
.Sh NAME
@@ -336,6 +336,7 @@ The
option has been deprecated and is silently ignored.
.Sh SEE ALSO
.Xr sysctl 3 ,
+.Xr dtrace_mib 4 ,
.Xr loader.conf 5 ,
.Xr sysctl.conf 5 ,
.Xr security 7 ,
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 60ab6e8bdab6..b9c441e97597 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -1023,12 +1023,14 @@ _dtrace_provs= dtrace_audit.4 \
dtrace_ip.4 \
dtrace_kinst.4 \
dtrace_lockstat.4 \
+ dtrace_mib.4 \
dtrace_pid.4 \
dtrace_priv.4 \
dtrace_proc.4 \
dtrace_profile.4 \
dtrace_sched.4 \
dtrace_sctp.4 \
+ dtrace_syscall.4 \
dtrace_tcp.4 \
dtrace_udp.4 \
dtrace_udplite.4 \
diff --git a/share/man/man4/dtrace_cam.4 b/share/man/man4/dtrace_cam.4
index e5b7ae34c391..8e2790e72d22 100644
--- a/share/man/man4/dtrace_cam.4
+++ b/share/man/man4/dtrace_cam.4
@@ -2,7 +2,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd December 26, 2025
+.Dd May 7, 2026
.Dt DTRACE_CAM 4
.Os
.Sh NAME
@@ -25,11 +25,9 @@ probe fires when that request completes.
The
.Fn cam::xpt:async-cb
probe fires just before an async callback is called.
-.Sh ARGUMENTS
-.Sh FILES
-.Sh EXAMPLES
.Sh SEE ALSO
.Xr dtrace 1 ,
+.Xr cam 4 ,
.Xr SDT 9
.Sh HISTORY
The
diff --git a/share/man/man4/dtrace_ip.4 b/share/man/man4/dtrace_ip.4
index e9fbdfa3cf43..6faeb305ffc5 100644
--- a/share/man/man4/dtrace_ip.4
+++ b/share/man/man4/dtrace_ip.4
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 14, 2015
+.Dd May 7, 2026
.Dt DTRACE_IP 4
.Os
.Sh NAME
@@ -266,6 +266,7 @@ This provider is compatible with the
providers found in Solaris and Darwin.
.Sh SEE ALSO
.Xr dtrace 1 ,
+.Xr dtrace_mib 4 ,
.Xr dtrace_tcp 4 ,
.Xr dtrace_udp 4 ,
.Xr ip 4 ,
diff --git a/share/man/man4/dtrace_mib.4 b/share/man/man4/dtrace_mib.4
new file mode 100644
index 000000000000..e8c2dd3a6f05
--- /dev/null
+++ b/share/man/man4/dtrace_mib.4
@@ -0,0 +1,123 @@
+.\"
+.\" Copyright (c) 2025-2026 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd May 7, 2026
+.Dt DTRACE_MIB 4
+.Os
+.Sh NAME
+.Nm dtrace_mib
+.Nd a DTrace provider for Management Information Base
+.Sh SYNOPSIS
+.Cm mib: Ns Ar module Ns Cm \&:count: Ns Ar counter
+.Pp
+In
+.Xr config 5 :
+.Cd "options KDTRACE_MIB_SDT"
+.Sh DESCRIPTION
+The
+.Nm mib
+provider allows tracing of Management Information Base stats counters.
+.Pp
+The list of instrumented
+.Ar module Ns s
+includes:
+.Bl -tag -offset indent -width ipcomp -compact
+.It Cm ah
+IP Authentication Header (RFC 2402),
+.Xr ipsec 4
+.It Cm esp
+IP Encapsulating Security Payload (RFC 1827, RFC 2406),
+.Xr ipsec 4
+.It Cm icmp
+.Xr icmp 4
+.It Cm icmp6
+.Xr icmp6 4
+.It Cm ip
+.Xr ip 4
+.It Cm ip6
+.Xr ip6 4
+.It Cm ipcomp
+IP Payload Compression Protocol,
+.Xr ipsec 4
+.It Cm ipsec
+.Xr ipsec 4
+.It Cm tcp
+.Xr tcp 4
+.It Cm udp
+.Xr udp 4
+.El
+.Pp
+The
+.Cm mib: Ns Ar module Ns Cm \&:count: Ns Ar counter
+probes fire when the
+.Ar counter
+in
+.Ar module Ns s
+increases.
+.Pp
+The first probe argument,
+.Vt uint64_t Va args[0] ,
+is the increment that the
+.Ar counter
+will increase by.
+.Pp
+Note that some probes like
+.Cm mib:esp:count:esps_hist
+or
+.Cm mib:icmp6:count:icp6s_outhist
+provide additional probe-specific arguments.
+.Sh EXAMPLES
+.Ss Example 1 : Tracing IP Stats Counters
+When debugging network issues one common clue is an unexpectedly
+incrementing error counter.
+This is helpful, in that it gives us an
+idea of what might be going wrong, but often these counters may be
+incremented in different functions.
+.Pp
+Trace all
+.Nm mib
+probes in the
+.Xr ip 4
+module and print the current count and a stack trace:
+.Pp
+.Bd -literal -offset 2n
+# dtrace -n 'mib:ip:count: { printf("%d", arg0); stack(); }'
+dtrace: description 'mib:ip:count: ' matched 29 probes
+CPU ID FUNCTION:NAME
+ 7 98784 count:ips_localout 1
+ kernel`ip_output+0x17a2
+ kernel`udp_send+0xaca
+ kernel`sosend_dgram+0x315
+ kernel`sousrsend+0x79
+ kernel`kern_sendit+0x1be
+ kernel`sendit+0x1ab
+ kernel`sys_sendmsg+0x5b
+ kernel`amd64_syscall+0x169
+ kernel`0xffffffff81094b8b
+.Ed
+.Sh SEE ALSO
+.Xr dtrace 1 ,
+.Xr dtrace_ip 4 ,
+.Xr dtrace_tcp 4 ,
+.Xr dtrace_udp 4 ,
+.Xr tracing 7 ,
+.Xr sysctl 8
+.Sh STANDARDS
+The probe descriptions in
+the
+.Fx
+.Nm mib
+provider are not compatible with those in the Solaris/illumos mib provider.
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm mib
+provider was added to
+.Fx
+by
+.An Kristof Provost Aq Mt kp@FreeBSD.org .
+.Pp
+This manual page was written by
+.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .
diff --git a/share/man/man4/dtrace_syscall.4 b/share/man/man4/dtrace_syscall.4
new file mode 100644
index 000000000000..e154e4c6046b
--- /dev/null
+++ b/share/man/man4/dtrace_syscall.4
@@ -0,0 +1,87 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2026 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\"
+.Dd May 7, 2026
+.Dt DTRACE_SYSCALL 4
+.Os
+.Sh NAME
+.Nm dtrace_syscall
+.Nd a DTrace provider for system calls
+.Sh SYNOPSIS
+.Nm syscall Ns Cm \&: Ns Ar abi Ns Cm \&: Ns Ar syscall Ns Cm :entry
+.Nm syscall Ns Cm \&: Ns Ar abi Ns Cm \&: Ns Ar syscall Ns Cm :return
+.Sh DESCRIPTION
+The
+.Nm syscall
+provider provides entry and return probes for system calls.
+.Pp
+The module in the probe's description is
+.Ar abi ,
+which indicates what system call ABI a
+.Ar syscall
+belongs to.
+.Nm
+supports the following system call ABIs:
+.Pp
+.Bl -tag -offset indent -width freebsd32 -compact
+.It Cm freebsd
+Native ABI.
+.It Cm freebsd32
+Non-native, 32-bit ABI.
+.It Cm linux
+Refer to
+.Xr linux 4 .
+.It Cm linux32
+Refer to
+.Xr linux 4 .
+.El
+.Pp
+The arguments to the
+.Cm entry
+probes are the arguments passed to the system call.
+.Pp
+The
+.Cm return
+probe stores the system call's return value in both
+.Fa arg0
+and
+.Fa arg1 .
+.Pp
+Inspect the
+.Xr d 7 Ap s
+.Va errno
+variable to check if a system call failed.
+.Sh EXAMPLES
+.Ss Example 1 : Count Up System Calls
+The following script traces all system calls and counts them for every process
+on the system.
+.Bd -literal -offset 2n
+syscall:::entry {
+ @[execname, pid] = count();
+}
+.Ed
+.Sh SEE ALSO
+.Xr dtrace 1 ,
+.Xr intro 2 ,
+.Xr tracing 7
+.Rs
+.%B The illumos Dynamic Tracing Guide
+.%O Chapter syscall Provider
+.%D 2008
+.%U https://illumos.org/books/dtrace/chp-syscall.html
+.Re
+.Rs
+.%A Brendan Gregg
+.%A Jim Mauro
+.%B DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD
+.%I Prentice Hall
+.%O Chapter Syscall Provider
+.%P pp. 315\(en327
+.%D 2011
+.%U https://www.brendangregg.com/dtracebook/
+.Re
+.Sh AUTHORS
+This manual page was written by
+.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .
diff --git a/share/man/man4/dtrace_tcp.4 b/share/man/man4/dtrace_tcp.4
index af57f6e94a63..5570dd965706 100644
--- a/share/man/man4/dtrace_tcp.4
+++ b/share/man/man4/dtrace_tcp.4
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 2, 2023
+.Dd May 7, 2026
.Dt DTRACE_TCP 4
.Os
.Sh NAME
@@ -501,6 +501,7 @@ provider in Solaris.
.Sh SEE ALSO
.Xr dtrace 1 ,
.Xr dtrace_ip 4 ,
+.Xr dtrace_mib 4 ,
.Xr dtrace_sctp 4 ,
.Xr dtrace_udp 4 ,
.Xr dtrace_udplite 4 ,
diff --git a/share/man/man4/icmp.4 b/share/man/man4/icmp.4
index c8c92a794e24..493d2d218cec 100644
--- a/share/man/man4/icmp.4
+++ b/share/man/man4/icmp.4
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 11, 2024
+.Dd May 7, 2026
.Dt ICMP 4
.Os
.Sh NAME
@@ -264,6 +264,7 @@ exists.
.Xr recv 2 ,
.Xr send 2 ,
.Xr sysctl 3 ,
+.Xr dtrace_mib 4 ,
.Xr inet 4 ,
.Xr intro 4 ,
.Xr ip 4 ,
diff --git a/share/man/man4/icmp6.4 b/share/man/man4/icmp6.4
index 8730e3fefacb..d9a8bd34a81a 100644
--- a/share/man/man4/icmp6.4
+++ b/share/man/man4/icmp6.4
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 1, 2018
+.Dd May 7, 2026
.Dt ICMP6 4
.Os
.Sh NAME
@@ -243,6 +243,7 @@ structure as the option value.
.Xr setsockopt 2 ,
.Xr socket 2 ,
.Xr getprotobyname 3 ,
+.Xr dtrace_mib 4 ,
.Xr inet6 4 ,
.Xr ip6 4 ,
.Xr netintro 4
diff --git a/share/man/man4/ifmib.4 b/share/man/man4/ifmib.4
index 20b5613b6873..48e79c1f9411 100644
--- a/share/man/man4/ifmib.4
+++ b/share/man/man4/ifmib.4
@@ -25,7 +25,7 @@
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 26, 2020
+.Dd May 7, 2026
.Dt IFMIB 4
.Os
.Sh NAME
@@ -165,6 +165,7 @@ and implements a superset of the
MIB for Ethernet-like networks.
.Sh SEE ALSO
.Xr sysctl 3 ,
+.Xr dtrace_mib 4 ,
.Xr intro 4 ,
.Xr ifnet 9
.\" .Xr ethermib 4 ,
diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4
index fb5ea398c840..140866f6fcf6 100644
--- a/share/man/man4/ip.4
+++ b/share/man/man4/ip.4
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 9, 2021
+.Dd May 7, 2026
.Dt IP 4
.Os
.Sh NAME
@@ -907,6 +907,7 @@ field was not equal to the length of the datagram written to the socket.
.Xr byteorder 3 ,
.Xr CMSG_DATA 3 ,
.Xr sourcefilter 3 ,
+.Xr dtrace_mib 4 ,
.Xr icmp 4 ,
.Xr igmp 4 ,
.Xr inet 4 ,
diff --git a/share/man/man4/ipsec.4 b/share/man/man4/ipsec.4
index 9fd6207c2f14..0c60e0e3c121 100644
--- a/share/man/man4/ipsec.4
+++ b/share/man/man4/ipsec.4
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 4, 2025
+.Dd May 7, 2026
.Dt IPSEC 4
.Os
.Sh NAME
@@ -336,6 +336,7 @@ routines from looking into the IP payload.
.Xr socket 2 ,
.Xr ipsec_set_policy 3 ,
.Xr crypto 4 ,
+.Xr dtrace_mib 4 ,
.Xr enc 4 ,
.Xr icmp6 4 ,
.Xr if_ipsec 4 ,
diff --git a/share/man/man4/linux.4 b/share/man/man4/linux.4
index 711ac11e8fce..ec8342efe705 100644
--- a/share/man/man4/linux.4
+++ b/share/man/man4/linux.4
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 19, 2024
+.Dd May 7, 2026
.Dt LINUX 4
.Os
.Sh NAME
@@ -179,6 +179,7 @@ Linux kernel objects file system, see
.El
.Sh SEE ALSO
.Xr brandelf 1 ,
+.Xr dtrace_syscall 4 ,
.Xr fdescfs 4 ,
.Xr linprocfs 4 ,
.Xr linsysfs 4 ,
diff --git a/share/man/man4/scsi.4 b/share/man/man4/scsi.4
index e66fccf53e64..b6390fec646e 100644
--- a/share/man/man4/scsi.4
+++ b/share/man/man4/scsi.4
@@ -22,7 +22,7 @@
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
-.Dd December 11, 2025
+.Dd May 7, 2026
.Dt CAM 4
.Os
.Sh NAME
@@ -530,6 +530,8 @@ for details.
.\" .Xr ps3cdrom 4 ,
.Xr sbp 4 ,
.Xr twa 4
+.It Sy DTrace Providers:
+.Xr dtrace_cam 4
.El
.Sh HISTORY
The
diff --git a/share/man/man4/smartpqi.4 b/share/man/man4/smartpqi.4
index ef5f903fe422..ae85e184114d 100644
--- a/share/man/man4/smartpqi.4
+++ b/share/man/man4/smartpqi.4
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2019-2025, Microchip Technology Inc. and its subsidiaries
+.\" Copyright (C) 2019-2026, Microchip Technology Inc. and its subsidiaries
.\" Copyright (C) 2016-2018, Microsemi Corporation
.\" Copyright (C) 2016, PMC-Sierra, Inc.
.\" Written by John Hall <john.hall@microchip.com>
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 28, 2025
+.Dd April 14, 2026
.Dt SMARTPQI 4 amd64
.Os
.Sh NAME
@@ -64,11 +64,13 @@ OEM Controllers based on the Microchip Technology Inc. SmartROC
and SmartIOC Chipsets
.El
.Sh DEBUGGING
-Driver diagnostic printing is controlled in
+Driver diagnostic printing is controlled at boot time in
.Xr loader.conf 5
by using the global
.Va hw.smartpqi.debug_level
-tunable.
+tunable, or at runtime via the per-controller
+.Va dev.smartpqi.<unit>.debug_level
+sysctl.
.Pp
The
.Va debug_level
@@ -82,11 +84,27 @@ The following levels are available:
.It 0x0002 Ta info Ta Basic information
.It 0x0004 Ta function Ta Used to show function entry and exit
.It 0x0008 Ta io Ta Logging data from controller
-.It 0x0010 Ta discovery Ta Device discovery
+.It 0x0010 Ta discovery Ta Device discovery state transitions
.It 0x0020 Ta warning Ta Operational warnings
.It 0x0040 Ta error Ta Parameter errors and programming bugs
.It 0x0080 Ta note Ta More detailed information
.El
+.Pp
+In addition to the level-gated debug output, the driver always logs
+device addition, device removal, and controller events
+(hotplug, hardware, physical/logical device changes, AIO state and
+configuration changes) via
+.Xr device_printf 9 ,
+which appear in
+.Xr dmesg 8
+regardless of the
+.Va debug_level
+setting.
+.Pp
+For example, to enable discovery logging at runtime on the first controller:
+.Bd -literal -offset indent
+sysctl dev.smartpqi.0.debug_level=0x0070
+.Ed
.Sh DEVICE HINTS
The following tunable values can be set in
.Pa /boot/device.hints
@@ -162,7 +180,9 @@ https://www.microchip.com/design-centers/storage
.Xr xpt 4 ,
.Xr loader.conf 5 ,
.Xr camcontrol 8 ,
-.Xr kldload 8
+.Xr dmesg 8 ,
+.Xr kldload 8 ,
+.Xr sysctl 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4
index 3c9f4ff83f3d..4c01daf4e14e 100644
--- a/share/man/man4/tcp.4
+++ b/share/man/man4/tcp.4
@@ -31,7 +31,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 5, 2025
+.Dd May 7, 2026
.Dt TCP 4
.Os
.Sh NAME
@@ -1098,6 +1098,7 @@ when trying to use a TCP function block that is not available;
.Xr stats 3 ,
.Xr sysctl 3 ,
.Xr blackhole 4 ,
+.Xr dtrace_mib 4 ,
.Xr inet 4 ,
.Xr intro 4 ,
.Xr ip 4 ,
diff --git a/share/man/man4/udp.4 b/share/man/man4/udp.4
index b1dbff56154f..db9d0e0ae2c7 100644
--- a/share/man/man4/udp.4
+++ b/share/man/man4/udp.4
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 20, 2025
+.Dd May 7, 2026
.Dt UDP 4
.Os
.Sh NAME
@@ -175,6 +175,7 @@ exists.
.Xr send 2 ,
.Xr socket 2 ,
.Xr blackhole 4 ,
+.Xr dtrace_mib 4 ,
.Xr inet 4 ,
.Xr intro 4 ,
.Xr ip 4 ,
diff --git a/share/man/man7/d.7 b/share/man/man7/d.7
index 59b3389b121b..792f6d36ce73 100644
--- a/share/man/man7/d.7
+++ b/share/man/man7/d.7
@@ -1,9 +1,9 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org>
+.\" Copyright (c) 2025-2026 Mateusz Piotrowski <0mp@FreeBSD.org>
.\"
-.Dd October 28, 2025
+.Dd May 7, 2026
.Dt D 7
.Os
.Sh NAME
@@ -39,6 +39,41 @@ This manual page serves as a short reference of the language.
Refer to books listed in
.Sx SEE ALSO
for a complete reference.
+.Sh MACRO VARIABLES
+.Bl -column "$1, $2, $3, ..." "Syntax"
+.It Sy Name Ta Sy Description
+.It Va $1 , $2 , $3 , .\&.\&. Ta Macro arguments
+.It Va $egid Ta Effective group ID Pq Xr getegid 2
+.It Va $euid Ta Effective user ID Pq Xr geteuid 2
+.It Va $gid Ta Real group ID Pq Xr getgid 2
+.It Va $pid Ta Process ID Pq Xr getpid 2
+.It Va $pgid Ta Process group ID Pq Xr getpgrp 2
+.It Va $ppid Ta Parent process ID Pq Xr getppid 2
+.It Va $sid Ta Session ID Pq Xr getsid 2
+.It Va $target Ta Target process ID of the process
+specified via the
+.Fl p
+flag or created via the
+.Fl c
+flag.
+.It Va $uid Ta Real user ID Pq Xr getuid 2
+.El
+.Pp
+The macro arguments correspond to the command-line operands.
+They expand to an integer, identifier, or string depending on the context.
+Prepending a macro argument with an extra dollar sign
+.Pq Ql $
+forces string expansion.
+.Pp
+For example,
+.Bd -literal -compact -offset indent
+dtrace -n 'syscall::fstatat: /execname == $$1/ {}' -- ls
+.Ed
+uses
+.Va $$1
+instead of
+.Va $1
+to expand to a string instead rather than to a global variable identifier.
.Sh PROBE'S DESCRIPTION
A probe's description consists of four elements:
.Sm off
@@ -411,3 +446,10 @@ variable which typically provides the current working directory is
not supported on
.Fx
at the moment.
+.Pp
+Macro variables
+.Va $projid
+and
+.Va $taskid
+are always 0 on
+.Fx .
diff --git a/share/man/man7/freebsd-base.7 b/share/man/man7/freebsd-base.7
index 51de679ea9d1..b23d1ae44d34 100644
--- a/share/man/man7/freebsd-base.7
+++ b/share/man/man7/freebsd-base.7
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd April 14, 2026
+.Dd April 23, 2026
.Dt FREEBSD-BASE 7
.Os
.Sh NAME
@@ -50,7 +50,7 @@ and
.Dq CURRENT
.\" re@ will provide their own repository before release, at which
.\" point this text will need updating.
-branches are hosted on the Internet at
+branches are hosted on the Internet at
.Lk https://pkg.freebsd.org .
These packages are updated when new errata or security updates are
released (for supported release versions), or twice daily for
@@ -92,7 +92,8 @@ option was enabled when building the system, which is not the default.
.El
.Pp
The exact set of available subpackages differs for each individual
-package. For example, some packages may not provide any development
+package.
+For example, some packages may not provide any development
files, in which case the
.Sy -dev
subpackage is not present.
@@ -217,6 +218,27 @@ for a different target than the host system):
pkg -r /ppcdev -oABI=FreeBSD:16:powerpc64le \e
install FreeBSD-set-devel
.Ed
+.Ss Adding a locally built repository for snapshots
+Disable the predefined repository,
+and add a local repo for locally built base system packages:
+.Bd -literal -offset indent
+cat << EOF > /usr/local/etc/pkg/repos/FreeBSD.conf
+FreeBSD-base: { enabled: no }
+FreeBSD-local: {
+ url: "file:///usr/obj/usr/src/repo/${ABI}/latest",
+ enabled: yes
+}
+EOF
+.Ed
+.Pp
+The packages are created by the
+.Xr build 7
+system at
+.Pa ${REPODIR}/${PKG_ABI}/<VERSION> ,
+which defaults to the example directory.
+.Pp
+.Sy Note :
+The repo must have a different name than the predefined repository.
.Ss Unregister a currently running system
Systems managed through
.Xr pkg 8
diff --git a/share/man/man7/stats.7 b/share/man/man7/stats.7
index 0b57d525522c..f81c2fef0155 100644
--- a/share/man/man7/stats.7
+++ b/share/man/man7/stats.7
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 28, 2025
+.Dd May 7, 2026
.Dt STATS 7
.Os
.Sh NAME
@@ -44,6 +44,8 @@ are currently included in the base system, with more appearing periodically.
Show Bluetooth socket information
.It Nm ctlstat
CAM Target Layer statistics utility
+.It Nm dtrace_mib
+Access the MIB stats counters with DTrace
.It Nm dwatch
Watch processes as they trigger a particular DTrace probe
.It Nm fstat
@@ -99,6 +101,7 @@ Report ZFS I/O statistics
.Xr sockstat 1 ,
.Xr stat 1 ,
.Xr systat 1 ,
+.Xr dtrace_mib 4 ,
.Xr intro 7 ,
.Xr tuning 7 ,
.Xr ctlstat 8 ,
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 29c822c10eb2..fbb981891ce4 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -2333,6 +2333,7 @@ MLINKS+=uidinfo.9 uifind.9 \
uidinfo.9 uihold.9
MLINKS+=uio.9 uiomove.9 \
uio.9 uiomove_frombuf.9 \
+ uio.9 uiomove_fromphys.9 \
uio.9 uiomove_nofault.9
MLINKS+=unr.9 alloc_unr.9 \
unr.9 alloc_unrl.9 \
diff --git a/share/man/man9/cdefs.9 b/share/man/man9/cdefs.9
index cc56e34d070a..2bda50c3f875 100644
--- a/share/man/man9/cdefs.9
+++ b/share/man/man9/cdefs.9
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd May 9, 2025
+.Dd May 6, 2026
.Dt CDEFS 9
.Os
.Sh NAME
@@ -85,7 +85,9 @@ linkage.
.It Sy __weak_symbol Ta Declare the symbol to be a weak symbol
.It Sy __dead2 Ta Function will not return
.It Sy __pure2 Ta Function has no side effects
-.It Sy __unused Ta To Variable may be unused (usually arguments), so do not
+.It Sy __unused Ta Variable may be unused (usually arguments), so do not
+warn about it
+.It Sy __maybe_unused Ta Variable may be unused (usually arguments), so do not
warn about it
.It Sy __used Ta Function really is used, so emit it even if it appears unused.
.It Sy __deprecated Ta Function interface has been deprecated, and clients
diff --git a/share/man/man9/uio.9 b/share/man/man9/uio.9
index b143eb6e8e62..a7563125a351 100644
--- a/share/man/man9/uio.9
+++ b/share/man/man9/uio.9
@@ -23,13 +23,14 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 22, 2025
+.Dd May 7, 2026
.Dt UIO 9
.Os
.Sh NAME
.Nm uio ,
.Nm uiomove ,
.Nm uiomove_frombuf ,
+.Nm uiomove_fromphys ,
.Nm uiomove_nofault
.Nd device driver I/O routines
.Sh SYNOPSIS
@@ -37,25 +38,29 @@
.In sys/uio.h
.Bd -literal
struct uio {
- struct iovec *uio_iov; /* scatter/gather list */
- int uio_iovcnt; /* length of scatter/gather list */
- off_t uio_offset; /* offset in target object */
- ssize_t uio_resid; /* remaining bytes to copy */
- enum uio_seg uio_segflg; /* address space */
- enum uio_rw uio_rw; /* operation */
- struct thread *uio_td; /* owner */
+ struct iovec *uio_iov; /* scatter/gather list */
+ int uio_iovcnt; /* length of scatter/gather list */
+ off_t uio_offset; /* offset in target object */
+ ssize_t uio_resid; /* remaining bytes to process */
+ enum uio_seg uio_segflg; /* address space */
+ enum uio_rw uio_rw; /* operation */
+ struct thread *uio_td; /* owner */
};
.Ed
+.Pp
.Ft int
.Fn uiomove "void *buf" "int howmuch" "struct uio *uiop"
.Ft int
.Fn uiomove_frombuf "void *buf" "int howmuch" "struct uio *uiop"
.Ft int
+.Fn uiomove_fromphys "vm_page_t ma[]" "vm_offset_t offset" "int howmuch" "struct uio *uiop"
+.Ft int
.Fn uiomove_nofault "void *buf" "int howmuch" "struct uio *uiop"
.Sh DESCRIPTION
The functions
.Fn uiomove ,
.Fn uiomove_frombuf ,
+.Fn uiomove_fromphys ,
and
.Fn uiomove_nofault
are used to transfer data between buffers and I/O vectors that might
@@ -152,10 +157,27 @@ When
.Va uio_offset
is greater than or equal to the buffer size, the result is success
with no bytes transferred, effectively signaling EOF.
+.Pp
+The
+.Fn uiomove_fromphys
+function provides a machine-independent way to copy memory
+to and from the physical address space.
+The
+.Fa "ma[]"
+argument is an array of physical pages.
+Every physical page address in the array provides
+a page-sized chunk of the physical space.
+The
+.Fa "offset"
+argument is the offset into the
+.Fa "ma[]"
+array.
+In particular, the offset does not have to lie within the first page.
.Sh RETURN VALUES
On success
.Fn uiomove ,
.Fn uiomove_frombuf ,
+.Fn uiomove_fromphys ,
and
.Fn uiomove_nofault
will return 0; on error they will return an appropriate error code.
@@ -168,7 +190,7 @@ will not work (the buffer pointer is not being advanced in case of a
partial read), it is just here to demonstrate the
.Nm
handling.
-.Bd -literal
+.Bd -literal -offset 2n
/* MIN() can be found there: */
#include <sys/param.h>
@@ -200,7 +222,8 @@ fooread(struct cdev *dev, struct uio *uio, int flag)
}
.Ed
.Sh ERRORS
-.Fn uiomove
+.Fn uiomove ,
+.Fn uiomove_fromphys
and
.Fn uiomove_nofault
will fail and return the following error code if:
@@ -211,7 +234,7 @@ The invoked
or
.Xr copyout 9
returned
-.Er EFAULT
+.Er EFAULT .
.El
.Pp
In addition,
diff --git a/stand/libsa/zfs/Makefile.inc b/stand/libsa/zfs/Makefile.inc
index 3df6779559c9..540635d144ef 100644
--- a/stand/libsa/zfs/Makefile.inc
+++ b/stand/libsa/zfs/Makefile.inc
@@ -75,9 +75,13 @@ CFLAGS.zfs.c+= -DHAS_ZSTD_ZFS \
#
# ZSTD coding style has some issues, so suppress clang's warnings. Also, zstd's
# use of BMI instrucitons is broken in this environment, so avoid them.
+# Avoid generating the DYNAMIC_BMI2 code paths because the code duplication
+# inflates the resulting binaries. Disable ZSTD_TRACE because we don't need it
+# and the bfd linker trips over the weak undefined symbols it generates.
#
.for i in ${ZSTD_SRC}
-CFLAGS.$i+= -U__BMI__ ${NO_WBITWISE_INSTEAD_OF_LOGICAL}
+CFLAGS.$i+= -U__BMI__ -DDYNAMIC_BMI2=0 -DZSTD_TRACE=0 \
+ ${NO_WBITWISE_INSTEAD_OF_LOGICAL}
.endfor
CFLAGS.zfs_zstd.c+= -DIN_BASE -DIN_LIBSA
diff --git a/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h b/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h
index 42908bb6c2b5..159c833802c5 100644
--- a/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h
+++ b/sys/compat/linuxkpi/common/include/linux/compiler_attributes.h
@@ -39,7 +39,6 @@
#define noinline_for_stack __noinline
-#define __maybe_unused __unused
#define __always_unused __unused
#define __must_check __result_use_check
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index a5b21cdbe843..d1556660094a 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -157,11 +157,9 @@ NORMAL_FWO= ${CC:N${CCACHE_BIN}} -c ${ASM_CFLAGS} ${WERROR} -o ${.TARGET} \
NOSAN_C= ${NORMAL_C:N-fsanitize*:N-fno-sanitize*:N-fasan-shadow-offset*}
# for ZSTD in the kernel (include zstd/lib/freebsd before other CFLAGS)
-ZSTD_C= ${CC} -c -I$S/contrib/zstd/lib/freebsd ${CFLAGS} \
+ZSTD_C= ${CC} -c -DZSTD_HEAPMODE=1 -I$S/contrib/zstd/lib/freebsd ${CFLAGS} \
-I$S/contrib/zstd/lib -I$S/contrib/zstd/lib/common ${WERROR} \
- -Wno-missing-prototypes -U__BMI__ \
- -DZSTD_HEAPMODE=1 -DZSTD_NO_INTRINSICS -DZSTD_NO_TRACE \
- ${.IMPSRC}
+ -Wno-missing-prototypes -U__BMI__ -DZSTD_NO_INTRINSICS ${.IMPSRC}
# https://github.com/facebook/zstd/commit/812e8f2a [zstd 1.4.1]
# "Note that [GCC] autovectorization still does not do a good job on the
# optimized version, so it's turned off via attribute and flag. I found
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 f4e70c31c4cd..e63aece389c0 100755
--- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
+++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh
@@ -88,6 +88,11 @@ case "$OS" in
OSv="fedora-unknown"
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2"
;;
+ fedora44)
+ OSNAME="Fedora 44"
+ OSv="fedora-unknown"
+ URL="https://download.fedoraproject.org/pub/fedora/linux/releases/44/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-44-1.7.x86_64.qcow2"
+ ;;
freebsd13-5r)
FreeBSD="13.5-RELEASE"
OSNAME="FreeBSD $FreeBSD"
@@ -103,6 +108,13 @@ case "$OS" in
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
;;
+ freebsd15-0r)
+ FreeBSD="15.0-RELEASE"
+ OSNAME="FreeBSD $FreeBSD"
+ OSv="freebsd15.0"
+ URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
+ KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
+ ;;
freebsd13-5s)
FreeBSD="13.5-STABLE"
OSNAME="FreeBSD $FreeBSD"
@@ -118,8 +130,8 @@ case "$OS" in
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
;;
- freebsd15-0s)
- FreeBSD="15.0-STABLE"
+ freebsd15-1s)
+ FreeBSD="15.1-PRERELEASE"
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/.github/workflows/zfs-qemu-packages.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml
index 88d85a06d975..c3a7397c6aef 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml
@@ -58,7 +58,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora42', 'fedora43']
+ os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora42', 'fedora43', 'fedora44']
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
index f83b319a331f..4b4fd27543fd 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml
@@ -46,17 +46,17 @@ jobs:
case "$ci_type" in
quick)
- os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-0s", "ubuntu24"]'
+ os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-1s", "ubuntu24"]'
;;
linux)
- os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora42", "fedora43", "ubuntu22", "ubuntu24"]'
+ os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora42", "fedora43", "fedora44", "ubuntu22", "ubuntu24"]'
;;
freebsd)
- os_selection='["freebsd13-5r", "freebsd14-4r", "freebsd13-5s", "freebsd14-4s", "freebsd15-0s", "freebsd16-0c"]'
+ os_selection='["freebsd13-5r", "freebsd14-4r", "freebsd13-5s", "freebsd14-4s", "freebsd15-1s", "freebsd16-0c"]'
;;
*)
# default list
- os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "freebsd14-4r", "freebsd15-0s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
+ os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "fedora44", "freebsd14-4r", "freebsd15-1s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
;;
esac
@@ -99,7 +99,7 @@ jobs:
# misc: archlinux, tumbleweed
# FreeBSD variants of november 2025:
# FreeBSD Release: freebsd13-5r, freebsd14-4r, freebsd15-0r
- # FreeBSD Stable: freebsd13-5s, freebsd14-4s, freebsd15-0s
+ # FreeBSD Stable: freebsd13-5s, freebsd14-4s, freebsd15-1s
# FreeBSD Current: freebsd16-0c
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
runs-on: ubuntu-24.04
diff --git a/sys/contrib/openzfs/cmd/zed/zed_event.c b/sys/contrib/openzfs/cmd/zed/zed_event.c
index ba7cba304b1d..e252e0999c18 100644
--- a/sys/contrib/openzfs/cmd/zed/zed_event.c
+++ b/sys/contrib/openzfs/cmd/zed/zed_event.c
@@ -238,7 +238,7 @@ _zed_event_value_is_hex(const char *name)
NULL
};
const char **pp;
- char *p;
+ const char *p;
if (!name)
return (0);
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
index 631ddda5c6e6..4c21c92bcd2f 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
@@ -6867,7 +6867,7 @@ holds_callback(zfs_handle_t *zhp, void *data)
if (cbp->cb_recursive) {
const char *snapname;
- char *delim = strchr(zname, '@');
+ const char *delim = strchr(zname, '@');
if (delim == NULL)
return (0);
@@ -9417,6 +9417,7 @@ main(int argc, char **argv)
/*
* Run the appropriate command.
*/
+ libzfs_mnttab_cache(g_zfs, B_TRUE);
if (find_command_idx(cmdname, &i) == 0) {
current_command = &command_table[i];
ret = command_table[i].func(argc - 1, newargv + 1);
diff --git a/sys/contrib/openzfs/config/kernel-dentry-alias.m4 b/sys/contrib/openzfs/config/kernel-dentry-alias.m4
new file mode 100644
index 000000000000..0baf1a06d3ce
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-dentry-alias.m4
@@ -0,0 +1,32 @@
+dnl # SPDX-License-Identifier: CDDL-1.0
+dnl #
+dnl # 7.1 API change
+dnl # d_u union in struct dentry is now anonmymous, so d_alias must be
+dnl # named directly
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U], [
+ ZFS_LINUX_TEST_SRC([dentry_alias_d_u], [
+ #include <linux/fs.h>
+ #include <linux/dcache.h>
+ #include <linux/list.h>
+ ], [
+ struct inode *inode __attribute__ ((unused)) = NULL;
+ struct dentry *dentry __attribute__ ((unused)) = NULL;
+ hlist_for_each_entry(dentry, &inode->i_dentry,
+ d_u.d_alias) {
+ d_drop(dentry);
+ }
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_DENTRY_ALIAS_D_U], [
+ AC_MSG_CHECKING([whether dentry aliases are in d_u member])
+ ZFS_LINUX_TEST_RESULT([dentry_alias_d_u], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_DENTRY_D_U_ALIASES, 1,
+ [dentry aliases are in d_u member])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
diff --git a/sys/contrib/openzfs/config/kernel.m4 b/sys/contrib/openzfs/config/kernel.m4
index e1dba34e5dbe..b40e34d373f6 100644
--- a/sys/contrib/openzfs/config/kernel.m4
+++ b/sys/contrib/openzfs/config/kernel.m4
@@ -74,6 +74,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_SETATTR_PREPARE
ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED
ZFS_AC_KERNEL_SRC_DENTRY
+ ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U
ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE
ZFS_AC_KERNEL_SRC_SECURITY_INODE
ZFS_AC_KERNEL_SRC_FS_CONTEXT
@@ -198,6 +199,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_SETATTR_PREPARE
ZFS_AC_KERNEL_INSERT_INODE_LOCKED
ZFS_AC_KERNEL_DENTRY
+ ZFS_AC_KERNEL_DENTRY_ALIAS_D_U
ZFS_AC_KERNEL_TRUNCATE_SETSIZE
ZFS_AC_KERNEL_SECURITY_INODE
ZFS_AC_KERNEL_FS_CONTEXT
diff --git a/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c b/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c
index 7ad9ff61d8ee..bbd90a7048f7 100644
--- a/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c
+++ b/sys/contrib/openzfs/etc/systemd/system-generators/zfs-mount-generator.c
@@ -202,6 +202,7 @@ line_worker(char *line, const char *cachefile)
void **tofree = tofree_all;
char *toktmp;
+ const char *toktmp2;
/* BEGIN CSTYLED */
const char *dataset = strtok_r(line, "\t", &toktmp);
char *p_mountpoint = strtok_r(NULL, "\t", &toktmp);
@@ -226,8 +227,8 @@ line_worker(char *line, const char *cachefile)
/* END CSTYLED */
size_t pool_len = strlen(dataset);
- if ((toktmp = strchr(dataset, '/')) != NULL)
- pool_len = toktmp - dataset;
+ if ((toktmp2 = strchr(dataset, '/')) != NULL)
+ pool_len = toktmp2 - dataset;
const char *pool = *(tofree++) = strndup(dataset, pool_len);
if (p_nbmand == NULL) {
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h
index f94dcda6175b..e27158926917 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h
@@ -32,7 +32,9 @@
#define dname(dentry) ((char *)((dentry)->d_name.name))
#define dlen(dentry) ((int)((dentry)->d_name.len))
+#ifdef HAVE_DENTRY_D_U_ALIASES
#define d_alias d_u.d_alias
+#endif
#ifdef HAVE_MM_PAGE_FLAGS_STRUCT
/*
diff --git a/sys/contrib/openzfs/include/sys/vdev_rebuild.h b/sys/contrib/openzfs/include/sys/vdev_rebuild.h
index b787b1d5d993..8ecb30659434 100644
--- a/sys/contrib/openzfs/include/sys/vdev_rebuild.h
+++ b/sys/contrib/openzfs/include/sys/vdev_rebuild.h
@@ -70,6 +70,7 @@ typedef struct vdev_rebuild {
zfs_range_tree_t *vr_scan_tree;
kmutex_t vr_io_lock; /* inflight IO lock */
kcondvar_t vr_io_cv; /* inflight IO cv */
+ uint64_t vr_last_txg; /* last used txg */
/* In-core state and progress */
uint64_t vr_scan_offset[TXG_SIZE];
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c b/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c
index 923bbd995de5..ea316010629b 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c
@@ -708,7 +708,7 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
{
zfs_handle_t *zhp;
char errbuf[ERRBUFLEN];
- char *bookp;
+ const char *bookp;
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
@@ -2958,7 +2958,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
{
zfs_userquota_prop_t type;
- char *cp;
+ const char *cp;
boolean_t isuser;
boolean_t isgroup;
boolean_t isproject;
@@ -4314,12 +4314,13 @@ zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
{
int ret = 0;
zfs_cmd_t zc = {"\0"};
- char *delim;
prop_changelist_t *cl = NULL;
char parent[ZFS_MAX_DATASET_NAME_LEN];
char property[ZFS_MAXPROPLEN];
libzfs_handle_t *hdl = zhp->zfs_hdl;
char errbuf[ERRBUFLEN];
+ const char *delim;
+ char *delim2;
/* if we have the same exact name, just return success */
if (strcmp(zhp->zfs_name, target) == 0)
@@ -4344,11 +4345,11 @@ zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
*/
(void) strlcpy(parent, zhp->zfs_name,
sizeof (parent));
- delim = strchr(parent, '@');
+ delim2 = strchr(parent, '@');
if (strchr(target, '@') == NULL)
- *(++delim) = '\0';
+ *(++delim2) = '\0';
else
- *delim = '\0';
+ *delim2 = '\0';
(void) strlcat(parent, target, sizeof (parent));
target = parent;
} else {
@@ -4369,6 +4370,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
} else {
+
if (flags.recursive) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"recursive rename must be a snapshot"));
@@ -4424,8 +4426,8 @@ zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
}
if (flags.recursive) {
char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
- delim = strchr(parentname, '@');
- *delim = '\0';
+ delim2 = strchr(parentname, '@');
+ *delim2 = '\0';
zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname,
ZFS_TYPE_DATASET);
free(parentname);
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
index 8e71dfa450b1..7f2130682118 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
@@ -550,8 +550,8 @@ get_snapshot_names(differ_info_t *di, const char *fromsnap,
const char *tosnap)
{
libzfs_handle_t *hdl = di->zhp->zfs_hdl;
- char *atptrf = NULL;
- char *atptrt = NULL;
+ const char *atptrf = NULL;
+ const char *atptrt = NULL;
int fdslen, fsnlen;
int tdslen, tsnlen;
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_impl.h b/sys/contrib/openzfs/lib/libzfs/libzfs_impl.h
index 2ce8d49f08bc..6d7eca981d26 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_impl.h
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_impl.h
@@ -66,6 +66,7 @@ struct libzfs_handle {
char *libfetch_load_error;
kmutex_t zh_mnttab_lock;
avl_tree_t zh_mnttab;
+ boolean_t zh_mnttab_cache_enabled;
};
struct zfs_handle {
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_mnttab.c b/sys/contrib/openzfs/lib/libzfs/libzfs_mnttab.c
index 473e3a7b45a1..75277066063c 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_mnttab.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_mnttab.c
@@ -81,34 +81,13 @@ mnttab_compare(const void *arg1, const void *arg2)
return (TREE_ISIGN(rv));
}
-void
-libzfs_mnttab_init(libzfs_handle_t *hdl)
-{
- mutex_init(&hdl->zh_mnttab_lock, NULL, MUTEX_DEFAULT, NULL);
- assert(avl_numnodes(&hdl->zh_mnttab) == 0);
- avl_create(&hdl->zh_mnttab, mnttab_compare,
- sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
-}
-
-void
-libzfs_mnttab_fini(libzfs_handle_t *hdl)
+static void
+mnttab_drop(libzfs_handle_t *hdl)
{
- void *cookie = NULL;
mnttab_node_t *mtn;
-
- while ((mtn = avl_destroy_nodes(&hdl->zh_mnttab, &cookie))
- != NULL)
+ void *cookie = NULL;
+ while ((mtn = avl_destroy_nodes(&hdl->zh_mnttab, &cookie)) != NULL)
mnttab_node_free(hdl, mtn);
-
- avl_destroy(&hdl->zh_mnttab);
- (void) mutex_destroy(&hdl->zh_mnttab_lock);
-}
-
-void
-libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
-{
- /* This is a no-op to preserve ABI backward compatibility. */
- (void) hdl, (void) enable;
}
static int
@@ -145,6 +124,33 @@ mnttab_update(libzfs_handle_t *hdl)
return (0);
}
+
+void
+libzfs_mnttab_init(libzfs_handle_t *hdl)
+{
+ mutex_init(&hdl->zh_mnttab_lock, NULL, MUTEX_DEFAULT, NULL);
+ assert(avl_numnodes(&hdl->zh_mnttab) == 0);
+ avl_create(&hdl->zh_mnttab, mnttab_compare,
+ sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
+ hdl->zh_mnttab_cache_enabled = B_FALSE;
+}
+
+void
+libzfs_mnttab_fini(libzfs_handle_t *hdl)
+{
+ mnttab_drop(hdl);
+ avl_destroy(&hdl->zh_mnttab);
+ (void) mutex_destroy(&hdl->zh_mnttab_lock);
+}
+
+void
+libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
+{
+ mutex_enter(&hdl->zh_mnttab_lock);
+ hdl->zh_mnttab_cache_enabled = enable;
+ mutex_exit(&hdl->zh_mnttab_lock);
+}
+
int
libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
struct mnttab *entry)
@@ -154,6 +160,9 @@ libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
int ret = ENOENT;
mutex_enter(&hdl->zh_mnttab_lock);
+ if (!hdl->zh_mnttab_cache_enabled)
+ mnttab_drop(hdl);
+
if (avl_numnodes(&hdl->zh_mnttab) == 0) {
int error;
@@ -180,6 +189,11 @@ libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
mnttab_node_t *mtn;
mutex_enter(&hdl->zh_mnttab_lock);
+ if (!hdl->zh_mnttab_cache_enabled) {
+ /* Don't bother; we're going to discard it anyway. */
+ mutex_exit(&hdl->zh_mnttab_lock);
+ return;
+ }
mtn = mnttab_node_alloc(hdl, special, mountp, mntopts);
@@ -202,6 +216,12 @@ libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
mnttab_node_t *ret;
mutex_enter(&hdl->zh_mnttab_lock);
+ if (!hdl->zh_mnttab_cache_enabled) {
+ /* Don't bother; we're going to discard it anyway. */
+ mutex_exit(&hdl->zh_mnttab_lock);
+ return;
+ }
+
find.mtn_mt.mnt_special = (char *)fsname;
if ((ret = avl_find(&hdl->zh_mnttab, (void *)&find, NULL)) != NULL) {
avl_remove(&hdl->zh_mnttab, ret);
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
index 7cd6a768084b..0b015d8bce64 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
@@ -640,7 +640,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
prop = zpool_name_to_prop(propname);
if (prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname)) {
int err;
- char *fname = strchr(propname, '@') + 1;
+ const char *fname = strchr(propname, '@') + 1;
err = zfeature_lookup_name(fname, NULL);
if (err != 0) {
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
index 18130a34fea8..f55d0c646bdf 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
@@ -2697,7 +2697,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
char bookname[ZFS_MAX_DATASET_NAME_LEN];
nvlist_t *redact_snaps;
zfs_handle_t *book_zhp;
- char *at, *pound;
+ const char *at, *pound;
int dsnamelen;
pound = strchr(redactbook, '#');
diff --git a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c
index 8ed062bf9b37..64e05f52d95e 100644
--- a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c
+++ b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c
@@ -218,7 +218,8 @@ zfs_get_pci_slots_sys_path(const char *dev_name)
char *address2 = NULL;
char *path = NULL;
char buf[MAXPATHLEN];
- char *tmp;
+ const char *tmp;
+ char *tmp2;
/* If they preface 'dev' with a path (like "/dev") then strip it off */
tmp = strrchr(dev_name, '/');
@@ -240,9 +241,9 @@ zfs_get_pci_slots_sys_path(const char *dev_name)
* be "0000:01:00.0" while /sys/bus/pci/slots/0/address will be
* "0000:01:00". Just NULL terminate at the '.' so they match.
*/
- tmp = strrchr(address1, '.');
- if (tmp != NULL)
- *tmp = '\0';
+ tmp2 = strrchr(address1, '.');
+ if (tmp2 != NULL)
+ *tmp2 = '\0';
dp = opendir("/sys/bus/pci/slots/");
if (dp == NULL) {
@@ -311,6 +312,7 @@ zfs_get_enclosure_sysfs_path(const char *dev_name)
DIR *dp = NULL;
struct dirent *ep;
char buf[MAXPATHLEN];
+ const char *tmp0;
char *tmp1 = NULL;
char *tmp2 = NULL;
char *tmp3 = NULL;
@@ -322,9 +324,9 @@ zfs_get_enclosure_sysfs_path(const char *dev_name)
return (NULL);
/* If they preface 'dev' with a path (like "/dev") then strip it off */
- tmp1 = strrchr(dev_name, '/');
- if (tmp1 != NULL)
- dev_name = tmp1 + 1; /* +1 since we want the chr after '/' */
+ tmp0 = strrchr(dev_name, '/');
+ if (tmp0 != NULL)
+ dev_name = tmp0 + 1; /* +1 since we want the chr after '/' */
tmpsize = asprintf(&tmp1, "/sys/block/%s/device", dev_name);
if (tmpsize == -1 || tmp1 == NULL) {
diff --git a/sys/contrib/openzfs/man/man4/spl.4 b/sys/contrib/openzfs/man/man4/spl.4
index 61dfe42e463d..2ca69e929778 100644
--- a/sys/contrib/openzfs/man/man4/spl.4
+++ b/sys/contrib/openzfs/man/man4/spl.4
@@ -130,6 +130,19 @@ When not enabled, the thread is halted to facilitate further debugging.
.Pp
Set to a non-zero value to enable.
.
+.It Sy spl_schedule_hrtimeout_slack_us Ns = Ns Sy 0 Pq uint
+Slack value in microseconds passed to
+.Fn schedule_hrtimeout_range
+when a condition variable times out.
+A non-zero value enforces the kernel coalesce the wakeup with other timers
+to reduce wakeup count, at the cost of some additional sleep duration.
+The maximum is
+.Sy 1000 ,
+as defined by
+.Sy MAX_HRTIMEOUT_SLACK_US .
+.Pp
+Linux-only.
+.
.It Sy spl_taskq_kick Ns = Ns Sy 0 Pq uint
Kick stuck taskq to spawn threads.
When writing a non-zero value to it, it will scan all the taskqs.
diff --git a/sys/contrib/openzfs/man/man7/vdevprops.7 b/sys/contrib/openzfs/man/man7/vdevprops.7
index bb5fec65eff6..b45128dd9242 100644
--- a/sys/contrib/openzfs/man/man7/vdevprops.7
+++ b/sys/contrib/openzfs/man/man7/vdevprops.7
@@ -134,6 +134,12 @@ The number of I/O operations of each type performed by this vdev
The cumulative size of all operations of each type performed by this vdev
.It Sy removing
If this device is currently being removed from the pool
+.It Sy raidz_expanding
+Set while a
+.Nm zpool Cm attach
+expansion is in progress on this RAID-Z vdev; cleared on completion.
+See
+.Xr zpool-attach 8 .
.It Sy trim_support
Indicates if a leaf device supports trim operations.
.El
diff --git a/sys/contrib/openzfs/man/man7/zfsprops.7 b/sys/contrib/openzfs/man/man7/zfsprops.7
index 183e6ea95745..302dffa0e6d1 100644
--- a/sys/contrib/openzfs/man/man7/zfsprops.7
+++ b/sys/contrib/openzfs/man/man7/zfsprops.7
@@ -1360,6 +1360,21 @@ This was only supported by Linux prior to 5.15, and was buggy there,
and is not supported by
.Fx .
On Solaris it's used for SMB clients.
+.It Sy longname Ns = Ns Sy on Ns | Ns Sy off
+Controls support for filenames longer than 255 bytes, up to 1023 bytes.
+The default is
+.Sy off .
+Setting this property to
+.Sy on
+activates the
+.Sy longname
+pool feature, which must be enabled
+.Po see
+.Xr zpool-features 7
+.Pc .
+Once a file with a long name is created, the feature becomes active and
+the pool can no longer be imported by an OpenZFS implementation that does
+not support it.
.It Sy overlay Ns = Ns Sy on Ns | Ns Sy off
Allow mounting on a busy directory or a directory which already contains
files or directories.
diff --git a/sys/contrib/openzfs/module/nvpair/nvpair.c b/sys/contrib/openzfs/module/nvpair/nvpair.c
index 14fbddb60f6b..07ac102145e2 100644
--- a/sys/contrib/openzfs/module/nvpair/nvpair.c
+++ b/sys/contrib/openzfs/module/nvpair/nvpair.c
@@ -1923,8 +1923,9 @@ nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
{
nvpair_t *nvp;
const char *np;
- char *sepp = NULL;
- char *idxp, *idxep;
+ const char *sepp = NULL;
+ const char *idxp;
+ char *idxep;
nvlist_t **nva;
long idx = 0;
int n;
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
index c73ef86df4dc..767272177fb7 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
@@ -1138,15 +1138,28 @@ zfsctl_snapshot_unmount(const char *snapname, int flags)
cv_wait(&se->se_cv, &se->se_mtx);
mutex_exit(&se->se_mtx);
- exportfs_flush();
-
if (flags & MNT_FORCE)
argv[4] = "-fn";
argv[5] = se->se_path;
dprintf("unmount; path=%s\n", se->se_path);
error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
- zfsctl_snapshot_rele(se);
+ /*
+ * The kernel's NFS export cache can hold references to the
+ * snapshot mountpoint and cause umount to fail. ZFS cannot
+ * invalidate individual entries because the relevant kernel
+ * APIs are exported GPL-only, so we issue a global flush
+ * instead. To avoid impacting unrelated snapshots, the flush
+ * runs only on umount failure. Not perfect, but better than
+ * flushing unconditionally.
+ */
+ if (error) {
+ exportfs_flush();
+ error = call_usermodehelper(argv[0], argv, envp,
+ UMH_WAIT_PROC);
+ }
+
+ zfsctl_snapshot_rele(se);
/*
* The umount system utility will return 256 on error. We must
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 9c0d92551843..d7b502429923 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
@@ -953,11 +953,12 @@ objs:
int
zfs_statvfs(struct inode *ip, struct kstatfs *statp)
{
+ znode_t *zp = ITOZ(ip);
zfsvfs_t *zfsvfs = ITOZSB(ip);
uint64_t refdbytes, availbytes, usedobjs, availobjs;
int err = 0;
- if ((err = zfs_enter(zfsvfs, FTAG)) != 0)
+ if ((err = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
return (err);
dmu_objset_space(zfsvfs->z_os,
@@ -1013,8 +1014,6 @@ zfs_statvfs(struct inode *ip, struct kstatfs *statp)
if (dmu_objset_projectquota_enabled(zfsvfs->z_os) &&
dmu_objset_projectquota_present(zfsvfs->z_os)) {
- znode_t *zp = ITOZ(ip);
-
if (zp->z_pflags & ZFS_PROJINHERIT && zp->z_projid &&
zpl_is_valid_projid(zp->z_projid))
err = zfs_statfs_project(zfsvfs, zp, statp, bshift);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
index ffe227796f0a..6d57bff56540 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
@@ -673,6 +673,8 @@ static long
zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
{
cred_t *cr = CRED();
+ znode_t *zp = ITOZ(ip);
+ zfsvfs_t *zfsvfs = ITOZSB(ip);
loff_t olen;
fstrans_cookie_t cookie;
int error = 0;
@@ -706,7 +708,7 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
bf.l_len = len;
bf.l_pid = 0;
- error = -zfs_space(ITOZ(ip), F_FREESP, &bf, O_RDWR, offset, cr);
+ error = -zfs_space(zp, F_FREESP, &bf, O_RDWR, offset, cr);
} else if ((mode & ~FALLOC_FL_KEEP_SIZE) == 0) {
unsigned int percent = zfs_fallocate_reserve_percent;
struct kstatfs statfs;
@@ -721,7 +723,7 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
* Use zfs_statvfs() instead of dmu_objset_space() since it
* also checks project quota limits, which are relevant here.
*/
- error = zfs_statvfs(ip, &statfs);
+ error = -zfs_statvfs(ip, &statfs);
if (error)
goto out_unmark;
@@ -734,8 +736,14 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
error = -ENOSPC;
goto out_unmark;
}
- if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + len > olen)
- error = zfs_freesp(ITOZ(ip), offset + len, 0, 0, FALSE);
+ if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + len > olen) {
+ error = zpl_enter_verify_zp(zfsvfs, zp, FTAG);
+ if (error)
+ goto out_unmark;
+
+ error = -zfs_freesp(zp, offset + len, 0, 0, FALSE);
+ zfs_exit(zfsvfs, FTAG);
+ }
}
out_unmark:
spl_fstrans_unmark(cookie);
diff --git a/sys/contrib/openzfs/module/zfs/dmu.c b/sys/contrib/openzfs/module/zfs/dmu.c
index 0f40164ecc95..d709f9a34aff 100644
--- a/sys/contrib/openzfs/module/zfs/dmu.c
+++ b/sys/contrib/openzfs/module/zfs/dmu.c
@@ -966,8 +966,14 @@ dmu_evict_range(objset_t *os, uint64_t object, uint64_t offset, uint64_t len)
* access patterns are rare.
*/
rw_enter(&dn->dn_struct_rwlock, RW_READER);
- uint64_t start = dbuf_whichblock(dn, 0, offset);
- uint64_t end = dbuf_whichblock(dn, 0, offset + len);
+ uint64_t start, end;
+ if (dn->dn_datablkshift != 0) {
+ start = dbuf_whichblock(dn, 0, offset);
+ end = dbuf_whichblock(dn, 0, offset + len);
+ } else {
+ start = (offset >= dn->dn_datablksz);
+ end = (offset + len >= dn->dn_datablksz);
+ }
if (end > start)
dbuf_evict_range(dn, start, end - 1);
rw_exit(&dn->dn_struct_rwlock);
diff --git a/sys/contrib/openzfs/module/zfs/dmu_objset.c b/sys/contrib/openzfs/module/zfs/dmu_objset.c
index ed81647bcfa3..4919ead3cea6 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_objset.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_objset.c
@@ -3011,7 +3011,7 @@ dmu_objset_get_user(objset_t *os)
int
dmu_fsname(const char *snapname, char *buf)
{
- char *atp = strchr(snapname, '@');
+ const char *atp = strchr(snapname, '@');
if (atp == NULL)
return (SET_ERROR(EINVAL));
if (atp - snapname >= ZFS_MAX_DATASET_NAME_LEN)
diff --git a/sys/contrib/openzfs/module/zfs/dmu_send.c b/sys/contrib/openzfs/module/zfs/dmu_send.c
index 8ecb99d5f57c..4c354722e4f8 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_send.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_send.c
@@ -1844,7 +1844,7 @@ send_reader_thread(void *arg)
continue;
}
uint64_t file_max =
- MIN(dn->dn_maxblkid, range->end_blkid);
+ MIN(dn->dn_maxblkid + 1, range->end_blkid);
/*
* The object exists, so we need to try to find the
* blkptr for each block in the range we're processing.
diff --git a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
index 8533657ad03b..4ffd75ceace9 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
@@ -39,10 +39,10 @@
static int
dsl_bookmark_hold_ds(dsl_pool_t *dp, const char *fullname,
- dsl_dataset_t **dsp, const void *tag, char **shortnamep)
+ dsl_dataset_t **dsp, const void *tag, const char **shortnamep)
{
char buf[ZFS_MAX_DATASET_NAME_LEN];
- char *hashp;
+ const char *hashp;
if (strlen(fullname) >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
@@ -105,7 +105,7 @@ int
dsl_bookmark_lookup(dsl_pool_t *dp, const char *fullname,
dsl_dataset_t *later_ds, zfs_bookmark_phys_t *bmp)
{
- char *shortname;
+ const char *shortname;
dsl_dataset_t *ds;
int error;
@@ -219,7 +219,7 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp,
int error;
dsl_dataset_t *newbm_ds;
- char *newbm_short;
+ const char *newbm_short;
zfs_bookmark_phys_t bmark_phys;
error = dsl_bookmark_hold_ds(dp, newbm, &newbm_ds, FTAG, &newbm_short);
@@ -329,7 +329,7 @@ dsl_bookmark_create_check(void *arg, dmu_tx_t *tx)
}
static dsl_bookmark_node_t *
-dsl_bookmark_node_alloc(char *shortname)
+dsl_bookmark_node_alloc(const char *shortname)
{
dsl_bookmark_node_t *dbn = kmem_alloc(sizeof (*dbn), KM_SLEEP);
dbn->dbn_name = spa_strdup(shortname);
@@ -445,7 +445,7 @@ dsl_bookmark_create_sync_impl_snap(const char *bookmark, const char *snapshot,
dsl_pool_t *dp = dmu_tx_pool(tx);
objset_t *mos = dp->dp_meta_objset;
dsl_dataset_t *snapds, *bmark_fs;
- char *shortname;
+ const char *shortname;
boolean_t bookmark_redacted;
uint64_t *dsredactsnaps;
uint64_t dsnumsnaps;
@@ -535,7 +535,7 @@ dsl_bookmark_create_sync_impl_book(
{
dsl_pool_t *dp = dmu_tx_pool(tx);
dsl_dataset_t *bmark_fs_source, *bmark_fs_new;
- char *source_shortname, *new_shortname;
+ const char *source_shortname, *new_shortname;
zfs_bookmark_phys_t source_phys;
VERIFY0(dsl_bookmark_hold_ds(dp, source_name, &bmark_fs_source, FTAG,
@@ -1105,7 +1105,7 @@ dsl_bookmark_destroy_check(void *arg, dmu_tx_t *tx)
dsl_dataset_t *ds;
zfs_bookmark_phys_t bm;
int error;
- char *shortname;
+ const char *shortname;
error = dsl_bookmark_hold_ds(dp, fullname, &ds,
FTAG, &shortname);
@@ -1161,7 +1161,7 @@ dsl_bookmark_destroy_sync(void *arg, dmu_tx_t *tx)
for (nvpair_t *pair = nvlist_next_nvpair(dbda->dbda_success, NULL);
pair != NULL; pair = nvlist_next_nvpair(dbda->dbda_success, pair)) {
dsl_dataset_t *ds;
- char *shortname;
+ const char *shortname;
uint64_t zap_cnt;
VERIFY0(dsl_bookmark_hold_ds(dp, nvpair_name(pair),
diff --git a/sys/contrib/openzfs/module/zfs/dsl_dir.c b/sys/contrib/openzfs/module/zfs/dsl_dir.c
index 6ce1890cfea1..2253b868b53c 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_dir.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_dir.c
@@ -417,7 +417,7 @@ dsl_dir_namelen(dsl_dir_t *dd)
static int
getcomponent(const char *path, char *component, const char **nextp)
{
- char *p;
+ const char *p;
if ((path == NULL) || (path[0] == '\0'))
return (SET_ERROR(ENOENT));
diff --git a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
index 4fe6dc9d6fbb..de691f73e939 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
@@ -593,6 +593,7 @@ vdev_rebuild_range(vdev_rebuild_t *vr, uint64_t start, uint64_t size)
dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
VERIFY0(dmu_tx_assign(tx, DMU_TX_WAIT | DMU_TX_SUSPEND));
uint64_t txg = dmu_tx_get_txg(tx);
+ vr->vr_last_txg = txg;
spa_config_enter(spa, SCL_STATE_ALL, vd, RW_READER);
mutex_enter(&vd->vdev_rebuild_lock);
@@ -824,6 +825,7 @@ vdev_rebuild_thread(void *arg)
uint64_t limit = (arc_c_max / 2) / MAX(rvd->vdev_children, 1);
vr->vr_bytes_inflight_max = MIN(limit, MAX(1ULL << 20,
zfs_rebuild_vdev_limit * vd->vdev_children));
+ vr->vr_last_txg = 0;
/*
* Removal of vdevs from the vdev tree may eliminate the need
@@ -910,8 +912,16 @@ vdev_rebuild_thread(void *arg)
error = vdev_rebuild_ranges(vr);
zfs_range_tree_vacate(vr->vr_scan_tree, NULL, NULL);
- spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
+ /*
+ * Allow rebuilt ranges to be sync-ed before enabling metaslab
+ * to avoid any interfering allocations. Otherwise, we might
+ * see checksum errors after scrub.
+ */
+ if (vr->vr_last_txg != 0)
+ txg_wait_synced(dp, vr->vr_last_txg);
+
metaslab_enable(msp, B_FALSE, B_FALSE);
+ spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
if (error != 0)
break;
diff --git a/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h b/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h
index b7ff1e9b0923..614d996ab619 100644
--- a/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h
+++ b/sys/contrib/openzfs/module/zstd/include/zstd_compat_wrapper.h
@@ -33,6 +33,8 @@
* Copyright (c) 2020, Sebastian Gottschall
*/
+#define _ZSTD_COMPAT_WRAPPER_H
+
/*
* This wrapper fixes a problem, in case the ZFS filesystem driver, is compiled
* statically into the kernel.
diff --git a/sys/contrib/openzfs/module/zstd/lib/common/zstd_common.c b/sys/contrib/openzfs/module/zstd/lib/common/zstd_common.c
index dfbe6f635627..90b9fe00fece 100644
--- a/sys/contrib/openzfs/module/zstd/lib/common/zstd_common.c
+++ b/sys/contrib/openzfs/module/zstd/lib/common/zstd_common.c
@@ -9,7 +9,9 @@
* You may select, at your option, one of the above-listed licenses.
*/
-
+#ifdef _ZSTD_COMPAT_WRAPPER_H
+#undef ZSTD_isError /* defined within zstd_internal.h */
+#endif
/*-*************************************
* Dependencies
@@ -34,8 +36,8 @@ const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; }
/*! ZSTD_isError() :
* tells if a return value is an error code
* symbol is required for external callers */
-#if !defined(_STANDALONE)
-unsigned ZSTD_isError(size_t code) __asm__("zfs_ZSTD_isError");
+#ifdef _ZSTD_COMPAT_WRAPPER_H
+#define ZSTD_isError zfs_ZSTD_isError
#endif
unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index 63913663a7b2..4c7e4e85ec00 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -906,7 +906,8 @@ tags = ['functional', 'quota']
[tests/functional/redacted_send]
tests = ['redacted_compressed', 'redacted_contents', 'redacted_deleted',
'redacted_disabled_feature', 'redacted_embedded', 'redacted_holes',
- 'redacted_incrementals', 'redacted_largeblocks', 'redacted_many_clones',
+ 'redacted_incrementals', 'redacted_largeblocks', 'redacted_max_blkid',
+ 'redacted_many_clones',
'redacted_mixed_recsize', 'redacted_mounts', 'redacted_negative',
'redacted_origin', 'redacted_panic', 'redacted_props', 'redacted_resume',
'redacted_size', 'redacted_volume']
@@ -1150,7 +1151,7 @@ tests = ['zvol_swap_001_pos', 'zvol_swap_002_pos', 'zvol_swap_004_pos']
tags = ['functional', 'zvol', 'zvol_swap']
[tests/functional/libzfs]
-tests = ['many_fds', 'libzfs_input']
+tests = ['many_fds', 'libzfs_input', 'libzfs_mnttab_cache']
tags = ['functional', 'libzfs']
[tests/functional/log_spacemap]
diff --git a/sys/contrib/openzfs/tests/runfiles/sanity.run b/sys/contrib/openzfs/tests/runfiles/sanity.run
index ca16bee67dda..936f2bcc32be 100644
--- a/sys/contrib/openzfs/tests/runfiles/sanity.run
+++ b/sys/contrib/openzfs/tests/runfiles/sanity.run
@@ -466,7 +466,7 @@ tests = ['large_files_001_pos', 'large_files_002_pos']
tags = ['functional', 'large_files']
[tests/functional/libzfs]
-tests = ['many_fds', 'libzfs_input']
+tests = ['many_fds', 'libzfs_input', 'libzfs_mnttab_cache']
tags = ['functional', 'libzfs']
[tests/functional/limits]
diff --git a/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in b/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in
index 22da0fc5cc13..29d2760ccb8f 100755
--- a/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in
+++ b/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in
@@ -201,7 +201,6 @@ elif sys.platform.startswith('linux'):
# reasons listed above can be used.
#
maybe = {
- 'append/threadsappend_001_pos': ['FAIL', 6136],
'chattr/setup': ['SKIP', exec_reason],
'crtime/crtime_001_pos': ['SKIP', statx_reason],
'cli_root/zdb/zdb_006_pos': ['FAIL', known_reason],
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore b/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
index 4bdca0acf52b..c0785d9a28e8 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
@@ -18,6 +18,7 @@
/getversion
/largest_file
/libzfs_input_check
+/libzfs_mnttab_cache_check
/manipulate_user_buffer
/mkbusy
/mkfile
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
index c4155ca3cacd..9f92310985e7 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
@@ -66,6 +66,10 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/libzfs_input_check
libzfs_core.la \
libnvpair.la
+scripts_zfs_tests_bin_PROGRAMS += %D%/libzfs_mnttab_cache_check
+%C%_libzfs_mnttab_cache_check_LDADD = \
+ libzfs.la
+
scripts_zfs_tests_bin_PROGRAMS += %D%/manipulate_user_buffer
%C%_manipulate_user_buffer_LDADD = -lpthread
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_mnttab_cache_check.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_mnttab_cache_check.c
new file mode 100644
index 000000000000..661c5ce43f66
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/libzfs_mnttab_cache_check.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2026 by Delphix. All rights reserved.
+ */
+
+/*
+ * libzfs_mnttab_cache_check.c
+ *
+ * Tests that libzfs_mnttab_cache(hdl, B_FALSE) does indeed disable the
+ * per-handle mnttab cache. It does this by adding a fake entry to it, then
+ * trying to read the status of a known-mounted dataset from it.
+ *
+ * As currently implemented, when enabled, libzfs_mnttab_find() assumes the
+ * cache is correct and up to date if it has any entries in it at all. So by
+ * putting something in it before searching, the initial load from /etc/mtab
+ * never happens, and the real mounted datasets are never seen.
+ *
+ * When disabled, the entire cache is discarded and reloaded on every lookup,
+ * so the fake entry will disappear and the real state will be found correctly.
+ * to date if it has any entries in it at all.
+ *
+ * Run (as a user that can read /etc/mtab):
+ * ./libzfs_mnttab_cache_check <name-of-any-currently-mounted-zfs-dataset>
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mnttab.h>
+#include <libzfs.h>
+
+int
+main(int argc, char *argv[])
+{
+ if (argc != 2) {
+ fprintf(stderr,
+ "usage: %s <currently-mounted-zfs-dataset>\n", argv[0]);
+ return (2);
+ }
+ const char *real_ds = argv[1];
+
+ libzfs_handle_t *hdl = libzfs_init();
+ if (hdl == NULL) {
+ fprintf(stderr, "libzfs_init failed\n");
+ return (1);
+ }
+
+ /* Ask libzfs to disable the per-handle mnttab cache. */
+ libzfs_mnttab_cache(hdl, B_FALSE);
+
+ /*
+ * Stand-in for what zfs_mount() does internally on every successful
+ * mount: zfs_mount_at() calls libzfs_mnttab_add(hdl, ...) after
+ * do_mount(). In a real consumer, this happens implicitly; we call it
+ * directly here so the reproducer doesn't need root or a mountable
+ * dataset.
+ */
+ libzfs_mnttab_add(hdl, "fake/dataset", "/fake/mountpoint", "rw");
+
+ /*
+ * Now query ZFS_PROP_MOUNTED on a real, currently-mounted dataset.
+ * This is the standard libzfs API a consumer uses to check mount
+ * state. Internally it calls libzfs_mnttab_find().
+ */
+ zfs_handle_t *zhp = zfs_open(hdl, real_ds, ZFS_TYPE_FILESYSTEM);
+ if (zhp == NULL) {
+ fprintf(stderr, "zfs_open(%s) failed\n", real_ds);
+ libzfs_fini(hdl);
+ return (1);
+ }
+
+ uint64_t mounted = zfs_prop_get_int(zhp, ZFS_PROP_MOUNTED);
+ zfs_close(zhp);
+
+ int rc;
+ if (mounted) {
+ printf("OK: ZFS_PROP_MOUNTED reports %s as mounted\n", real_ds);
+ rc = 0;
+ } else {
+ printf("BUG: ZFS_PROP_MOUNTED reports %s as NOT mounted\n",
+ real_ds);
+ printf(" but %s IS mounted (see /etc/mtab and "
+ "`zfs get mounted`).\n", real_ds);
+ printf(" libzfs_mnttab_cache(hdl, B_FALSE) did not "
+ "actually disable the cache.\n");
+ rc = 1;
+ }
+
+ libzfs_fini(hdl);
+ return (rc);
+}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/threadsappend.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/threadsappend.c
index bdbb2881f529..ed0d74c3c279 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/threadsappend.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/threadsappend.c
@@ -87,7 +87,7 @@ usage(void)
int
main(int argc, char **argv)
{
- pthread_t tid;
+ pthread_t tid[2];
int ret = 0;
long ncpus = 0;
int i;
@@ -120,7 +120,7 @@ main(int argc, char **argv)
}
for (i = 0; i < 2; i++) {
- ret = pthread_create(&tid, NULL, go, (void *)&i);
+ ret = pthread_create(&tid[i], NULL, go, (void *)&i);
if (ret != 0) {
(void) fprintf(stderr,
"zfs_threadsappend: thr_create(#%d) "
@@ -129,8 +129,8 @@ main(int argc, char **argv)
}
}
- while (pthread_join(tid, NULL) == 0)
- continue;
+ for (i = 0; i < 2; i++)
+ (void) pthread_join(tid[i], NULL);
return (0);
}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
index a52cacec224a..19dbb5202c3c 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
+++ b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
@@ -202,6 +202,7 @@ export ZFSTEST_FILES_COMMON='badsend
get_diff
getversion
largest_file
+ libzfs_mnttab_cache_check
libzfs_input_check
manipulate_user_buffer
mkbusy
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
index 3d98f43f848d..c4bcfea55955 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
@@ -1700,6 +1700,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/largest_pool/largest_pool_001_pos.ksh \
functional/libzfs/cleanup.ksh \
functional/libzfs/libzfs_input.ksh \
+ functional/libzfs/libzfs_mnttab_cache.ksh \
functional/libzfs/setup.ksh \
functional/limits/cleanup.ksh \
functional/limits/filesystem_count.ksh \
@@ -1898,6 +1899,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/redacted_send/redacted_holes.ksh \
functional/redacted_send/redacted_incrementals.ksh \
functional/redacted_send/redacted_largeblocks.ksh \
+ functional/redacted_send/redacted_max_blkid.ksh \
functional/redacted_send/redacted_many_clones.ksh \
functional/redacted_send/redacted_mixed_recsize.ksh \
functional/redacted_send/redacted_mounts.ksh \
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fadvise/fadvise_dontneed.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fadvise/fadvise_dontneed.ksh
index b19f576adcf4..53f3ad999d3b 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fadvise/fadvise_dontneed.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fadvise/fadvise_dontneed.ksh
@@ -32,11 +32,13 @@
# 2. Record cache_count from dbufstats
# 3. Call file_fadvise with POSIX_FADV_DONTNEED on the file
# 4. Verify that cache_count decreased
+# 5. Sanity-check eviction for single-block files.
#
verify_runnable "global"
-FILE=$TESTDIR/$TESTFILE0
+FILE0=$TESTDIR/$TESTFILE0
+FILE1=$TESTDIR/$TESTFILE1
BLKSZ=$(get_prop recordsize $TESTPOOL)
function cleanup
@@ -48,16 +50,21 @@ log_assert "Ensure POSIX_FADV_DONTNEED evicts data from the dbuf cache"
log_onexit cleanup
-log_must file_write -o create -f $FILE -b $BLKSZ -c 100
+log_must file_write -o create -f $FILE0 -b $BLKSZ -c 100
sync_pool $TESTPOOL
evicts1=$(kstat dbufstats.cache_count)
-log_must file_fadvise -f $FILE -a POSIX_FADV_DONTNEED
+log_must file_fadvise -f $FILE0 -a POSIX_FADV_DONTNEED
evicts2=$(kstat dbufstats.cache_count)
log_note "cache_count before=$evicts1 after=$evicts2"
log_must [ $evicts1 -gt $evicts2 ]
+log_must file_write -o create -f $FILE1 -b 12000 -c 1
+sync_pool $TESTPOOL
+
+log_must file_fadvise -f $FILE1 -a POSIX_FADV_DONTNEED
+
log_pass "POSIX_FADV_DONTNEED evicts data from the dbuf cache"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/libzfs/libzfs_mnttab_cache.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/libzfs/libzfs_mnttab_cache.ksh
new file mode 100755
index 000000000000..2459e364c1d7
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/libzfs/libzfs_mnttab_cache.ksh
@@ -0,0 +1,26 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2026, TrueNAS.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+log_assert "libzfs mnttab cache works as expected"
+
+log_must libzfs_mnttab_cache_check $TESTPOOL/$TESTFS
+
+log_pass "libzfs mnttab cache works as expected"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redacted_send/redacted_max_blkid.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redacted_send/redacted_max_blkid.ksh
new file mode 100755
index 000000000000..13820b470222
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redacted_send/redacted_max_blkid.ksh
@@ -0,0 +1,118 @@
+#!/bin/ksh
+# SPDX-License-Identifier: CDDL-1.0
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2026 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/redacted_send/redacted.kshlib
+
+#
+# Description:
+# Verify that an incremental send from a redaction bookmark correctly sends
+# the last block (dn_maxblkid) of a file through the PREVIOUSLY_REDACTED
+# path.
+#
+# Regression test for an off-by-one bug in the PREVIOUSLY_REDACTED handler
+# in send_reader_thread(). file_max was computed as:
+#
+# MIN(dn->dn_maxblkid, range->end_blkid)
+#
+# dn_maxblkid is an inclusive maximum block ID while range->end_blkid is
+# exclusive (one past the last block). Mixing these in MIN() caused the
+# loop condition "blkid < file_max" to skip block dn_maxblkid, silently
+# dropping the last block of any file whose last block was in the redaction
+# list. The block remained as zeros on the receiver even though ZFS
+# reported the send and receive as successful.
+#
+# Strategy:
+# 1. Create a dataset with a 16-block file of random data and snapshot it.
+# 2. Create a clone (redact_clone) that overwrites only the last block
+# (block 15, i.e., dn_maxblkid).
+# 3. Redact the base snapshot using redact_clone; block 15 enters the
+# redaction list.
+# 4. Create a second clone (send_clone) of the base snapshot that does NOT
+# modify block 15. Because block 15 in send_clone has birth <=
+# snap.creation_txg the TO traversal thread skips it; it must be sent
+# via the PREVIOUSLY_REDACTED path.
+# 5. Redacted-send the base snapshot to the receiver (block 15 = zeros).
+# 6. Incrementally send send_clone from the redaction bookmark; block 15
+# must be filled in by the PREVIOUSLY_REDACTED handler.
+# 7. Verify that block 15 on the receiver matches the original.
+#
+
+typeset ds_name="max_blkid"
+typeset sendfs="$POOL/$ds_name"
+typeset redact_clone="$POOL/${ds_name}_redact"
+typeset send_clone="$POOL/${ds_name}_send"
+typeset recvfs="$POOL2/$ds_name"
+typeset recv_clone="$POOL2/${ds_name}_send"
+typeset tmpdir="$(get_prop mountpoint $POOL)/tmp"
+typeset stream=$(mktemp $tmpdir/stream.XXXX)
+
+log_onexit redacted_cleanup $sendfs $recvfs $recv_clone
+
+# Create a dataset with a 16-block file.
+log_must zfs create $sendfs
+typeset mntpnt=$(get_prop mountpoint $sendfs)
+typeset bs=$(get_prop recsize $sendfs)
+log_must dd if=/dev/urandom of=$mntpnt/f1 bs=$bs count=16
+
+# Take the base snapshot.
+log_must zfs snapshot $sendfs@snap
+
+# Create redact_clone and overwrite ONLY the last block (block 15).
+# This is the block at index dn_maxblkid for a 16-block file.
+log_must zfs clone $sendfs@snap $redact_clone
+typeset redact_mnt=$(get_prop mountpoint $redact_clone)
+log_must dd if=/dev/urandom of=$redact_mnt/f1 bs=$bs count=1 seek=15 conv=notrunc
+log_must zfs snapshot $redact_clone@snap
+
+# Create the redaction bookmark; block 15 is now in the redaction list.
+log_must zfs redact $sendfs@snap book1 $redact_clone@snap
+
+# Create send_clone as an unmodified clone of the base snapshot.
+# Block 15 in send_clone is inherited (birth <= snap.creation_txg), so the
+# TO traversal thread does not include it. The PREVIOUSLY_REDACTED path
+# must send it.
+log_must zfs clone $sendfs@snap $send_clone
+log_must zfs snapshot $send_clone@snap
+
+# Redacted send of the base snapshot; block 15 of f1 is omitted.
+log_must eval "zfs send --redact book1 $sendfs@snap >$stream"
+log_must eval "zfs recv $recvfs <$stream"
+
+# Incremental send of send_clone from the redaction bookmark.
+# Block 15 must be sent via the PREVIOUSLY_REDACTED path.
+log_must eval "zfs send -i $sendfs#book1 $send_clone@snap >$stream"
+log_must eval "zfs recv $recv_clone <$stream"
+
+# Verify that the received clone is identical to the source.
+# If the bug is present, block 15 is zeros on the receiver and this fails.
+typeset send_mnt=$(get_prop mountpoint $send_clone)
+typeset recv_mnt=$(get_prop mountpoint $recv_clone)
+log_must directory_diff $send_mnt $recv_mnt
+
+# Explicitly verify block 15 is not all zeros and matches the source.
+typeset src_block=$(mktemp $tmpdir/src_block.XXXX)
+typeset recv_block=$(mktemp $tmpdir/recv_block.XXXX)
+typeset zero_block=$(mktemp $tmpdir/zero_block.XXXX)
+log_must dd if=$mntpnt/f1 bs=$bs skip=15 count=1 of=$src_block 2>/dev/null
+log_must dd if=$recv_mnt/f1 bs=$bs skip=15 count=1 of=$recv_block 2>/dev/null
+log_must dd if=/dev/zero bs=$bs count=1 of=$zero_block 2>/dev/null
+
+cmp -s $recv_block $zero_block && log_fail "Block 15 is all zeros on receiver (off-by-one bug)"
+log_must cmp $src_block $recv_block
+
+log_pass "Incremental send from bookmark correctly sends the last block (dn_maxblkid)."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib
index 91430c0e8fc0..2b5a28b06206 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/redundancy/redundancy.kshlib
@@ -419,12 +419,7 @@ function recover_bad_missing_devs
# expected state after a healing resilver of a healthy pool.
#
# 2. sequential - The pool is fully intact. There should never be a
-# checksum error, but the occasional checksum error does occur in
-# practice. Until the root cause is identified and resolved, tolerate
-# a checksum error when scrubbing after a sequential resilver.
-#
-# https://github.com/openzfs/zfs/issues/18307
-# https://github.com/openzfs/zfs/issues/18319
+# checksum error.
#
# 3. damaged - The pool was intentionally silently damaged. Checksum
# errors are expected to be reported as the damaged blocks are
@@ -454,7 +449,7 @@ function verify_draid_pool
log_fail "Unexpected repair IO found for $pool ($cksum)"
fi
elif [[ "$replace_mode" = "sequential" ]]; then
- if [[ $cksum -gt 3 ]]; then
+ if [[ $cksum -gt 0 ]]; then
log_must zpool status -v $pool
log_fail "Unexpected CKSUM errors found for $pool ($cksum)"
fi
diff --git a/sys/dev/acpi_support/acpi_panasonic.c b/sys/dev/acpi_support/acpi_panasonic.c
index 8fea47ee45e8..5f54ca07c5a6 100644
--- a/sys/dev/acpi_support/acpi_panasonic.c
+++ b/sys/dev/acpi_support/acpi_panasonic.c
@@ -233,7 +233,9 @@ acpi_panasonic_shutdown(device_t dev)
/* Mute the main audio during reboot to prevent static burst to speaker. */
sc = device_get_softc(dev);
mute = 1;
+ ACPI_SERIAL_BEGIN(panasonic);
hkey_sound_mute(sc->handle, HKEY_SET, &mute);
+ ACPI_SERIAL_END(panasonic);
return (0);
}
diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c
index af3e0f004b88..7f9409e4452c 100644
--- a/sys/dev/ichsmb/ichsmb_pci.c
+++ b/sys/dev/ichsmb/ichsmb_pci.c
@@ -110,7 +110,8 @@
#define ID_ELKHARTLAKE 0x4b23
#define ID_GEMINILAKE 0x31d4
#define ID_CEDARFORK 0x18df
-#define ID_ICELAKE 0x34a3
+#define ID_ICELAKELP 0x34a3
+#define ID_ICELAKEN 0x38a3
#define ID_ALDERLAKE 0x7aa3
#define ID_ALDERLAKE2 0x51a3
#define ID_ALDERLAKE3 0x54a3
@@ -255,8 +256,10 @@ static const struct pci_device_table ichsmb_devices[] = {
PCI_DESCR("Intel Gemini Lake SMBus controller") },
{ PCI_DEV(PCI_VENDOR_INTEL, ID_CEDARFORK),
PCI_DESCR("Intel Cedar Fork SMBus controller") },
- { PCI_DEV(PCI_VENDOR_INTEL, ID_ICELAKE),
- PCI_DESCR("Intel Ice Lake SMBus controller") },
+ { PCI_DEV(PCI_VENDOR_INTEL, ID_ICELAKELP),
+ PCI_DESCR("Intel Ice Lake-LP SMBus controller") },
+ { PCI_DEV(PCI_VENDOR_INTEL, ID_ICELAKEN),
+ PCI_DESCR("Intel Ice Lake-N SMBus controller") },
{ PCI_DEV(PCI_VENDOR_INTEL, ID_ALDERLAKE),
.driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER,
PCI_DESCR("Intel Alder Lake SMBus controller") },
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index ca7e78a1cdd5..89d8e54a1843 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -72,7 +72,7 @@ oui RDC 0x00d02d RDC Semiconductor
oui REALTEK 0x00e04c Realtek Semicondctor
oui SEEQ 0x00a07d Seeq Technology
oui SIS 0x00e006 Silicon Integrated Systems
-oui SMC 0x00800f SMC
+oui SMSC 0x00800f Microchip (formerly SMSC)
oui TI 0x080028 Texas Instruments
oui TSC 0x00c039 TDK Semiconductor
oui VITESSE 0x0001c1 Vitesse Semiconductor
@@ -361,6 +361,6 @@ model xxVITESSE VSC8514 0x0027 Vitesse VSC8514 10/100/1000TX PHY
/* XaQti Corp. PHYs */
model xxXAQTI XMACII 0x0000 XaQti Corp. XMAC II gigabit interface
-/* SMC */
-model SMC LAN8710A 0x000F SMC LAN8710A 10/100 interface
-model SMC LAN8700 0x000C SMC LAN8700 10/100 interface
+/* Microchip (formerly SMSC) */
+model SMSC LAN8710A 0x000F Microchip LAN8710A 10/100 interface
+model SMSC LAN8700 0x000C Microchip LAN8700 10/100 interface
diff --git a/sys/dev/mii/smscphy.c b/sys/dev/mii/smscphy.c
index 4e0d3cd3e18e..d578242f5a61 100644
--- a/sys/dev/mii/smscphy.c
+++ b/sys/dev/mii/smscphy.c
@@ -74,8 +74,8 @@ static driver_t smscphy_driver = {
DRIVER_MODULE(smscphy, miibus, smscphy_driver, 0, 0);
static const struct mii_phydesc smscphys[] = {
- MII_PHY_DESC(SMC, LAN8710A),
- MII_PHY_DESC(SMC, LAN8700),
+ MII_PHY_DESC(SMSC, LAN8710A),
+ MII_PHY_DESC(SMSC, LAN8700),
MII_PHY_END
};
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
index 89d2010656c5..b6a9a0c01d09 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c
@@ -596,14 +596,21 @@ mlx5e_tls_rx_work(struct work_struct *work)
if (ptag->flow_rule != NULL)
mlx5e_accel_fs_del_inpcb(ptag->flow_rule);
+ /*
+ * Destroy TIR before DEK. DESTROY_TIR for a TLS-
+ * enabled TIR issues a TRA RX fence that drains all
+ * in-flight packets from the crypto pipeline. If the
+ * DEK were destroyed first, packets still in flight
+ * would hit a TPT encryption error (vendor syndrome
+ * 0x55) because the key they reference is already gone.
+ */
+ if (ptag->tirn != 0)
+ mlx5_tls_close_tir(priv->mdev, ptag->tirn);
+
/* try to destroy DEK context by ID */
if (ptag->dek_index_ok)
mlx5_encryption_key_destroy(priv->mdev, ptag->dek_index);
- /* try to destroy TIR context by ID */
- if (ptag->tirn != 0)
- mlx5_tls_close_tir(priv->mdev, ptag->tirn);
-
/* free tag */
mlx5e_tls_rx_tag_zfree(ptag);
break;
diff --git a/sys/dev/smartpqi/smartpqi_cam.c b/sys/dev/smartpqi/smartpqi_cam.c
index 690b38c9f855..6ded8aa97e39 100644
--- a/sys/dev/smartpqi/smartpqi_cam.c
+++ b/sys/dev/smartpqi/smartpqi_cam.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1300,7 +1300,7 @@ register_sim(struct pqisrc_softstate *softs, int card_index)
csa.callback_arg = softs;
xpt_action((union ccb *)&csa);
if (csa.ccb_h.status != CAM_REQ_CMP) {
- DBG_ERR("Unable to register smartpqi_aysnc handler: %d!\n",
+ DBG_ERR("Unable to register smartpqi_async handler: %d!\n",
csa.ccb_h.status);
}
diff --git a/sys/dev/smartpqi/smartpqi_defines.h b/sys/dev/smartpqi/smartpqi_defines.h
index 0277abd3e318..c4084f069588 100644
--- a/sys/dev/smartpqi/smartpqi_defines.h
+++ b/sys/dev/smartpqi/smartpqi_defines.h
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -944,12 +944,12 @@ typedef uint8_t *passthru_buf_type_t;
#define PQISRC_DRIVER_MAJOR __FreeBSD__
#if __FreeBSD__ <= 14
-#define PQISRC_DRIVER_MINOR 4690
+#define PQISRC_DRIVER_MINOR 4691
#else
#define PQISRC_DRIVER_MINOR 2
#endif
-#define PQISRC_DRIVER_RELEASE 0
-#define PQISRC_DRIVER_REVISION 2008
+#define PQISRC_DRIVER_RELEASE 1
+#define PQISRC_DRIVER_REVISION 2000
#define STR(s) # s
#define PQISRC_VERSION(a, b, c, d) STR(a.b.c-d)
diff --git a/sys/dev/smartpqi/smartpqi_discovery.c b/sys/dev/smartpqi/smartpqi_discovery.c
index a7de5a149810..8682e6cabd7e 100644
--- a/sys/dev/smartpqi/smartpqi_discovery.c
+++ b/sys/dev/smartpqi/smartpqi_discovery.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -155,7 +155,7 @@ pqisrc_remove_target_bit(pqisrc_softstate_t *softs, int target)
softs->bit_map.bit_vector[target] = SLOT_AVAILABLE;
}
-/* Use bit map to find availible targets */
+/* Use bit map to find available targets */
int
pqisrc_find_avail_target(pqisrc_softstate_t *softs)
{
@@ -1423,7 +1423,11 @@ pqisrc_add_device(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
if(device->expose_device) {
pqisrc_init_device_active_io(softs, device);
- /* TBD: Call OS upper layer function to add the device entry */
+ device_printf(softs->os_specific.pqi_dev,
+ "device added: vendor=%s model=%s B%d:T%d:L%d type=%s\n",
+ device->vendor, device->model,
+ device->bus, device->target, device->lun,
+ device->is_physical_device ? "physical" : "logical");
os_add_device(softs,device);
}
DBG_FUNC("OUT\n");
@@ -1451,6 +1455,11 @@ pqisrc_remove_device(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
}
/* Wait for device outstanding Io's */
pqisrc_wait_for_device_commands_to_complete(softs, device);
+ device_printf(softs->os_specific.pqi_dev,
+ "device removed: vendor=%s model=%s B%d:T%d:L%d type=%s\n",
+ device->vendor, device->model,
+ device->bus, device->target, device->lun,
+ device->is_physical_device ? "physical" : "logical");
/* Call OS upper layer function to remove the exposed device entry */
os_remove_device(softs,device);
DBG_FUNC("OUT\n");
@@ -1674,10 +1683,14 @@ pqisrc_update_device_list(pqisrc_softstate_t *softs,
case DEVICE_NOT_FOUND:
/* Device not found in existing list */
device->new_device = true;
+ DBG_DISC("new device found B%d:T%d:L%d\n",
+ device->bus, device->target, device->lun);
break;
case DEVICE_CHANGED:
/* Actual device gone need to add device to list*/
device->new_device = true;
+ DBG_DISC("device changed B%d:T%d:L%d\n",
+ device->bus, device->target, device->lun);
break;
case DEVICE_IN_REMOVE:
/*Older device with same target/lun is in removal stage*/
@@ -1686,6 +1699,8 @@ pqisrc_update_device_list(pqisrc_softstate_t *softs,
* free call*/
device->new_device = false;
same_device->schedule_rescan = true;
+ DBG_DISC("device in removal B%d:T%d:L%d, scheduling rescan\n",
+ device->bus, device->target, device->lun);
break;
default:
break;
diff --git a/sys/dev/smartpqi/smartpqi_event.c b/sys/dev/smartpqi/smartpqi_event.c
index 77a70f9fb031..c3c27c9e1c0b 100644
--- a/sys/dev/smartpqi/smartpqi_event.c
+++ b/sys/dev/smartpqi/smartpqi_event.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -204,6 +204,17 @@ pqisrc_process_event_intr_src(pqisrc_softstate_t *softs,int obq_id)
}
if (event_index >= 0) {
+ static const char *event_names[] = {
+ [PQI_EVENT_HOTPLUG] = "hotplug",
+ [PQI_EVENT_HARDWARE] = "hardware",
+ [PQI_EVENT_PHYSICAL_DEVICE] = "physical device",
+ [PQI_EVENT_LOGICAL_DEVICE] = "logical device",
+ [PQI_EVENT_AIO_STATE_CHANGE] = "AIO state change",
+ [PQI_EVENT_AIO_CONFIG_CHANGE] = "AIO config change",
+ };
+ device_printf(softs->os_specific.pqi_dev,
+ "event: %s (type=0x%x)\n",
+ event_names[event_index], response.event_type);
if(response.request_acknowledge) {
pending_event = &softs->pending_events[event_index];
pending_event->pending = true;
@@ -385,7 +396,7 @@ pqisrc_report_event_config(pqisrc_softstate_t *softs)
pqi_event_config_request_t request;
pqi_event_config_t *event_config_p ;
dma_mem_t buf_report_event ;
- /*bytes to be allocaed for report event config data-in buffer */
+ /*bytes to be allocated for report event config data-in buffer */
uint32_t alloc_size = sizeof(pqi_event_config_t) ;
memset(&request, 0 , sizeof(request));
@@ -446,7 +457,7 @@ pqisrc_set_event_config(pqisrc_softstate_t *softs)
pqi_event_config_request_t request;
pqi_event_config_t *event_config_p;
dma_mem_t buf_set_event;
- /*bytes to be allocaed for set event config data-out buffer */
+ /*bytes to be allocated for set event config data-out buffer */
uint32_t alloc_size = sizeof(pqi_event_config_t);
memset(&request, 0 , sizeof(request));
diff --git a/sys/dev/smartpqi/smartpqi_main.c b/sys/dev/smartpqi/smartpqi_main.c
index 1f006939bf7c..fbfbcc962f35 100644
--- a/sys/dev/smartpqi/smartpqi_main.c
+++ b/sys/dev/smartpqi/smartpqi_main.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -427,6 +427,16 @@ smartpqi_attach(device_t dev)
goto out;
}
+ /* Register sysctl for runtime debug_level changes */
+ {
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
+ struct sysctl_oid *tree = device_get_sysctl_tree(dev);
+
+ SYSCTL_ADD_ULONG(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "debug_level", CTLFLAG_RW, &logging_level,
+ "Debug logging bitmask");
+ }
+
goto out;
dma_out:
diff --git a/sys/dev/smartpqi/smartpqi_misc.c b/sys/dev/smartpqi/smartpqi_misc.c
index 6db0d80ed993..fd0b907aa252 100644
--- a/sys/dev/smartpqi/smartpqi_misc.c
+++ b/sys/dev/smartpqi/smartpqi_misc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -252,7 +252,7 @@ bsd_set_hint_scatter_gather_config(struct pqisrc_softstate *softs)
DBG_FUNC("IN\n");
- /* At least > 16 sg's required to wotk hint correctly.
+ /* At least > 16 sg's required to work hint correctly.
* Default the sg count set by driver/controller. */
if ((!softs->hint.sg_segments) || (softs->hint.sg_segments >
diff --git a/sys/dev/smartpqi/smartpqi_queue.c b/sys/dev/smartpqi/smartpqi_queue.c
index e8a467531aa4..679d956f6f36 100644
--- a/sys/dev/smartpqi/smartpqi_queue.c
+++ b/sys/dev/smartpqi/smartpqi_queue.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -729,7 +729,7 @@ pqisrc_create_op_ibq(pqisrc_softstate_t *softs,
op_ib_q->pi_register_offset);
} else {
int i = 0;
- DBG_WARN("Error Status Decsriptors\n");
+ DBG_WARN("Error Status Descriptors\n");
for (i = 0; i < 4; i++)
DBG_WARN(" %x\n",admin_resp.resp_type.create_op_iq.status_desc[i]);
}
diff --git a/sys/dev/smartpqi/smartpqi_request.c b/sys/dev/smartpqi/smartpqi_request.c
index c5f8ac3c41ba..655660615797 100644
--- a/sys/dev/smartpqi/smartpqi_request.c
+++ b/sys/dev/smartpqi/smartpqi_request.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1998,7 +1998,7 @@ pqisrc_send_raid_tmf(pqisrc_softstate_t *softs, pqi_scsi_dev_t const *devp,
if (softs->timeout_in_tmf &&
tmf_type == SOP_TASK_MANAGEMENT_LUN_RESET) {
- /* OS_TMF_TIMEOUT_SEC - 1 to accomodate driver processing */
+ /* OS_TMF_TIMEOUT_SEC - 1 to accommodate driver processing */
tmf_req.timeout_in_sec = OS_TMF_TIMEOUT_SEC - 1;
}
diff --git a/sys/dev/smartpqi/smartpqi_response.c b/sys/dev/smartpqi/smartpqi_response.c
index 38695860e520..1ae74a5b95ff 100644
--- a/sys/dev/smartpqi/smartpqi_response.c
+++ b/sys/dev/smartpqi/smartpqi_response.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -275,7 +275,7 @@ pqisrc_is_innocuous_error(pqisrc_softstate_t *softs, rcb_t *rcb, void *err_info)
if (raid_err->data_out_result == PQI_RAID_DATA_IN_OUT_UNDERFLOW)
return true;
- /* We get these a alot: leave a tiny breadcrumb about the error,
+ /* We get these a lot: leave a tiny breadcrumb about the error,
but don't do full spew about it */
if (raid_err->status == PQI_AIO_STATUS_CHECK_CONDITION)
{
diff --git a/sys/dev/smartpqi/smartpqi_sis.c b/sys/dev/smartpqi/smartpqi_sis.c
index 82eb999ca4b8..99aa952eb149 100644
--- a/sys/dev/smartpqi/smartpqi_sis.c
+++ b/sys/dev/smartpqi/smartpqi_sis.c
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
#include "smartpqi_includes.h"
-/* Function for disabling msix interrupots */
+/* Function for disabling msix interrupts */
void
sis_disable_msix(pqisrc_softstate_t *softs)
{
@@ -96,7 +96,7 @@ sis_disable_interrupt(pqisrc_softstate_t *softs)
sis_disable_msix(softs);
break;
default:
- DBG_ERR("Inerrupt mode none!\n");
+ DBG_ERR("Interrupt mode none!\n");
break;
}
diff --git a/sys/dev/smartpqi/smartpqi_structures.h b/sys/dev/smartpqi/smartpqi_structures.h
index 0c9ad375823d..ada6676ada8f 100644
--- a/sys/dev/smartpqi/smartpqi_structures.h
+++ b/sys/dev/smartpqi/smartpqi_structures.h
@@ -1,5 +1,5 @@
/*-
- * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries.
+ * Copyright 2016-2026 Microchip Technology, Inc. and/or its subsidiaries.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1168,7 +1168,7 @@ typedef struct bmic_sense_feature_page_header {
uint8_t page;
uint8_t sub_page;
uint16_t total_length; /** Total length of the page.
- * The length is the same wheteher the request buffer is too short or not.
+ * The length is the same whether the request buffer is too short or not.
* When printing out the page, only print the buffer length. */
} OS_ATTRIBUTE_PACKED bmic_sense_feature_page_header_t;
diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c
index 8e16b8609144..c3c21fd22472 100644
--- a/sys/dev/usb/net/if_smsc.c
+++ b/sys/dev/usb/net/if_smsc.c
@@ -1296,7 +1296,7 @@ smsc_phy_init(struct smsc_softc *sc)
} while ((bmcr & BMCR_RESET) && ((ticks - start_ticks) < max_ticks));
if (((usb_ticks_t)(ticks - start_ticks)) >= max_ticks) {
- smsc_err_printf(sc, "PHY reset timed-out");
+ smsc_err_printf(sc, "PHY reset timed-out\n");
return (EIO);
}
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 40792482672c..ef01833b9e03 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -96,17 +96,6 @@
#define VTNET_ETHER_ALIGN ETHER_ALIGN
#endif
-/*
- * Worst case offset to ensure header doesn't share any cache lines with
- * payload.
- */
-#define VTNET_RX_BUFFER_HEADER_OFFSET 128
-
-struct vtnet_rx_buffer_header {
- bus_addr_t addr;
- bus_dmamap_t dmap;
-};
-
static int vtnet_modevent(module_t, int, void *);
static int vtnet_probe(device_t);
@@ -219,7 +208,7 @@ static void vtnet_init_locked(struct vtnet_softc *, int);
static void vtnet_init(void *);
static void vtnet_free_ctrl_vq(struct vtnet_softc *);
-static int vtnet_exec_ctrl_cmd(struct vtnet_softc *, uint8_t *,
+static void vtnet_exec_ctrl_cmd(struct vtnet_softc *, void *,
struct sglist *, int, int);
static int vtnet_ctrl_mac_cmd(struct vtnet_softc *, uint8_t *);
static int vtnet_ctrl_guest_offloads(struct vtnet_softc *, uint64_t);
@@ -395,17 +384,6 @@ MODULE_DEPEND(vtnet, netmap, 1, 1, 1);
VIRTIO_SIMPLE_PNPINFO(vtnet, VIRTIO_ID_NETWORK, "VirtIO Networking Adapter");
-static struct vtnet_rx_buffer_header *
-vtnet_mbuf_to_rx_buffer_header(struct vtnet_softc *sc, struct mbuf *m)
-{
- if (VTNET_ETHER_ALIGN != 0 && sc->vtnet_hdr_size % 4 == 0)
- return (struct vtnet_rx_buffer_header *)((uintptr_t)m->m_data -
- VTNET_RX_BUFFER_HEADER_OFFSET - VTNET_ETHER_ALIGN);
- else
- return (struct vtnet_rx_buffer_header *)((uintptr_t)m->m_data -
- VTNET_RX_BUFFER_HEADER_OFFSET);
-}
-
static int
vtnet_modevent(module_t mod __unused, int type, void *unused __unused)
{
@@ -479,106 +457,6 @@ vtnet_attach(device_t dev)
goto fail;
}
- mtx_init(&sc->vtnet_rx_mtx, device_get_nameunit(dev),
- "VirtIO Net RX lock", MTX_DEF);
-
- error = bus_dma_tag_create(
- bus_get_dma_tag(dev), /* parent */
- sizeof(uint16_t), /* alignment */
- 0, /* boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MJUM9BYTES, /* max request size */
- 1, /* max # segments */
- MJUM9BYTES, /* maxsegsize - worst case */
- BUS_DMA_COHERENT, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->vtnet_rx_mtx, /* lockarg */
- &sc->vtnet_rx_dmat);
- if (error) {
- device_printf(dev, "cannot create bus_dma_tag\n");
- goto fail;
- }
-
- mtx_init(&sc->vtnet_tx_mtx, device_get_nameunit(dev),
- "VirtIO Net TX lock", MTX_DEF);
-
- error = bus_dma_tag_create(
- bus_get_dma_tag(dev), /* parent */
- sizeof(uint16_t), /* alignment */
- 0, /* boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- sc->vtnet_tx_nsegs * MJUM9BYTES, /* max request size */
- sc->vtnet_tx_nsegs, /* max # segments */
- MJUM9BYTES, /* maxsegsize */
- BUS_DMA_COHERENT, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->vtnet_tx_mtx, /* lockarg */
- &sc->vtnet_tx_dmat);
- if (error) {
- device_printf(dev, "cannot create bus_dma_tag\n");
- goto fail;
- }
-
- mtx_init(&sc->vtnet_hdr_mtx, device_get_nameunit(dev),
- "VirtIO Net header lock", MTX_DEF);
-
- error = bus_dma_tag_create(
- bus_get_dma_tag(dev), /* parent */
- sizeof(uint16_t), /* alignment */
- 0, /* boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- PAGE_SIZE, /* max request size */
- 1, /* max # segments */
- PAGE_SIZE, /* maxsegsize */
- BUS_DMA_COHERENT, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->vtnet_hdr_mtx, /* lockarg */
- &sc->vtnet_hdr_dmat);
- if (error) {
- device_printf(dev, "cannot create bus_dma_tag\n");
- goto fail;
- }
-
- mtx_init(&sc->vtnet_ack_mtx, device_get_nameunit(dev),
- "VirtIO Net ACK lock", MTX_DEF);
-
- error = bus_dma_tag_create(
- bus_get_dma_tag(dev), /* parent */
- sizeof(uint8_t), /* alignment */
- 0, /* boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- sizeof(uint8_t), /* max request size */
- 1, /* max # segments */
- sizeof(uint8_t), /* maxsegsize */
- BUS_DMA_COHERENT, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->vtnet_ack_mtx, /* lockarg */
- &sc->vtnet_ack_dmat);
- if (error) {
- device_printf(dev, "cannot create bus_dma_tag\n");
- goto fail;
- }
-
-#ifdef __powerpc__
- /*
- * Virtio uses physical addresses rather than bus addresses, so we
- * need to ask busdma to skip the iommu physical->bus mapping. At
- * present, this is only a thing on the powerpc architectures.
- */
- bus_dma_tag_set_iommu(sc->vtnet_rx_dmat, NULL, NULL);
- bus_dma_tag_set_iommu(sc->vtnet_tx_dmat, NULL, NULL);
- bus_dma_tag_set_iommu(sc->vtnet_hdr_dmat, NULL, NULL);
- bus_dma_tag_set_iommu(sc->vtnet_ack_dmat, NULL, NULL);
-#endif
-
error = vtnet_alloc_rx_filters(sc);
if (error) {
device_printf(dev, "cannot allocate Rx filters\n");
@@ -1667,11 +1545,6 @@ static struct mbuf *
vtnet_rx_alloc_buf(struct vtnet_softc *sc, int nbufs, struct mbuf **m_tailp)
{
struct mbuf *m_head, *m_tail, *m;
- struct vtnet_rx_buffer_header *vthdr;
- bus_dma_segment_t segs[1];
- bus_dmamap_t dmap;
- int nsegs;
- int err;
int i, size;
m_head = NULL;
@@ -1689,43 +1562,13 @@ vtnet_rx_alloc_buf(struct vtnet_softc *sc, int nbufs, struct mbuf **m_tailp)
}
m->m_len = size;
- vthdr = (struct vtnet_rx_buffer_header *)m->m_data;
-
- /* Reserve space for header */
- m_adj(m, VTNET_RX_BUFFER_HEADER_OFFSET);
-
/*
* Need to offset the mbuf if the header we're going to add
* will misalign.
*/
- if (VTNET_ETHER_ALIGN != 0 && sc->vtnet_hdr_size % 4 == 0)
+ if (VTNET_ETHER_ALIGN != 0 && sc->vtnet_hdr_size % 4 == 0) {
m_adj(m, VTNET_ETHER_ALIGN);
-
- err = bus_dmamap_create(sc->vtnet_rx_dmat, 0, &dmap);
- if (err) {
- printf("Failed to create dmamap, err :%d\n",
- err);
- m_freem(m);
- return (NULL);
- }
-
- nsegs = 0;
- err = bus_dmamap_load_mbuf_sg(sc->vtnet_rx_dmat, dmap, m, segs,
- &nsegs, BUS_DMA_NOWAIT);
- if (err != 0) {
- printf("Failed to map mbuf into DMA visible memory, err: %d\n",
- err);
- m_freem(m);
- bus_dmamap_destroy(sc->vtnet_rx_dmat, dmap);
- return (NULL);
}
- KASSERT(nsegs == 1,
- ("%s: unexpected number of DMA segments for rx buffer: %d",
- __func__, nsegs));
-
- vthdr->addr = segs[0].ds_addr;
- vthdr->dmap = dmap;
-
if (m_head != NULL) {
m_tail->m_next = m;
m_tail = m;
@@ -1751,7 +1594,7 @@ vtnet_rxq_replace_lro_nomrg_buf(struct vtnet_rxq *rxq, struct mbuf *m0,
int len, clustersz, nreplace, error;
sc = rxq->vtnrx_sc;
- clustersz = sc->vtnet_rx_clustersz - VTNET_RX_BUFFER_HEADER_OFFSET;
+ clustersz = sc->vtnet_rx_clustersz;
/*
* Need to offset the mbuf if the header we're going to add will
* misalign, account for that here.
@@ -1866,12 +1709,9 @@ vtnet_rxq_replace_buf(struct vtnet_rxq *rxq, struct mbuf *m, int len)
static int
vtnet_rxq_enqueue_buf(struct vtnet_rxq *rxq, struct mbuf *m)
{
- struct vtnet_rx_buffer_header *hdr;
struct vtnet_softc *sc;
struct sglist *sg;
int header_inlined, error;
- bus_addr_t paddr;
- struct mbuf *mp;
sc = rxq->vtnrx_sc;
sg = rxq->vtnrx_sg;
@@ -1884,38 +1724,28 @@ vtnet_rxq_enqueue_buf(struct vtnet_rxq *rxq, struct mbuf *m)
header_inlined = vtnet_modern(sc) ||
(sc->vtnet_flags & VTNET_FLAG_MRG_RXBUFS) != 0; /* TODO: ANY_LAYOUT */
- hdr = vtnet_mbuf_to_rx_buffer_header(sc, m);
- paddr = hdr->addr;
-
/*
* Note: The mbuf has been already adjusted when we allocate it if we
* have to do strict alignment.
*/
- if (header_inlined) {
- error = sglist_append_phys(sg, paddr, m->m_len);
- } else {
+ if (header_inlined)
+ error = sglist_append_mbuf(sg, m);
+ else {
+ struct vtnet_rx_header *rxhdr =
+ mtod(m, struct vtnet_rx_header *);
MPASS(sc->vtnet_hdr_size == sizeof(struct virtio_net_hdr));
/* Append the header and remaining mbuf data. */
- error = sglist_append_phys(sg, paddr, sc->vtnet_hdr_size);
+ error = sglist_append(sg, &rxhdr->vrh_hdr, sc->vtnet_hdr_size);
if (error)
return (error);
- error = sglist_append_phys(sg,
- paddr + sizeof(struct vtnet_rx_header),
+ error = sglist_append(sg, &rxhdr[1],
m->m_len - sizeof(struct vtnet_rx_header));
if (error)
return (error);
- mp = m->m_next;
- while (mp) {
- hdr = vtnet_mbuf_to_rx_buffer_header(sc, mp);
- paddr = hdr->addr;
- error = sglist_append_phys(sg, paddr, mp->m_len);
- if (error)
- return (error);
-
- mp = mp->m_next;
- }
+ if (m->m_next != NULL)
+ error = sglist_append_mbuf(sg, m->m_next);
}
if (error)
@@ -2101,7 +1931,6 @@ vtnet_rxq_merged_eof(struct vtnet_rxq *rxq, struct mbuf *m_head, int nbufs)
m_tail = m_head;
while (--nbufs > 0) {
- struct vtnet_rx_buffer_header *vthdr;
struct mbuf *m;
uint32_t len;
@@ -2111,10 +1940,6 @@ vtnet_rxq_merged_eof(struct vtnet_rxq *rxq, struct mbuf *m_head, int nbufs)
goto fail;
}
- vthdr = vtnet_mbuf_to_rx_buffer_header(sc, m);
- bus_dmamap_sync(sc->vtnet_rx_dmat, vthdr->dmap,
- BUS_DMASYNC_POSTREAD);
-
if (vtnet_rxq_new_buf(rxq) != 0) {
rxq->vtnrx_stats.vrxs_iqdrops++;
vtnet_rxq_discard_buf(rxq, m);
@@ -2235,7 +2060,6 @@ static int
vtnet_rxq_eof(struct vtnet_rxq *rxq)
{
struct virtio_net_hdr lhdr, *hdr;
- struct vtnet_rx_buffer_header *vthdr;
struct vtnet_softc *sc;
if_t ifp;
struct virtqueue *vq;
@@ -2251,31 +2075,14 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq)
CURVNET_SET(if_getvnet(ifp));
while (count-- > 0) {
- struct mbuf *m, *mp;
+ struct mbuf *m;
uint32_t len, nbufs, adjsz;
- uint32_t synced;
m = virtqueue_dequeue(vq, &len);
if (m == NULL)
break;
deq++;
- mp = m;
-
- /*
- * Sync all mbufs in this packet. There will only be a single
- * mbuf unless LRO is in use.
- */
- synced = 0;
- while (mp && synced < len) {
- vthdr = vtnet_mbuf_to_rx_buffer_header(sc, mp);
- bus_dmamap_sync(sc->vtnet_rx_dmat, vthdr->dmap,
- BUS_DMASYNC_POSTREAD);
-
- synced += mp->m_len;
- mp = mp->m_next;
- }
-
if (len < sc->vtnet_hdr_size + ETHER_HDR_LEN) {
rxq->vtnrx_stats.vrxs_ierrors++;
vtnet_rxq_discard_buf(rxq, m);
@@ -2535,14 +2342,6 @@ vtnet_txq_free_mbufs(struct vtnet_txq *txq)
while ((txhdr = virtqueue_drain(vq, &last)) != NULL) {
if (kring == NULL) {
- bus_dmamap_unload(txq->vtntx_sc->vtnet_tx_dmat,
- txhdr->dmap);
- bus_dmamap_destroy(txq->vtntx_sc->vtnet_tx_dmat,
- txhdr->dmap);
- bus_dmamap_unload(txq->vtntx_sc->vtnet_tx_dmat,
- txhdr->hdr_dmap);
- bus_dmamap_destroy(txq->vtntx_sc->vtnet_tx_dmat,
- txhdr->hdr_dmap);
m_freem(txhdr->vth_mbuf);
uma_zfree(vtnet_tx_header_zone, txhdr);
}
@@ -2712,36 +2511,15 @@ drop:
return (NULL);
}
-static void
-vtnet_txq_enqueue_callback(void *arg, bus_dma_segment_t *segs,
- int nsegs, int error)
-{
- vm_paddr_t *hdr_paddr;
-
- if (error != 0)
- return;
-
- KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
-
- hdr_paddr = (vm_paddr_t *)arg;
- *hdr_paddr = segs[0].ds_addr;
-}
-
static int
vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
struct vtnet_tx_header *txhdr)
{
- bus_dma_segment_t segs[VTNET_TX_SEGS_MAX];
- int nsegs;
struct vtnet_softc *sc;
struct virtqueue *vq;
struct sglist *sg;
struct mbuf *m;
int error;
- vm_paddr_t hdr_paddr;
- bus_dmamap_t hdr_dmap;
- bus_dmamap_t dmap;
- int i;
sc = txq->vtntx_sc;
vq = txq->vtntx_vq;
@@ -2749,55 +2527,15 @@ vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
m = *m_head;
sglist_reset(sg);
-
- error = bus_dmamap_create(sc->vtnet_tx_dmat, 0, &hdr_dmap);
- if (error)
- goto fail;
-
- error = bus_dmamap_load(sc->vtnet_tx_dmat, hdr_dmap, &txhdr->vth_uhdr,
- sc->vtnet_hdr_size, vtnet_txq_enqueue_callback, &hdr_paddr,
- BUS_DMA_NOWAIT);
- if (error)
- goto fail_hdr_dmamap_destroy;
-
- error = sglist_append_phys(sg, hdr_paddr, sc->vtnet_hdr_size);
+ error = sglist_append(sg, &txhdr->vth_uhdr, sc->vtnet_hdr_size);
if (error != 0 || sg->sg_nseg != 1) {
KASSERT(0, ("%s: cannot add header to sglist error %d nseg %d",
__func__, error, sg->sg_nseg));
- goto fail_hdr_dmamap_unload;
+ goto fail;
}
- bus_dmamap_sync(sc->vtnet_tx_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
-
- error = bus_dmamap_create(sc->vtnet_tx_dmat, 0, &dmap);
- if (error)
- goto fail_hdr_dmamap_unload;
-
- nsegs = 0;
- error = bus_dmamap_load_mbuf_sg(sc->vtnet_tx_dmat, dmap, m, segs,
- &nsegs, BUS_DMA_NOWAIT);
- if (error != 0)
- goto fail_dmamap_destroy;
- KASSERT(nsegs <= sc->vtnet_tx_nsegs,
- ("%s: unexpected number of DMA segments for tx buffer: %d (max %d)",
- __func__, nsegs, sc->vtnet_tx_nsegs));
-
- bus_dmamap_sync(sc->vtnet_tx_dmat, dmap, BUS_DMASYNC_PREWRITE);
-
- for (i = 0; i < nsegs && !error; i++)
- error = sglist_append_phys(sg, segs[i].ds_addr, segs[i].ds_len);
-
+ error = sglist_append_mbuf(sg, m);
if (error) {
- sglist_reset(sg);
- bus_dmamap_unload(sc->vtnet_tx_dmat, dmap);
-
- error = sglist_append_phys(sg, hdr_paddr, sc->vtnet_hdr_size);
- if (error != 0 || sg->sg_nseg != 1) {
- KASSERT(0, ("%s: cannot add header to sglist error %d nseg %d",
- __func__, error, sg->sg_nseg));
- goto fail_dmamap_destroy;
- }
-
m = m_defrag(m, M_NOWAIT);
if (m == NULL) {
sc->vtnet_stats.tx_defrag_failed++;
@@ -2807,41 +2545,16 @@ vtnet_txq_enqueue_buf(struct vtnet_txq *txq, struct mbuf **m_head,
*m_head = m;
sc->vtnet_stats.tx_defragged++;
- nsegs = 0;
- error = bus_dmamap_load_mbuf_sg(sc->vtnet_tx_dmat, dmap, m,
- segs, &nsegs, BUS_DMA_NOWAIT);
- if (error != 0)
- goto fail_dmamap_destroy;
- KASSERT(nsegs <= sc->vtnet_tx_nsegs,
- ("%s: unexpected number of DMA segments for tx buffer: %d (max %d)",
- __func__, nsegs, sc->vtnet_tx_nsegs));
-
- bus_dmamap_sync(sc->vtnet_tx_dmat, dmap, BUS_DMASYNC_PREWRITE);
-
- for (i = 0; i < nsegs && !error; i++)
- error = sglist_append_phys(sg, segs[i].ds_addr,
- segs[i].ds_len);
-
+ error = sglist_append_mbuf(sg, m);
if (error)
- goto fail_dmamap_unload;
+ goto fail;
}
txhdr->vth_mbuf = m;
- txhdr->dmap = dmap;
- txhdr->hdr_dmap = hdr_dmap;
-
error = virtqueue_enqueue(vq, txhdr, sg, sg->sg_nseg, 0);
return (error);
-fail_dmamap_unload:
- bus_dmamap_unload(sc->vtnet_tx_dmat, dmap);
-fail_dmamap_destroy:
- bus_dmamap_destroy(sc->vtnet_tx_dmat, dmap);
-fail_hdr_dmamap_unload:
- bus_dmamap_unload(sc->vtnet_tx_dmat, hdr_dmap);
-fail_hdr_dmamap_destroy:
- bus_dmamap_destroy(sc->vtnet_tx_dmat, hdr_dmap);
fail:
m_freem(*m_head);
*m_head = NULL;
@@ -3797,43 +3510,10 @@ vtnet_free_ctrl_vq(struct vtnet_softc *sc)
}
static void
-vtnet_load_callback(void *arg, bus_dma_segment_t *segs, int nsegs,
- int error)
-{
- bus_addr_t *paddr;
-
- if (error != 0)
- return;
-
- KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
-
- paddr = (bus_addr_t *)arg;
- *paddr = segs[0].ds_addr;
-}
-
-static int
-vtnet_exec_ctrl_cmd(struct vtnet_softc *sc, uint8_t *ack, struct sglist *sg,
- int readable, int writable)
+vtnet_exec_ctrl_cmd(struct vtnet_softc *sc, void *cookie,
+ struct sglist *sg, int readable, int writable)
{
- bus_dmamap_t ack_dmap;
- bus_addr_t ack_paddr;
struct virtqueue *vq;
- int error;
-
- error = bus_dmamap_create(sc->vtnet_ack_dmat, 0, &ack_dmap);
- if (error)
- goto error_out;
-
- error = bus_dmamap_load(sc->vtnet_ack_dmat, ack_dmap, ack,
- sizeof(uint8_t), vtnet_load_callback, &ack_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto error_destroy;
-
- bus_dmamap_sync(sc->vtnet_ack_dmat, ack_dmap, BUS_DMASYNC_PREWRITE);
-
- error = sglist_append_phys(sg, ack_paddr, sizeof(uint8_t));
- if (error)
- goto error_unload;
vq = sc->vtnet_ctrl_vq;
@@ -3841,237 +3521,152 @@ vtnet_exec_ctrl_cmd(struct vtnet_softc *sc, uint8_t *ack, struct sglist *sg,
VTNET_CORE_LOCK_ASSERT(sc);
if (!virtqueue_empty(vq))
- goto error_unload;
+ return;
/*
* Poll for the response, but the command is likely completed before
* returning from the notify.
*/
- if (virtqueue_enqueue(vq, (void *)ack, sg, readable, writable) == 0) {
+ if (virtqueue_enqueue(vq, cookie, sg, readable, writable) == 0) {
virtqueue_notify(vq);
virtqueue_poll(vq, NULL);
}
-
- bus_dmamap_sync(sc->vtnet_ack_dmat, ack_dmap, BUS_DMASYNC_POSTREAD);
-
-error_unload:
- bus_dmamap_unload(sc->vtnet_ack_dmat, ack_dmap);
-error_destroy:
- bus_dmamap_destroy(sc->vtnet_ack_dmat, ack_dmap);
-error_out:
- return (error);
}
static int
vtnet_ctrl_mac_cmd(struct vtnet_softc *sc, uint8_t *hwaddr)
{
struct sglist_seg segs[3];
- bus_dmamap_t hdr_dmap;
- bus_addr_t hdr_paddr;
struct sglist sg;
struct {
struct virtio_net_ctrl_hdr hdr __aligned(2);
uint8_t pad1;
uint8_t addr[ETHER_ADDR_LEN] __aligned(8);
uint8_t pad2;
+ uint8_t ack;
} s;
- uint8_t ack;
int error;
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap);
- if (error)
- goto error_out;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &s,
- sizeof(s), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto error_destroy_hdr;
-
+ error = 0;
MPASS(sc->vtnet_flags & VTNET_FLAG_CTRL_MAC);
s.hdr.class = VIRTIO_NET_CTRL_MAC;
s.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
bcopy(hwaddr, &s.addr[0], ETHER_ADDR_LEN);
- ack = VIRTIO_NET_ERR;
- bus_dmamap_sync(sc->vtnet_hdr_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
+ s.ack = VIRTIO_NET_ERR;
sglist_init(&sg, nitems(segs), segs);
- error |= sglist_append_phys(&sg, hdr_paddr,
- sizeof(struct virtio_net_ctrl_hdr));
- error |= sglist_append_phys(&sg,
- hdr_paddr + ((uintptr_t)&s.addr - (uintptr_t)&s),
- ETHER_ADDR_LEN);
- MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1);
+ error |= sglist_append(&sg, &s.hdr, sizeof(struct virtio_net_ctrl_hdr));
+ error |= sglist_append(&sg, &s.addr[0], ETHER_ADDR_LEN);
+ error |= sglist_append(&sg, &s.ack, sizeof(uint8_t));
+ MPASS(error == 0 && sg.sg_nseg == nitems(segs));
if (error == 0)
- error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1);
- if (error == 0)
- error = (ack == VIRTIO_NET_OK ? 0 : EIO);
+ vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, sg.sg_nseg - 1, 1);
- bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap);
-error_destroy_hdr:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap);
-error_out:
- return (error);
+ return (s.ack == VIRTIO_NET_OK ? 0 : EIO);
}
static int
vtnet_ctrl_guest_offloads(struct vtnet_softc *sc, uint64_t offloads)
{
struct sglist_seg segs[3];
- bus_dmamap_t hdr_dmap;
- bus_addr_t hdr_paddr;
struct sglist sg;
struct {
struct virtio_net_ctrl_hdr hdr __aligned(2);
uint8_t pad1;
uint64_t offloads __aligned(8);
uint8_t pad2;
+ uint8_t ack;
} s;
- uint8_t ack;
int error;
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap);
- if (error)
- goto error_out;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &s,
- sizeof(s), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto error_destroy_hdr;
-
+ error = 0;
MPASS(sc->vtnet_features & VIRTIO_NET_F_CTRL_GUEST_OFFLOADS);
s.hdr.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
s.hdr.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
s.offloads = vtnet_gtoh64(sc, offloads);
- ack = VIRTIO_NET_ERR;
- bus_dmamap_sync(sc->vtnet_hdr_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
+ s.ack = VIRTIO_NET_ERR;
sglist_init(&sg, nitems(segs), segs);
- error |= sglist_append_phys(&sg, hdr_paddr,
- sizeof(struct virtio_net_ctrl_hdr));
- error |= sglist_append_phys(&sg,
- hdr_paddr + ((uintptr_t)&s.offloads - (uintptr_t)&s),
- sizeof(uint64_t));
- MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1);
+ error |= sglist_append(&sg, &s.hdr, sizeof(struct virtio_net_ctrl_hdr));
+ error |= sglist_append(&sg, &s.offloads, sizeof(uint64_t));
+ error |= sglist_append(&sg, &s.ack, sizeof(uint8_t));
+ MPASS(error == 0 && sg.sg_nseg == nitems(segs));
if (error == 0)
- error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1);
- if (error == 0)
- error = (ack == VIRTIO_NET_OK ? 0 : EIO);
+ vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, sg.sg_nseg - 1, 1);
- bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap);
-error_destroy_hdr:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap);
-error_out:
- return (error);
+ return (s.ack == VIRTIO_NET_OK ? 0 : EIO);
}
static int
vtnet_ctrl_mq_cmd(struct vtnet_softc *sc, uint16_t npairs)
{
struct sglist_seg segs[3];
- bus_dmamap_t hdr_dmap;
- bus_addr_t hdr_paddr;
struct sglist sg;
struct {
struct virtio_net_ctrl_hdr hdr __aligned(2);
uint8_t pad1;
struct virtio_net_ctrl_mq mq __aligned(2);
uint8_t pad2;
+ uint8_t ack;
} s;
- uint8_t ack;
int error;
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap);
- if (error)
- goto error_out;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &s,
- sizeof(s), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto error_destroy_hdr;
-
+ error = 0;
MPASS(sc->vtnet_flags & VTNET_FLAG_MQ);
s.hdr.class = VIRTIO_NET_CTRL_MQ;
s.hdr.cmd = VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET;
s.mq.virtqueue_pairs = vtnet_gtoh16(sc, npairs);
- ack = VIRTIO_NET_ERR;
- bus_dmamap_sync(sc->vtnet_hdr_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
+ s.ack = VIRTIO_NET_ERR;
sglist_init(&sg, nitems(segs), segs);
- error |= sglist_append_phys(&sg, hdr_paddr,
- sizeof(struct virtio_net_ctrl_hdr));
- error |= sglist_append_phys(&sg,
- hdr_paddr + ((uintptr_t)&s.mq - (uintptr_t)&s),
- sizeof(struct virtio_net_ctrl_mq));
- MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1);
+ error |= sglist_append(&sg, &s.hdr, sizeof(struct virtio_net_ctrl_hdr));
+ error |= sglist_append(&sg, &s.mq, sizeof(struct virtio_net_ctrl_mq));
+ error |= sglist_append(&sg, &s.ack, sizeof(uint8_t));
+ MPASS(error == 0 && sg.sg_nseg == nitems(segs));
if (error == 0)
- error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1);
- if (error == 0)
- error = (ack == VIRTIO_NET_OK ? 0 : EIO);
+ vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, sg.sg_nseg - 1, 1);
- bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap);
-error_destroy_hdr:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap);
-error_out:
- return (error);
+ return (s.ack == VIRTIO_NET_OK ? 0 : EIO);
}
static int
vtnet_ctrl_rx_cmd(struct vtnet_softc *sc, uint8_t cmd, bool on)
{
struct sglist_seg segs[3];
- bus_dmamap_t hdr_dmap;
- bus_addr_t hdr_paddr;
struct sglist sg;
struct {
struct virtio_net_ctrl_hdr hdr __aligned(2);
uint8_t pad1;
uint8_t onoff;
uint8_t pad2;
+ uint8_t ack;
} s;
- uint8_t ack;
int error;
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap);
- if (error)
- goto error_out;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &s,
- sizeof(s), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto error_destroy_hdr;
-
+ error = 0;
MPASS(sc->vtnet_flags & VTNET_FLAG_CTRL_RX);
s.hdr.class = VIRTIO_NET_CTRL_RX;
s.hdr.cmd = cmd;
s.onoff = on;
- ack = VIRTIO_NET_ERR;
- bus_dmamap_sync(sc->vtnet_hdr_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
+ s.ack = VIRTIO_NET_ERR;
sglist_init(&sg, nitems(segs), segs);
- error |= sglist_append_phys(&sg, hdr_paddr,
- sizeof(struct virtio_net_ctrl_hdr));
- error |= sglist_append_phys(&sg,
- hdr_paddr + ((uintptr_t)&s.onoff - (uintptr_t)&s),
- sizeof(uint8_t));
- MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1);
+ error |= sglist_append(&sg, &s.hdr, sizeof(struct virtio_net_ctrl_hdr));
+ error |= sglist_append(&sg, &s.onoff, sizeof(uint8_t));
+ error |= sglist_append(&sg, &s.ack, sizeof(uint8_t));
+ MPASS(error == 0 && sg.sg_nseg == nitems(segs));
if (error == 0)
- error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1);
- if (error == 0)
- error = (ack == VIRTIO_NET_OK ? 0 : EIO);
+ vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, sg.sg_nseg - 1, 1);
- bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap);
-error_destroy_hdr:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap);
-error_out:
- return (error);
+ return (s.ack == VIRTIO_NET_OK ? 0 : EIO);
}
static int
@@ -4142,10 +3737,6 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc)
struct virtio_net_ctrl_hdr hdr __aligned(2);
struct vtnet_mac_filter *filter;
struct sglist_seg segs[4];
- bus_dmamap_t filter_dmap;
- bus_addr_t filter_paddr;
- bus_dmamap_t hdr_dmap;
- bus_addr_t hdr_paddr;
struct sglist sg;
if_t ifp;
bool promisc, allmulti;
@@ -4185,25 +3776,6 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc)
if (promisc && allmulti)
goto out;
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap);
- if (error)
- goto out_error;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &hdr,
- sizeof(hdr), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto out_destroy_hdr;
-
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &filter_dmap);
- if (error)
- goto out_unload_hdr;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, filter,
- sizeof(*filter), vtnet_load_callback, &filter_paddr,
- BUS_DMA_NOWAIT);
- if (error)
- goto out_destroy_filter;
-
filter->vmf_unicast.nentries = vtnet_gtoh32(sc, ucnt);
filter->vmf_multicast.nentries = vtnet_gtoh32(sc, mcnt);
@@ -4212,33 +3784,19 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc)
ack = VIRTIO_NET_ERR;
sglist_init(&sg, nitems(segs), segs);
- error |= sglist_append_phys(&sg, hdr_paddr,
- sizeof(struct virtio_net_ctrl_hdr));
- error |= sglist_append_phys(&sg,
- filter_paddr + ((uintptr_t)&filter->vmf_unicast -
- (uintptr_t)filter),
+ error |= sglist_append(&sg, &hdr, sizeof(struct virtio_net_ctrl_hdr));
+ error |= sglist_append(&sg, &filter->vmf_unicast,
sizeof(uint32_t) + ucnt * ETHER_ADDR_LEN);
- error |= sglist_append_phys(&sg,
- filter_paddr + ((uintptr_t)&filter->vmf_multicast -
- (uintptr_t)filter),
+ error |= sglist_append(&sg, &filter->vmf_multicast,
sizeof(uint32_t) + mcnt * ETHER_ADDR_LEN);
- MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1);
+ error |= sglist_append(&sg, &ack, sizeof(uint8_t));
+ MPASS(error == 0 && sg.sg_nseg == nitems(segs));
if (error == 0)
- error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1);
- if (error == 0)
- error = (ack == VIRTIO_NET_OK ? 0 : EIO);
-
- bus_dmamap_unload(sc->vtnet_hdr_dmat, filter_dmap);
-out_destroy_filter:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, filter_dmap);
-out_unload_hdr:
- bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap);
-out_destroy_hdr:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap);
-out_error:
- if (error != 0)
+ vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg - 1, 1);
+ if (ack != VIRTIO_NET_OK)
if_printf(ifp, "error setting host MAC filter table\n");
+
out:
if (promisc && vtnet_set_promisc(sc, true) != 0)
if_printf(ifp, "cannot enable promiscuous mode\n");
@@ -4250,53 +3808,34 @@ static int
vtnet_exec_vlan_filter(struct vtnet_softc *sc, int add, uint16_t tag)
{
struct sglist_seg segs[3];
- bus_dmamap_t hdr_dmap;
- bus_addr_t hdr_paddr;
struct sglist sg;
struct {
struct virtio_net_ctrl_hdr hdr __aligned(2);
uint8_t pad1;
uint16_t tag __aligned(2);
uint8_t pad2;
+ uint8_t ack;
} s;
- uint8_t ack;
int error;
- error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap);
- if (error)
- goto error_out;
-
- error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &s,
- sizeof(s), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT);
- if (error)
- goto error_destroy_hdr;
-
+ error = 0;
MPASS(sc->vtnet_flags & VTNET_FLAG_VLAN_FILTER);
s.hdr.class = VIRTIO_NET_CTRL_VLAN;
s.hdr.cmd = add ? VIRTIO_NET_CTRL_VLAN_ADD : VIRTIO_NET_CTRL_VLAN_DEL;
s.tag = vtnet_gtoh16(sc, tag);
- ack = VIRTIO_NET_ERR;
- bus_dmamap_sync(sc->vtnet_hdr_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE);
+ s.ack = VIRTIO_NET_ERR;
sglist_init(&sg, nitems(segs), segs);
- error |= sglist_append_phys(&sg, hdr_paddr,
- sizeof(struct virtio_net_ctrl_hdr));
- error |= sglist_append_phys(&sg,
- hdr_paddr + ((uintptr_t)&s.tag - (uintptr_t)&s),
- sizeof(uint16_t));
- MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1);
+ error |= sglist_append(&sg, &s.hdr, sizeof(struct virtio_net_ctrl_hdr));
+ error |= sglist_append(&sg, &s.tag, sizeof(uint16_t));
+ error |= sglist_append(&sg, &s.ack, sizeof(uint8_t));
+ MPASS(error == 0 && sg.sg_nseg == nitems(segs));
if (error == 0)
- error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1);
- if (error == 0)
- error = (ack == VIRTIO_NET_OK ? 0 : EIO);
+ vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, sg.sg_nseg - 1, 1);
- bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap);
-error_destroy_hdr:
- bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap);
-error_out:
- return (error);
+ return (s.ack == VIRTIO_NET_OK ? 0 : EIO);
}
static void
diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h
index e445bdf6d6cb..eb5e6784b07f 100644
--- a/sys/dev/virtio/network/if_vtnetvar.h
+++ b/sys/dev/virtio/network/if_vtnetvar.h
@@ -190,18 +190,6 @@ struct vtnet_softc {
struct mtx vtnet_mtx;
char vtnet_mtx_name[16];
uint8_t vtnet_hwaddr[ETHER_ADDR_LEN];
-
- bus_dma_tag_t vtnet_rx_dmat;
- struct mtx vtnet_rx_mtx;
-
- bus_dma_tag_t vtnet_tx_dmat;
- struct mtx vtnet_tx_mtx;
-
- bus_dma_tag_t vtnet_hdr_dmat;
- struct mtx vtnet_hdr_mtx;
-
- bus_dma_tag_t vtnet_ack_dmat;
- struct mtx vtnet_ack_mtx;
};
/* vtnet flag descriptions for use with printf(9) %b identifier. */
#define VTNET_FLAGS_BITS \
@@ -285,10 +273,6 @@ struct vtnet_tx_header {
} vth_uhdr;
struct mbuf *vth_mbuf;
-
- bus_dmamap_t dmap;
-
- bus_dmamap_t hdr_dmap;
};
/*
diff --git a/sys/dev/virtio/p9fs/virtio_p9fs.c b/sys/dev/virtio/p9fs/virtio_p9fs.c
index 2b276a60aa9a..19a32fea458e 100644
--- a/sys/dev/virtio/p9fs/virtio_p9fs.c
+++ b/sys/dev/virtio/p9fs/virtio_p9fs.c
@@ -464,16 +464,20 @@ static int
vt9p_modevent(module_t mod, int type, void *unused)
{
int error;
+ static int loaded = 0;
error = 0;
switch (type) {
case MOD_LOAD:
- p9_init_zones();
- p9_register_trans(&vt9p_trans);
+ if (loaded++ == 0) {
+ p9_register_trans(&vt9p_trans);
+ }
break;
case MOD_UNLOAD:
- p9_destroy_zones();
+ if (--loaded == 0) {
+ p9_unregister_trans(&vt9p_trans);
+ }
break;
case MOD_SHUTDOWN:
break;
@@ -481,6 +485,7 @@ vt9p_modevent(module_t mod, int type, void *unused)
error = EOPNOTSUPP;
break;
}
+
return (error);
}
diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/sys/fs/nfsclient/nfs_clsubs.c
index ae9fa51947cc..6361ae5f2901 100644
--- a/sys/fs/nfsclient/nfs_clsubs.c
+++ b/sys/fs/nfsclient/nfs_clsubs.c
@@ -263,9 +263,17 @@ nfsuint64 *
ncl_getcookie(struct nfsnode *np, off_t off, int add)
{
struct nfsdmap *dp, *dp2;
- int pos;
+ u_int pos;
nfsuint64 *retval = NULL;
+ /*
+ * Limiting "off" to 50Gbytes sets a limit of 100 million directory
+ * entries of maximum filename length. Much more with shorter
+ * file names. This limit ensures "pos" will not be truncated
+ * in the devision below.
+ */
+ if (off > 53687091200ull)
+ goto out;
pos = (uoff_t)off / NFS_DIRBLKSIZ;
if (pos == 0 || off < 0) {
KASSERT(!add, ("nfs getcookie add at <= 0"));
diff --git a/sys/fs/nfsclient/nfsnode.h b/sys/fs/nfsclient/nfsnode.h
index 07c7ccb0ff10..cd9ded943c2f 100644
--- a/sys/fs/nfsclient/nfsnode.h
+++ b/sys/fs/nfsclient/nfsnode.h
@@ -61,7 +61,7 @@ struct sillyrename {
struct nfsdmap {
LIST_ENTRY(nfsdmap) ndm_list;
- int ndm_eocookie;
+ u_int ndm_eocookie;
union {
nfsuint64 ndmu3_cookies[NFSNUMCOOKIES];
uint64_t ndmu4_cookies[NFSNUMCOOKIES];
diff --git a/sys/fs/p9fs/p9fs.h b/sys/fs/p9fs/p9fs.h
index 2470734fef4d..b469495ef69e 100644
--- a/sys/fs/p9fs/p9fs.h
+++ b/sys/fs/p9fs/p9fs.h
@@ -154,6 +154,7 @@ struct p9fs_session {
struct mtx p9fs_mtx; /* mutex used for guarding the chain.*/
STAILQ_HEAD( ,p9fs_node) virt_node_list; /* list of p9fs nodes in this session*/
struct p9_fid *mnt_fid; /* to save nobody 's fid for unmounting as root user */
+ unsigned int name_max; /* cached max filename length */
};
struct p9fs_mount {
diff --git a/sys/fs/p9fs/p9fs_subr.c b/sys/fs/p9fs/p9fs_subr.c
index d0f04f6c5e97..f66e7a171029 100644
--- a/sys/fs/p9fs/p9fs_subr.c
+++ b/sys/fs/p9fs/p9fs_subr.c
@@ -275,16 +275,20 @@ p9fs_compatible_mode(struct p9_fid *fid, int mode)
{
/*
* Return TRUE for an exact match. For OREAD and OWRITE, allow
- * existing ORDWR fids to match. Only check the low two bits
- * of mode.
+ * existing ORDWR fids to match.
*
- * TODO: figure out if this is correct for O_APPEND
+ * We mask both the requested mode and the existing fid's mode
+ * with 3 (0b11) to isolate the base access intent (O_RDONLY,
+ * O_WRONLY, or O_RDWR). This prevents extended open flags like
+ * O_EXCL or O_APPEND from causing a mismatch when we are merely
+ * looking for an appropriately privileged open descriptor.
*/
int fid_mode = fid->mode & 3;
- if (fid_mode == mode)
+ int req_mode = mode & 3;
+ if (fid_mode == req_mode)
return (TRUE);
if (fid_mode == P9PROTO_ORDWR)
- return (mode == P9PROTO_OREAD || mode == P9PROTO_OWRITE);
+ return (req_mode == P9PROTO_OREAD || req_mode == P9PROTO_OWRITE);
return (FALSE);
}
diff --git a/sys/fs/p9fs/p9fs_vfsops.c b/sys/fs/p9fs/p9fs_vfsops.c
index 0e09c58e57b6..a0f0a5a4e494 100644
--- a/sys/fs/p9fs/p9fs_vfsops.c
+++ b/sys/fs/p9fs/p9fs_vfsops.c
@@ -119,6 +119,8 @@ p9fs_init(struct vfsconf *vfsp)
p9fs_io_buffer_zone = uma_zcreate("p9fs io_buffer zone",
P9FS_MTU, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+ p9_init_zones();
+
return (0);
}
@@ -127,6 +129,8 @@ static int
p9fs_uninit(struct vfsconf *vfsp)
{
+ p9_destroy_zones();
+
uma_zdestroy(p9fs_node_zone);
uma_zdestroy(p9fs_io_buffer_zone);
uma_zdestroy(p9fs_getattr_zone);
diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c
index 7141e9700602..2519e5cd050a 100644
--- a/sys/fs/p9fs/p9fs_vnops.c
+++ b/sys/fs/p9fs/p9fs_vnops.c
@@ -37,10 +37,12 @@
#include <sys/fcntl.h>
#include <sys/namei.h>
#include <sys/priv.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
#include <sys/rwlock.h>
+#include <sys/stat.h>
+#include <sys/syslimits.h>
+#include <sys/unistd.h>
#include <sys/vmmeter.h>
+#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -417,7 +419,7 @@ out:
* the name and perm specified under the parent dir. If this succeeds (an entry
* is created for the new file on the server), we create our metadata for this
* file (vnode, p9fs node calling vget). Once we are done, we clunk the open
- * fid of the parent directory.
+ * fid of the parent directory if it was not retained.
*/
static int
create_common(struct p9fs_node *dnp, struct componentname *cnp,
@@ -471,6 +473,28 @@ create_common(struct p9fs_node *dnp, struct componentname *cnp,
dnp, newfid, vpp, cnp->cn_nameptr);
if (error != 0)
goto out;
+
+ if (ofid != NULL) {
+ struct p9fs_node *np = P9FS_VTON(*vpp);
+ ofid->v_opens = 0;
+ /*
+ * The 9P file creation request natively opens
+ * the file as part of the create operation and
+ * gives us a writable file handle (ofid).
+ * We retain this open descriptor by adding it
+ * to the VOFID list of the new vnode. This
+ * guarantees that a subsequent VOP_OPEN call
+ * does not need to send a redundant TOPEN
+ * request. This is particularly important
+ * because if a file was requested to be created
+ * with 000 permissions, the host will reject
+ * subsequent TOPEN requests due to insufficient
+ * permissions, which would cause an overall
+ * open() failure.
+ */
+ p9fs_fid_add(np, ofid, VOFID);
+ ofid = NULL; /* prevent closing handle below */
+ }
} else {
/* Not found return NOENTRY.*/
goto out;
@@ -2248,6 +2272,72 @@ p9fs_delayed_setsize(struct vop_delayed_setsize_args *ap)
return (0);
}
+static unsigned int
+p9fs_get_name_max(struct p9fs_node *np)
+{
+ struct p9fs_session *vses = np->p9fs_ses;
+ struct p9_statfs statfs;
+ struct p9_fid *vfid;
+ unsigned int name_max;
+ int error = 0;
+
+ name_max = atomic_load_int(&vses->name_max);
+ if (name_max != 0)
+ return (name_max);
+
+ P9_DEBUG(VOPS, "%s: querying _PC_NAME_MAX\n", __func__);
+ vfid = p9fs_get_fid(vses->clnt, np, NULL, VFID, -1, &error);
+ if (vfid != NULL) {
+ error = p9_client_statfs(vfid, &statfs);
+ if (error == 0) {
+ /*
+ * Note that this is not strictly correct if you have
+ * nested mounts on the host (e.g. when using qemu with
+ * multidevs=remap), but is a better estimate than just
+ * returning 255.
+ */
+ name_max = statfs.namelen;
+ }
+ }
+ P9_DEBUG(VOPS, "%s: max_name=%u error=%d\n", __func__, name_max, error);
+ if (error != 0 || name_max == 0) {
+ printf("p9fs: warning: failed to query name_max (error %d), "
+ "using fallback %d\n", error, NAME_MAX);
+ name_max = NAME_MAX; /* fallback and prevent retrying */
+ }
+ atomic_store_int(&vses->name_max, name_max);
+ return (name_max);
+}
+
+/*
+ * Return POSIX pathconf information applicable to p9fs filesystems.
+ */
+static int
+p9fs_pathconf(struct vop_pathconf_args *ap)
+{
+ int error = 0;
+ struct vnode *vp = ap->a_vp;
+ struct p9fs_node *np = P9FS_VTON(vp);
+
+ switch (ap->a_name) {
+ case _PC_NAME_MAX:
+ *ap->a_retval = p9fs_get_name_max(np);
+ break;
+ case _PC_SYMLINK_MAX:
+ case _PC_PATH_MAX:
+ /*
+ * These are conservative estimates, the real value depends on
+ * the host file system.
+ */
+ *ap->a_retval = MAXPATHLEN;
+ break;
+ default:
+ error = vop_stdpathconf(ap);
+ break;
+ }
+ return (error);
+}
+
struct vop_vector p9fs_vnops = {
.vop_default = &default_vnodeops,
.vop_lookup = p9fs_lookup,
@@ -2257,6 +2347,7 @@ struct vop_vector p9fs_vnops = {
.vop_delayed_setsize = p9fs_delayed_setsize,
.vop_getattr = p9fs_getattr_dotl,
.vop_setattr = p9fs_setattr_dotl,
+ .vop_pathconf = p9fs_pathconf,
.vop_reclaim = p9fs_reclaim,
.vop_inactive = p9fs_inactive,
.vop_readdir = p9fs_readdir,
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c
index 7568101dabd2..ccc62253d81e 100644
--- a/sys/kern/subr_eventhandler.c
+++ b/sys/kern/subr_eventhandler.c
@@ -198,7 +198,10 @@ _eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag,
} else {
CTR3(KTR_EVH, "%s: marking item %p from \"%s\" as dead", __func__,
ep, list->el_name);
+ KASSERT(ep->ee_priority != EHE_DEAD_PRIORITY,
+ ("%s: handler for %s is dead", __func__, list->el_name));
ep->ee_priority = EHE_DEAD_PRIORITY;
+ list->el_deadcount++;
}
} else {
/* remove entire list */
@@ -213,11 +216,15 @@ _eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag,
} else {
CTR2(KTR_EVH, "%s: marking all items from \"%s\" as dead",
__func__, list->el_name);
- TAILQ_FOREACH(ep, &list->el_entries, ee_link)
+ TAILQ_FOREACH(ep, &list->el_entries, ee_link) {
+ KASSERT(ep->ee_priority != EHE_DEAD_PRIORITY,
+ ("%s: handler for %s is dead", __func__, list->el_name));
ep->ee_priority = EHE_DEAD_PRIORITY;
+ list->el_deadcount++;
+ }
}
}
- while (wait && list->el_runcount > 0)
+ while (wait && list->el_deadcount > 0)
mtx_sleep(list, &list->el_lock, 0, "evhrm", 0);
EHL_UNLOCK(list);
}
@@ -281,10 +288,12 @@ void
eventhandler_prune_list(struct eventhandler_list *list)
{
struct eventhandler_entry *ep, *en;
- int pruned = 0;
+ int pruned __diagused;
CTR2(KTR_EVH, "%s: pruning list \"%s\"", __func__, list->el_name);
EHL_LOCK_ASSERT(list, MA_OWNED);
+
+ pruned = 0;
TAILQ_FOREACH_SAFE(ep, &list->el_entries, ee_link, en) {
if (ep->ee_priority == EHE_DEAD_PRIORITY) {
TAILQ_REMOVE(&list->el_entries, ep, ee_link);
@@ -292,8 +301,11 @@ eventhandler_prune_list(struct eventhandler_list *list)
pruned++;
}
}
- if (pruned > 0)
- wakeup(list);
+ KASSERT(pruned == list->el_deadcount,
+ ("%s: pruned %u entries from \"%s\" but expected %u",
+ __func__, pruned, list->el_name, list->el_deadcount));
+ list->el_deadcount = 0;
+ wakeup(list);
}
/*
diff --git a/sys/kern/subr_kobj.c b/sys/kern/subr_kobj.c
index d97834b3fe58..a88639289954 100644
--- a/sys/kern/subr_kobj.c
+++ b/sys/kern/subr_kobj.c
@@ -308,7 +308,7 @@ kobj_init(kobj_t obj, kobj_class_t cls)
{
int error;
- error = kobj_init1(obj, cls, M_NOWAIT);
+ error = kobj_init1(obj, cls, M_WAITOK);
if (error != 0)
panic("kobj_init1 failed: error %d", error);
}
@@ -317,6 +317,8 @@ void
kobj_init_static(kobj_t obj, kobj_class_t cls)
{
+ KASSERT(cls->ops != NULL,
+ ("%s: class %p is not compiled", __func__, cls));
KASSERT(kobj_mutex_inited == 0,
("%s: only supported during early cycles", __func__));
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index c67996ad7df1..dece6457a4bf 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -108,7 +108,12 @@ proc_read_regs(struct thread *td, struct reg *regs)
int
proc_write_regs(struct thread *td, struct reg *regs)
{
+ int error;
+
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
return (set_regs(td, regs));
}
@@ -122,7 +127,12 @@ proc_read_dbregs(struct thread *td, struct dbreg *dbregs)
int
proc_write_dbregs(struct thread *td, struct dbreg *dbregs)
{
+ int error;
+
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
return (set_dbregs(td, dbregs));
}
@@ -140,7 +150,12 @@ proc_read_fpregs(struct thread *td, struct fpreg *fpregs)
int
proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
{
+ int error;
+
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
return (set_fpregs(td, fpregs));
}
@@ -261,6 +276,10 @@ proc_write_regset(struct thread *td, int note, struct iovec *iov)
if (regset->set == NULL)
return (EINVAL);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
+
p = td->td_proc;
/* Drop the proc lock while allocating the temp buffer */
@@ -293,7 +312,12 @@ proc_read_regs32(struct thread *td, struct reg32 *regs32)
int
proc_write_regs32(struct thread *td, struct reg32 *regs32)
{
+ int error;
+
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
return (set_regs32(td, regs32));
}
@@ -307,7 +331,12 @@ proc_read_dbregs32(struct thread *td, struct dbreg32 *dbregs32)
int
proc_write_dbregs32(struct thread *td, struct dbreg32 *dbregs32)
{
+ int error;
+
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
return (set_dbregs32(td, dbregs32));
}
@@ -321,7 +350,12 @@ proc_read_fpregs32(struct thread *td, struct fpreg32 *fpregs32)
int
proc_write_fpregs32(struct thread *td, struct fpreg32 *fpregs32)
{
+ int error;
+
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
+ return (error);
return (set_fpregs32(td, fpregs32));
}
#endif
@@ -363,8 +397,8 @@ proc_rwmem(struct proc *p, struct uio *uio)
fault_flags = writing ? VM_FAULT_DIRTY : VM_FAULT_NORMAL;
if (writing) {
- error = priv_check_cred(p->p_ucred, PRIV_PROC_MEM_WRITE);
- if (error)
+ error = priv_check(curthread, PRIV_PROC_MEM_WRITE);
+ if (error != 0)
return (error);
}
@@ -697,11 +731,11 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
addr = uap->addr;
break;
}
- if (error)
+ if (error != 0)
return (error);
error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data);
- if (error)
+ if (error != 0)
return (error);
switch (uap->req) {
@@ -1237,7 +1271,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
CTR3(KTR_PTRACE, "PT_STEP: tid %d (pid %d), sig = %d",
td2->td_tid, p->p_pid, data);
error = ptrace_single_step(td2);
- if (error)
+ if (error != 0)
goto out;
break;
case PT_CONTINUE:
@@ -1247,7 +1281,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (addr != (void *)1) {
error = ptrace_set_pc(td2,
(u_long)(uintfptr_t)addr);
- if (error)
+ if (error != 0)
goto out;
td2->td_dbgflags |= TDB_USERWR;
}
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 8ff9822ee9eb..2508f7edd1c5 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -83,6 +83,7 @@
#include <sys/socketvar.h>
#include <sys/signalvar.h>
#include <sys/stat.h>
+#include <sys/sysent.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@@ -2752,8 +2753,24 @@ uipc_ctloutput(struct socket *so, struct sockopt *sopt)
error = EINVAL;
}
UNP_PCB_UNLOCK(unp);
- if (error == 0)
- error = sooptcopyout(sopt, &xu, sizeof(xu));
+ if (error != 0)
+ break;
+#ifdef COMPAT_FREEBSD32
+ if (SV_PROC_FLAG(sopt->sopt_td->td_proc, SV_ILP32)) {
+ struct xucred32 xu32 = {};
+ int i;
+
+ xu32.cr_version = xu.cr_version;
+ xu32.cr_uid = xu.cr_uid;
+ xu32.cr_ngroups = xu.cr_ngroups;
+ for (i = 0; i < XU_NGROUPS; i++)
+ xu32.cr_groups[i] = xu.cr_groups[i];
+ xu32.cr_pid = xu.cr_pid;
+ error = sooptcopyout(sopt, &xu32, sizeof(xu32));
+ break;
+ }
+#endif
+ error = sooptcopyout(sopt, &xu, sizeof(xu));
break;
case LOCAL_CREDS:
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 8f47a7abbc5e..675f6fb4e526 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -727,7 +727,8 @@ bufspace_wait(struct bufdomain *bd, struct vnode *vp, int gbflags,
BD_LOCK(bd);
while (bd->bd_wanted) {
if (vp != NULL && vp->v_type != VCHR &&
- (td->td_pflags & TDP_BUFNEED) == 0) {
+ (td->td_pflags & TDP_BUFNEED) == 0 &&
+ vp->v_bufobj.bo_dirty.bv_cnt > 0) {
BD_UNLOCK(bd);
/*
* getblk() is called with a vnode locked, and
diff --git a/sys/modules/ath10k/Makefile b/sys/modules/ath10k/Makefile
index b28df768c3d5..becf42a6a79a 100644
--- a/sys/modules/ath10k/Makefile
+++ b/sys/modules/ath10k/Makefile
@@ -1,3 +1,5 @@
+.include <kmod.opts.mk>
+
DEVATH10KDIR= ${SRCTOP}/sys/contrib/dev/athk/ath10k
.PATH: ${DEVATH10KDIR}
diff --git a/sys/modules/ath11k/Makefile b/sys/modules/ath11k/Makefile
index a2f0064c2ae9..eaf196af5b55 100644
--- a/sys/modules/ath11k/Makefile
+++ b/sys/modules/ath11k/Makefile
@@ -1,3 +1,5 @@
+.include <kmod.opts.mk>
+
DEVATH11KDIR= ${SRCTOP}/sys/contrib/dev/athk/ath11k
.PATH: ${DEVATH11KDIR}
diff --git a/sys/modules/ath12k/Makefile b/sys/modules/ath12k/Makefile
index ecca0bc3b409..071bb88a8b37 100644
--- a/sys/modules/ath12k/Makefile
+++ b/sys/modules/ath12k/Makefile
@@ -1,3 +1,5 @@
+.include <kmod.opts.mk>
+
DEVATH12KDIR= ${SRCTOP}/sys/contrib/dev/athk/ath12k
.PATH: ${DEVATH12KDIR}
diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h
index 77c310c268f8..b4e4c1e4d29b 100644
--- a/sys/modules/zfs/zfs_config.h
+++ b/sys/modules/zfs/zfs_config.h
@@ -204,6 +204,9 @@
/* DECLARE_EVENT_CLASS() is available */
/* #undef HAVE_DECLARE_EVENT_CLASS */
+/* dentry aliases are in d_u member */
+/* #undef HAVE_DENTRY_D_U_ALIASES */
+
/* 3-arg dequeue_signal() takes a type argument */
/* #undef HAVE_DEQUEUE_SIGNAL_3ARG_TYPE */
@@ -911,7 +914,7 @@
/* #undef ZFS_DEVICE_MINOR */
/* Define the project alias string. */
-#define ZFS_META_ALIAS "zfs-2.4.99-551-FreeBSD_g84ffe564d"
+#define ZFS_META_ALIAS "zfs-2.4.99-566-FreeBSD_ga12c6ed62"
/* Define the project author. */
#define ZFS_META_AUTHOR "OpenZFS"
@@ -941,7 +944,7 @@
#define ZFS_META_NAME "zfs"
/* Define the project release. */
-#define ZFS_META_RELEASE "551-FreeBSD_g84ffe564d"
+#define ZFS_META_RELEASE "566-FreeBSD_ga12c6ed62"
/* 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 af9caaa07622..113c3d7a5bbb 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-551-g84ffe564d-dirty"
+#define ZFS_META_GITREV "zfs-2.4.99-566-ga12c6ed62-dirty"
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index c254e2aa3107..ab05b4d075c7 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -236,25 +236,15 @@ static eventhandler_tag ifevent_tag;
* must be sleepable and also have safe concurrent access to a vlan interface.
* Since the sx(9) exists, it is used by default in most paths unless sleeping
* is not permitted, or if it is not clear whether sleeping is permitted.
- *
*/
-#define _VLAN_SX_ID ifv_sx
-
-static struct sx _VLAN_SX_ID;
-
-#define VLAN_LOCKING_INIT() \
- sx_init_flags(&_VLAN_SX_ID, "vlan_sx", SX_RECURSE)
-
-#define VLAN_LOCKING_DESTROY() \
- sx_destroy(&_VLAN_SX_ID)
+static struct sx vlan_sx;
-#define VLAN_SLOCK() sx_slock(&_VLAN_SX_ID)
-#define VLAN_SUNLOCK() sx_sunlock(&_VLAN_SX_ID)
-#define VLAN_XLOCK() sx_xlock(&_VLAN_SX_ID)
-#define VLAN_XUNLOCK() sx_xunlock(&_VLAN_SX_ID)
-#define VLAN_SLOCK_ASSERT() sx_assert(&_VLAN_SX_ID, SA_SLOCKED)
-#define VLAN_XLOCK_ASSERT() sx_assert(&_VLAN_SX_ID, SA_XLOCKED)
-#define VLAN_SXLOCK_ASSERT() sx_assert(&_VLAN_SX_ID, SA_LOCKED)
+#define VLAN_LOCK_INIT() \
+ sx_init_flags(&vlan_sx, "vlan_sx", SX_RECURSE)
+#define VLAN_LOCK_DESTROY() sx_destroy(&vlan_sx)
+#define VLAN_LOCK() sx_xlock(&vlan_sx)
+#define VLAN_UNLOCK() sx_xunlock(&vlan_sx)
+#define VLAN_LOCK_ASSERT() sx_assert(&vlan_sx, SA_XLOCKED)
/*
* We also have a per-trunk mutex that should be acquired when changing
@@ -262,9 +252,9 @@ static struct sx _VLAN_SX_ID;
*/
#define TRUNK_LOCK_INIT(trunk) mtx_init(&(trunk)->lock, vlanname, NULL, MTX_DEF)
#define TRUNK_LOCK_DESTROY(trunk) mtx_destroy(&(trunk)->lock)
-#define TRUNK_WLOCK(trunk) mtx_lock(&(trunk)->lock)
-#define TRUNK_WUNLOCK(trunk) mtx_unlock(&(trunk)->lock)
-#define TRUNK_WLOCK_ASSERT(trunk) mtx_assert(&(trunk)->lock, MA_OWNED);
+#define TRUNK_LOCK(trunk) mtx_lock(&(trunk)->lock)
+#define TRUNK_UNLOCK(trunk) mtx_unlock(&(trunk)->lock)
+#define TRUNK_LOCK_ASSERT(trunk) mtx_assert(&(trunk)->lock, MA_OWNED)
/*
* The VLAN_ARRAY substitutes the dynamic hash with a static array
@@ -434,7 +424,7 @@ vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
int i, b;
struct ifvlan *ifv2;
- VLAN_XLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
b = 1 << trunk->hwidth;
@@ -464,7 +454,7 @@ vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
int i, b;
struct ifvlan *ifv2;
- VLAN_XLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
b = 1 << (trunk->hwidth - 1);
@@ -492,7 +482,7 @@ vlan_growhash(struct ifvlantrunk *trunk, int howmuch)
struct ifvlanhead *hash2;
int hwidth2, i, j, n, n2;
- VLAN_XLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
if (howmuch == 0) {
@@ -603,7 +593,7 @@ vlan_inithash(struct ifvlantrunk *trunk)
static void
trunk_destroy(struct ifvlantrunk *trunk)
{
- VLAN_XLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
vlan_freehash(trunk);
trunk->parent->if_vlantrunk = NULL;
@@ -629,7 +619,7 @@ vlan_setmulti(struct ifnet *ifp)
struct vlan_mc_entry *mc;
int error;
- VLAN_XLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
/* Find the parent. */
sc = ifp->if_softc;
@@ -693,11 +683,11 @@ vlan_ifevent(void *arg __unused, struct ifnet *ifp, int event)
return;
}
- TRUNK_WLOCK(trunk);
+ TRUNK_LOCK(trunk);
VLAN_FOREACH(ifv, trunk) {
ifv->ifv_ifp->if_baudrate = ifp->if_baudrate;
}
- TRUNK_WUNLOCK(trunk);
+ TRUNK_UNLOCK(trunk);
NET_EPOCH_EXIT(et);
}
@@ -728,7 +718,7 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
* We need an exclusive lock here to prevent concurrent SIOCSIFLLADDR
* ioctl calls on the parent garbling the lladdr of the child vlan.
*/
- TRUNK_WLOCK(trunk);
+ TRUNK_LOCK(trunk);
VLAN_FOREACH(ifv, trunk) {
/*
* Copy new new lladdr into the ifv_ifp, enqueue a task
@@ -744,7 +734,7 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
sdl->sdl_alen = ifp->if_addrlen;
taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task);
}
- TRUNK_WUNLOCK(trunk);
+ TRUNK_UNLOCK(trunk);
NET_EPOCH_EXIT(et);
}
@@ -761,10 +751,10 @@ vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
struct ifvlan *ifv;
struct ifvlantrunk *trunk;
- VLAN_XLOCK();
+ VLAN_LOCK();
trunk = ifp->if_vlantrunk;
if (trunk == NULL) {
- VLAN_XUNLOCK();
+ VLAN_UNLOCK();
return;
}
@@ -779,7 +769,7 @@ vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
/* Trunk should have been destroyed in vlan_unconfig(). */
KASSERT(ifp->if_vlantrunk == NULL, ("%s: purge failed", __func__));
- VLAN_XUNLOCK();
+ VLAN_UNLOCK();
}
/*
@@ -916,7 +906,7 @@ vlan_modevent(module_t mod, int type, void *data)
vlan_ifevent, NULL, EVENTHANDLER_PRI_ANY);
if (ifevent_tag == NULL)
return (ENOMEM);
- VLAN_LOCKING_INIT();
+ VLAN_LOCK_INIT();
vlan_input_p = vlan_input;
vlan_link_state_p = vlan_link_state;
vlan_trunk_cap_p = vlan_trunk_capabilities;
@@ -954,7 +944,7 @@ vlan_modevent(module_t mod, int type, void *data)
vlan_cookie_p = NULL;
vlan_setcookie_p = NULL;
vlan_devat_p = NULL;
- VLAN_LOCKING_DESTROY();
+ VLAN_LOCK_DESTROY();
if (bootverbose)
printf("vlan: unloaded\n");
break;
@@ -1343,9 +1333,9 @@ vlan_clone_dump_nl(struct ifnet *ifp, struct nl_writer *nw)
uint16_t vlan_id = 0;
uint16_t vlan_proto = 0;
- VLAN_SLOCK();
+ VLAN_LOCK();
if (__predict_false((ifv = ifp->if_softc) == NULL)) {
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
/*
* XXXGL: the interface already went through if_dead(). This
* check to be removed when we got better interface removal.
@@ -1356,7 +1346,7 @@ vlan_clone_dump_nl(struct ifnet *ifp, struct nl_writer *nw)
parent_index = PARENT(ifv)->if_index;
vlan_id = ifv->ifv_vid;
vlan_proto = ifv->ifv_proto;
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
if (parent_index != 0)
nlattr_add_u32(nw, IFLA_LINK, parent_index);
@@ -1696,7 +1686,7 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid,
if (trunk->parent != p)
return (EBUSY);
- VLAN_XLOCK();
+ VLAN_LOCK();
ifv->ifv_proto = proto;
@@ -1720,17 +1710,17 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid,
goto done;
}
- VLAN_XLOCK();
+ VLAN_LOCK();
if (p->if_vlantrunk == NULL) {
trunk = malloc(sizeof(struct ifvlantrunk),
M_VLAN, M_WAITOK | M_ZERO);
vlan_inithash(trunk);
TRUNK_LOCK_INIT(trunk);
- TRUNK_WLOCK(trunk);
+ TRUNK_LOCK(trunk);
p->if_vlantrunk = trunk;
trunk->parent = p;
if_ref(trunk->parent);
- TRUNK_WUNLOCK(trunk);
+ TRUNK_UNLOCK(trunk);
} else {
trunk = p->if_vlantrunk;
}
@@ -1838,7 +1828,7 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid,
done:
if (error == 0)
EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid);
- VLAN_XUNLOCK();
+ VLAN_UNLOCK();
return (error);
}
@@ -1847,9 +1837,9 @@ static void
vlan_unconfig(struct ifnet *ifp)
{
- VLAN_XLOCK();
+ VLAN_LOCK();
vlan_unconfig_locked(ifp, 0);
- VLAN_XUNLOCK();
+ VLAN_UNLOCK();
}
static void
@@ -1861,7 +1851,7 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing)
struct ifnet *parent;
int error;
- VLAN_XLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
ifv = ifp->if_softc;
trunk = ifv->ifv_trunk;
@@ -1935,7 +1925,7 @@ vlan_setflag(struct ifnet *ifp, int flag, int status,
struct ifvlan *ifv;
int error;
- VLAN_SXLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
ifv = ifp->if_softc;
status = status ? (ifp->if_flags & flag) : 0;
@@ -1994,13 +1984,13 @@ vlan_link_state(struct ifnet *ifp)
return;
}
- TRUNK_WLOCK(trunk);
+ TRUNK_LOCK(trunk);
VLAN_FOREACH(ifv, trunk) {
ifv->ifv_ifp->if_baudrate = trunk->parent->if_baudrate;
if_link_state_change(ifv->ifv_ifp,
trunk->parent->if_link_state);
}
- TRUNK_WUNLOCK(trunk);
+ TRUNK_UNLOCK(trunk);
NET_EPOCH_EXIT(et);
}
@@ -2011,7 +2001,7 @@ vlan_link_state(struct ifnet *ifp)
int error; \
\
ifv = ifp->if_softc; \
- VLAN_SLOCK(); \
+ VLAN_LOCK(); \
if (TRUNK(ifv) != NULL) { \
p = PARENT(ifv); \
if_ref(p); \
@@ -2020,7 +2010,7 @@ vlan_link_state(struct ifnet *ifp)
} else { \
error = ENXIO; \
} \
- VLAN_SUNLOCK(); \
+ VLAN_UNLOCK(); \
return (error);
@@ -2091,7 +2081,7 @@ vlan_capabilities(struct ifvlan *ifv)
u_long hwa = 0;
NET_EPOCH_ASSERT();
- VLAN_SXLOCK_ASSERT();
+ VLAN_LOCK_ASSERT();
p = PARENT(ifv);
ifp = ifv->ifv_ifp;
@@ -2222,17 +2212,17 @@ vlan_trunk_capabilities(struct ifnet *ifp)
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
- VLAN_SLOCK();
+ VLAN_LOCK();
trunk = ifp->if_vlantrunk;
if (trunk == NULL) {
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
return;
}
NET_EPOCH_ENTER(et);
VLAN_FOREACH(ifv, trunk)
vlan_capabilities(ifv);
NET_EPOCH_EXIT(et);
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
}
static int
@@ -2267,7 +2257,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_addrlen);
break;
case SIOCGIFMEDIA:
- VLAN_SLOCK();
+ VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
p = PARENT(ifv);
if_ref(p);
@@ -2288,7 +2278,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
} else {
error = EINVAL;
}
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
break;
case SIOCSIFMEDIA:
@@ -2299,10 +2289,10 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/*
* Set the interface MTU.
*/
- VLAN_SLOCK();
+ VLAN_LOCK();
trunk = TRUNK(ifv);
if (trunk != NULL) {
- TRUNK_WLOCK(trunk);
+ TRUNK_LOCK(trunk);
if (ifr->ifr_mtu >
(PARENT(ifv)->if_mtu - ifv->ifv_mtufudge) ||
ifr->ifr_mtu <
@@ -2310,10 +2300,10 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = EINVAL;
else
ifp->if_mtu = ifr->ifr_mtu;
- TRUNK_WUNLOCK(trunk);
+ TRUNK_UNLOCK(trunk);
} else
error = EINVAL;
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
break;
case SIOCSETVLAN:
@@ -2376,14 +2366,14 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
#endif
bzero(&vlr, sizeof(vlr));
- VLAN_SLOCK();
+ VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname,
sizeof(vlr.vlr_parent));
vlr.vlr_tag = ifv->ifv_vid;
vlr.vlr_proto = ifv->ifv_proto;
}
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
error = copyout(&vlr, ifr_data_get_ptr(ifr), sizeof(vlr));
break;
@@ -2392,10 +2382,10 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* We should propagate selected flags to the parent,
* e.g., promiscuous mode.
*/
- VLAN_SLOCK();
+ VLAN_LOCK();
if (TRUNK(ifv) != NULL)
error = vlan_setflags(ifp, 1);
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
break;
case SIOCADDMULTI:
@@ -2407,11 +2397,11 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* XXX We need the rmlock here to avoid sleeping while
* holding in6_multi_mtx.
*/
- VLAN_XLOCK();
+ VLAN_LOCK();
trunk = TRUNK(ifv);
if (trunk != NULL)
error = vlan_setmulti(ifp);
- VLAN_XUNLOCK();
+ VLAN_UNLOCK();
break;
case SIOCGVLANPCP:
@@ -2445,7 +2435,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSIFCAP:
- VLAN_SLOCK();
+ VLAN_LOCK();
ifv->ifv_capenable = ifr->ifr_reqcap;
trunk = TRUNK(ifv);
if (trunk != NULL) {
@@ -2455,7 +2445,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
vlan_capabilities(ifv);
NET_EPOCH_EXIT(et);
}
- VLAN_SUNLOCK();
+ VLAN_UNLOCK();
break;
default:
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 3edf08aefeb5..a5f377e84307 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -873,6 +873,13 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
(st->act.rtableid >= 0 && st->act.rtableid < rt_numfibs)))
goto cleanup;
+ if (sks->proto == IPPROTO_SCTP && st->src.scrub == NULL) {
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+ printf("%s: invalid SCTP state from creator id: %08x\n", __func__,
+ ntohl(sp->pfs_1301.creatorid));
+ goto cleanup;
+ }
+
st->id = sp->pfs_1301.id;
st->creatorid = sp->pfs_1301.creatorid;
pf_state_peer_ntoh(&sp->pfs_1301.src, &st->src);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index d3e60b137c1a..ab2140a60ce7 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -3226,14 +3226,12 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
PF_RULES_WUNLOCK();
pf_hash_rule(rule);
- if (RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule) != NULL) {
- PF_RULES_WLOCK();
- TAILQ_REMOVE(ruleset->rules[rs_num].inactive.ptr, rule, entries);
- ruleset->rules[rs_num].inactive.rcount--;
- pf_free_rule(rule);
- rule = NULL;
- ERROUT(EEXIST);
- }
+ /**
+ * Note: rule hashes may collide. Accept this, because the worst that can
+ * happen is that we get counter preservation wrong.
+ * Failing to insert here would be worse.
+ **/
+ RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule);
PF_CONFIG_UNLOCK();
return (0);
@@ -4895,14 +4893,8 @@ DIOCGETRULENV_error:
ruleset->rules[rs_num].active.rcount--;
} else {
pf_hash_rule(newrule);
- if (RB_INSERT(pf_krule_global,
- ruleset->rules[rs_num].active.tree, newrule) != NULL) {
- pf_free_rule(newrule);
- PF_RULES_WUNLOCK();
- PF_CONFIG_UNLOCK();
- error = EEXIST;
- goto fail;
- }
+ RB_INSERT(pf_krule_global,
+ ruleset->rules[rs_num].active.tree, newrule);
if (oldrule == NULL)
TAILQ_INSERT_TAIL(
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index e4ce9e64f637..d1beb7681c21 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -51,8 +51,11 @@
#include <netlink/netlink_debug.h>
_DECLARE_DEBUG(LOG_DEBUG);
+static bool nlattr_add_labels(struct nl_writer *nw, int attrtype,
+ const struct pf_krule *r);
+static bool nlattr_add_rule(struct nl_writer *nw, const struct pf_krule *rule);
static bool nlattr_add_pf_threshold(struct nl_writer *, int,
- struct pf_kthreshold *);
+ const struct pf_kthreshold *);
struct nl_parsed_state {
uint8_t version;
@@ -63,6 +66,7 @@ struct nl_parsed_state {
sa_family_t af;
struct pf_addr addr;
struct pf_addr mask;
+ bool include_rule;
};
#define _IN(_field) offsetof(struct genlmsghdr, _field)
@@ -75,6 +79,7 @@ static const struct nlattr_parser nla_p_state[] = {
{ .type = PF_ST_PROTO, .off = _OUT(proto), .cb = nlattr_get_uint16 },
{ .type = PF_ST_FILTER_ADDR, .off = _OUT(addr), .cb = nlattr_get_in6_addr },
{ .type = PF_ST_FILTER_MASK, .off = _OUT(mask), .cb = nlattr_get_in6_addr },
+ { .type = PF_ST_INCLUDE_RULE, .off = _OUT(include_rule), .cb = nlattr_get_bool },
};
static const struct nlfield_parser nlf_p_generic[] = {
{ .off_in = _IN(version), .off_out = _OUT(version), .cb = nlf_get_u8 },
@@ -146,8 +151,26 @@ dump_state_key(struct nl_writer *nw, int attr, const struct pf_state_key *key)
return (true);
}
+static bool
+nlattr_add_rule_nested(struct nl_writer *nw, int attr, const struct pf_krule *r)
+{
+ int off;
+ bool ret;
+
+ off = nlattr_add_nested(nw, attr);
+ if (off == 0)
+ return (false);
+
+ ret = nlattr_add_rule(nw, r);
+
+ nlattr_set_len(nw, off);
+
+ return (ret);
+}
+
static int
-dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr, struct pf_kstate *s,
+dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr,
+ struct nl_parsed_state *attrs, struct pf_kstate *s,
struct nl_pstate *npt)
{
struct nl_writer *nw = npt->nw;
@@ -231,6 +254,9 @@ dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr, struct pf_kstate *s,
if (!dump_state_peer(nw, PF_ST_PEER_DST, &s->dst))
goto enomem;
+ if (attrs->include_rule && s->rule != NULL)
+ nlattr_add_rule_nested(nw, PF_ST_CREATED_BY_RULE, s->rule);
+
if (nlmsg_end(nw))
return (0);
@@ -282,7 +308,7 @@ handle_dumpstates(struct nlpcb *nlp, struct nl_parsed_state *attrs,
&attrs->mask, &attrs->addr, af))
continue;
- error = dump_state(nlp, hdr, s, npt);
+ error = dump_state(nlp, hdr, attrs, s, npt);
if (error != 0)
break;
}
@@ -307,7 +333,7 @@ handle_getstate(struct nlpcb *nlp, struct nl_parsed_state *attrs,
s = pf_find_state_byid(attrs->id, attrs->creatorid);
if (s == NULL)
return (ENOENT);
- ret = dump_state(nlp, hdr, s, npt);
+ ret = dump_state(nlp, hdr, attrs, s, npt);
PF_STATE_UNLOCK(s);
return (ret);
@@ -465,7 +491,8 @@ NL_DECLARE_ATTR_PARSER(rule_addr_parser, nla_p_ruleaddr);
#undef _OUT
static bool
-nlattr_add_rule_addr(struct nl_writer *nw, int attrtype, struct pf_rule_addr *r)
+nlattr_add_rule_addr(struct nl_writer *nw, int attrtype,
+ const struct pf_rule_addr *r)
{
struct pf_addr_wrap aw = {0};
int off = nlattr_add_nested(nw, attrtype);
@@ -687,7 +714,8 @@ nlattr_get_nested_timeouts(struct nlattr *nla, struct nl_pstate *npt, const void
}
static bool
-nlattr_add_timeout(struct nl_writer *nw, int attrtype, uint32_t *timeout)
+nlattr_add_timeout(struct nl_writer *nw, int attrtype,
+ const uint32_t *timeout)
{
int off = nlattr_add_nested(nw, attrtype);
@@ -875,76 +903,10 @@ out:
return (error);
}
-struct nl_parsed_get_rule {
- char anchor[MAXPATHLEN];
- uint8_t action;
- uint32_t nr;
- uint32_t ticket;
- uint8_t clear;
-};
-#define _OUT(_field) offsetof(struct nl_parsed_get_rule, _field)
-static const struct nlattr_parser nla_p_getrule[] = {
- { .type = PF_GR_ANCHOR, .off = _OUT(anchor), .arg = (void *)MAXPATHLEN, .cb = nlattr_get_chara },
- { .type = PF_GR_ACTION, .off = _OUT(action), .cb = nlattr_get_uint8 },
- { .type = PF_GR_NR, .off = _OUT(nr), .cb = nlattr_get_uint32 },
- { .type = PF_GR_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
- { .type = PF_GR_CLEAR, .off = _OUT(clear), .cb = nlattr_get_uint8 },
-};
-#undef _OUT
-NL_DECLARE_PARSER(getrule_parser, struct genlmsghdr, nlf_p_empty, nla_p_getrule);
-
-static int
-pf_handle_getrule(struct nlmsghdr *hdr, struct nl_pstate *npt)
+static bool
+nlattr_add_rule(struct nl_writer *nw, const struct pf_krule *rule)
{
- char anchor_call[MAXPATHLEN];
- struct nl_parsed_get_rule attrs = {};
- struct nl_writer *nw = npt->nw;
- struct genlmsghdr *ghdr_new;
- struct pf_kruleset *ruleset;
- struct pf_krule *rule;
- u_int64_t src_nodes_total = 0;
- int rs_num;
- int error;
-
- error = nl_parse_nlmsg(hdr, &getrule_parser, npt, &attrs);
- if (error != 0)
- return (error);
-
- if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
- return (ENOMEM);
-
- ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
- ghdr_new->cmd = PFNL_CMD_GETRULE;
-
- PF_RULES_WLOCK();
- ruleset = pf_find_kruleset(attrs.anchor);
- if (ruleset == NULL) {
- PF_RULES_WUNLOCK();
- error = ENOENT;
- goto out;
- }
-
- rs_num = pf_get_ruleset_number(attrs.action);
- if (rs_num >= PF_RULESET_MAX) {
- PF_RULES_WUNLOCK();
- error = EINVAL;
- goto out;
- }
-
- if (attrs.ticket != ruleset->rules[rs_num].active.ticket) {
- PF_RULES_WUNLOCK();
- error = EBUSY;
- goto out;
- }
-
- rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
- while ((rule != NULL) && (rule->nr != attrs.nr))
- rule = TAILQ_NEXT(rule, entries);
- if (rule == NULL) {
- PF_RULES_WUNLOCK();
- error = EBUSY;
- goto out;
- }
+ u_int64_t src_nodes_total = 0;
nlattr_add_rule_addr(nw, PF_RT_SRC, &rule->src);
nlattr_add_rule_addr(nw, PF_RT_DST, &rule->dst);
@@ -1050,6 +1012,81 @@ pf_handle_getrule(struct nlmsghdr *hdr, struct nl_pstate *npt)
nlattr_add_u8(nw, PF_RT_SOURCE_LIMIT, rule->sourcelim.id);
nlattr_add_u32(nw, PF_RT_SOURCE_LIMIT_ACTION, rule->sourcelim.limiter_action);
+ return (true);
+}
+
+struct nl_parsed_get_rule {
+ char anchor[MAXPATHLEN];
+ uint8_t action;
+ uint32_t nr;
+ uint32_t ticket;
+ uint8_t clear;
+};
+#define _OUT(_field) offsetof(struct nl_parsed_get_rule, _field)
+static const struct nlattr_parser nla_p_getrule[] = {
+ { .type = PF_GR_ANCHOR, .off = _OUT(anchor), .arg = (void *)MAXPATHLEN, .cb = nlattr_get_chara },
+ { .type = PF_GR_ACTION, .off = _OUT(action), .cb = nlattr_get_uint8 },
+ { .type = PF_GR_NR, .off = _OUT(nr), .cb = nlattr_get_uint32 },
+ { .type = PF_GR_TICKET, .off = _OUT(ticket), .cb = nlattr_get_uint32 },
+ { .type = PF_GR_CLEAR, .off = _OUT(clear), .cb = nlattr_get_uint8 },
+};
+#undef _OUT
+NL_DECLARE_PARSER(getrule_parser, struct genlmsghdr, nlf_p_empty, nla_p_getrule);
+
+static int
+pf_handle_getrule(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ char anchor_call[MAXPATHLEN];
+ struct nl_parsed_get_rule attrs = {};
+ struct nl_writer *nw = npt->nw;
+ struct genlmsghdr *ghdr_new;
+ struct pf_kruleset *ruleset;
+ struct pf_krule *rule;
+ int rs_num;
+ int error;
+
+ error = nl_parse_nlmsg(hdr, &getrule_parser, npt, &attrs);
+ if (error != 0)
+ return (error);
+
+ if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
+ return (ENOMEM);
+
+ ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+ ghdr_new->cmd = PFNL_CMD_GETRULE;
+
+ PF_RULES_WLOCK();
+ ruleset = pf_find_kruleset(attrs.anchor);
+ if (ruleset == NULL) {
+ PF_RULES_WUNLOCK();
+ error = ENOENT;
+ goto out;
+ }
+
+ rs_num = pf_get_ruleset_number(attrs.action);
+ if (rs_num >= PF_RULESET_MAX) {
+ PF_RULES_WUNLOCK();
+ error = EINVAL;
+ goto out;
+ }
+
+ if (attrs.ticket != ruleset->rules[rs_num].active.ticket) {
+ PF_RULES_WUNLOCK();
+ error = EBUSY;
+ goto out;
+ }
+
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
+ while ((rule != NULL) && (rule->nr != attrs.nr))
+ rule = TAILQ_NEXT(rule, entries);
+ if (rule == NULL) {
+ PF_RULES_WUNLOCK();
+ error = EBUSY;
+ goto out;
+ }
+
+ nlattr_add_rule(nw, rule);
+
error = pf_kanchor_copyout(ruleset, rule, anchor_call, sizeof(anchor_call));
MPASS(error == 0);
@@ -1729,7 +1766,7 @@ pf_handle_get_ruleset(struct nlmsghdr *hdr, struct nl_pstate *npt)
static bool
nlattr_add_pf_threshold(struct nl_writer *nw, int attrtype,
- struct pf_kthreshold *t)
+ const struct pf_kthreshold *t)
{
int off = nlattr_add_nested(nw, attrtype);
int conn_rate_count = 0;
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
index 6591c707d9a4..4d0186ea86a5 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -152,6 +152,8 @@ enum pfstate_type_t {
PF_ST_RT_IFNAME = 37, /* string */
PF_ST_SRC_NODE_FLAGS = 38, /* u8 */
PF_ST_RT_AF = 39, /* u8 */
+ PF_ST_INCLUDE_RULE = 40, /* bool */
+ PF_ST_CREATED_BY_RULE = 41, /* nested, pf_rule_type_t */
};
enum pf_addr_type_t {
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index 132d4809b0ed..a08c50c8439a 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -152,6 +152,7 @@
#define __weak_symbol __attribute__((__weak__))
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
+#define __maybe_unused __attribute__((__unused__))
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
#define __deprecated __attribute__((__deprecated__))
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h
index 29a16b393b52..f37b1150a7e8 100644
--- a/sys/sys/eventhandler.h
+++ b/sys/sys/eventhandler.h
@@ -46,7 +46,7 @@ struct eventhandler_entry_vimage {
struct eventhandler_list {
char *el_name;
- int el_flags; /* Unused. */
+ u_int el_deadcount;
u_int el_runcount;
struct mtx el_lock;
TAILQ_ENTRY(eventhandler_list) el_link;
@@ -82,7 +82,7 @@ struct eventhandler_list {
KASSERT((list)->el_runcount > 0, \
("eventhandler_invoke: runcount underflow")); \
(list)->el_runcount--; \
- if ((list)->el_runcount == 0) \
+ if ((list)->el_runcount == 0 && (list)->el_deadcount != 0) \
eventhandler_prune_list(list); \
EHL_UNLOCK((list)); \
} while (0)
diff --git a/sys/sys/priority.h b/sys/sys/priority.h
index 93dd5aa90d95..3a3537bee1b2 100644
--- a/sys/sys/priority.h
+++ b/sys/sys/priority.h
@@ -136,10 +136,10 @@
#endif
struct priority {
- u_char pri_class; /* Scheduling class. */
- u_char pri_level; /* Normal priority level. */
- u_char pri_native; /* Priority before propagation. */
- u_char pri_user; /* User priority based on p_cpu and p_nice. */
+ unsigned char pri_class; /* Scheduling class. */
+ unsigned char pri_level; /* Normal priority level. */
+ unsigned char pri_native; /* Priority before propagation. */
+ unsigned char pri_user; /* User priority based on p_cpu and p_nice. */
};
#endif /* !_SYS_PRIORITY_H_ */
diff --git a/sys/sys/rtprio.h b/sys/sys/rtprio.h
index 6e0d8c7b0fe7..d6968a9e58a4 100644
--- a/sys/sys/rtprio.h
+++ b/sys/sys/rtprio.h
@@ -34,6 +34,7 @@
#ifndef _SYS_RTPRIO_H_
#define _SYS_RTPRIO_H_
+#include <sys/_types.h>
#include <sys/priority.h>
/*
@@ -71,8 +72,8 @@
* Scheduling class information.
*/
struct rtprio {
- u_short type; /* scheduling class */
- u_short prio;
+ unsigned short type; /* scheduling class */
+ unsigned short prio;
};
#ifdef _KERNEL
@@ -86,8 +87,8 @@ void pri_to_rtp(struct thread *, struct rtprio *);
#include <sys/cdefs.h>
__BEGIN_DECLS
-int rtprio(int, pid_t, struct rtprio *);
-int rtprio_thread(int, lwpid_t, struct rtprio *);
+int rtprio(int, __pid_t, struct rtprio *);
+int rtprio_thread(int, __lwpid_t, struct rtprio *);
__END_DECLS
#endif /* !_KERNEL */
#endif /* !_SYS_RTPRIO_H_ */
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index ba241cf9ff3a..4bf48a5e4b87 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -193,6 +193,17 @@ struct setcred32 {
uint32_t sc_label; /* struct mac32 [*] */
};
+#ifdef COMPAT_FREEBSD32
+/* 32-bit compatible version of xucred */
+struct xucred32 {
+ u_int cr_version; /* structure layout version */
+ uid_t cr_uid; /* effective user id */
+ short cr_ngroups; /* number of groups (incl. cr_gid). */
+ gid_t cr_groups[XU_NGROUPS]; /* groups */
+ pid_t cr_pid;
+};
+#endif
+
struct thread;
/* Common native and 32-bit compatibility entry point. */
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 63bdce9d60f8..94dd7d3a19bc 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -4723,6 +4723,11 @@ vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
return (rv);
}
+static bool report_stackoverflow = true;
+SYSCTL_BOOL(_vm, OID_AUTO, report_stackoverflow, CTLFLAG_RWTUN,
+ &report_stackoverflow, 0,
+ "uprintf() on stack overflow");
+
/*
* Attempts to grow a vm stack entry. Returns KERN_SUCCESS if we
* successfully grow the stack.
@@ -4731,6 +4736,7 @@ static int
vm_map_growstack(vm_map_t map, vm_offset_t addr, vm_map_entry_t gap_entry)
{
vm_map_entry_t stack_entry;
+ struct thread *td;
struct proc *p;
struct vmspace *vm;
vm_offset_t gap_end, gap_start, grow_start;
@@ -4746,7 +4752,8 @@ vm_map_growstack(vm_map_t map, vm_offset_t addr, vm_map_entry_t gap_entry)
int error __diagused;
#endif
- p = curproc;
+ td = curthread;
+ p = td->td_proc;
vm = p->p_vmspace;
/*
@@ -4754,15 +4761,14 @@ vm_map_growstack(vm_map_t map, vm_offset_t addr, vm_map_entry_t gap_entry)
* debugger or AIO daemon. The reason is that the wrong
* resource limits are applied.
*/
- if (p != initproc && (map != &p->p_vmspace->vm_map ||
- p->p_textvp == NULL))
+ if (p != initproc && (map != &vm->vm_map || p->p_textvp == NULL))
return (KERN_FAILURE);
MPASS(!vm_map_is_system(map));
- lmemlim = lim_cur(curthread, RLIMIT_MEMLOCK);
- stacklim = lim_cur(curthread, RLIMIT_STACK);
- vmemlim = lim_cur(curthread, RLIMIT_VMEM);
+ lmemlim = lim_cur(td, RLIMIT_MEMLOCK);
+ stacklim = lim_cur(td, RLIMIT_STACK);
+ vmemlim = lim_cur(td, RLIMIT_VMEM);
retry:
/* If addr is not in a hole for a stack grow area, no need to grow. */
if (gap_entry == NULL && !vm_map_lookup_entry(map, addr, &gap_entry))
@@ -4778,15 +4784,19 @@ retry:
} else {
return (KERN_FAILURE);
}
- guard = ((curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 ||
- (curproc->p_fctl0 & NT_FREEBSD_FCTL_STKGAP_DISABLE) != 0) ? 0 :
+ guard = ((p->p_flag2 & P2_STKGAP_DISABLE) != 0 ||
+ (p->p_fctl0 & NT_FREEBSD_FCTL_STKGAP_DISABLE) != 0) ? 0 :
gap_entry->next_read;
max_grow = gap_entry->end - gap_entry->start;
if (guard > max_grow)
return (KERN_NO_SPACE);
max_grow -= guard;
- if (grow_amount > max_grow)
+ if (grow_amount > max_grow) {
+ if (report_stackoverflow)
+ uprintf("pid %d comm %s tid %d stack overflow\n",
+ p->p_pid, p->p_comm, td->td_tid);
return (KERN_NO_SPACE);
+ }
/*
* If this is the main process stack, see if we're over the stack
@@ -4794,8 +4804,12 @@ retry:
*/
is_procstack = addr >= (vm_offset_t)vm->vm_maxsaddr &&
addr < (vm_offset_t)vm->vm_stacktop;
- if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > stacklim))
+ if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > stacklim)) {
+ if (report_stackoverflow)
+ uprintf("pid %d comm %s tid %d stack overflow\n",
+ p->p_pid, p->p_comm, td->td_tid);
return (KERN_NO_SPACE);
+ }
#ifdef RACCT
if (racct_enable) {
diff --git a/tests/sys/netinet6/frag6/frag6_19.sh b/tests/sys/netinet6/frag6/frag6_19.sh
index 187876c4c2bc..34095ed74f7a 100755
--- a/tests/sys/netinet6/frag6/frag6_19.sh
+++ b/tests/sys/netinet6/frag6/frag6_19.sh
@@ -207,9 +207,6 @@ frag6_19_head() {
}
frag6_19_body() {
- if [ "$(atf_config_get ci false)" = "true" ]; then
- atf_skip "https://bugs.freebsd.org/274941"
- fi
frag6_body 19 frag6_19_check_stats
}
diff --git a/tests/sys/netpfil/pf/get_state.sh b/tests/sys/netpfil/pf/get_state.sh
index eb2bc854c800..eb2e2f37a15d 100644
--- a/tests/sys/netpfil/pf/get_state.sh
+++ b/tests/sys/netpfil/pf/get_state.sh
@@ -74,7 +74,51 @@ many_cleanup()
pft_cleanup
}
+atf_test_case "rule" "cleanup"
+rule_head()
+{
+ atf_set descr 'Test retrieving original state establishing rule'
+ atf_set require.user root
+}
+
+rule_body()
+{
+ pft_init
+
+ epair=$(vnet_mkepair)
+ ifconfig ${epair}a 192.0.2.1/24 up
+
+ vnet_mkjail alcatraz ${epair}b
+ jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
+ jexec alcatraz pfctl -e
+
+ pft_set_rules alcatraz \
+ "pass in proto icmp label \"icmplabel\""
+
+ # Establish state
+ atf_check -o ignore ping -c 1 -W 1 192.0.2.2
+
+ # We should see the rule now
+ atf_check -o match:"rule: pass in proto icmp all keep state label \"icmplabel\"" \
+ -e ignore \
+ jexec alcatraz pfctl -ss -vv
+
+ pft_set_rules noflush alcatraz \
+ "pass"
+
+ # Even after the rules changes we should see the original rule
+ atf_check -o match:"rule: pass in proto icmp all keep state label \"icmplabel\"" \
+ -e ignore \
+ jexec alcatraz pfctl -ss -vv
+}
+
+rule_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "many"
+ atf_add_test_case "rule"
}
diff --git a/tests/sys/netpfil/pf/killstate.sh b/tests/sys/netpfil/pf/killstate.sh
index f5925d715e7c..161a8b7668f2 100644
--- a/tests/sys/netpfil/pf/killstate.sh
+++ b/tests/sys/netpfil/pf/killstate.sh
@@ -666,7 +666,7 @@ key_body()
--replyif ${epair}a
# Get the state key
- key=$(jexec alcatraz pfctl -ss -vvv | awk '/icmp/ { print($2 " " $3 " " $4 " " $5); }')
+ key=$(jexec alcatraz pfctl -ss -vvv | awk '/all icmp/ { print($2 " " $3 " " $4 " " $5); }')
bad_key=$(echo ${key} | sed 's/icmp/tcp/')
# Kill the wrong key
diff --git a/tests/sys/netpfil/pf/match.sh b/tests/sys/netpfil/pf/match.sh
index 992e32d9f887..c732ec7c5c17 100644
--- a/tests/sys/netpfil/pf/match.sh
+++ b/tests/sys/netpfil/pf/match.sh
@@ -234,10 +234,46 @@ double_match_cleanup()
pft_cleanup
}
+atf_test_case "duplicate_rules" "cleanup"
+duplicate_rules_head()
+{
+ atf_set descr 'Test identical rules'
+ atf_set require.user root
+}
+
+duplicate_rules_body()
+{
+ pft_init
+
+ epair=$(vnet_mkepair)
+ vnet_mkjail alcatraz ${epair}b
+
+ ifconfig ${epair}a 192.0.2.1/24 up
+ jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
+
+ # Sanity check
+ atf_check -s exit:0 -o ignore ping -c 1 192.0.2.2
+
+ jexec alcatraz pfctl -e
+ pft_set_rules alcatraz \
+ "block" \
+ "pass tagged FOO" \
+ "match tag FOO" \
+ "pass tagged FOO"
+
+ atf_check -s exit:0 -o ignore ping -c 3 192.0.2.2
+}
+
+duplicate_rules_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "dummynet"
atf_add_test_case "quick"
atf_add_test_case "allow_opts"
atf_add_test_case "double_match"
+ atf_add_test_case "duplicate_rules"
}
diff --git a/tests/sys/netpfil/pf/names.sh b/tests/sys/netpfil/pf/names.sh
index e47b0917cfec..c6f2a06c15f9 100644
--- a/tests/sys/netpfil/pf/names.sh
+++ b/tests/sys/netpfil/pf/names.sh
@@ -95,8 +95,48 @@ group_cleanup()
pft_cleanup
}
+atf_test_case "start_number" "cleanup"
+start_number_head()
+{
+ atf_set descr 'Test interface names starting with a number'
+ atf_set require.user root
+}
+
+start_number_body()
+{
+ pft_init
+
+ epair=$(vnet_mkepair)
+ ifconfig ${epair}a 192.0.2.1/24 up
+
+ vnet_mkjail alcatraz ${epair}b
+ jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
+ jexec alcatraz ifconfig ${epair}b name 4ever
+ jexec alcatraz pfctl -e
+
+ jexec alcatraz ifconfig
+
+ pft_set_rules alcatraz \
+ "block" \
+ "pass in from any to (4ever)"
+
+ atf_check -o ignore ping -c 3 192.0.2.2
+
+ # Negative test, if the interface doesn't exist we don't pass packets
+ pft_set_rules alcatraz \
+ "block" \
+ "pass in from any to (5ever)"
+ atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2
+}
+
+start_number_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "names"
atf_add_test_case "group"
+ atf_add_test_case "start_number"
}
diff --git a/tools/build/test-includes/badfiles.inc b/tools/build/test-includes/badfiles.inc
index a0aada4f016f..e7e9e67c4518 100644
--- a/tools/build/test-includes/badfiles.inc
+++ b/tools/build/test-includes/badfiles.inc
@@ -90,14 +90,12 @@ BADHDRS= \
sys/pmckern.h \
sys/posix4.h \
sys/power.h \
- sys/priority.h \
sys/prng.h \
sys/qmath.h \
sys/racct.h \
sys/resourcevar.h \
sys/rman.h \
sys/rmlock.h \
- sys/rtprio.h \
sys/runq.h \
sys/rwlock.h \
sys/sbuf.h \
diff --git a/tools/tools/git/git-arc.sh b/tools/tools/git/git-arc.sh
index 395787df970c..f2a325f3452a 100755
--- a/tools/tools/git/git-arc.sh
+++ b/tools/tools/git/git-arc.sh
@@ -57,7 +57,7 @@ err_usage()
Usage: git arc [-vy] <command> <arguments>
Commands:
- create [-l] [-r <reviewer1>[,<reviewer2>...]] [-s subscriber[,...]] [<commit>|<commit range>]
+ create [-dl] [-r <reviewer1>[,<reviewer2>...]] [-s subscriber[,...]] [<commit>|<commit range>]
list <commit>|<commit range>
patch [-bcrs] <diff1> [<diff2> ...]
stage [-b branch] [<commit>|<commit range>]
diff --git a/usr.bin/stat/tests/stat_test.sh b/usr.bin/stat/tests/stat_test.sh
index f2de15cf4f9b..aa8563c62ccc 100755
--- a/usr.bin/stat/tests/stat_test.sh
+++ b/usr.bin/stat/tests/stat_test.sh
@@ -1,7 +1,7 @@
#
# Copyright (c) 2017 Dell EMC
# All rights reserved.
-# Copyright (c) 2025 Klara, Inc.
+# Copyright (c) 2025-2026 Klara, Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
#
: ${CHKPATH:="mnt"}
+: ${NODEV:="#NODEV"}
atf_test_case F_flag
F_flag_head()
@@ -234,9 +235,9 @@ t_flag_head()
{
atf_set "descr" "Verify the output format for -t"
}
-
t_flag_body()
{
+ export TZ=UTC
atf_check touch foo
atf_check touch -d 1970-01-01T00:00:42 foo
atf_check -o inline:'42\n' \
@@ -323,6 +324,7 @@ devname_body()
atf_check -o inline:"$devname\n" stat -f '%Sd' "$CHKPATH"
atf_check -o inline:"$devname\n" stat -f '%Sr' "$devpath"
+ atf_check -o inline:"$NODEV\n" stat -f '%Sr' "$CHKPATH"
}
devname_cleanup()
{
diff --git a/usr.sbin/bhyve/pci_virtio_scsi.c b/usr.sbin/bhyve/pci_virtio_scsi.c
index dafff50fa531..5fb867e5eae7 100644
--- a/usr.sbin/bhyve/pci_virtio_scsi.c
+++ b/usr.sbin/bhyve/pci_virtio_scsi.c
@@ -669,6 +669,7 @@ pci_vtscsi_queue_request(struct pci_vtscsi_softc *sc, struct vqueue_info *vq)
struct pci_vtscsi_queue *q = &sc->vss_queues[vq->vq_num - 2];
struct pci_vtscsi_request *req;
struct vi_req vireq;
+ size_t res __maybe_unused;
int n;
pthread_mutex_lock(&q->vsq_fmtx);
@@ -747,8 +748,9 @@ pci_vtscsi_queue_request(struct pci_vtscsi_softc *sc, struct vqueue_info *vq)
* This will have to change if we begin allowing config space writes
* to change sense size.
*/
- assert(iov_to_buf(req->vsr_iov_in, req->vsr_niov_in,
- (void **)&req->vsr_cmd_rd) == VTSCSI_IN_HEADER_LEN(q->vsq_sc));
+ res = iov_to_buf(req->vsr_iov_in, req->vsr_niov_in,
+ (void **)&req->vsr_cmd_rd);
+ assert(res == VTSCSI_IN_HEADER_LEN(q->vsq_sc));
/* Make sure this request addresses a valid LUN. */
if (pci_vtscsi_check_lun(req->vsr_cmd_rd->lun) == false) {
diff --git a/usr.sbin/certctl/certctl.8 b/usr.sbin/certctl/certctl.8
index 2d38ce020c04..7df89e4d35d0 100644
--- a/usr.sbin/certctl/certctl.8
+++ b/usr.sbin/certctl/certctl.8
@@ -24,7 +24,7 @@
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd December 3, 2025
+.Dd April 24, 2026
.Dt CERTCTL 8
.Os
.Sh NAME
@@ -113,8 +113,19 @@ In addition, a bundle containing the trusted certificates is placed in
.Ev BUNDLE .
.It Ic untrust
Add the specified file to the untrusted list.
+Note that the next
+.Ic rehash
+will remove it unless a copy of it is also placed somewhere in a
+directory included in
+.Ev UNTRUSTPATH .
.It Ic trust
-Remove the specified file from the untrusted list.
+Add the specified file to the trusted list, unless it is already
+untrusted.
+Note that the next
+.Ic rehash
+will remove it unless a copy of it is also placed somewhere in a
+directory included in
+.Ev TRUSTPATH .
.El
.Sh ENVIRONMENT
.Bl -tag -width UNTRUSTDESTDIR
diff --git a/usr.sbin/certctl/certctl.c b/usr.sbin/certctl/certctl.c
index a53ed7b2b4b2..0a07703bf37b 100644
--- a/usr.sbin/certctl/certctl.c
+++ b/usr.sbin/certctl/certctl.c
@@ -636,23 +636,18 @@ write_bundle(const char *dir, const char *file, struct cert_tree *tree)
* Returns the number of certificates loaded.
*/
static unsigned int
-load_trusted(bool all, struct cert_tree *exclude)
+load_trusted(void)
{
unsigned int i, n;
int ret;
/* load external trusted certs */
- for (i = n = 0; all && trusted_paths[i] != NULL; i++) {
- ret = read_certs(trusted_paths[i], &trusted, exclude);
+ for (i = n = 0; trusted_paths[i] != NULL; i++) {
+ ret = read_certs(trusted_paths[i], &trusted, &untrusted);
if (ret > 0)
n += ret;
}
- /* load installed trusted certs */
- ret = read_certs(trusted_dest, &trusted, exclude);
- if (ret > 0)
- n += ret;
-
info("%d trusted certificates found", n);
return (n);
}
@@ -663,24 +658,19 @@ load_trusted(bool all, struct cert_tree *exclude)
* Returns the number of certificates loaded.
*/
static unsigned int
-load_untrusted(bool all)
+load_untrusted(void)
{
char *path;
unsigned int i, n;
int ret;
/* load external untrusted certs */
- for (i = n = 0; all && untrusted_paths[i] != NULL; i++) {
+ for (i = n = 0; untrusted_paths[i] != NULL; i++) {
ret = read_certs(untrusted_paths[i], &untrusted, NULL);
if (ret > 0)
n += ret;
}
- /* load installed untrusted certs */
- ret = read_certs(untrusted_dest, &untrusted, NULL);
- if (ret > 0)
- n += ret;
-
/* load legacy untrusted certs */
path = expand_path(LEGACY_PATH);
ret = read_certs(path, &untrusted, NULL);
@@ -796,8 +786,8 @@ certctl_list(int argc, char **argv __unused)
{
if (argc > 1)
usage();
- /* load trusted certificates */
- load_trusted(false, NULL);
+ /* load installed trusted certificates */
+ read_certs(trusted_dest, &trusted, NULL);
/* list them */
list_certs(&trusted);
free_certs(&trusted);
@@ -814,8 +804,8 @@ certctl_untrusted(int argc, char **argv __unused)
{
if (argc > 1)
usage();
- /* load untrusted certificates */
- load_untrusted(false);
+ /* load installed untrusted certificates */
+ read_certs(untrusted_dest, &untrusted, NULL);
/* list them */
list_certs(&untrusted);
free_certs(&untrusted);
@@ -842,10 +832,10 @@ certctl_rehash(int argc, char **argv __unused)
}
/* load untrusted certs first */
- load_untrusted(true);
+ load_untrusted();
/* load trusted certs, excluding any that are already untrusted */
- load_trusted(true, &untrusted);
+ load_trusted();
/* save everything */
ret = save_all();
@@ -859,7 +849,8 @@ certctl_rehash(int argc, char **argv __unused)
}
/*
- * Manually add one or more certificates to the list of trusted certificates.
+ * Manually add one or more certificates to the list of trusted
+ * certificates.
*
* Returns 0 on success and -1 on failure.
*/
@@ -875,10 +866,10 @@ certctl_trust(int argc, char **argv)
usage();
/* load untrusted certs first */
- load_untrusted(true);
+ load_untrusted();
/* load trusted certs, excluding any that are already untrusted */
- load_trusted(true, &untrusted);
+ load_trusted();
/* now load the additional trusted certificates */
n = 0;
@@ -891,9 +882,9 @@ certctl_trust(int argc, char **argv)
warnx("no new trusted certificates found");
free_certs(&untrusted);
free_certs(&trusted);
- free_certs(&extra);
return (0);
}
+ warnx("%u new trusted certificate%s found", n, n > 1 ? "s" : "");
/*
* For each new trusted cert, move it from the extra list to the
@@ -906,10 +897,16 @@ certctl_trust(int argc, char **argv)
RB_INSERT(cert_tree, &trusted, cert);
if ((other = RB_FIND(cert_tree, &untrusted, cert)) != NULL) {
warnx("%s was previously untrusted", cert->name);
+ warnx("source of untrust: %s", other->path);
RB_REMOVE(cert_tree, &untrusted, other);
free_cert(other);
}
}
+ warnx("This operation is not persistent. To persistently add");
+ warnx("trusted certificates to the system store, copy them to");
+ warnx("one of these directories, then run `certctl rehash`:");
+ for (i = 0; trusted_paths[i] != NULL; i++)
+ warnx(" %s", trusted_paths[i]);
/* save everything */
ret = save_all();
@@ -929,6 +926,8 @@ certctl_trust(int argc, char **argv)
static int
certctl_untrust(int argc, char **argv)
{
+ struct cert_tree extra = RB_INITIALIZER(&extra);
+ struct cert *cert, *other, *tmp;
unsigned int n;
int i, ret;
@@ -936,23 +935,47 @@ certctl_untrust(int argc, char **argv)
usage();
/* load untrusted certs first */
- load_untrusted(true);
+ load_untrusted();
+
+ /* load trusted certs, excluding any that are already untrusted */
+ load_trusted();
/* now load the additional untrusted certificates */
n = 0;
for (i = 1; i < argc; i++) {
- ret = read_cert(argv[i], &untrusted, NULL);
+ ret = read_cert(argv[i], &extra, NULL);
if (ret > 0)
n += ret;
}
if (n == 0) {
warnx("no new untrusted certificates found");
free_certs(&untrusted);
+ free_certs(&trusted);
return (0);
}
+ warnx("%u new untrusted certificate%s found", n, n > 1 ? "s" : "");
- /* load trusted certs, excluding any that are already untrusted */
- load_trusted(true, &untrusted);
+ /*
+ * For each new untrusted cert, move it from the extra list to the
+ * untrusted list, then check if a matching certificate exists on
+ * the trusted list. If that is the case, warn the user, then
+ * remove the matching certificate from the trusted list.
+ */
+ RB_FOREACH_SAFE(cert, cert_tree, &extra, tmp) {
+ RB_REMOVE(cert_tree, &extra, cert);
+ RB_INSERT(cert_tree, &untrusted, cert);
+ if ((other = RB_FIND(cert_tree, &trusted, cert)) != NULL) {
+ warnx("%s was previously trusted", cert->name);
+ warnx("source of trust: %s", other->path);
+ RB_REMOVE(cert_tree, &trusted, other);
+ free_cert(other);
+ }
+ }
+ warnx("This operation is not persistent. To persistently add");
+ warnx("untrusted certificates to the system store, copy them to");
+ warnx("one of these directories, then run `certctl rehash`:");
+ for (i = 0; untrusted_paths[i] != NULL; i++)
+ warnx(" %s", untrusted_paths[i]);
/* save everything */
ret = save_all();
diff --git a/usr.sbin/certctl/tests/certctl_test.sh b/usr.sbin/certctl/tests/certctl_test.sh
index 74749db0b3f5..133d65854c42 100644
--- a/usr.sbin/certctl/tests/certctl_test.sh
+++ b/usr.sbin/certctl/tests/certctl_test.sh
@@ -271,7 +271,8 @@ untrust_body()
crtfile=usr/share/certs/trusted/${crtname}.crt
check_trusted "${crtname}"
check_in_bundle ${crtfile}
- atf_check certctl untrust "${crtfile}"
+ atf_check -e match:"1 new untrusted" \
+ certctl untrust "${crtfile}"
check_untrusted "${crtname}"
check_not_in_bundle ${crtfile}
}
diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c
index 1bad04ccde68..188f48732561 100644
--- a/usr.sbin/jail/config.c
+++ b/usr.sbin/jail/config.c
@@ -321,6 +321,7 @@ static void
parse_config(const char *cfname, int is_stdin)
{
struct cflex cflex = {.cfname = cfname, .error = 0};
+ FILE *yfp = NULL;
void *scanner;
yylex_init_extra(&cflex, &scanner);
@@ -328,7 +329,7 @@ parse_config(const char *cfname, int is_stdin)
cflex.cfname = "STDIN";
yyset_in(stdin, scanner);
} else {
- FILE *yfp = fopen(cfname, "r");
+ yfp = fopen(cfname, "re");
if (!yfp)
err(1, "%s", cfname);
yyset_in(yfp, scanner);
@@ -336,6 +337,8 @@ parse_config(const char *cfname, int is_stdin)
if (yyparse(scanner) || cflex.error)
exit(1);
yylex_destroy(scanner);
+ if (yfp != NULL)
+ fclose(yfp);
}
/*
@@ -723,7 +726,7 @@ check_intparams(struct cfjail *j)
TAILQ_FOREACH(s, &j->intparams[IP_MOUNT_FSTAB]->val, tq) {
if (s->len == 0)
continue;
- f = fopen(s->s, "r");
+ f = fopen(s->s, "re");
if (f == NULL) {
jail_warnx(j, "mount.fstab: %s: %s",
s->s, strerror(errno));
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c
index 8b7079c17822..df4473841312 100644
--- a/usr.sbin/rtadvd/config.c
+++ b/usr.sbin/rtadvd/config.c
@@ -1107,6 +1107,7 @@ get_prefix(struct rainfo *rai)
ifi = rai->rai_ifinfo;
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ int64_t val64;
int plen;
if (strcmp(ifa->ifa_name, ifi->ifi_ifname) != 0)
@@ -1155,9 +1156,26 @@ get_prefix(struct rainfo *rai)
"<%s> add %s/%d to prefix list on %s",
__func__, ntopbuf, pfx->pfx_prefixlen, ifi->ifi_ifname);
+ MAYHAVE(val64, "vltime", DEF_ADVVALIDLIFETIME);
+ if (val64 < 0 || val64 > 0xffffffff) {
+ syslog(LOG_WARNING,
+ "<%s> vltime (%" PRIu64 ") for %s/%d on %s "
+ "is out of range, use default value instead.", __func__,
+ val64, ntopbuf, pfx->pfx_prefixlen, ifi->ifi_ifname);
+ pfx->pfx_validlifetime = DEF_ADVVALIDLIFETIME;
+ } else
+ pfx->pfx_validlifetime = val64;
+ MAYHAVE(val64, "pltime", DEF_ADVPREFERREDLIFETIME);
+ if (val64 < 0 || val64 > 0xffffffff) {
+ syslog(LOG_WARNING,
+ "<%s> pltime (%" PRIu64 ") for %s/%d on %s "
+ "is out of range, use default value instead.", __func__,
+ val64, ntopbuf, pfx->pfx_prefixlen, ifi->ifi_ifname);
+ pfx->pfx_preflifetime = DEF_ADVPREFERREDLIFETIME;
+ } else
+ pfx->pfx_preflifetime = val64;
+
/* set other fields with protocol defaults */
- pfx->pfx_validlifetime = DEF_ADVVALIDLIFETIME;
- pfx->pfx_preflifetime = DEF_ADVPREFERREDLIFETIME;
pfx->pfx_onlinkflg = 1;
pfx->pfx_autoconfflg = 1;
pfx->pfx_origin = PREFIX_FROM_KERNEL;