aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ObsoleteFiles.inc5
-rw-r--r--UPDATING6
-rw-r--r--cddl/lib/libspl/Makefile6
-rw-r--r--etc/mtree/BSD.tests.dist2
-rw-r--r--lib/libsys/pathconf.28
-rw-r--r--lib/libsys/shm_open.25
-rw-r--r--lib/libutil/Makefile1
-rw-r--r--lib/libutil/login.conf.57
-rw-r--r--lib/libutil/login_auth.34
-rw-r--r--lib/libutil/login_cap.31
-rw-r--r--lib/libutil/mntopts.310
-rw-r--r--lib/libutil/uucplock.31
-rw-r--r--lib/msun/src/e_fmod.c30
-rw-r--r--lib/msun/src/math_private.h21
-rw-r--r--lib/msun/src/s_ilogb.c13
-rw-r--r--lib/msun/src/s_remquo.c30
-rw-r--r--share/man/man4/epair.422
-rw-r--r--share/man/man4/sa.48
-rw-r--r--share/mk/bsd.man.mk18
-rw-r--r--sys/arm/allwinner/aw_gpio.c3
-rw-r--r--sys/arm/allwinner/axp209.c5
-rw-r--r--sys/arm/allwinner/axp81x.c3
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_gpio.c3
-rw-r--r--sys/arm/broadcom/bcm2835/raspberrypi_gpio.c3
-rw-r--r--sys/arm/freescale/imx/imx_gpio.c3
-rw-r--r--sys/arm/freescale/vybrid/vf_gpio.c3
-rw-r--r--sys/arm/mv/a37x0_gpio.c3
-rw-r--r--sys/arm/mv/gpio.c3
-rw-r--r--sys/arm/mv/mvebu_gpio.c3
-rw-r--r--sys/arm/nvidia/tegra_gpio.c3
-rw-r--r--sys/arm/ti/ti_gpio.c3
-rw-r--r--sys/arm/xilinx/zy7_gpio.c3
-rw-r--r--sys/arm64/apple/apple_pinctrl.c3
-rw-r--r--sys/arm64/rockchip/rk_gpio.c3
-rw-r--r--sys/arm64/rockchip/rk_grf_gpio.c3
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c30
-rw-r--r--sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh3
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_main.c2
-rw-r--r--sys/contrib/openzfs/cmd/zhack.c10
-rwxr-xr-xsys/contrib/openzfs/cmd/zilstat.in1
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_main.c13
-rw-r--r--sys/contrib/openzfs/cmd/ztest.c29
-rw-r--r--sys/contrib/openzfs/config/toolchain-simd.m469
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h4
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/proc.h4
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/simd_x86.h21
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/debug.h4
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/mutex.h2
-rw-r--r--sys/contrib/openzfs/include/sys/dmu.h4
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_znode.h2
-rw-r--r--sys/contrib/openzfs/include/sys/zil.h33
-rw-r--r--sys/contrib/openzfs/include/sys/zil_impl.h4
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/debug.h4
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_diff.c4
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_import.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_mount.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c8
-rw-r--r--sys/contrib/openzfs/lib/libzpool/abd_os.c4
-rw-r--r--sys/contrib/openzfs/lib/libzpool/kernel.c2
-rw-r--r--sys/contrib/openzfs/lib/libzpool/util.c8
-rw-r--r--sys/contrib/openzfs/lib/libzutil/zutil_import.c4
-rw-r--r--sys/contrib/openzfs/module/avl/avl.c16
-rw-r--r--sys/contrib/openzfs/module/icp/core/kcf_sched.c2
-rw-r--r--sys/contrib/openzfs/module/icp/io/aes.c10
-rw-r--r--sys/contrib/openzfs/module/nvpair/nvpair.c6
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c2
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c2
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c8
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c2
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c11
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c90
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c18
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c20
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c8
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-generic.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c24
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-kstat.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-thread.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-tsd.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/abd_os.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c8
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c24
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c27
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c132
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_znode_os.c58
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c63
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c4
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c4
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c57
-rw-r--r--sys/contrib/openzfs/module/zfs/abd.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/arc.c68
-rw-r--r--sys/contrib/openzfs/module/zfs/bpobj.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/btree.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/dataset_kstats.c1
-rw-r--r--sys/contrib/openzfs/module/zfs/dbuf.c74
-rw-r--r--sys/contrib/openzfs/module/zfs/ddt.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/ddt_log.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu.c12
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_direct.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_object.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_objset.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_recv.c12
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_redact.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_send.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_tx.c18
-rw-r--r--sys/contrib/openzfs/module/zfs/dnode.c22
-rw-r--r--sys/contrib/openzfs/module/zfs/dnode_sync.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_bookmark.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_crypt.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_dataset.c10
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_deadlist.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_deleg.c20
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_destroy.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_dir.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_pool.c10
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_prop.c31
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_scan.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_userhold.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/fm.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/metaslab.c34
-rw-r--r--sys/contrib/openzfs/module/zfs/mmp.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/range_tree.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/rrwlock.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/sa.c24
-rw-r--r--sys/contrib/openzfs/module/zfs/spa.c66
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_misc.c19
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_stats.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/space_map.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/space_reftree.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev.c46
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_draid.c16
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_indirect.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_initialize.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_label.c14
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_queue.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_raidz.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_rebuild.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_removal.c22
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_trim.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/zap.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/zap_micro.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/zcp.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zfeature.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_fuid.c44
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_ioctl.c119
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_log.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_quota.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_rlock.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_sa.c15
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_vnops.c27
-rw-r--r--sys/contrib/openzfs/module/zfs/zil.c461
-rw-r--r--sys/contrib/openzfs/module/zfs/zio.c62
-rw-r--r--sys/contrib/openzfs/module/zfs/zio_checksum.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zio_compress.c15
-rw-r--r--sys/contrib/openzfs/module/zfs/zio_inject.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zrlock.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zthr.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zvol.c117
-rw-r--r--sys/contrib/openzfs/rpm/generic/zfs.spec.in1
-rw-r--r--sys/contrib/openzfs/tests/runfiles/common.run6
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c4
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_write_sync.c84
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am9
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode.kshlib149
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_continue.ksh36
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_wait.ksh36
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_continue.ksh36
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_wait.ksh36
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_continue.ksh36
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_wait.ksh37
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_continue.ksh37
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_wait.ksh37
-rw-r--r--sys/dev/amdgpio/amdgpio.c3
-rw-r--r--sys/dev/bhnd/cores/chipc/chipc_gpio.c4
-rw-r--r--sys/dev/ftgpio/ftgpio.c3
-rw-r--r--sys/dev/gpio/acpi_gpiobus.c3
-rw-r--r--sys/dev/gpio/bytgpio.c3
-rw-r--r--sys/dev/gpio/chvgpio.c3
-rw-r--r--sys/dev/gpio/dwgpio/dwgpio.c3
-rw-r--r--sys/dev/gpio/gpiobus.c18
-rw-r--r--sys/dev/gpio/gpiobusvar.h1
-rw-r--r--sys/dev/gpio/pl061.c3
-rw-r--r--sys/dev/gpio/qoriq_gpio.c3
-rw-r--r--sys/dev/iicbus/gpio/pcf8574.c7
-rw-r--r--sys/dev/iicbus/gpio/tca64xx.c7
-rw-r--r--sys/dev/nctgpio/nctgpio.c3
-rw-r--r--sys/dev/p2sb/lewisburg_gpio.c3
-rw-r--r--sys/dev/qcom_tlmm/qcom_tlmm_ipq4018.c3
-rw-r--r--sys/dev/rccgpio/rccgpio.c3
-rw-r--r--sys/dev/uart/uart_cpu_acpi.c20
-rw-r--r--sys/dev/uart/uart_cpu_acpi.h17
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c42
-rw-r--r--sys/dev/uart/uart_dev_pl011.c16
-rw-r--r--sys/dev/usb/misc/cp2112.c5
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c1
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c45
-rw-r--r--sys/fs/nfs/nfs_var.h17
-rw-r--r--sys/fs/nfs/nfsport.h7
-rw-r--r--sys/fs/nfs/nfsproto.h13
-rw-r--r--sys/fs/nfsclient/nfs_clcomsubs.c2
-rw-r--r--sys/fs/nfsclient/nfs_clport.c13
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c237
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c2
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c10
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c139
-rw-r--r--sys/fs/nfsclient/nfsmount.h1
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c45
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c216
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c2
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c2
-rw-r--r--sys/kern/uipc_shm.c3
-rw-r--r--sys/modules/zfs/zfs_config.h4
-rw-r--r--sys/modules/zfs/zfs_gitrev.h2
-rw-r--r--sys/net/iflib.c108
-rw-r--r--sys/netinet/icmp6.h3
-rw-r--r--sys/netinet/tcp_input.c58
-rw-r--r--sys/netinet/tcp_stacks/bbr.c26
-rw-r--r--sys/netinet/tcp_stacks/rack.c26
-rw-r--r--sys/netinet/tcp_stacks/rack_bbr_common.c10
-rw-r--r--sys/netinet/tcp_stacks/rack_bbr_common.h4
-rw-r--r--sys/netinet/tcp_subr.c2
-rw-r--r--sys/netinet/tcp_timewait.c2
-rw-r--r--sys/netinet/tcp_var.h3
-rw-r--r--sys/netinet/udp_usrreq.c6
-rw-r--r--sys/netinet6/icmp6.c38
-rw-r--r--sys/netinet6/ip6_output.c107
-rw-r--r--sys/powerpc/mpc85xx/mpc85xx_gpio.c3
-rw-r--r--sys/riscv/sifive/sifive_gpio.c3
-rw-r--r--sys/riscv/starfive/jh7110_gpio.c3
-rw-r--r--sys/sys/param.h2
-rw-r--r--tests/sys/kern/Makefile2
-rw-r--r--tests/sys/kern/copy_file_range.c231
-rwxr-xr-xtools/tools/nanobsd/defaults.sh9
-rw-r--r--usr.bin/last/last.c27
-rw-r--r--usr.bin/netstat/inet.c12
-rw-r--r--usr.bin/sockstat/Makefile4
-rw-r--r--usr.bin/sockstat/main.c1883
-rw-r--r--usr.bin/sockstat/sockstat.c1883
-rw-r--r--usr.bin/sockstat/sockstat.h35
-rw-r--r--usr.bin/sockstat/tests/Makefile8
-rw-r--r--usr.bin/sockstat/tests/sockstat_test.c190
-rw-r--r--usr.bin/systat/ip.c20
-rw-r--r--usr.bin/tcopy/Makefile4
-rw-r--r--usr.bin/tcopy/tcopy.1195
-rw-r--r--usr.bin/tcopy/tcopy.c338
-rw-r--r--usr.bin/tcopy/tcopy.cc837
-rw-r--r--usr.sbin/autofs/common.c1
-rw-r--r--usr.sbin/chroot/chroot.c43
259 files changed, 6510 insertions, 3824 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 0a4a567dff0b..4db0704d88ef 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,6 +51,9 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20250812: Remove a bogus manlink
+OLD_FILES+=usr/share/man/man3/quota_statfs.3.gz
+
# 20250810: Removal of remaining Secure RPC (DES) bits
OLD_FILES+=usr/sbin/rpc.ypupdated
OLD_FILES+=etc/rc.d/ypupdated
@@ -60,7 +63,9 @@ OLD_FILES+=usr/sbin/nvmfd
OLD_FILES+=usr/share/man/man8/nvmfd.8.gz
# 20250807: Replace lib/libgssapi with krb5/lib/gssapi
+OLD_FILES+=usr/include/gssapi_krb5/gssapi.h
OLD_FILES+=usr/include/gssapi_krb5/gssapi/gssapi.h
+OLD_FILES+=usr/include/gssapi_krb5/gssapi/mechglue.h
OLD_DIRS+=usr/include/gssapi_krb5/gssapi
OLD_DIRS+=usr/include/gssapi_krb5
OLD_FILES+=etc/gssapi/qop
diff --git a/UPDATING b/UPDATING
index 78562d021e37..c4452354b189 100644
--- a/UPDATING
+++ b/UPDATING
@@ -27,6 +27,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW:
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20250813:
+ The gpiobus_attach_bus() function has been removed. Drivers should now
+ use the gpiobus_add_bus() function instead. The difference being that
+ gpiobus_add_bus() doesn't call bus_attach_children(), calling it will
+ be the responsibility of the caller now.
+
20250810:
Support for Secure RPC DES authentication has been removed.
The keyserv(8) daemon was already removed, but support for it in libc
diff --git a/cddl/lib/libspl/Makefile b/cddl/lib/libspl/Makefile
index 13fd6d96f2af..d8d997c6f377 100644
--- a/cddl/lib/libspl/Makefile
+++ b/cddl/lib/libspl/Makefile
@@ -16,16 +16,16 @@ SRCS = \
os/freebsd/zone.c \
page.c \
timestamp.c \
- tunables.c \
include/sys/list.h \
include/sys/list_impl.h
-# These functions are not required when bootstrapping and the atomic code
-# will not compile when building on macOS.
+# These functions are not required when bootstrapping and the atomic code,
+# among others, will not compile when building on macOS.
.if !defined(BOOTSTRAPPING)
SRCS += \
atomic.c \
getexecname.c \
+ tunables.c \
os/freebsd/getexecname.c \
os/freebsd/gethostid.c \
os/freebsd/getmntany.c \
diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index b3b2b61da143..2c25d9386032 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -1205,6 +1205,8 @@
..
seq
..
+ sockstat
+ ..
soelim
..
sort
diff --git a/lib/libsys/pathconf.2 b/lib/libsys/pathconf.2
index 79ac8310000d..5a983a3a13e2 100644
--- a/lib/libsys/pathconf.2
+++ b/lib/libsys/pathconf.2
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 5, 2025
+.Dd August 6, 2025
.Dt PATHCONF 2
.Os
.Sh NAME
@@ -187,6 +187,11 @@ and
flags can be set by
.Xr chflags 2 ,
otherwise 0.
+.It Li _PC_CLONE_BLKSIZE
+Returns the block size required for block cloning via
+.Xr copy_file_range 2
+for a file system if block cloning is supported,
+otherwise 0.
.El
.Sh RETURN VALUES
If the call to
@@ -264,6 +269,7 @@ Corrupted data was detected while reading from the file system.
.El
.Sh SEE ALSO
.Xr chflags 2 ,
+.Xr copy_file_range 2 ,
.Xr lseek 2 ,
.Xr sysctl 3
.Sh HISTORY
diff --git a/lib/libsys/shm_open.2 b/lib/libsys/shm_open.2
index 8bea939690ba..c3196d966e6b 100644
--- a/lib/libsys/shm_open.2
+++ b/lib/libsys/shm_open.2
@@ -26,7 +26,7 @@
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 30, 2023
+.Dd August 4, 2025
.Dt SHM_OPEN 2
.Os
.Sh NAME
@@ -74,8 +74,9 @@ must be included in
The optional flags
.Dv O_CREAT ,
.Dv O_EXCL ,
+.Dv O_TRUNC ,
and
-.Dv O_TRUNC
+.Dv O_CLOFORK
may also be specified.
.Pp
If
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index f8c566ca731a..f6251c093345 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -136,7 +136,6 @@ MLINKS+=quotafile.3 quota_on.3
MLINKS+=quotafile.3 quota_open.3
MLINKS+=quotafile.3 quota_qfname.3
MLINKS+=quotafile.3 quota_read.3
-MLINKS+=quotafile.3 quota_statfs.3
MLINKS+=quotafile.3 quota_write_limits.3
MLINKS+=quotafile.3 quota_write_usage.3
MAN+= realhostname.3
diff --git a/lib/libutil/login.conf.5 b/lib/libutil/login.conf.5
index d43fdfb761f3..27f37fb5fc30 100644
--- a/lib/libutil/login.conf.5
+++ b/lib/libutil/login.conf.5
@@ -380,14 +380,15 @@ If
is specified, then logins are only allowed during the periods given.
If
.Em times.deny
-is specified, then logins are denied during the periods given, regardless of whether
-one of the periods specified in
+is specified, then logins are denied during the periods given,
+regardless of whether one of the periods specified in
.Em times.allow
applies.
.Pp
Note that
.Xr login 1
-enforces only that the actual login falls within periods allowed by these entries.
+enforces only that the actual login falls within periods allowed by
+these entries.
Further enforcement over the life of a session requires a separate daemon to
monitor transitions from an allowed period to a non-allowed one.
.Pp
diff --git a/lib/libutil/login_auth.3 b/lib/libutil/login_auth.3
index fafe43b906e6..dd5ba3e01265 100644
--- a/lib/libutil/login_auth.3
+++ b/lib/libutil/login_auth.3
@@ -58,8 +58,8 @@
.\" .Ft int
.\" .Fn auth_timesok "login_cap_t *lc" "time_t now"
.Sh DESCRIPTION
-This set of functions support the login class authorisation style interface provided
-by
+This set of functions support the login class authorisation style
+interface provided by
.Xr login.conf 5 .
.\" .Sh RETURN VALUES
.Sh SEE ALSO
diff --git a/lib/libutil/login_cap.3 b/lib/libutil/login_cap.3
index 86142c3b19f9..48af0e3c9c46 100644
--- a/lib/libutil/login_cap.3
+++ b/lib/libutil/login_cap.3
@@ -31,6 +31,7 @@
.Nm login_getcaptime ,
.Nm login_getclass ,
.Nm login_getclassbyname ,
+.Nm login_getpath ,
.Nm login_getpwclass ,
.Nm login_getstyle ,
.Nm login_getuserclass ,
diff --git a/lib/libutil/mntopts.3 b/lib/libutil/mntopts.3
index 35f6d476fcec..28e5a02442c2 100644
--- a/lib/libutil/mntopts.3
+++ b/lib/libutil/mntopts.3
@@ -342,9 +342,9 @@ By default
.Va getmnt_silent
is zero.
.Sh SEE ALSO
+.Xr nmount 2 ,
.Xr err 3 ,
-.Xr mount 8 ,
-.Xr nmount 8
+.Xr mount 8
.Sh HISTORY
The
.Fn getmntopts
@@ -358,7 +358,7 @@ The
and
.Fn rmslashes
functions were added with
-.Xr nmount 8
+.Xr nmount 2
in
.Fx 5.0 .
The
@@ -368,7 +368,9 @@ and
functions were added in
.Fx 13.2 .
.Pp
-Historically, these functions were found in getmntopts.c in the sources for the
+Historically, these functions were found in
+.Pa getmntopts.c
+in the source code of the
.Xr mount 8
program.
As of
diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3
index dd19d0311b4e..ee8c9f6bb995 100644
--- a/lib/libutil/uucplock.3
+++ b/lib/libutil/uucplock.3
@@ -28,6 +28,7 @@
.Os
.Sh NAME
.Nm uu_lock ,
+.Nm uu_lock_txfr ,
.Nm uu_unlock ,
.Nm uu_lockerr
.Nd acquire and release control of a serial device
diff --git a/lib/msun/src/e_fmod.c b/lib/msun/src/e_fmod.c
index 77afd116c658..ced9cce33aa0 100644
--- a/lib/msun/src/e_fmod.c
+++ b/lib/msun/src/e_fmod.c
@@ -26,14 +26,14 @@ static const double one = 1.0, Zero[] = {0.0, -0.0,};
double
fmod(double x, double y)
{
- int32_t n,hx,hy,hz,ix,iy,sx,i;
- u_int32_t lx,ly,lz;
+ int32_t hx, hy, hz, ix, iy, n, sx;
+ u_int32_t lx, ly, lz;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
sx = hx&0x80000000; /* sign of x */
- hx ^=sx; /* |x| */
- hy &= 0x7fffffff; /* |y| */
+ hx ^= sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
/* purge off exception values */
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
@@ -46,22 +46,16 @@ fmod(double x, double y)
}
/* determine ix = ilogb(x) */
- if(hx<0x00100000) { /* subnormal x */
- if(hx==0) {
- for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
- } else {
- for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
- }
- } else ix = (hx>>20)-1023;
+ if(hx<0x00100000)
+ ix = subnormal_ilogb(hx, lx);
+ else
+ ix = (hx>>20)-1023;
/* determine iy = ilogb(y) */
- if(hy<0x00100000) { /* subnormal y */
- if(hy==0) {
- for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
- } else {
- for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
- }
- } else iy = (hy>>20)-1023;
+ if(hy<0x00100000)
+ iy = subnormal_ilogb(hy, ly);
+ else
+ iy = (hy>>20)-1023;
/* set up {hx,lx}, {hy,ly} and align y to x */
if(ix >= -1022)
diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h
index 1595f902846c..0711f2f33c41 100644
--- a/lib/msun/src/math_private.h
+++ b/lib/msun/src/math_private.h
@@ -739,6 +739,27 @@ irintl(long double x)
(ar) = (x) - (ai); \
} while (0)
+/*
+ * For a double entity split into high and low parts, compute ilogb.
+ */
+static inline int32_t
+subnormal_ilogb(int32_t hi, int32_t lo)
+{
+ int32_t j;
+ uint32_t i;
+
+ j = -1022;
+ if (hi == 0) {
+ j -= 21;
+ i = (uint32_t)lo;
+ } else
+ i = (uint32_t)hi << 11;
+
+ for (; i < 0x7fffffff; i <<= 1) j -= 1;
+
+ return (j);
+}
+
#ifdef DEBUG
#if defined(__amd64__) || defined(__i386__)
#define breakpoint() asm("int $3")
diff --git a/lib/msun/src/s_ilogb.c b/lib/msun/src/s_ilogb.c
index 27e0bbb8735b..aa707d51d7b7 100644
--- a/lib/msun/src/s_ilogb.c
+++ b/lib/msun/src/s_ilogb.c
@@ -21,21 +21,18 @@
#include "math.h"
#include "math_private.h"
- int ilogb(double x)
+int
+ilogb(double x)
{
- int32_t hx,lx,ix;
+ int32_t hx, ix, lx;
EXTRACT_WORDS(hx,lx,x);
hx &= 0x7fffffff;
if(hx<0x00100000) {
if((hx|lx)==0)
return FP_ILOGB0;
- else /* subnormal x */
- if(hx==0) {
- for (ix = -1043; lx>0; lx<<=1) ix -=1;
- } else {
- for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
- }
+ else
+ ix = subnormal_ilogb(hx, lx);
return ix;
}
else if (hx<0x7ff00000) return (hx>>20)-1023;
diff --git a/lib/msun/src/s_remquo.c b/lib/msun/src/s_remquo.c
index 206d2903cd86..b26b5619f3ad 100644
--- a/lib/msun/src/s_remquo.c
+++ b/lib/msun/src/s_remquo.c
@@ -4,7 +4,7 @@
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
@@ -27,7 +27,7 @@ static const double Zero[] = {0.0, -0.0,};
double
remquo(double x, double y, int *quo)
{
- int32_t n,hx,hy,hz,ix,iy,sx,i;
+ int32_t hx,hy,hz,ix,iy,n,sx;
u_int32_t lx,ly,lz,q,sxy;
EXTRACT_WORDS(hx,lx,x);
@@ -53,25 +53,19 @@ remquo(double x, double y, int *quo)
}
/* determine ix = ilogb(x) */
- if(hx<0x00100000) { /* subnormal x */
- if(hx==0) {
- for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
- } else {
- for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
- }
- } else ix = (hx>>20)-1023;
+ if(hx<0x00100000)
+ ix = subnormal_ilogb(hx, lx);
+ else
+ ix = (hx>>20)-1023;
/* determine iy = ilogb(y) */
- if(hy<0x00100000) { /* subnormal y */
- if(hy==0) {
- for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
- } else {
- for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
- }
- } else iy = (hy>>20)-1023;
+ if(hy<0x00100000)
+ iy = subnormal_ilogb(hy, ly);
+ else
+ iy = (hy>>20)-1023;
/* set up {hx,lx}, {hy,ly} and align y to x */
- if(ix >= -1022)
+ if(ix >= -1022)
hx = 0x00100000|(0x000fffff&hx);
else { /* subnormal x, shift x to normal */
n = -1022-ix;
@@ -83,7 +77,7 @@ remquo(double x, double y, int *quo)
lx = 0;
}
}
- if(iy >= -1022)
+ if(iy >= -1022)
hy = 0x00100000|(0x000fffff&hy);
else { /* subnormal y, shift y to normal */
n = -1022-iy;
diff --git a/share/man/man4/epair.4 b/share/man/man4/epair.4
index 4bcb54c936cb..342b15b5612a 100644
--- a/share/man/man4/epair.4
+++ b/share/man/man4/epair.4
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 18, 2015
+.Dd August 12, 2025
.Dt EPAIR 4
.Os
.Sh NAME
@@ -79,12 +79,24 @@ and
Like any other Ethernet interface, an
.Nm
needs to have a network address.
-Each
+If the tunable
+.Va net.link.epair.ether_gen_addr Ns
+=0, each
.Nm
-will be assigned a locally administered address by default,
+will be assigned a random locally administered address,
that is only guaranteed to be unique within one network stack.
-To change the default addresses one may use the SIOCSIFADDR ioctl(2) or
-ifconfig(8) utility.
+The tunable
+.Va net.link.epair.ether_gen_addr Ns
+=1 will generate a stable MAC address with
+.Fx
+OUI using
+.Xr ether_gen_addr 9 .
+This tunable defaults to 1 in
+.Fx 15.0 and might be removed in
+.Fx 16.0 .
+To change the default addresses one may use the SIOCSIFADDR
+.Xr ioctl 2 or
+.Xr ifconfig 8 utility.
.Pp
The basic intent is to provide connectivity between two virtual
network stack instances.
diff --git a/share/man/man4/sa.4 b/share/man/man4/sa.4
index 699a940a34d1..6c948a0f21ab 100644
--- a/share/man/man4/sa.4
+++ b/share/man/man4/sa.4
@@ -82,21 +82,19 @@ the case where a control mode device is opened.
In the latter case, exclusive
access is only sought when needed (e.g., to set parameters).
.Sh SUB-MODES
-Bits 0 and 1 of the minor number are interpreted as
-.Sq sub-modes .
The sub-modes differ in the action taken when the device is closed:
.Bl -tag -width XXXX
-.It 00
+.It Pa /dev/sa*
A close will rewind the device; if the tape has been
written, then a file mark will be written before the rewind is requested.
The device is unmounted.
-.It 01
+.It Pa /dev/nsa*
A close will leave the tape mounted.
If the tape was written to, a file mark will be written.
No other head positioning takes place.
Any further reads or writes will occur directly after the
last read, or the written file mark.
-.It 10
+.It Pa /dev/esa*
A close will rewind the device.
If the tape has been
written, then a file mark will be written before the rewind is requested.
diff --git a/share/mk/bsd.man.mk b/share/mk/bsd.man.mk
index f44048b4e453..66155d1b4cd9 100644
--- a/share/mk/bsd.man.mk
+++ b/share/mk/bsd.man.mk
@@ -288,11 +288,11 @@ manlinksinstall-${__group}:
.endif
.endfor
-manlint:
+manlint: .PHONY checkmanlinks
.if defined(${__group}) && !empty(${__group})
.for __page in ${${__group}}
manlint: ${__page:S/:/\:/g}lint
-${__page:S/:/\:/g}lint: ${__page}
+${__page:S/:/\:/g}lint: .PHONY ${__page}
.if defined(MANFILTER)
${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} -Tlint
.else
@@ -301,4 +301,18 @@ ${__page:S/:/\:/g}lint: ${__page}
.endfor
.endif
+checkmanlinks: .PHONY
+.if defined(${__group}LINKS)
+checkmanlinks: checkmanlinks-${__group}
+checkmanlinks-${__group}: .PHONY
+.for __page __link in ${${__group}LINKS}
+checkmanlinks-${__group}: checkmanlinks-${__group}-${__link}
+checkmanlinks-${__group}-${__link}: .PHONY ${__page}
+ @if ! egrep -q "^(\.\\\\\" )?\.Nm ${__link:R}( ,)?$$" ${.ALLSRC}; then \
+ echo "${__group}LINKS: '.Nm ${__link:R}' not found in ${__page}"; \
+ exit 1; \
+ fi >&2
+.endfor # __page __link in ${${__group}LINKS}
+.endif # defined(${__group}LINKS)
+
.endfor # __group in ${MANGROUPS}
diff --git a/sys/arm/allwinner/aw_gpio.c b/sys/arm/allwinner/aw_gpio.c
index 2061e38a155f..f1b6f0bc9193 100644
--- a/sys/arm/allwinner/aw_gpio.c
+++ b/sys/arm/allwinner/aw_gpio.c
@@ -1162,11 +1162,12 @@ aw_gpio_attach(device_t dev)
fdt_pinctrl_register(dev, "allwinner,pins");
fdt_pinctrl_configure_tree(dev);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL)
goto fail;
config_intrhook_oneshot(aw_gpio_enable_bank_supply, sc);
+ bus_attach_children(dev);
return (0);
diff --git a/sys/arm/allwinner/axp209.c b/sys/arm/allwinner/axp209.c
index 239ead02d0e0..ff999a0f9b9b 100644
--- a/sys/arm/allwinner/axp209.c
+++ b/sys/arm/allwinner/axp209.c
@@ -1322,7 +1322,7 @@ axp2xx_attach(device_t dev)
case AXP209:
sc->pins = axp209_pins;
sc->npins = nitems(axp209_pins);
- sc->gpiodev = gpiobus_attach_bus(dev);
+ sc->gpiodev = gpiobus_add_bus(dev);
sc->sensors = axp209_sensors;
sc->nsensors = nitems(axp209_sensors);
@@ -1333,7 +1333,7 @@ axp2xx_attach(device_t dev)
case AXP221:
sc->pins = axp221_pins;
sc->npins = nitems(axp221_pins);
- sc->gpiodev = gpiobus_attach_bus(dev);
+ sc->gpiodev = gpiobus_add_bus(dev);
sc->sensors = axp221_sensors;
sc->nsensors = nitems(axp221_sensors);
@@ -1374,6 +1374,7 @@ axp2xx_attach(device_t dev)
}
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/allwinner/axp81x.c b/sys/arm/allwinner/axp81x.c
index fc1a168595e5..71f0c8156a0d 100644
--- a/sys/arm/allwinner/axp81x.c
+++ b/sys/arm/allwinner/axp81x.c
@@ -1609,7 +1609,8 @@ axp8xx_attach(device_t dev)
EVENTHANDLER_REGISTER(shutdown_final, axp8xx_shutdown, dev,
SHUTDOWN_PRI_LAST);
- sc->gpiodev = gpiobus_attach_bus(dev);
+ sc->gpiodev = gpiobus_add_bus(dev);
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
index 48d1d2af5abc..93ee5d7c8bd3 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
@@ -840,10 +840,11 @@ bcm_gpio_attach(device_t dev)
fdt_pinctrl_register(dev, "brcm,pins");
fdt_pinctrl_configure_tree(dev);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL)
goto fail;
+ bus_attach_children(dev);
return (0);
fail:
diff --git a/sys/arm/broadcom/bcm2835/raspberrypi_gpio.c b/sys/arm/broadcom/bcm2835/raspberrypi_gpio.c
index 5a0f5cf2b1b3..b286654c6f18 100644
--- a/sys/arm/broadcom/bcm2835/raspberrypi_gpio.c
+++ b/sys/arm/broadcom/bcm2835/raspberrypi_gpio.c
@@ -404,10 +404,11 @@ rpi_fw_gpio_attach(device_t dev)
}
}
free(names, M_OFWPROP);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL)
goto fail;
+ bus_attach_children(dev);
return (0);
fail:
diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c
index 7610d28af90e..3b19ef1b5e67 100644
--- a/sys/arm/freescale/imx/imx_gpio.c
+++ b/sys/arm/freescale/imx/imx_gpio.c
@@ -861,13 +861,14 @@ imx51_gpio_attach(device_t dev)
gpio_pic_register_isrcs(sc);
intr_pic_register(dev, OF_xref_from_node(ofw_bus_get_node(dev)));
#endif
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
imx51_gpio_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/freescale/vybrid/vf_gpio.c b/sys/arm/freescale/vybrid/vf_gpio.c
index c81524a8a27e..b4e1ba9af586 100644
--- a/sys/arm/freescale/vybrid/vf_gpio.c
+++ b/sys/arm/freescale/vybrid/vf_gpio.c
@@ -147,13 +147,14 @@ vf_gpio_attach(device_t dev)
"vf_gpio%d.%d", device_get_unit(dev), i);
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
bus_release_resources(dev, vf_gpio_spec, sc->res);
mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/mv/a37x0_gpio.c b/sys/arm/mv/a37x0_gpio.c
index 86110ff87ab1..754663d2991e 100644
--- a/sys/arm/mv/a37x0_gpio.c
+++ b/sys/arm/mv/a37x0_gpio.c
@@ -291,10 +291,11 @@ a37x0_gpio_attach(device_t dev)
if (sc->sc_npins > sc->sc_max_pins)
return (ENXIO);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL)
return (ENXIO);
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/mv/gpio.c b/sys/arm/mv/gpio.c
index 934c00236153..b3c2314fb2d6 100644
--- a/sys/arm/mv/gpio.c
+++ b/sys/arm/mv/gpio.c
@@ -340,7 +340,7 @@ mv_gpio_attach(device_t dev)
if (rv != 0)
return (rv);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
mtx_destroy(&sc->mutex);
bus_release_resource(dev, SYS_RES_IRQ,
@@ -348,6 +348,7 @@ mv_gpio_attach(device_t dev)
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/mv/mvebu_gpio.c b/sys/arm/mv/mvebu_gpio.c
index 7acdfff539dc..4cc9b7030a65 100644
--- a/sys/arm/mv/mvebu_gpio.c
+++ b/sys/arm/mv/mvebu_gpio.c
@@ -804,12 +804,13 @@ mvebu_gpio_attach(device_t dev)
}
}
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
mvebu_gpio_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c
index e37fd69a121e..aa34537352be 100644
--- a/sys/arm/nvidia/tegra_gpio.c
+++ b/sys/arm/nvidia/tegra_gpio.c
@@ -818,12 +818,13 @@ tegra_gpio_attach(device_t dev)
return (ENXIO);
}
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
tegra_gpio_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c
index aceb3d63204e..01b9597a4418 100644
--- a/sys/arm/ti/ti_gpio.c
+++ b/sys/arm/ti/ti_gpio.c
@@ -674,12 +674,13 @@ ti_gpio_attach(device_t dev)
}
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
ti_gpio_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm/xilinx/zy7_gpio.c b/sys/arm/xilinx/zy7_gpio.c
index 71b6fc3c0586..2434e43bf27c 100644
--- a/sys/arm/xilinx/zy7_gpio.c
+++ b/sys/arm/xilinx/zy7_gpio.c
@@ -441,12 +441,13 @@ zy7_gpio_attach(device_t dev)
return (ENOMEM);
}
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
zy7_gpio_detach(dev);
return (ENOMEM);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm64/apple/apple_pinctrl.c b/sys/arm64/apple/apple_pinctrl.c
index ebaaccea1d99..c28b1c62d78c 100644
--- a/sys/arm64/apple/apple_pinctrl.c
+++ b/sys/arm64/apple/apple_pinctrl.c
@@ -171,12 +171,13 @@ apple_pinctrl_attach(device_t dev)
OF_xref_from_node(ofw_bus_get_node(dev)));
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
device_printf(dev, "failed to attach gpiobus\n");
goto error;
}
+ bus_attach_children(dev);
return (0);
error:
mtx_destroy(&sc->sc_mtx);
diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c
index 847bc7394dd0..61614f532634 100644
--- a/sys/arm64/rockchip/rk_gpio.c
+++ b/sys/arm64/rockchip/rk_gpio.c
@@ -371,12 +371,13 @@ rk_gpio_attach(device_t dev)
sc->swporta_ddr = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DDR);
RK_GPIO_UNLOCK(sc);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
rk_gpio_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/arm64/rockchip/rk_grf_gpio.c b/sys/arm64/rockchip/rk_grf_gpio.c
index 6818bd85bb95..6ac419889614 100644
--- a/sys/arm64/rockchip/rk_grf_gpio.c
+++ b/sys/arm64/rockchip/rk_grf_gpio.c
@@ -181,11 +181,12 @@ rk_grf_gpio_attach(device_t dev)
return (ENXIO);
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index bf44d9c322b4..66d5fbd6adbe 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -176,7 +176,7 @@ static int
sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
dmu_tx_t *tx)
{
- ASSERT3P(tx, ==, NULL);
+ ASSERT0P(tx);
struct sublivelist_verify *sv = arg;
sublivelist_verify_block_refcnt_t current = {
.svbr_blk = *bp,
@@ -892,9 +892,9 @@ dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
size_t nvsize = *(uint64_t *)data;
char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
- VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
+ VERIFY0(dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
- VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
+ VERIFY0(nvlist_unpack(packed, nvsize, &nv, 0));
umem_free(packed, nvsize);
@@ -1455,8 +1455,8 @@ get_obsolete_refcount(vdev_t *vd)
refcount++;
}
} else {
- ASSERT3P(vd->vdev_obsolete_sm, ==, NULL);
- ASSERT3U(obsolete_sm_object, ==, 0);
+ ASSERT0P(vd->vdev_obsolete_sm);
+ ASSERT0(obsolete_sm_object);
}
for (unsigned c = 0; c < vd->vdev_children; c++) {
refcount += get_obsolete_refcount(vd->vdev_child[c]);
@@ -1792,7 +1792,7 @@ print_vdev_indirect(vdev_t *vd)
vdev_indirect_births_t *vib = vd->vdev_indirect_births;
if (vim == NULL) {
- ASSERT3P(vib, ==, NULL);
+ ASSERT0P(vib);
return;
}
@@ -2043,10 +2043,10 @@ dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
if (error == ENOENT)
return;
- ASSERT(error == 0);
+ ASSERT0(error);
error = ddt_object_count(ddt, type, class, &count);
- ASSERT(error == 0);
+ ASSERT0(error);
if (count == 0)
return;
@@ -3109,7 +3109,7 @@ dsl_deadlist_entry_count_refd(void *arg, dsl_deadlist_entry_t *dle)
static int
dsl_deadlist_entry_dump(void *arg, dsl_deadlist_entry_t *dle)
{
- ASSERT(arg == NULL);
+ ASSERT0P(arg);
if (dump_opt['d'] >= 5) {
char buf[128];
(void) snprintf(buf, sizeof (buf),
@@ -3347,7 +3347,7 @@ open_objset(const char *path, const void *tag, objset_t **osp)
uint64_t sa_attrs = 0;
uint64_t version = 0;
- VERIFY3P(sa_os, ==, NULL);
+ VERIFY0P(sa_os);
/*
* We can't own an objset if it's redacted. Therefore, we do this
@@ -3520,8 +3520,8 @@ dump_uidgid(objset_t *os, uint64_t uid, uint64_t gid)
uint64_t fuid_obj;
/* first find the fuid object. It lives in the master node */
- VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES,
- 8, 1, &fuid_obj) == 0);
+ VERIFY0(zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES,
+ 8, 1, &fuid_obj));
zfs_fuid_avl_tree_create(&idx_tree, &domain_tree);
(void) zfs_fuid_table_load(os, fuid_obj,
&idx_tree, &domain_tree);
@@ -7016,7 +7016,7 @@ deleted_livelists_count_blocks(spa_t *spa, zdb_cb_t *zbc)
static void
dump_livelist_cb(dsl_deadlist_t *ll, void *arg)
{
- ASSERT3P(arg, ==, NULL);
+ ASSERT0P(arg);
global_feature_count[SPA_FEATURE_LIVELIST]++;
dump_blkptr_list(ll, "Deleted Livelist");
dsl_deadlist_iterate(ll, sublivelist_verify_lightweight, NULL);
@@ -7913,7 +7913,7 @@ verify_checkpoint_vdev_spacemaps(spa_t *checkpoint, spa_t *current)
for (uint64_t c = ckpoint_rvd->vdev_children;
c < current_rvd->vdev_children; c++) {
vdev_t *current_vd = current_rvd->vdev_child[c];
- VERIFY3P(current_vd->vdev_checkpoint_sm, ==, NULL);
+ VERIFY0P(current_vd->vdev_checkpoint_sm);
}
}
@@ -9743,7 +9743,7 @@ main(int argc, char **argv)
if (error == 0) {
if (dump_opt['k'] && (target_is_spa || dump_opt['R'])) {
ASSERT(checkpoint_pool != NULL);
- ASSERT(checkpoint_target == NULL);
+ ASSERT0P(checkpoint_target);
error = spa_open(checkpoint_pool, &spa, FTAG);
if (error != 0) {
diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh b/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh
index 6e00f153be1c..78d8f658ddd8 100644
--- a/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh
+++ b/sys/contrib/openzfs/cmd/zed/zed.d/zed-functions.sh
@@ -441,8 +441,9 @@ zed_notify_slack_webhook()
"${pathname}")"
# Construct the JSON message for posting.
+ # shellcheck disable=SC2016
#
- msg_json="$(printf '{"text": "*%s*\\n%s"}' "${subject}" "${msg_body}" )"
+ msg_json="$(printf '{"text": "*%s*\\n```%s```"}' "${subject}" "${msg_body}" )"
# Send the POST request and check for errors.
#
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
index 363bb6da74ec..235f011af953 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
@@ -923,7 +923,7 @@ zfs_do_clone(int argc, char **argv)
return (!!ret);
usage:
- ASSERT3P(zhp, ==, NULL);
+ ASSERT0P(zhp);
nvlist_free(props);
usage(B_FALSE);
return (-1);
diff --git a/sys/contrib/openzfs/cmd/zhack.c b/sys/contrib/openzfs/cmd/zhack.c
index 8244bc83fa0d..2bd3051dce7b 100644
--- a/sys/contrib/openzfs/cmd/zhack.c
+++ b/sys/contrib/openzfs/cmd/zhack.c
@@ -162,9 +162,9 @@ zhack_import(char *target, boolean_t readonly)
props = NULL;
if (readonly) {
- VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
- VERIFY(nvlist_add_uint64(props,
- zpool_prop_to_name(ZPOOL_PROP_READONLY), 1) == 0);
+ VERIFY0(nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
+ VERIFY0(nvlist_add_uint64(props,
+ zpool_prop_to_name(ZPOOL_PROP_READONLY), 1));
}
zfeature_checks_disable = B_TRUE;
@@ -218,8 +218,8 @@ dump_obj(objset_t *os, uint64_t obj, const char *name)
} else {
ASSERT(za->za_integer_length == 1);
char val[1024];
- VERIFY(zap_lookup(os, obj, za->za_name,
- 1, sizeof (val), val) == 0);
+ VERIFY0(zap_lookup(os, obj, za->za_name,
+ 1, sizeof (val), val));
(void) printf("\t%s = %s\n", za->za_name, val);
}
}
diff --git a/sys/contrib/openzfs/cmd/zilstat.in b/sys/contrib/openzfs/cmd/zilstat.in
index 4140398bf4a3..d01db9b0914b 100755
--- a/sys/contrib/openzfs/cmd/zilstat.in
+++ b/sys/contrib/openzfs/cmd/zilstat.in
@@ -47,6 +47,7 @@ cols = {
"cec": [5, 1000, "zil_commit_error_count"],
"csc": [5, 1000, "zil_commit_stall_count"],
"cSc": [5, 1000, "zil_commit_suspend_count"],
+ "cCc": [5, 1000, "zil_commit_crash_count"],
"ic": [5, 1000, "zil_itx_count"],
"iic": [5, 1000, "zil_itx_indirect_count"],
"iib": [5, 1024, "zil_itx_indirect_bytes"],
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index d401e087916b..237e558da65b 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -752,10 +752,11 @@ usage(boolean_t requested)
}
/*
- * zpool initialize [-c | -s | -u] [-w] <pool> [<vdev> ...]
+ * zpool initialize [-c | -s | -u] [-w] <-a | pool> [<vdev> ...]
* Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
* if none specified.
*
+ * -a Use all pools.
* -c Cancel. Ends active initializing.
* -s Suspend. Initializing can then be restarted with no flags.
* -u Uninitialize. Clears initialization state.
@@ -776,7 +777,7 @@ zpool_do_initialize(int argc, char **argv)
{"suspend", no_argument, NULL, 's'},
{"uninit", no_argument, NULL, 'u'},
{"wait", no_argument, NULL, 'w'},
- {"all", no_argument, NULL, 'a'},
+ {"all", no_argument, NULL, 'a'},
{0, 0, 0, 0}
};
@@ -8446,8 +8447,9 @@ date_string_to_sec(const char *timestr, boolean_t rounding)
}
/*
- * zpool scrub [-e | -s | -p | -C | -E | -S] [-w] <pool> ...
+ * zpool scrub [-e | -s | -p | -C | -E | -S] [-w] [-a | <pool> ...]
*
+ * -a Scrub all pools.
* -e Only scrub blocks in the error log.
* -E End date of scrub.
* -S Start date of scrub.
@@ -8621,8 +8623,9 @@ zpool_do_resilver(int argc, char **argv)
}
/*
- * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...]
+ * zpool trim [-d] [-r <rate>] [-c | -s] <-a | pool> [<device> ...]
*
+ * -a Trim all pools.
* -c Cancel. Ends any in-progress trim.
* -d Secure trim. Requires kernel and device support.
* -r <rate> Sets the TRIM rate in bytes (per second). Supports
@@ -12374,7 +12377,7 @@ zpool_do_events_next(ev_opts_t *opts)
nvlist_free(nvl);
}
- VERIFY(0 == close(zevent_fd));
+ VERIFY0(close(zevent_fd));
return (ret);
}
diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c
index 2e88ae3e7994..89752dcb0f0f 100644
--- a/sys/contrib/openzfs/cmd/ztest.c
+++ b/sys/contrib/openzfs/cmd/ztest.c
@@ -273,7 +273,6 @@ extern int zfs_compressed_arc_enabled;
extern int zfs_abd_scatter_enabled;
extern uint_t dmu_object_alloc_chunk_shift;
extern boolean_t zfs_force_some_double_word_sm_entries;
-extern unsigned long zio_decompress_fail_fraction;
extern unsigned long zfs_reconstruct_indirect_damage_fraction;
extern uint64_t raidz_expand_max_reflow_bytes;
extern uint_t raidz_expand_pause_point;
@@ -829,8 +828,8 @@ static char *short_opts = NULL;
static void
init_options(void)
{
- ASSERT3P(long_opts, ==, NULL);
- ASSERT3P(short_opts, ==, NULL);
+ ASSERT0P(long_opts);
+ ASSERT0P(short_opts);
int count = sizeof (option_table) / sizeof (option_table[0]);
long_opts = umem_alloc(sizeof (struct option) * count, UMEM_NOFAIL);
@@ -1686,7 +1685,7 @@ ztest_rll_init(rll_t *rll)
static void
ztest_rll_destroy(rll_t *rll)
{
- ASSERT3P(rll->rll_writer, ==, NULL);
+ ASSERT0P(rll->rll_writer);
ASSERT0(rll->rll_readers);
mutex_destroy(&rll->rll_lock);
cv_destroy(&rll->rll_cv);
@@ -1720,7 +1719,7 @@ ztest_rll_unlock(rll_t *rll)
rll->rll_writer = NULL;
} else {
ASSERT3S(rll->rll_readers, >, 0);
- ASSERT3P(rll->rll_writer, ==, NULL);
+ ASSERT0P(rll->rll_writer);
rll->rll_readers--;
}
@@ -1996,7 +1995,7 @@ ztest_log_write(ztest_ds_t *zd, dmu_tx_t *tx, lr_write_t *lr)
dmu_read(zd->zd_os, lr->lr_foid, lr->lr_offset, lr->lr_length,
((lr_write_t *)&itx->itx_lr) + 1, DMU_READ_NO_PREFETCH |
DMU_KEEP_CACHING) != 0) {
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
itx = zil_itx_create(TX_WRITE, sizeof (*lr));
write_state = WR_NEED_COPY;
}
@@ -2278,8 +2277,8 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
ztest_block_tag_t rbt;
- VERIFY(dmu_read(os, lr->lr_foid, offset,
- sizeof (rbt), &rbt, flags) == 0);
+ VERIFY0(dmu_read(os, lr->lr_foid, offset,
+ sizeof (rbt), &rbt, flags));
if (rbt.bt_magic == BT_MAGIC) {
ztest_bt_verify(&rbt, os, lr->lr_foid, 0,
offset, gen, txg, crtxg);
@@ -2966,7 +2965,7 @@ ztest_zil_commit(ztest_ds_t *zd, uint64_t id)
(void) pthread_rwlock_rdlock(&zd->zd_zilog_lock);
- zil_commit(zilog, ztest_random(ZTEST_OBJECTS));
+ VERIFY0(zil_commit(zilog, ztest_random(ZTEST_OBJECTS)));
/*
* Remember the committed values in zd, which is in parent/child
@@ -4007,7 +4006,7 @@ raidz_scratch_verify(void)
* requested by user, but scratch object was not created.
*/
case RRSS_SCRATCH_NOT_IN_USE:
- ASSERT3U(offset, ==, 0);
+ ASSERT0(offset);
break;
/*
@@ -5537,8 +5536,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
}
if (i == 1) {
- VERIFY(dmu_buf_hold(os, bigobj, off,
- FTAG, &dbt, DMU_READ_NO_PREFETCH) == 0);
+ VERIFY0(dmu_buf_hold(os, bigobj, off,
+ FTAG, &dbt, DMU_READ_NO_PREFETCH));
}
if (i != 5 || chunksize < (SPA_MINBLOCKSIZE * 2)) {
VERIFY0(dmu_assign_arcbuf_by_dbuf(bonus_db,
@@ -7937,7 +7936,7 @@ ztest_freeze(void)
*/
while (BP_IS_HOLE(&zd->zd_zilog->zl_header->zh_log)) {
ztest_dmu_object_alloc_free(zd, 0);
- zil_commit(zd->zd_zilog, 0);
+ VERIFY0(zil_commit(zd->zd_zilog, 0));
}
txg_wait_synced(spa_get_dsl(spa), 0);
@@ -7979,7 +7978,7 @@ ztest_freeze(void)
/*
* Commit all of the changes we just generated.
*/
- zil_commit(zd->zd_zilog, 0);
+ VERIFY0(zil_commit(zd->zd_zilog, 0));
txg_wait_synced(spa_get_dsl(spa), 0);
/*
@@ -8979,7 +8978,7 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
} else {
/* children should not be spawned if setting gvars fails */
- VERIFY3S(err, ==, 0);
+ VERIFY0(err);
}
/* Override location of zpool.cache */
diff --git a/sys/contrib/openzfs/config/toolchain-simd.m4 b/sys/contrib/openzfs/config/toolchain-simd.m4
index 061576fd94e3..344807fc830c 100644
--- a/sys/contrib/openzfs/config/toolchain-simd.m4
+++ b/sys/contrib/openzfs/config/toolchain-simd.m4
@@ -38,9 +38,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE], [
AC_MSG_CHECKING([whether host toolchain supports SSE])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
__asm__ __volatile__("xorps %xmm0, %xmm1");
+ return (0);
}
]])], [
AC_DEFINE([HAVE_SSE], 1, [Define if host toolchain supports SSE])
@@ -57,9 +58,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2], [
AC_MSG_CHECKING([whether host toolchain supports SSE2])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
__asm__ __volatile__("pxor %xmm0, %xmm1");
+ return (0);
}
]])], [
AC_DEFINE([HAVE_SSE2], 1, [Define if host toolchain supports SSE2])
@@ -76,10 +78,11 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3], [
AC_MSG_CHECKING([whether host toolchain supports SSE3])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
char v[16];
__asm__ __volatile__("lddqu %0,%%xmm0" :: "m"(v[0]));
+ return (0);
}
]])], [
AC_DEFINE([HAVE_SSE3], 1, [Define if host toolchain supports SSE3])
@@ -96,9 +99,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3], [
AC_MSG_CHECKING([whether host toolchain supports SSSE3])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
__asm__ __volatile__("pshufb %xmm0,%xmm1");
+ return (0);
}
]])], [
AC_DEFINE([HAVE_SSSE3], 1, [Define if host toolchain supports SSSE3])
@@ -115,9 +119,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1], [
AC_MSG_CHECKING([whether host toolchain supports SSE4.1])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
__asm__ __volatile__("pmaxsb %xmm0,%xmm1");
+ return (0);
}
]])], [
AC_DEFINE([HAVE_SSE4_1], 1, [Define if host toolchain supports SSE4.1])
@@ -134,9 +139,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2], [
AC_MSG_CHECKING([whether host toolchain supports SSE4.2])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
__asm__ __volatile__("pcmpgtq %xmm0, %xmm1");
+ return (0);
}
]])], [
AC_DEFINE([HAVE_SSE4_2], 1, [Define if host toolchain supports SSE4.2])
@@ -153,10 +159,11 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX], [
AC_MSG_CHECKING([whether host toolchain supports AVX])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
- void main()
+ int main()
{
char v[32];
__asm__ __volatile__("vmovdqa %0,%%ymm0" :: "m"(v[0]));
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -174,9 +181,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vpshufb %ymm0,%ymm1,%ymm2");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -194,9 +202,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vpandd %zmm0,%zmm1,%zmm2");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -214,9 +223,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vplzcntd %zmm0,%zmm1");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -234,9 +244,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vandpd %zmm0,%zmm1,%zmm2");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -254,9 +265,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vpshufb %zmm0,%zmm1,%zmm2");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -274,9 +286,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vpmadd52luq %zmm0,%zmm1,%zmm2");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -294,9 +307,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vpermb %zmm0,%zmm1,%zmm2");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -314,9 +328,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vgatherpf0dps (%rsi,%zmm0,4){%k1}");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -334,9 +349,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vexp2pd %zmm0,%zmm1");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -354,9 +370,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("vpabsq %zmm0,%zmm1");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -374,9 +391,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("aesenc %xmm0, %xmm1");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -394,9 +412,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("pclmulqdq %0, %%xmm0, %%xmm1" :: "i"(0));
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -414,9 +433,10 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
__asm__ __volatile__("movbe 0(%eax), %eax");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -434,10 +454,11 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVE], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
char b[4096] __attribute__ ((aligned (64)));
__asm__ __volatile__("xsave %[b]\n" : : [b] "m" (*b) : "memory");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -455,10 +476,11 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVEOPT], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
char b[4096] __attribute__ ((aligned (64)));
__asm__ __volatile__("xsaveopt %[b]\n" : : [b] "m" (*b) : "memory");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
@@ -476,10 +498,11 @@ AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_XSAVES], [
AC_LINK_IFELSE([AC_LANG_SOURCE([
[
- void main()
+ int main()
{
char b[4096] __attribute__ ((aligned (64)));
__asm__ __volatile__("xsaves %[b]\n" : : [b] "m" (*b) : "memory");
+ return (0);
}
]])], [
AC_MSG_RESULT([yes])
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h
index 974704e92bbd..32bc02f3dc86 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h
@@ -69,6 +69,10 @@
#define __maybe_unused __attribute__((unused))
#endif
+#ifndef __must_check
+#define __must_check __attribute__((__warn_unused_result__))
+#endif
+
/*
* Without this, we see warnings from objtool during normal Linux builds when
* the kernel is built with CONFIG_STACK_VALIDATION=y:
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/proc.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/proc.h
index c6bc10d6babe..1cbd79ec893f 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/proc.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/proc.h
@@ -77,8 +77,8 @@ do_thread_create(caddr_t stk, size_t stksize, void (*proc)(void *), void *arg,
/*
* Be sure there are no surprises.
*/
- ASSERT(stk == NULL);
- ASSERT(len == 0);
+ ASSERT0P(stk);
+ ASSERT0(len);
ASSERT(state == TS_RUN);
if (pp == &p0)
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_x86.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_x86.h
index cd245a5f0135..e8004e18c4a4 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_x86.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_x86.h
@@ -139,15 +139,6 @@
*/
#if defined(HAVE_KERNEL_FPU_INTERNAL)
-/*
- * For kernels not exporting *kfpu_{begin,end} we have to use inline assembly
- * with the XSAVE{,OPT,S} instructions, so we need the toolchain to support at
- * least XSAVE.
- */
-#if !defined(HAVE_XSAVE)
-#error "Toolchain needs to support the XSAVE assembler instruction"
-#endif
-
#ifndef XFEATURE_MASK_XTILE
/*
* For kernels where this doesn't exist yet, we still don't want to break
@@ -335,9 +326,13 @@ kfpu_begin(void)
return;
}
#endif
+#if defined(HAVE_XSAVE)
if (static_cpu_has(X86_FEATURE_XSAVE)) {
kfpu_do_xsave("xsave", state, ~XFEATURE_MASK_XTILE);
- } else if (static_cpu_has(X86_FEATURE_FXSR)) {
+ return;
+ }
+#endif
+ if (static_cpu_has(X86_FEATURE_FXSR)) {
kfpu_save_fxsr(state);
} else {
kfpu_save_fsave(state);
@@ -390,9 +385,13 @@ kfpu_end(void)
goto out;
}
#endif
+#if defined(HAVE_XSAVE)
if (static_cpu_has(X86_FEATURE_XSAVE)) {
kfpu_do_xrstor("xrstor", state, ~XFEATURE_MASK_XTILE);
- } else if (static_cpu_has(X86_FEATURE_FXSR)) {
+ goto out;
+ }
+#endif
+ if (static_cpu_has(X86_FEATURE_FXSR)) {
kfpu_restore_fxsr(state);
} else {
kfpu_restore_fsave(state);
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/debug.h b/sys/contrib/openzfs/include/os/linux/spl/sys/debug.h
index 1671ba4074da..85b96e1e23a7 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/debug.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/debug.h
@@ -69,6 +69,10 @@
#define __maybe_unused __attribute__((unused))
#endif
+#ifndef __must_check
+#define __must_check __attribute__((__warn_unused_result__))
+#endif
+
/*
* Without this, we see warnings from objtool during normal Linux builds when
* the kernel is built with CONFIG_STACK_VALIDATION=y:
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/mutex.h b/sys/contrib/openzfs/include/os/linux/spl/sys/mutex.h
index f000f53ab9b6..4eca2414fc5b 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/mutex.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/mutex.h
@@ -111,7 +111,7 @@ spl_mutex_lockdep_on_maybe(kmutex_t *mp) \
#undef mutex_destroy
#define mutex_destroy(mp) \
{ \
- VERIFY3P(mutex_owner(mp), ==, NULL); \
+ VERIFY0P(mutex_owner(mp)); \
}
#define mutex_tryenter(mp) \
diff --git a/sys/contrib/openzfs/include/sys/dmu.h b/sys/contrib/openzfs/include/sys/dmu.h
index 7c2024a16d8f..b18961be1282 100644
--- a/sys/contrib/openzfs/include/sys/dmu.h
+++ b/sys/contrib/openzfs/include/sys/dmu.h
@@ -742,8 +742,8 @@ dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_sync,
dmu_buf_evict_func_t *evict_func_async,
dmu_buf_t **clear_on_evict_dbufp __maybe_unused)
{
- ASSERT(dbu->dbu_evict_func_sync == NULL);
- ASSERT(dbu->dbu_evict_func_async == NULL);
+ ASSERT0P(dbu->dbu_evict_func_sync);
+ ASSERT0P(dbu->dbu_evict_func_async);
/* must have at least one evict func */
IMPLY(evict_func_sync == NULL, evict_func_async != NULL);
diff --git a/sys/contrib/openzfs/include/sys/zfs_znode.h b/sys/contrib/openzfs/include/sys/zfs_znode.h
index ba577b80c98f..79b845a672a8 100644
--- a/sys/contrib/openzfs/include/sys/zfs_znode.h
+++ b/sys/contrib/openzfs/include/sys/zfs_znode.h
@@ -73,7 +73,7 @@ extern "C" {
pflags |= attr; \
else \
pflags &= ~attr; \
- VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(ZTOZSB(zp)), \
+ VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(ZTOZSB(zp)), \
&pflags, sizeof (pflags), tx)); \
}
diff --git a/sys/contrib/openzfs/include/sys/zil.h b/sys/contrib/openzfs/include/sys/zil.h
index 9d1fb47e2dfc..da085998879b 100644
--- a/sys/contrib/openzfs/include/sys/zil.h
+++ b/sys/contrib/openzfs/include/sys/zil.h
@@ -456,7 +456,7 @@ typedef enum {
WR_NUM_STATES /* number of states */
} itx_wr_state_t;
-typedef void (*zil_callback_t)(void *data);
+typedef void (*zil_callback_t)(void *data, int err);
typedef struct itx {
list_node_t itx_node; /* linkage on zl_itx_list */
@@ -498,10 +498,13 @@ typedef struct zil_stats {
* (see zil_commit_writer_stall())
* - suspend: ZIL suspended
* (see zil_commit(), zil_get_commit_list())
+ * - crash: ZIL crashed
+ * (see zil_crash(), zil_commit(), ...)
*/
kstat_named_t zil_commit_error_count;
kstat_named_t zil_commit_stall_count;
kstat_named_t zil_commit_suspend_count;
+ kstat_named_t zil_commit_crash_count;
/*
* Number of transactions (reads, writes, renames, etc.)
@@ -549,6 +552,7 @@ typedef struct zil_sums {
wmsum_t zil_commit_error_count;
wmsum_t zil_commit_stall_count;
wmsum_t zil_commit_suspend_count;
+ wmsum_t zil_commit_crash_count;
wmsum_t zil_itx_count;
wmsum_t zil_itx_indirect_count;
wmsum_t zil_itx_indirect_bytes;
@@ -577,6 +581,25 @@ typedef struct zil_sums {
#define ZIL_STAT_BUMP(zil, stat) \
ZIL_STAT_INCR(zil, stat, 1);
+/*
+ * Flags for zil_commit_flags(). zil_commit() is a shortcut for
+ * zil_commit_flags(ZIL_COMMIT_FAILMODE), which is the most common use.
+ */
+typedef enum {
+ /*
+ * Try to commit the ZIL. If it fails, fall back to txg_wait_synced().
+ * If that fails, return EIO.
+ */
+ ZIL_COMMIT_NOW = 0,
+
+ /*
+ * Like ZIL_COMMIT_NOW, but if the ZIL commit fails because the pool
+ * suspended, act according to the pool's failmode= setting (wait for
+ * the pool to resume, or return EIO).
+ */
+ ZIL_COMMIT_FAILMODE = (1 << 1),
+} zil_commit_flag_t;
+
typedef int zil_parse_blk_func_t(zilog_t *zilog, const blkptr_t *bp, void *arg,
uint64_t txg);
typedef int zil_parse_lr_func_t(zilog_t *zilog, const lr_t *lr, void *arg,
@@ -606,14 +629,16 @@ extern boolean_t zil_destroy(zilog_t *zilog, boolean_t keep_first);
extern void zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx);
extern itx_t *zil_itx_create(uint64_t txtype, size_t lrsize);
-extern void zil_itx_destroy(itx_t *itx);
+extern void zil_itx_destroy(itx_t *itx, int err);
extern void zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
extern void zil_async_to_sync(zilog_t *zilog, uint64_t oid);
-extern void zil_commit(zilog_t *zilog, uint64_t oid);
-extern void zil_commit_impl(zilog_t *zilog, uint64_t oid);
extern void zil_remove_async(zilog_t *zilog, uint64_t oid);
+extern int zil_commit_flags(zilog_t *zilog, uint64_t oid,
+ zil_commit_flag_t flags);
+extern int __must_check zil_commit(zilog_t *zilog, uint64_t oid);
+
extern int zil_reset(const char *osname, void *txarg);
extern int zil_claim(struct dsl_pool *dp,
struct dsl_dataset *ds, void *txarg);
diff --git a/sys/contrib/openzfs/include/sys/zil_impl.h b/sys/contrib/openzfs/include/sys/zil_impl.h
index 252264b9eae9..44b776e16b52 100644
--- a/sys/contrib/openzfs/include/sys/zil_impl.h
+++ b/sys/contrib/openzfs/include/sys/zil_impl.h
@@ -221,6 +221,7 @@ struct zilog {
uint64_t zl_cur_left; /* current burst remaining size */
uint64_t zl_cur_max; /* biggest record in current burst */
list_t zl_lwb_list; /* in-flight log write list */
+ list_t zl_lwb_crash_list; /* log writes in-flight at crash */
avl_tree_t zl_bp_tree; /* track bps during log parse */
clock_t zl_replay_time; /* lbolt of when replay started */
uint64_t zl_replay_blks; /* number of log blocks replayed */
@@ -245,6 +246,9 @@ struct zilog {
*/
uint64_t zl_max_block_size;
+ /* After crash, txg to restart zil */
+ uint64_t zl_restart_txg;
+
/* Pointer for per dataset zil sums */
zil_sums_t *zl_sums;
};
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
index cced309bd1bb..02f33a68b75b 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h
@@ -38,4 +38,8 @@
#define __maybe_unused __attribute__((unused))
#endif
+#ifndef __must_check
+#define __must_check __attribute__((warn_unused_result))
+#endif
+
#endif
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
index 6aa0375f98d7..5f50bce531f7 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
@@ -81,7 +81,7 @@ get_stats_for_obj(differ_info_t *di, const char *dsname, uint64_t obj,
/* we can get stats even if we failed to get a path */
(void) memcpy(sb, &zc.zc_stat, sizeof (zfs_stat_t));
if (error == 0) {
- ASSERT(di->zerr == 0);
+ ASSERT0(di->zerr);
(void) strlcpy(pn, zc.zc_value, maxlen);
return (0);
}
@@ -404,7 +404,7 @@ write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
(void) strlcpy(zc.zc_name, di->fromsnap, sizeof (zc.zc_name));
zc.zc_obj = dr->ddr_first - 1;
- ASSERT(di->zerr == 0);
+ ASSERT0(di->zerr);
while (zc.zc_obj < dr->ddr_last) {
int err;
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_import.c b/sys/contrib/openzfs/lib/libzfs/libzfs_import.c
index 599e8e6f7819..7f276e9592c9 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_import.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_import.c
@@ -122,7 +122,7 @@ const pool_config_ops_t libzfs_config_ops = {
static uint64_t
label_offset(uint64_t size, int l)
{
- ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
+ ASSERT0(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t));
return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
}
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c b/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c
index 2a81b658d342..5c9e2199eed4 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_mount.c
@@ -516,7 +516,7 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags,
} else if (rc == ENOTSUP) {
int spa_version;
- VERIFY(zfs_spa_version(zhp, &spa_version) == 0);
+ VERIFY0(zfs_spa_version(zhp, &spa_version));
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"Can't mount a version %llu "
"file system on a version %d pool. Pool must be"
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
index 1ad10ebb3c15..77134d197904 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
@@ -2505,7 +2505,7 @@ zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
err = ENOENT;
if (sdd.cleanup_fd != -1) {
- VERIFY(0 == close(sdd.cleanup_fd));
+ VERIFY0(close(sdd.cleanup_fd));
sdd.cleanup_fd = -1;
}
@@ -2531,7 +2531,7 @@ err_out:
fnvlist_free(sdd.snapholds);
if (sdd.cleanup_fd != -1)
- VERIFY(0 == close(sdd.cleanup_fd));
+ VERIFY0(close(sdd.cleanup_fd));
return (err);
}
@@ -5108,7 +5108,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
nvlist_t *holds, *errors = NULL;
int cleanup_fd = -1;
- VERIFY(0 == nvlist_alloc(&holds, 0, KM_SLEEP));
+ VERIFY0(nvlist_alloc(&holds, 0, KM_SLEEP));
for (pair = nvlist_next_nvpair(snapholds_nvlist, NULL);
pair != NULL;
pair = nvlist_next_nvpair(snapholds_nvlist, pair)) {
@@ -5560,7 +5560,7 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
*cp = '\0';
sendfs = nonpackage_sendfs;
- VERIFY(finalsnap == NULL);
+ VERIFY0P(finalsnap);
}
return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
diff --git a/sys/contrib/openzfs/lib/libzpool/abd_os.c b/sys/contrib/openzfs/lib/libzpool/abd_os.c
index 0d5795de143a..8bd7a64ab24a 100644
--- a/sys/contrib/openzfs/lib/libzpool/abd_os.c
+++ b/sys/contrib/openzfs/lib/libzpool/abd_os.c
@@ -302,7 +302,7 @@ abd_iter_at_end(struct abd_iter *aiter)
void
abd_iter_advance(struct abd_iter *aiter, size_t amount)
{
- ASSERT3P(aiter->iter_mapaddr, ==, NULL);
+ ASSERT0P(aiter->iter_mapaddr);
ASSERT0(aiter->iter_mapsize);
if (abd_iter_at_end(aiter))
@@ -315,7 +315,7 @@ abd_iter_advance(struct abd_iter *aiter, size_t amount)
void
abd_iter_map(struct abd_iter *aiter)
{
- ASSERT3P(aiter->iter_mapaddr, ==, NULL);
+ ASSERT0P(aiter->iter_mapaddr);
ASSERT0(aiter->iter_mapsize);
if (abd_iter_at_end(aiter))
diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c
index 2e8bf160465a..e63153a03370 100644
--- a/sys/contrib/openzfs/lib/libzpool/kernel.c
+++ b/sys/contrib/openzfs/lib/libzpool/kernel.c
@@ -369,7 +369,7 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
if (delta <= 0)
return (-1);
- VERIFY(gettimeofday(&tv, NULL) == 0);
+ VERIFY0(gettimeofday(&tv, NULL));
ts.tv_sec = tv.tv_sec + delta / hz;
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);
diff --git a/sys/contrib/openzfs/lib/libzpool/util.c b/sys/contrib/openzfs/lib/libzpool/util.c
index 1d0d1a1e56d9..66d6f43967d5 100644
--- a/sys/contrib/openzfs/lib/libzpool/util.c
+++ b/sys/contrib/openzfs/lib/libzpool/util.c
@@ -137,12 +137,10 @@ show_pool_stats(spa_t *spa)
nvlist_t *config, *nvroot;
const char *name;
- VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0);
+ VERIFY0(spa_get_stats(spa_name(spa), &config, NULL, 0));
- VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
- &nvroot) == 0);
- VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
- &name) == 0);
+ VERIFY0(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot));
+ VERIFY0(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name));
show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0);
show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0);
diff --git a/sys/contrib/openzfs/lib/libzutil/zutil_import.c b/sys/contrib/openzfs/lib/libzutil/zutil_import.c
index ccdc874076c3..a4a6e76a1d09 100644
--- a/sys/contrib/openzfs/lib/libzutil/zutil_import.c
+++ b/sys/contrib/openzfs/lib/libzutil/zutil_import.c
@@ -917,7 +917,7 @@ error:
static uint64_t
label_offset(uint64_t size, int l)
{
- ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
+ ASSERT0(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t));
return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
}
@@ -1769,7 +1769,7 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg)
fnvlist_add_nvlist(pools, nvpair_name(pair),
fnvpair_value_nvlist(pair));
- VERIFY3P(nvlist_next_nvpair(nv, pair), ==, NULL);
+ VERIFY0P(nvlist_next_nvpair(nv, pair));
iarg->guid = saved_guid;
iarg->poolname = saved_poolname;
diff --git a/sys/contrib/openzfs/module/avl/avl.c b/sys/contrib/openzfs/module/avl/avl.c
index b6c1c02bc3f2..67cbcd3adeec 100644
--- a/sys/contrib/openzfs/module/avl/avl.c
+++ b/sys/contrib/openzfs/module/avl/avl.c
@@ -225,7 +225,7 @@ avl_nearest(avl_tree_t *tree, avl_index_t where, int direction)
size_t off = tree->avl_offset;
if (node == NULL) {
- ASSERT(tree->avl_root == NULL);
+ ASSERT0P(tree->avl_root);
return (NULL);
}
data = AVL_NODE2DATA(node, off);
@@ -478,7 +478,7 @@ avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where)
size_t off = tree->avl_offset;
#ifdef _LP64
- ASSERT(((uintptr_t)new_data & 0x7) == 0);
+ ASSERT0(((uintptr_t)new_data & 0x7));
#endif
node = AVL_DATA2NODE(new_data, off);
@@ -495,10 +495,10 @@ avl_insert(avl_tree_t *tree, void *new_data, avl_index_t where)
AVL_SETBALANCE(node, 0);
AVL_SETPARENT(node, parent);
if (parent != NULL) {
- ASSERT(parent->avl_child[which_child] == NULL);
+ ASSERT0P(parent->avl_child[which_child]);
parent->avl_child[which_child] = node;
} else {
- ASSERT(tree->avl_root == NULL);
+ ASSERT0P(tree->avl_root);
tree->avl_root = node;
}
/*
@@ -608,7 +608,7 @@ avl_insert_here(
ASSERT(diff > 0 ? child == 1 : child == 0);
#endif
}
- ASSERT(node->avl_child[child] == NULL);
+ ASSERT0P(node->avl_child[child]);
avl_insert(tree, new_data, AVL_MKINDEX(node, child));
}
@@ -881,7 +881,7 @@ avl_create(avl_tree_t *tree, int (*compar) (const void *, const void *),
ASSERT(size > 0);
ASSERT(size >= offset + sizeof (avl_node_t));
#ifdef _LP64
- ASSERT((offset & 0x7) == 0);
+ ASSERT0((offset & 0x7));
#endif
tree->avl_compar = compar;
@@ -897,8 +897,8 @@ void
avl_destroy(avl_tree_t *tree)
{
ASSERT(tree);
- ASSERT(tree->avl_numnodes == 0);
- ASSERT(tree->avl_root == NULL);
+ ASSERT0(tree->avl_numnodes);
+ ASSERT0P(tree->avl_root);
}
diff --git a/sys/contrib/openzfs/module/icp/core/kcf_sched.c b/sys/contrib/openzfs/module/icp/core/kcf_sched.c
index 759f0d81d521..75e1052a4ed4 100644
--- a/sys/contrib/openzfs/module/icp/core/kcf_sched.c
+++ b/sys/contrib/openzfs/module/icp/core/kcf_sched.c
@@ -124,7 +124,7 @@ kcf_context_cache_destructor(void *buf, void *cdrarg)
(void) cdrarg;
kcf_context_t *kctx = (kcf_context_t *)buf;
- ASSERT(kctx->kc_refcnt == 0);
+ ASSERT0(kctx->kc_refcnt);
}
void
diff --git a/sys/contrib/openzfs/module/icp/io/aes.c b/sys/contrib/openzfs/module/icp/io/aes.c
index ba703efa71fc..ca586eaf97ef 100644
--- a/sys/contrib/openzfs/module/icp/io/aes.c
+++ b/sys/contrib/openzfs/module/icp/io/aes.c
@@ -236,16 +236,16 @@ aes_encrypt_atomic(crypto_mechanism_t *mechanism,
aes_xor_block);
if (ret != CRYPTO_SUCCESS)
goto out;
- ASSERT(aes_ctx.ac_remainder_len == 0);
+ ASSERT0(aes_ctx.ac_remainder_len);
} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE) {
ret = gcm_encrypt_final((gcm_ctx_t *)&aes_ctx,
ciphertext, AES_BLOCK_LEN, aes_encrypt_block,
aes_copy_block, aes_xor_block);
if (ret != CRYPTO_SUCCESS)
goto out;
- ASSERT(aes_ctx.ac_remainder_len == 0);
+ ASSERT0(aes_ctx.ac_remainder_len);
} else {
- ASSERT(aes_ctx.ac_remainder_len == 0);
+ ASSERT0(aes_ctx.ac_remainder_len);
}
if (plaintext != ciphertext) {
@@ -337,7 +337,7 @@ aes_decrypt_atomic(crypto_mechanism_t *mechanism,
ret = ccm_decrypt_final((ccm_ctx_t *)&aes_ctx,
plaintext, AES_BLOCK_LEN, aes_encrypt_block,
aes_copy_block, aes_xor_block);
- ASSERT(aes_ctx.ac_remainder_len == 0);
+ ASSERT0(aes_ctx.ac_remainder_len);
if ((ret == CRYPTO_SUCCESS) &&
(ciphertext != plaintext)) {
plaintext->cd_length =
@@ -349,7 +349,7 @@ aes_decrypt_atomic(crypto_mechanism_t *mechanism,
ret = gcm_decrypt_final((gcm_ctx_t *)&aes_ctx,
plaintext, AES_BLOCK_LEN, aes_encrypt_block,
aes_xor_block);
- ASSERT(aes_ctx.ac_remainder_len == 0);
+ ASSERT0(aes_ctx.ac_remainder_len);
if ((ret == CRYPTO_SUCCESS) &&
(ciphertext != plaintext)) {
plaintext->cd_length =
diff --git a/sys/contrib/openzfs/module/nvpair/nvpair.c b/sys/contrib/openzfs/module/nvpair/nvpair.c
index 811cfc87d7a4..eb8c14b4a783 100644
--- a/sys/contrib/openzfs/module/nvpair/nvpair.c
+++ b/sys/contrib/openzfs/module/nvpair/nvpair.c
@@ -265,7 +265,7 @@ nv_priv_alloc_embedded(nvpriv_t *priv)
static int
nvt_tab_alloc(nvpriv_t *priv, uint64_t buckets)
{
- ASSERT3P(priv->nvp_hashtable, ==, NULL);
+ ASSERT0P(priv->nvp_hashtable);
ASSERT0(priv->nvp_nbuckets);
ASSERT0(priv->nvp_nentries);
@@ -334,7 +334,7 @@ nvt_lookup_name_type(const nvlist_t *nvl, const char *name, data_type_t type)
i_nvp_t **tab = priv->nvp_hashtable;
if (tab == NULL) {
- ASSERT3P(priv->nvp_list, ==, NULL);
+ ASSERT0P(priv->nvp_list);
ASSERT0(priv->nvp_nbuckets);
ASSERT0(priv->nvp_nentries);
return (NULL);
@@ -540,7 +540,7 @@ nvt_add_nvpair(nvlist_t *nvl, nvpair_t *nvp)
/* insert link at the beginning of the bucket */
i_nvp_t *new_entry = NVPAIR2I_NVP(nvp);
- ASSERT3P(new_entry->nvi_hashtable_next, ==, NULL);
+ ASSERT0P(new_entry->nvi_hashtable_next);
new_entry->nvi_hashtable_next = bucket;
// cppcheck-suppress nullPointerRedundantCheck
tab[index] = new_entry;
diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c
index 6d198fad5203..ae6e36d988c2 100644
--- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c
+++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_kmem.c
@@ -160,7 +160,7 @@ kmem_cache_create(const char *name, size_t bufsize, size_t align,
{
kmem_cache_t *cache;
- ASSERT3P(vmp, ==, NULL);
+ ASSERT0P(vmp);
cache = kmem_alloc(sizeof (*cache), KM_SLEEP);
strlcpy(cache->kc_name, name, sizeof (cache->kc_name));
diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c
index 9da633c2b1be..3c2d39b20c09 100644
--- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c
+++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c
@@ -256,7 +256,7 @@ sysevent_worker(void *arg __unused)
* free `ze`, so just inline the free() here -- events have already
* been drained.
*/
- VERIFY3P(ze->ze_zevent, ==, NULL);
+ VERIFY0P(ze->ze_zevent);
kmem_free(ze, sizeof (zfs_zevent_t));
kthread_exit();
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c
index fbf67f6a14a8..4bf487cdc469 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c
@@ -507,7 +507,7 @@ abd_iter_at_end(struct abd_iter *aiter)
void
abd_iter_advance(struct abd_iter *aiter, size_t amount)
{
- ASSERT3P(aiter->iter_mapaddr, ==, NULL);
+ ASSERT0P(aiter->iter_mapaddr);
ASSERT0(aiter->iter_mapsize);
/* There's nothing left to advance to, so do nothing */
@@ -526,7 +526,7 @@ abd_iter_map(struct abd_iter *aiter)
{
void *paddr;
- ASSERT3P(aiter->iter_mapaddr, ==, NULL);
+ ASSERT0P(aiter->iter_mapaddr);
ASSERT0(aiter->iter_mapsize);
/* There's nothing left to iterate over, so do nothing */
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c
index 364bbfc60abd..26cc7981bfcd 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c
@@ -156,7 +156,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
if (dbp[0]->db_offset != 0 || numbufs > 1) {
for (i = 0; i < numbufs; i++) {
ASSERT(ISP2(dbp[i]->db_size));
- ASSERT3U((dbp[i]->db_offset % dbp[i]->db_size), ==, 0);
+ ASSERT0((dbp[i]->db_offset % dbp[i]->db_size));
ASSERT3U(dbp[i]->db_size, ==, dbp[0]->db_size);
}
}
@@ -175,7 +175,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
vm_page_sunbusy(m);
break;
}
- ASSERT3U(m->dirty, ==, 0);
+ ASSERT0(m->dirty);
ASSERT(!pmap_page_is_write_mapped(m));
ASSERT3U(db->db_size, >, PAGE_SIZE);
@@ -201,7 +201,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
if (m != bogus_page) {
vm_page_assert_xbusied(m);
ASSERT(vm_page_none_valid(m));
- ASSERT3U(m->dirty, ==, 0);
+ ASSERT0(m->dirty);
ASSERT(!pmap_page_is_write_mapped(m));
va = zfs_map_page(m, &sf);
}
@@ -295,7 +295,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
vm_page_sunbusy(m);
break;
}
- ASSERT3U(m->dirty, ==, 0);
+ ASSERT0(m->dirty);
ASSERT(!pmap_page_is_write_mapped(m));
ASSERT3U(db->db_size, >, PAGE_SIZE);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c
index c8ab7cc7cf8e..bbd1dafc69be 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c
@@ -1236,7 +1236,7 @@ vdev_geom_io_done(zio_t *zio)
struct bio *bp = zio->io_bio;
if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) {
- ASSERT3P(bp, ==, NULL);
+ ASSERT0P(bp);
return;
}
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
index 5c5adc6cc12b..b15a3e6e38c0 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
@@ -1632,7 +1632,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
if (zfsvfs->z_replay == B_FALSE)
ASSERT_VOP_ELOCKED(ZTOV(dzp), __func__);
} else
- ASSERT3P(dzp->z_vnode, ==, NULL);
+ ASSERT0P(dzp->z_vnode);
memset(acl_ids, 0, sizeof (zfs_acl_ids_t));
acl_ids->z_mode = MAKEIMODE(vap->va_type, vap->va_mode);
@@ -2014,7 +2014,7 @@ top:
error = zfs_aclset_common(zp, aclp, cr, tx);
ASSERT0(error);
- ASSERT3P(zp->z_acl_cached, ==, NULL);
+ ASSERT0P(zp->z_acl_cached);
zp->z_acl_cached = aclp;
if (fuid_dirtied)
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
index 8d0ff9b25e30..61d0bb26d1e5 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
@@ -357,7 +357,7 @@ zfsctl_create(zfsvfs_t *zfsvfs)
vnode_t *rvp;
uint64_t crtime[2];
- ASSERT3P(zfsvfs->z_ctldir, ==, NULL);
+ ASSERT0P(zfsvfs->z_ctldir);
snapdir = sfs_alloc_node(sizeof (*snapdir), "snapshot", ZFSCTL_INO_ROOT,
ZFSCTL_INO_SNAPDIR);
@@ -1367,7 +1367,7 @@ zfsctl_snapshot_unmount(const char *snapname, int flags __unused)
int err = getzfsvfs(snapname, &zfsvfs);
if (err != 0) {
- ASSERT3P(zfsvfs, ==, NULL);
+ ASSERT0P(zfsvfs);
return (0);
}
vfsp = zfsvfs->z_vfs;
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c
index 191df832d726..75ba2ea0cb9e 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c
@@ -273,7 +273,7 @@ zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
ASSERT(zp->z_unlinked);
- ASSERT3U(zp->z_links, ==, 0);
+ ASSERT0(zp->z_links);
VERIFY0(zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx));
@@ -437,7 +437,7 @@ zfs_rmnode(znode_t *zp)
uint64_t count;
int error;
- ASSERT3U(zp->z_links, ==, 0);
+ ASSERT0(zp->z_links);
if (zfsvfs->z_replay == B_FALSE)
ASSERT_VOP_ELOCKED(ZTOV(zp), __func__);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
index 0456552ed07e..79b784288911 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
@@ -455,8 +455,13 @@ zfs_sync(vfs_t *vfsp, int waitfor)
return (0);
}
- if (zfsvfs->z_log != NULL)
- zil_commit(zfsvfs->z_log, 0);
+ if (zfsvfs->z_log != NULL) {
+ error = zil_commit(zfsvfs->z_log, 0);
+ if (error != 0) {
+ zfs_exit(zfsvfs, FTAG);
+ return (error);
+ }
+ }
zfs_exit(zfsvfs, FTAG);
} else {
@@ -1091,7 +1096,7 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
if (mounting) {
boolean_t readonly;
- ASSERT3P(zfsvfs->z_kstat.dk_kstats, ==, NULL);
+ ASSERT0P(zfsvfs->z_kstat.dk_kstats);
error = dataset_kstats_create(&zfsvfs->z_kstat, zfsvfs->z_os);
if (error)
return (error);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
index c4270d8b5d5c..1813c411b013 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
@@ -1101,7 +1101,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
zfs_exit(zfsvfs, FTAG);
return (error);
}
- ASSERT3P(zp, ==, NULL);
+ ASSERT0P(zp);
/*
* Create a new file object and update the directory
@@ -1193,8 +1193,8 @@ out:
*zpp = zp;
}
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1323,9 +1323,8 @@ out:
if (xzp)
vrele(ZTOV(xzp));
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
-
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1482,7 +1481,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
zfs_exit(zfsvfs, FTAG);
return (error);
}
- ASSERT3P(zp, ==, NULL);
+ ASSERT0P(zp);
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr,
mnt_ns))) {
@@ -1556,8 +1555,8 @@ out:
getnewvnode_drop_reserve();
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1637,8 +1636,8 @@ zfs_rmdir_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr)
if (zfsvfs->z_use_namecache)
cache_vop_rmdir(dvp, vp);
out:
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -3009,8 +3008,8 @@ out:
}
out2:
- if (os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (err == 0 && os->os_sync == ZFS_SYNC_ALWAYS)
+ err = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (err);
@@ -3539,7 +3538,7 @@ out_seq:
out:
if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -3731,7 +3730,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
*zpp = zp;
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ error = zil_commit(zilog, 0);
}
zfs_exit(zfsvfs, FTAG);
@@ -3921,8 +3920,8 @@ zfs_link(znode_t *tdzp, znode_t *szp, const char *name, cred_t *cr,
vnevent_link(ZTOV(szp), ct);
}
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -4313,7 +4312,7 @@ typedef struct {
} putpage_commit_arg_t;
static void
-zfs_putpage_commit_cb(void *arg)
+zfs_putpage_commit_cb(void *arg, int err)
{
putpage_commit_arg_t *pca = arg;
vm_object_t object = pca->pca_pages[0]->object;
@@ -4322,7 +4321,17 @@ zfs_putpage_commit_cb(void *arg)
for (uint_t i = 0; i < pca->pca_npages; i++) {
vm_page_t pp = pca->pca_pages[i];
- vm_page_undirty(pp);
+
+ if (err == 0) {
+ /*
+ * Writeback succeeded, so undirty the page. If it
+ * fails, we leave it in the same state it was. That's
+ * most likely dirty, so it will get tried again some
+ * other time.
+ */
+ vm_page_undirty(pp);
+ }
+
vm_page_sunbusy(pp);
}
@@ -4510,8 +4519,13 @@ zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags,
out:
zfs_rangelock_exit(lr);
- if (commit)
- zil_commit(zfsvfs->z_log, zp->z_id);
+ if (commit) {
+ err = zil_commit(zfsvfs->z_log, zp->z_id);
+ if (err != 0) {
+ zfs_exit(zfsvfs, FTAG);
+ return (err);
+ }
+ }
dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, len);
@@ -5223,8 +5237,32 @@ struct vop_fsync_args {
static int
zfs_freebsd_fsync(struct vop_fsync_args *ap)
{
+ vnode_t *vp = ap->a_vp;
+ int err = 0;
+
+ /*
+ * Push any dirty mmap()'d data out to the DMU and ZIL, ready for
+ * zil_commit() to be called in zfs_fsync().
+ */
+ if (vm_object_mightbedirty(vp->v_object)) {
+ zfs_vmobject_wlock(vp->v_object);
+ if (!vm_object_page_clean(vp->v_object, 0, 0, 0))
+ err = SET_ERROR(EIO);
+ zfs_vmobject_wunlock(vp->v_object);
+ if (err) {
+ /*
+ * Unclear what state things are in. zfs_putpages()
+ * will ensure the pages remain dirty if they haven't
+ * been written down to the DMU, but because there may
+ * be nothing logged, we can't assume that zfs_sync()
+ * -> zil_commit() will give us a useful error. It's
+ * safest if we just error out here.
+ */
+ return (err);
+ }
+ }
- return (zfs_fsync(VTOZ(ap->a_vp), 0, ap->a_td->td_ucred));
+ return (zfs_fsync(VTOZ(vp), 0, ap->a_td->td_ucred));
}
#ifndef _SYS_SYSPROTO_H_
@@ -6773,9 +6811,11 @@ zfs_deallocate(struct vop_deallocate_args *ap)
if (error == 0) {
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS ||
(ap->a_ioflag & IO_SYNC) != 0)
- zil_commit(zilog, zp->z_id);
- *ap->a_offset = off + len;
- *ap->a_len = 0;
+ error = zil_commit(zilog, zp->z_id);
+ if (error == 0) {
+ *ap->a_offset = off + len;
+ *ap->a_len = 0;
+ }
}
zfs_exit(zfsvfs, FTAG);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c
index 775f54a65f7d..7cd0a153577c 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode_os.c
@@ -161,15 +161,15 @@ zfs_znode_cache_destructor(void *buf, void *arg)
znode_t *zp = buf;
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs));
- ASSERT3P(zp->z_vnode, ==, NULL);
+ ASSERT0P(zp->z_vnode);
ASSERT(!list_link_active(&zp->z_link_node));
mutex_destroy(&zp->z_lock);
mutex_destroy(&zp->z_acl_lock);
rw_destroy(&zp->z_xattr_lock);
zfs_rangelock_fini(&zp->z_rangelock);
- ASSERT3P(zp->z_acl_cached, ==, NULL);
- ASSERT3P(zp->z_xattr_cached, ==, NULL);
+ ASSERT0P(zp->z_acl_cached);
+ ASSERT0P(zp->z_xattr_cached);
}
@@ -195,7 +195,7 @@ zfs_znode_init(void)
/*
* Initialize zcache
*/
- ASSERT3P(znode_uma_zone, ==, NULL);
+ ASSERT0P(znode_uma_zone);
znode_uma_zone = uma_zcreate("zfs_znode_cache",
sizeof (znode_t), zfs_znode_cache_constructor_smr,
zfs_znode_cache_destructor_smr, NULL, NULL, 0, 0);
@@ -224,7 +224,7 @@ zfs_znode_init(void)
/*
* Initialize zcache
*/
- ASSERT3P(znode_cache, ==, NULL);
+ ASSERT0P(znode_cache);
znode_cache = kmem_cache_create("zfs_znode_cache",
sizeof (znode_t), 0, zfs_znode_cache_constructor,
zfs_znode_cache_destructor, NULL, NULL, NULL, KMC_RECLAIMABLE);
@@ -353,8 +353,8 @@ zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp,
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs) || (zfsvfs == zp->z_zfsvfs));
ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id)));
- ASSERT3P(zp->z_sa_hdl, ==, NULL);
- ASSERT3P(zp->z_acl_cached, ==, NULL);
+ ASSERT0P(zp->z_sa_hdl);
+ ASSERT0P(zp->z_acl_cached);
if (sa_hdl == NULL) {
VERIFY0(sa_handle_get_from_db(zfsvfs->z_os, db, zp,
SA_HDL_SHARED, &zp->z_sa_hdl));
@@ -1127,7 +1127,7 @@ zfs_rezget(znode_t *zp)
}
rw_exit(&zp->z_xattr_lock);
- ASSERT3P(zp->z_sa_hdl, ==, NULL);
+ ASSERT0P(zp->z_sa_hdl);
err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db);
if (err) {
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
@@ -1298,7 +1298,7 @@ zfs_znode_free(znode_t *zp)
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
char *symlink;
- ASSERT3P(zp->z_sa_hdl, ==, NULL);
+ ASSERT0P(zp->z_sa_hdl);
zp->z_vnode = NULL;
mutex_enter(&zfsvfs->z_znodes_lock);
POINTER_INVALIDATE(&zp->z_zfsvfs);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
index 72a7c4ea082a..265dfd55fc4d 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
@@ -727,9 +727,9 @@ unlock:
break;
}
- if (commit) {
+ if (error == 0 && commit) {
commit:
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
}
resume:
rw_exit(&zv->zv_suspend_lock);
@@ -906,8 +906,8 @@ zvol_cdev_write(struct cdev *dev, struct uio *uio_s, int ioflag)
zfs_rangelock_exit(lr);
int64_t nwritten = start_resid - zfs_uio_resid(&uio);
dataset_kstats_update_write_kstats(&zv->zv_kstat, nwritten);
- if (commit)
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ if (error == 0 && commit)
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
rw_exit(&zv->zv_suspend_lock);
return (error);
@@ -1117,7 +1117,7 @@ zvol_cdev_ioctl(struct cdev *dev, ulong_t cmd, caddr_t data,
case DIOCGFLUSH:
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
if (zv->zv_zilog != NULL)
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
rw_exit(&zv->zv_suspend_lock);
break;
case DIOCGDELETE:
@@ -1152,7 +1152,7 @@ zvol_cdev_ioctl(struct cdev *dev, ulong_t cmd, caddr_t data,
}
zfs_rangelock_exit(lr);
if (sync)
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
rw_exit(&zv->zv_suspend_lock);
break;
case DIOCGSTRIPESIZE:
@@ -1415,7 +1415,7 @@ zvol_os_free(zvol_state_t *zv)
struct zvol_state_geom *zsg = &zv->zv_zso->zso_geom;
struct g_provider *pp __maybe_unused = zsg->zsg_provider;
- ASSERT3P(pp->private, ==, NULL);
+ ASSERT0P(pp->private);
g_topology_lock();
zvol_geom_destroy(zv);
@@ -1425,7 +1425,7 @@ zvol_os_free(zvol_state_t *zv)
struct cdev *dev = zsd->zsd_cdev;
if (dev != NULL) {
- ASSERT3P(dev->si_drv2, ==, NULL);
+ ASSERT0P(dev->si_drv2);
destroy_dev(dev);
knlist_clear(&zsd->zsd_selinfo.si_note, 0);
knlist_destroy(&zsd->zsd_selinfo.si_note);
@@ -1493,11 +1493,11 @@ zvol_os_create_minor(const char *name)
zv->zv_objset = os;
- ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL);
+ ASSERT0P(zv->zv_kstat.dk_kstats);
error = dataset_kstats_create(&zv->zv_kstat, zv->zv_objset);
if (error)
goto out_dmu_objset_disown;
- ASSERT3P(zv->zv_zilog, ==, NULL);
+ ASSERT0P(zv->zv_zilog);
zv->zv_zilog = zil_open(os, zvol_get_data, &zv->zv_kstat.dk_zil_sums);
if (spa_writeable(dmu_objset_spa(os))) {
if (zil_replay_disable)
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c b/sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c
index ce9c9e39e60c..aac5f2ebbfd2 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c
@@ -66,9 +66,9 @@ void
__cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg)
{
ASSERT(cvp);
- ASSERT(name == NULL);
+ ASSERT0P(name);
ASSERT(type == CV_DEFAULT);
- ASSERT(arg == NULL);
+ ASSERT0P(arg);
cvp->cv_magic = CV_MAGIC;
init_waitqueue_head(&cvp->cv_event);
@@ -83,7 +83,7 @@ static int
cv_destroy_wakeup(kcondvar_t *cvp)
{
if (!atomic_read(&cvp->cv_waiters) && !atomic_read(&cvp->cv_refs)) {
- ASSERT(cvp->cv_mutex == NULL);
+ ASSERT0P(cvp->cv_mutex);
ASSERT(!waitqueue_active(&cvp->cv_event));
return (1);
}
@@ -104,7 +104,7 @@ __cv_destroy(kcondvar_t *cvp)
while (cv_destroy_wakeup(cvp) == 0)
wait_event_timeout(cvp->cv_destroy, cv_destroy_wakeup(cvp), 1);
- ASSERT3P(cvp->cv_mutex, ==, NULL);
+ ASSERT0P(cvp->cv_mutex);
ASSERT3S(atomic_read(&cvp->cv_refs), ==, 0);
ASSERT3S(atomic_read(&cvp->cv_waiters), ==, 0);
ASSERT3S(waitqueue_active(&cvp->cv_event), ==, 0);
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c b/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c
index f37699b4347e..89ca4a648b2f 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c
@@ -709,7 +709,7 @@ zone_get_hostid(void *zone)
{
uint32_t hostid;
- ASSERT3P(zone, ==, NULL);
+ ASSERT0P(zone);
if (spl_hostid != 0)
return ((uint32_t)(spl_hostid & HW_HOSTID_MASK));
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c b/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c
index fab80289b278..22e4ed169d03 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c
@@ -296,7 +296,7 @@ spl_slab_free(spl_kmem_slab_t *sks,
spl_kmem_cache_t *skc;
ASSERT(sks->sks_magic == SKS_MAGIC);
- ASSERT(sks->sks_ref == 0);
+ ASSERT0(sks->sks_ref);
skc = sks->sks_cache;
ASSERT(skc->skc_magic == SKC_MAGIC);
@@ -598,7 +598,7 @@ static void
spl_magazine_free(spl_kmem_magazine_t *skm)
{
ASSERT(skm->skm_magic == SKM_MAGIC);
- ASSERT(skm->skm_avail == 0);
+ ASSERT0(skm->skm_avail);
kfree(skm);
}
@@ -610,7 +610,7 @@ spl_magazine_create(spl_kmem_cache_t *skc)
{
int i = 0;
- ASSERT((skc->skc_flags & KMC_SLAB) == 0);
+ ASSERT0((skc->skc_flags & KMC_SLAB));
skc->skc_mag = kzalloc(sizeof (spl_kmem_magazine_t *) *
num_possible_cpus(), kmem_flags_convert(KM_SLEEP));
@@ -640,7 +640,7 @@ spl_magazine_destroy(spl_kmem_cache_t *skc)
spl_kmem_magazine_t *skm;
int i = 0;
- ASSERT((skc->skc_flags & KMC_SLAB) == 0);
+ ASSERT0((skc->skc_flags & KMC_SLAB));
for_each_possible_cpu(i) {
skm = skc->skc_mag[i];
@@ -679,8 +679,8 @@ spl_kmem_cache_create(const char *name, size_t size, size_t align,
/*
* Unsupported flags
*/
- ASSERT(vmp == NULL);
- ASSERT(reclaim == NULL);
+ ASSERT0P(vmp);
+ ASSERT0P(reclaim);
might_sleep();
@@ -863,11 +863,11 @@ spl_kmem_cache_destroy(spl_kmem_cache_t *skc)
* Validate there are no objects in use and free all the
* spl_kmem_slab_t, spl_kmem_obj_t, and object buffers.
*/
- ASSERT3U(skc->skc_slab_alloc, ==, 0);
- ASSERT3U(skc->skc_obj_alloc, ==, 0);
- ASSERT3U(skc->skc_slab_total, ==, 0);
- ASSERT3U(skc->skc_obj_total, ==, 0);
- ASSERT3U(skc->skc_obj_emergency, ==, 0);
+ ASSERT0(skc->skc_slab_alloc);
+ ASSERT0(skc->skc_obj_alloc);
+ ASSERT0(skc->skc_slab_total);
+ ASSERT0(skc->skc_obj_total);
+ ASSERT0(skc->skc_obj_emergency);
ASSERT(list_empty(&skc->skc_complete_list));
ASSERT3U(percpu_counter_sum(&skc->skc_linux_alloc), ==, 0);
@@ -986,7 +986,7 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
ASSERT0(flags & ~KM_PUBLIC_MASK);
ASSERT(skc->skc_magic == SKC_MAGIC);
- ASSERT((skc->skc_flags & KMC_SLAB) == 0);
+ ASSERT0((skc->skc_flags & KMC_SLAB));
*obj = NULL;
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-kstat.c b/sys/contrib/openzfs/module/os/linux/spl/spl-kstat.c
index 48f70b00c96b..02c5b42bc4a0 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-kstat.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-kstat.c
@@ -541,7 +541,7 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
kstat_t *ksp;
ASSERT(ks_module);
- ASSERT(ks_instance == 0);
+ ASSERT0(ks_instance);
ASSERT(ks_name);
if ((ks_type == KSTAT_TYPE_INTR) || (ks_type == KSTAT_TYPE_IO))
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c b/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c
index f42f455222de..8f5c73b13df5 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-thread.c
@@ -80,7 +80,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
/* Option pp is simply ignored */
/* Variable stack size unsupported */
- ASSERT(stk == NULL);
+ ASSERT0P(stk);
tp = kmem_alloc(sizeof (thread_priv_t), KM_PUSHPAGE);
if (tp == NULL)
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-tsd.c b/sys/contrib/openzfs/module/os/linux/spl/spl-tsd.c
index 34a61bef7d4f..2e8cedf0dc87 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-tsd.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-tsd.c
@@ -161,7 +161,7 @@ tsd_hash_add(tsd_hash_table_t *table, uint_t key, pid_t pid, void *value)
ulong_t hash;
int rc = 0;
- ASSERT3P(tsd_hash_search(table, key, pid), ==, NULL);
+ ASSERT0P(tsd_hash_search(table, key, pid));
/* New entry allocate structure, set value, and add to hash */
entry = kmem_alloc(sizeof (tsd_hash_entry_t), KM_PUSHPAGE);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/abd_os.c b/sys/contrib/openzfs/module/os/linux/zfs/abd_os.c
index 248c9b7a6d3b..8a8316f63c48 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/abd_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/abd_os.c
@@ -863,9 +863,9 @@ abd_iter_advance(struct abd_iter *aiter, size_t amount)
* Ensure that last chunk is not in use. abd_iterate_*() must clear
* this state (directly or abd_iter_unmap()) before advancing.
*/
- ASSERT3P(aiter->iter_mapaddr, ==, NULL);
+ ASSERT0P(aiter->iter_mapaddr);
ASSERT0(aiter->iter_mapsize);
- ASSERT3P(aiter->iter_page, ==, NULL);
+ ASSERT0P(aiter->iter_page);
ASSERT0(aiter->iter_page_doff);
ASSERT0(aiter->iter_page_dsize);
@@ -897,7 +897,7 @@ abd_iter_map(struct abd_iter *aiter)
void *paddr;
size_t offset = 0;
- ASSERT3P(aiter->iter_mapaddr, ==, NULL);
+ ASSERT0P(aiter->iter_mapaddr);
ASSERT0(aiter->iter_mapsize);
/* There's nothing left to iterate over, so do nothing */
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
index 154ca22d9513..830fad7fe793 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
@@ -552,7 +552,7 @@ vdev_bio_associate_blkg(struct bio *bio)
#endif
ASSERT3P(q, !=, NULL);
- ASSERT3P(bio->bi_blkg, ==, NULL);
+ ASSERT0P(bio->bi_blkg);
if (q->root_blkg && vdev_blkg_tryget(q->root_blkg))
bio->bi_blkg = q->root_blkg;
@@ -574,7 +574,7 @@ vdev_bio_set_dev(struct bio *bio, struct block_device *bdev)
bio->bi_bdev = bdev;
ASSERT3P(q, !=, NULL);
- ASSERT3P(bio->bi_blkg, ==, NULL);
+ ASSERT0P(bio->bi_blkg);
if (q->root_blkg && vdev_blkg_tryget(q->root_blkg))
bio->bi_blkg = q->root_blkg;
@@ -806,7 +806,7 @@ vbio_completion(struct bio *bio)
* here; instead we stash vbio on the zio and take care of it in the
* done callback.
*/
- ASSERT3P(zio->io_bio, ==, NULL);
+ ASSERT0P(zio->io_bio);
zio->io_bio = vbio;
zio_delay_interrupt(zio);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
index 1b169122f25b..daa4b5776837 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
@@ -1900,7 +1900,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
if (!(flag & IS_ROOT_NODE) &&
(dzp->z_pflags & ZFS_INHERIT_ACE) &&
!(dzp->z_pflags & ZFS_XATTR)) {
- VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
+ VERIFY0(zfs_acl_node_read(dzp, B_TRUE,
&paclp, B_FALSE));
acl_ids->z_aclp = zfs_acl_inherit(zfsvfs,
vap->va_mode, paclp, acl_ids->z_mode, &need_chmod);
@@ -2204,8 +2204,8 @@ top:
}
error = zfs_aclset_common(zp, aclp, cr, tx);
- ASSERT(error == 0);
- ASSERT(zp->z_acl_cached == NULL);
+ ASSERT0(error);
+ ASSERT0P(zp->z_acl_cached);
zp->z_acl_cached = aclp;
if (fuid_dirtied)
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 6552a933ce0a..fb4de50480a3 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
@@ -494,9 +494,9 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
if (!creation)
now = current_time(ip);
zp = ITOZ(ip);
- ASSERT3P(zp->z_dirlocks, ==, NULL);
- ASSERT3P(zp->z_acl_cached, ==, NULL);
- ASSERT3P(zp->z_xattr_cached, ==, NULL);
+ ASSERT0P(zp->z_dirlocks);
+ ASSERT0P(zp->z_acl_cached);
+ ASSERT0P(zp->z_xattr_cached);
zp->z_id = id;
zp->z_unlinked = B_FALSE;
zp->z_atime_dirty = B_FALSE;
@@ -590,7 +590,7 @@ zfsctl_inode_lookup(zfsvfs_t *zfsvfs, uint64_t id,
int
zfsctl_create(zfsvfs_t *zfsvfs)
{
- ASSERT(zfsvfs->z_ctldir == NULL);
+ ASSERT0P(zfsvfs->z_ctldir);
zfsvfs->z_ctldir = zfsctl_inode_alloc(zfsvfs, ZFSCTL_INO_ROOT,
&zpl_fops_root, &zpl_ops_root, 0);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c
index 2f935bb3fc8c..e8de536606e2 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c
@@ -463,7 +463,7 @@ zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
zfsvfs_t *zfsvfs = ZTOZSB(zp);
ASSERT(zp->z_unlinked);
- ASSERT(ZTOI(zp)->i_nlink == 0);
+ ASSERT0(ZTOI(zp)->i_nlink);
VERIFY3U(0, ==,
zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx));
@@ -662,8 +662,8 @@ zfs_rmnode(znode_t *zp)
uint64_t links;
int error;
- ASSERT(ZTOI(zp)->i_nlink == 0);
- ASSERT(atomic_read(&ZTOI(zp)->i_count) == 0);
+ ASSERT0(ZTOI(zp)->i_nlink);
+ ASSERT0(atomic_read(&ZTOI(zp)->i_count));
/*
* If this is an attribute directory, purge its contents.
@@ -710,7 +710,7 @@ zfs_rmnode(znode_t *zp)
&xattr_obj, sizeof (xattr_obj));
if (error == 0 && xattr_obj) {
error = zfs_zget(zfsvfs, xattr_obj, &xzp);
- ASSERT(error == 0);
+ ASSERT0(error);
}
acl_obj = zfs_external_acl(zp);
@@ -744,12 +744,12 @@ zfs_rmnode(znode_t *zp)
}
if (xzp) {
- ASSERT(error == 0);
+ ASSERT0(error);
mutex_enter(&xzp->z_lock);
xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */
clear_nlink(ZTOI(xzp)); /* no more links to it */
links = 0;
- VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs),
+ VERIFY0(sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs),
&links, sizeof (links), tx));
mutex_exit(&xzp->z_lock);
zfs_unlinked_add(xzp, tx);
@@ -872,7 +872,7 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
ctime);
}
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
mutex_exit(&zp->z_lock);
@@ -894,7 +894,7 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
&dzp->z_pflags, sizeof (dzp->z_pflags));
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime);
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
mutex_exit(&dzp->z_lock);
return (0);
@@ -986,7 +986,7 @@ zfs_drop_nlink_locked(znode_t *zp, dmu_tx_t *tx, boolean_t *unlinkedp)
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs),
NULL, &links, sizeof (links));
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
- ASSERT3U(error, ==, 0);
+ ASSERT0(error);
if (unlinkedp != NULL)
*unlinkedp = unlinked;
@@ -1058,7 +1058,7 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
/* The only error is !zfs_dirempty() and we checked earlier. */
error = zfs_drop_nlink_locked(zp, tx, &unlinked);
- ASSERT3U(error, ==, 0);
+ ASSERT0(error);
mutex_exit(&zp->z_lock);
} else {
error = zfs_dropname(dl, zp, dzp, tx, flag);
@@ -1083,7 +1083,7 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
NULL, &dzp->z_pflags, sizeof (dzp->z_pflags));
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime);
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
mutex_exit(&dzp->z_lock);
if (unlinkedp != NULL)
@@ -1167,7 +1167,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr)
ASSERT(error == 0 && parent == zp->z_id);
#endif
- VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id,
+ VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id,
sizeof (xzp->z_id), tx));
if (!zp->z_unlinked)
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c
index 1c187d7b9cab..895d80b2d79e 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c
@@ -223,7 +223,7 @@ zfs_kobj_add(zfs_mod_kobj_t *zkobj, struct kobject *parent, const char *name)
{
/* zko_default_group.attrs must be NULL terminated */
ASSERT(zkobj->zko_default_group.attrs != NULL);
- ASSERT(zkobj->zko_default_group.attrs[zkobj->zko_attr_count] == NULL);
+ ASSERT0P(zkobj->zko_default_group.attrs[zkobj->zko_attr_count]);
kobject_init(&zkobj->zko_kobj, &zkobj->zko_kobj_type);
return (kobject_add(&zkobj->zko_kobj, parent, name));
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 396faef8f646..cd606e667bff 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
@@ -279,19 +279,14 @@ zfs_sync(struct super_block *sb, int wait, cred_t *cr)
return (err);
/*
- * If the pool is suspended, just return an error. This is to help
- * with shutting down with pools suspended, as we don't want to block
- * in that case.
+ * Sync any pending writes, but do not block if the pool is suspended.
+ * This is to help with shutting down with pools suspended, as we don't
+ * want to block in that case.
*/
- if (spa_suspended(zfsvfs->z_os->os_spa)) {
- zfs_exit(zfsvfs, FTAG);
- return (SET_ERROR(EIO));
- }
-
- zil_commit(zfsvfs->z_log, 0);
+ err = zil_commit_flags(zfsvfs->z_log, 0, ZIL_COMMIT_NOW);
zfs_exit(zfsvfs, FTAG);
- return (0);
+ return (err);
}
static void
@@ -883,7 +878,7 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
* operations out since we closed the ZIL.
*/
if (mounting) {
- ASSERT3P(zfsvfs->z_kstat.dk_kstats, ==, NULL);
+ ASSERT0P(zfsvfs->z_kstat.dk_kstats);
error = dataset_kstats_create(&zfsvfs->z_kstat, zfsvfs->z_os);
if (error)
return (error);
@@ -1676,7 +1671,7 @@ zfs_umount(struct super_block *sb)
if (zfsvfs->z_arc_prune != NULL)
arc_remove_prune_callback(zfsvfs->z_arc_prune);
- VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0);
+ VERIFY0(zfsvfs_teardown(zfsvfs, B_TRUE));
os = zfsvfs->z_os;
/*
@@ -1802,8 +1797,8 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
ASSERT(*ipp != NULL);
if (object == ZFSCTL_INO_SNAPDIR) {
- VERIFY(zfsctl_root_lookup(*ipp, "snapshot", ipp,
- 0, kcred, NULL, NULL) == 0);
+ VERIFY0(zfsctl_root_lookup(*ipp, "snapshot", ipp,
+ 0, kcred, NULL, NULL));
} else {
/*
* Must have an existing ref, so igrab()
@@ -1905,7 +1900,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
goto bail;
ds->ds_dir->dd_activity_cancelled = B_FALSE;
- VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0);
+ VERIFY0(zfsvfs_setup(zfsvfs, B_FALSE));
zfs_set_fuid_feature(zfsvfs);
zfsvfs->z_rollback_time = jiffies;
@@ -2078,7 +2073,7 @@ zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers)
ZFS_SA_ATTRS, 8, 1, &sa_obj, tx);
ASSERT0(error);
- VERIFY(0 == sa_set_sa_object(os, sa_obj));
+ VERIFY0(sa_set_sa_object(os, sa_obj));
sa_register_update_callback(os, zfs_sa_upgrade);
}
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c
index 6a2fc5ad7935..6106726651a3 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c
@@ -841,8 +841,8 @@ out:
*zpp = zp;
}
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1203,8 +1203,8 @@ out:
zfs_zrele_async(xzp);
}
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1392,14 +1392,15 @@ out:
zfs_dirent_unlock(dl);
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
-
if (error != 0) {
zrele(zp);
} else {
zfs_znode_update_vfs(dzp);
zfs_znode_update_vfs(zp);
+
+ if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
+
}
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1528,8 +1529,8 @@ out:
zfs_znode_update_vfs(zp);
zrele(zp);
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -2483,10 +2484,10 @@ top:
new_mode = zp->z_mode;
}
err = zfs_acl_chown_setattr(zp);
- ASSERT(err == 0);
+ ASSERT0(err);
if (attrzp) {
err = zfs_acl_chown_setattr(attrzp);
- ASSERT(err == 0);
+ ASSERT0(err);
}
}
@@ -2600,7 +2601,7 @@ out:
if (err == 0 && xattr_count > 0) {
err2 = sa_bulk_update(attrzp->z_sa_hdl, xattr_bulk,
xattr_count, tx);
- ASSERT(err2 == 0);
+ ASSERT0(err2);
}
if (aclp)
@@ -2630,8 +2631,8 @@ out:
}
out2:
- if (os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (err == 0 && os->os_sync == ZFS_SYNC_ALWAYS)
+ err = zil_commit(zilog, 0);
out3:
kmem_free(xattr_bulk, sizeof (sa_bulk_attr_t) * bulks);
@@ -3157,7 +3158,7 @@ top:
* zfs_link_create() to add back the same entry, but with a new
* dnode (szp), should not fail.
*/
- ASSERT3P(tzp, ==, NULL);
+ ASSERT0P(tzp);
goto commit_link_tzp;
}
@@ -3235,8 +3236,8 @@ out:
zfs_dirent_unlock(sdl);
zfs_dirent_unlock(tdl);
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -3436,7 +3437,7 @@ top:
*zpp = zp;
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ error = zil_commit(zilog, 0);
} else {
zrele(zp);
}
@@ -3654,8 +3655,8 @@ top:
* operation are sync safe.
*/
if (is_tmpfile) {
- VERIFY(zap_remove_int(zfsvfs->z_os,
- zfsvfs->z_unlinkedobj, szp->z_id, tx) == 0);
+ VERIFY0(zap_remove_int(zfsvfs->z_os,
+ zfsvfs->z_unlinkedobj, szp->z_id, tx));
} else {
if (flags & FIGNORECASE)
txtype |= TX_CI;
@@ -3670,18 +3671,20 @@ top:
zfs_dirent_unlock(dl);
- if (!is_tmpfile && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
-
- if (is_tmpfile && zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
- txg_wait_flag_t wait_flags =
- spa_get_failmode(dmu_objset_spa(zfsvfs->z_os)) ==
- ZIO_FAILURE_MODE_CONTINUE ? TXG_WAIT_SUSPEND : 0;
- error = txg_wait_synced_flags(dmu_objset_pool(zfsvfs->z_os),
- txg, wait_flags);
- if (error != 0) {
- ASSERT3U(error, ==, ESHUTDOWN);
- error = SET_ERROR(EIO);
+ if (error == 0) {
+ if (!is_tmpfile && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
+
+ if (is_tmpfile && zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
+ txg_wait_flag_t wait_flags =
+ spa_get_failmode(dmu_objset_spa(zfsvfs->z_os)) ==
+ ZIO_FAILURE_MODE_CONTINUE ? TXG_WAIT_SUSPEND : 0;
+ error = txg_wait_synced_flags(
+ dmu_objset_pool(zfsvfs->z_os), txg, wait_flags);
+ if (error != 0) {
+ ASSERT3U(error, ==, ESHUTDOWN);
+ error = SET_ERROR(EIO);
+ }
}
}
@@ -3691,16 +3694,42 @@ top:
return (error);
}
-static void
-zfs_putpage_commit_cb(void *arg)
+/* Finish page writeback. */
+static inline void
+zfs_page_writeback_done(struct page *pp, int err)
{
- struct page *pp = arg;
+ if (err != 0) {
+ /*
+ * Writeback failed. Re-dirty the page. It was undirtied before
+ * the IO was issued (in zfs_putpage() or write_cache_pages()).
+ * The kernel only considers writeback for dirty pages; if we
+ * don't do this, it is eligible for eviction without being
+ * written out, which we definitely don't want.
+ */
+#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO
+ filemap_dirty_folio(page_mapping(pp), page_folio(pp));
+#else
+ __set_page_dirty_nobuffers(pp);
+#endif
+ }
ClearPageError(pp);
end_page_writeback(pp);
}
/*
+ * ZIL callback for page writeback. Passes to zfs_log_write() in zfs_putpage()
+ * for syncing writes. Called when the ZIL itx has been written to the log or
+ * the whole txg syncs, or if the ZIL crashes or the pool suspends. Any failure
+ * is passed as `err`.
+ */
+static void
+zfs_putpage_commit_cb(void *arg, int err)
+{
+ zfs_page_writeback_done(arg, err);
+}
+
+/*
* Push a page out to disk, once the page is on stable storage the
* registered commit callback will be run as notification of completion.
*
@@ -3853,16 +3882,15 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
err = dmu_tx_assign(tx, DMU_TX_WAIT);
if (err != 0) {
dmu_tx_abort(tx);
-#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO
- filemap_dirty_folio(page_mapping(pp), page_folio(pp));
-#else
- __set_page_dirty_nobuffers(pp);
-#endif
- ClearPageError(pp);
- end_page_writeback(pp);
+ zfs_page_writeback_done(pp, err);
zfs_rangelock_exit(lr);
zfs_exit(zfsvfs, FTAG);
- return (err);
+
+ /*
+ * Don't return error for an async writeback; we've re-dirtied
+ * the page so it will be tried again some other time.
+ */
+ return (for_sync ? err : 0);
}
va = kmap(pp);
@@ -3916,7 +3944,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
* ALL, zfs_putpage should do it.
*
* Summary:
- * for_sync: 0=unlock immediately; 1 unlock once on disk
+ * for_sync: 0=unlock immediately; 1=unlock once on disk
* sync_mode: NONE=caller will commit; ALL=we will commit
*/
boolean_t need_commit = (wbc->sync_mode != WB_SYNC_NONE);
@@ -3931,16 +3959,24 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
B_FALSE, for_sync ? zfs_putpage_commit_cb : NULL, pp);
if (!for_sync) {
- ClearPageError(pp);
- end_page_writeback(pp);
+ /*
+ * Async writeback is logged and written to the DMU, so page
+ * can now be unlocked.
+ */
+ zfs_page_writeback_done(pp, 0);
}
dmu_tx_commit(tx);
zfs_rangelock_exit(lr);
- if (need_commit)
- zil_commit(zfsvfs->z_log, zp->z_id);
+ if (need_commit) {
+ err = zil_commit_flags(zfsvfs->z_log, zp->z_id, ZIL_COMMIT_NOW);
+ if (err != 0) {
+ zfs_exit(zfsvfs, FTAG);
+ return (err);
+ }
+ }
dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, pglen);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode_os.c
index 7683eeb3cf9f..bcaabeb32b8a 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode_os.c
@@ -144,9 +144,9 @@ zfs_znode_cache_destructor(void *buf, void *arg)
rw_destroy(&zp->z_xattr_lock);
zfs_rangelock_fini(&zp->z_rangelock);
- ASSERT3P(zp->z_dirlocks, ==, NULL);
- ASSERT3P(zp->z_acl_cached, ==, NULL);
- ASSERT3P(zp->z_xattr_cached, ==, NULL);
+ ASSERT0P(zp->z_dirlocks);
+ ASSERT0P(zp->z_acl_cached);
+ ASSERT0P(zp->z_xattr_cached);
}
static int
@@ -178,13 +178,13 @@ zfs_znode_init(void)
* backed by kmalloc() when on the Linux slab in order that any
* wait_on_bit() operations on the related inode operate properly.
*/
- ASSERT(znode_cache == NULL);
+ ASSERT0P(znode_cache);
znode_cache = kmem_cache_create("zfs_znode_cache",
sizeof (znode_t), 0, zfs_znode_cache_constructor,
zfs_znode_cache_destructor, NULL, NULL, NULL,
KMC_SLAB | KMC_RECLAIMABLE);
- ASSERT(znode_hold_cache == NULL);
+ ASSERT0P(znode_hold_cache);
znode_hold_cache = kmem_cache_create("zfs_znode_hold_cache",
sizeof (znode_hold_t), 0, zfs_znode_hold_cache_constructor,
zfs_znode_hold_cache_destructor, NULL, NULL, NULL, 0);
@@ -327,10 +327,10 @@ zfs_znode_sa_init(zfsvfs_t *zfsvfs, znode_t *zp,
mutex_enter(&zp->z_lock);
- ASSERT(zp->z_sa_hdl == NULL);
- ASSERT(zp->z_acl_cached == NULL);
+ ASSERT0P(zp->z_sa_hdl);
+ ASSERT0P(zp->z_acl_cached);
if (sa_hdl == NULL) {
- VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, zp,
+ VERIFY0(sa_handle_get_from_db(zfsvfs->z_os, db, zp,
SA_HDL_SHARED, &zp->z_sa_hdl));
} else {
zp->z_sa_hdl = sa_hdl;
@@ -530,9 +530,9 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
return (NULL);
zp = ITOZ(ip);
- ASSERT(zp->z_dirlocks == NULL);
- ASSERT3P(zp->z_acl_cached, ==, NULL);
- ASSERT3P(zp->z_xattr_cached, ==, NULL);
+ ASSERT0P(zp->z_dirlocks);
+ ASSERT0P(zp->z_acl_cached);
+ ASSERT0P(zp->z_xattr_cached);
zp->z_unlinked = B_FALSE;
zp->z_atime_dirty = B_FALSE;
zp->z_is_ctldir = B_FALSE;
@@ -611,7 +611,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
* processing so do not hash unlinked znodes.
*/
if (links > 0)
- VERIFY3S(insert_inode_locked(ip), ==, 0);
+ VERIFY0(insert_inode_locked(ip));
mutex_enter(&zfsvfs->z_znodes_lock);
list_insert_tail(&zfsvfs->z_all_znodes, zp);
@@ -811,7 +811,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
}
/* Now add in all of the "SA" attributes */
- VERIFY(0 == sa_handle_get_from_db(zfsvfs->z_os, db, NULL, SA_HDL_SHARED,
+ VERIFY0(sa_handle_get_from_db(zfsvfs->z_os, db, NULL, SA_HDL_SHARED,
&sa_hdl));
/*
@@ -901,7 +901,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
acl_ids->z_fuid, acl_ids->z_fgid);
}
- VERIFY(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx) == 0);
+ VERIFY0(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx));
if (!(flag & IS_ROOT_NODE)) {
/*
@@ -1200,7 +1200,7 @@ zfs_rezget(znode_t *zp)
}
rw_exit(&zp->z_xattr_lock);
- ASSERT(zp->z_sa_hdl == NULL);
+ ASSERT0P(zp->z_sa_hdl);
err = sa_buf_hold(zfsvfs->z_os, obj_num, NULL, &db);
if (err) {
zfs_znode_hold_exit(zfsvfs, zh);
@@ -1314,9 +1314,9 @@ zfs_znode_delete(znode_t *zp, dmu_tx_t *tx)
zh = zfs_znode_hold_enter(zfsvfs, obj);
if (acl_obj) {
VERIFY(!zp->z_is_sa);
- VERIFY(0 == dmu_object_free(os, acl_obj, tx));
+ VERIFY0(dmu_object_free(os, acl_obj, tx));
}
- VERIFY(0 == dmu_object_free(os, obj, tx));
+ VERIFY0(dmu_object_free(os, obj, tx));
zfs_znode_dmu_fini(zp);
zfs_znode_hold_exit(zfsvfs, zh);
}
@@ -1536,7 +1536,7 @@ zfs_extend(znode_t *zp, uint64_t end)
zp->z_size = end;
- VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(ZTOZSB(zp)),
+ VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(ZTOZSB(zp)),
&zp->z_size, sizeof (zp->z_size), tx));
zfs_rangelock_exit(lr);
@@ -1726,7 +1726,7 @@ zfs_trunc(znode_t *zp, uint64_t end)
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs),
NULL, &zp->z_pflags, 8);
}
- VERIFY(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx) == 0);
+ VERIFY0(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx));
dmu_tx_commit(tx);
zfs_rangelock_exit(lr);
@@ -1793,7 +1793,7 @@ log:
NULL, &zp->z_pflags, 8);
zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime);
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len);
@@ -1840,7 +1840,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
moid = MASTER_NODE_OBJ;
error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE,
DMU_OT_NONE, 0, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
/*
* Set starting attributes.
@@ -1853,7 +1853,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
const char *name;
ASSERT(nvpair_type(elem) == DATA_TYPE_UINT64);
- VERIFY(nvpair_value_uint64(elem, &val) == 0);
+ VERIFY0(nvpair_value_uint64(elem, &val));
name = nvpair_name(elem);
if (strcmp(name, zfs_prop_to_name(ZFS_PROP_VERSION)) == 0) {
if (val < version)
@@ -1861,7 +1861,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
} else {
error = zap_update(os, moid, name, 8, 1, &val, tx);
}
- ASSERT(error == 0);
+ ASSERT0(error);
if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0)
norm = val;
else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0)
@@ -1869,7 +1869,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
}
ASSERT(version != 0);
error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
/*
* Create zap object used for SA attribute registration
@@ -1879,7 +1879,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE,
DMU_OT_NONE, 0, tx);
error = zap_add(os, moid, ZFS_SA_ATTRS, 8, 1, &sa_obj, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
} else {
sa_obj = 0;
}
@@ -1889,7 +1889,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
obj = zap_create(os, DMU_OT_UNLINKED_SET, DMU_OT_NONE, 0, tx);
error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &obj, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
/*
* Create root znode. Create minimal znode/inode/zfsvfs/sb
@@ -1922,7 +1922,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
&zfsvfs->z_attr_table);
- ASSERT(error == 0);
+ ASSERT0(error);
/*
* Fold case on file systems that are always or sometimes case
@@ -1946,12 +1946,12 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
mutex_init(&zfsvfs->z_hold_locks[i], NULL, MUTEX_DEFAULT, NULL);
}
- VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
+ VERIFY0(zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
cr, NULL, &acl_ids, zfs_init_idmap));
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
ASSERT3P(zp, ==, rootzp);
error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
zfs_acl_ids_free(&acl_ids);
atomic_set(&ZTOI(rootzp)->i_count, 0);
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 ef7bd7352084..d07317b0d910 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2011, Lawrence Livermore National Security, LLC.
* Copyright (c) 2015 by Chunwei Chen. All rights reserved.
+ * Copyright (c) 2025, Klara, Inc.
*/
@@ -106,6 +107,10 @@ zpl_iterate(struct file *filp, struct dir_context *ctx)
return (error);
}
+static inline int
+zpl_write_cache_pages(struct address_space *mapping,
+ struct writeback_control *wbc, void *data);
+
static int
zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
{
@@ -115,9 +120,38 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
int error;
fstrans_cookie_t cookie;
- error = filemap_write_and_wait_range(inode->i_mapping, start, end);
- if (error)
- return (error);
+ /*
+ * Force dirty pages in the range out to the DMU and the log, ready
+ * for zil_commit() to write down.
+ *
+ * We call write_cache_pages() directly to ensure that zpl_putpage() is
+ * called with the flags we need. We need WB_SYNC_NONE to avoid a call
+ * to zil_commit() (since we're doing this as a kind of pre-sync); but
+ * we do need for_sync so that the pages remain in writeback until
+ * they're on disk, and so that we get an error if the DMU write fails.
+ */
+ if (filemap_range_has_page(inode->i_mapping, start, end)) {
+ int for_sync = 1;
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_NONE,
+ .nr_to_write = LONG_MAX,
+ .range_start = start,
+ .range_end = end,
+ };
+ error =
+ zpl_write_cache_pages(inode->i_mapping, &wbc, &for_sync);
+ if (error != 0) {
+ /*
+ * Unclear what state things are in. zfs_putpage() will
+ * ensure the pages remain dirty if they haven't been
+ * written down to the DMU, but because there may be
+ * nothing logged, we can't assume that zfs_sync() ->
+ * zil_commit() will give us a useful error. It's
+ * safest if we just error out here.
+ */
+ return (error);
+ }
+ }
crhold(cr);
cookie = spl_fstrans_mark();
@@ -494,11 +528,30 @@ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
if (sync_mode != wbc->sync_mode) {
if ((result = zpl_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
return (result);
- if (zfsvfs->z_log != NULL)
- zil_commit(zfsvfs->z_log, zp->z_id);
+
+ if (zfsvfs->z_log != NULL) {
+ /*
+ * We don't want to block here if the pool suspends,
+ * because this is not a syncing op by itself, but
+ * might be part of one that the caller will
+ * coordinate.
+ */
+ result = -zil_commit_flags(zfsvfs->z_log, zp->z_id,
+ ZIL_COMMIT_NOW);
+ }
+
zpl_exit(zfsvfs, FTAG);
/*
+ * If zil_commit_flags() failed, it's unclear what state things
+ * are currently in. putpage() has written back out what it can
+ * to the DMU, but it may not be on disk. We have little choice
+ * but to escape.
+ */
+ if (result != 0)
+ return (result);
+
+ /*
* We need to call write_cache_pages() again (we can't just
* return after the commit) because the previous call in
* non-SYNC mode does not guarantee that we got all the dirty
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c
index f9f6406f8b47..f97662d052c7 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c
@@ -247,7 +247,7 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
* and fifos, but we want to know if this behavior ever changes.
*/
if (S_ISSOCK(mode) || S_ISFIFO(mode))
- ASSERT(rdev == 0);
+ ASSERT0(rdev);
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
index 94dcdd0b887d..53819628627d 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
@@ -49,7 +49,7 @@ zpl_inode_alloc(struct super_block *sb)
static void
zpl_inode_free(struct inode *ip)
{
- ASSERT(atomic_read(&ip->i_count) == 0);
+ ASSERT0(atomic_read(&ip->i_count));
zfs_inode_free(ip);
}
#endif
@@ -57,7 +57,7 @@ zpl_inode_free(struct inode *ip)
static void
zpl_inode_destroy(struct inode *ip)
{
- ASSERT(atomic_read(&ip->i_count) == 0);
+ ASSERT0(atomic_read(&ip->i_count));
zfs_inode_destroy(ip);
}
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c
index a098197e7448..d93282db815a 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c
@@ -1494,7 +1494,7 @@ zpl_posix_acl_free(void *arg)
acl_rel_head = NULL;
if (cmpxchg(&acl_rel_tail, &a->next,
&acl_rel_head) == &a->next) {
- ASSERT3P(a->next, ==, NULL);
+ ASSERT0P(a->next);
a->next = freelist;
freelist = a;
break;
@@ -1544,7 +1544,7 @@ zpl_posix_acl_release_impl(struct posix_acl *acl)
a->time = ddi_get_lbolt();
/* atomically points tail to us and get the previous tail */
prev = xchg(&acl_rel_tail, &a->next);
- ASSERT3P(*prev, ==, NULL);
+ ASSERT0P(*prev);
*prev = a;
/* if it was empty before, schedule the free task */
if (prev == &acl_rel_head)
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
index a7431cc4da9d..a73acdad34ae 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -84,8 +84,9 @@ static unsigned int zvol_blk_mq_blocks_per_thread = 8;
static inline void
zvol_end_io(struct bio *bio, struct request *rq, int error)
{
+ ASSERT3U(error, >=, 0);
if (bio) {
- bio->bi_status = errno_to_bi_status(-error);
+ bio->bi_status = errno_to_bi_status(error);
bio_endio(bio);
} else {
blk_mq_end_request(rq, errno_to_bi_status(error));
@@ -208,8 +209,14 @@ zvol_write(zv_request_t *zvr)
disk = zv->zv_zso->zvo_disk;
/* bio marked as FLUSH need to flush before write */
- if (io_is_flush(bio, rq))
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ if (io_is_flush(bio, rq)) {
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ if (error != 0) {
+ rw_exit(&zv->zv_suspend_lock);
+ zvol_end_io(bio, rq, -error);
+ return;
+ }
+ }
/* Some requests are just for flush and nothing else. */
if (io_size(bio, rq) == 0) {
@@ -273,8 +280,8 @@ zvol_write(zv_request_t *zvr)
dataset_kstats_update_write_kstats(&zv->zv_kstat, nwritten);
task_io_account_write(nwritten);
- if (sync)
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ if (error == 0 && sync)
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
rw_exit(&zv->zv_suspend_lock);
@@ -282,7 +289,7 @@ zvol_write(zv_request_t *zvr)
blk_generic_end_io_acct(q, disk, WRITE, bio, start_time);
}
- zvol_end_io(bio, rq, -error);
+ zvol_end_io(bio, rq, error);
}
static void
@@ -361,7 +368,7 @@ zvol_discard(zv_request_t *zvr)
zfs_rangelock_exit(lr);
if (error == 0 && sync)
- zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
unlock:
rw_exit(&zv->zv_suspend_lock);
@@ -371,7 +378,7 @@ unlock:
start_time);
}
- zvol_end_io(bio, rq, -error);
+ zvol_end_io(bio, rq, error);
}
static void
@@ -449,7 +456,7 @@ zvol_read(zv_request_t *zvr)
blk_generic_end_io_acct(q, disk, READ, bio, start_time);
}
- zvol_end_io(bio, rq, -error);
+ zvol_end_io(bio, rq, error);
}
static void
@@ -480,7 +487,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
int rw = io_data_dir(bio, rq);
if (unlikely(zv->zv_flags & ZVOL_REMOVING)) {
- zvol_end_io(bio, rq, -SET_ERROR(ENXIO));
+ zvol_end_io(bio, rq, SET_ERROR(ENXIO));
goto out;
}
@@ -499,7 +506,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
(long long unsigned)offset,
(long unsigned)size);
- zvol_end_io(bio, rq, -SET_ERROR(EIO));
+ zvol_end_io(bio, rq, SET_ERROR(EIO));
goto out;
}
@@ -512,8 +519,8 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
#ifdef HAVE_BLK_MQ_RQ_HCTX
blk_mq_hw_queue = rq->mq_hctx->queue_num;
#else
- blk_mq_hw_queue =
- rq->q->queue_hw_ctx[rq->q->mq_map[rq->cpu]]->queue_num;
+ blk_mq_hw_queue = rq->q->queue_hw_ctx[
+ rq->q->mq_map[raw_smp_processor_id()]]->queue_num;
#endif
taskq_hash = cityhash3((uintptr_t)zv, offset >> ZVOL_TASKQ_OFFSET_SHIFT,
blk_mq_hw_queue);
@@ -521,7 +528,7 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
if (rw == WRITE) {
if (unlikely(zv->zv_flags & ZVOL_RDONLY)) {
- zvol_end_io(bio, rq, -SET_ERROR(EROFS));
+ zvol_end_io(bio, rq, SET_ERROR(EROFS));
goto out;
}
@@ -886,16 +893,18 @@ zvol_ioctl(struct block_device *bdev, fmode_t mode,
case BLKZNAME:
mutex_enter(&zv->zv_state_lock);
- error = copy_to_user((void *)arg, zv->zv_name, MAXNAMELEN);
+ error = -copy_to_user((void *)arg, zv->zv_name, MAXNAMELEN);
mutex_exit(&zv->zv_state_lock);
+ if (error)
+ error = SET_ERROR(error);
break;
default:
- error = -ENOTTY;
+ error = SET_ERROR(ENOTTY);
break;
}
- return (SET_ERROR(error));
+ return (-error);
}
#ifdef CONFIG_COMPAT
@@ -1426,7 +1435,7 @@ zvol_os_free(zvol_state_t *zv)
ASSERT(!RW_LOCK_HELD(&zv->zv_suspend_lock));
ASSERT(!MUTEX_HELD(&zv->zv_state_lock));
ASSERT0(zv->zv_open_count);
- ASSERT3P(zv->zv_zso->zvo_disk->private_data, ==, NULL);
+ ASSERT0P(zv->zv_zso->zvo_disk->private_data);
rw_destroy(&zv->zv_suspend_lock);
zfs_rangelock_fini(&zv->zv_rangelock);
@@ -1474,7 +1483,9 @@ __zvol_os_add_disk(struct gendisk *disk)
{
int error = 0;
#ifdef HAVE_ADD_DISK_RET
- error = add_disk(disk);
+ error = -add_disk(disk);
+ if (error)
+ error = SET_ERROR(error);
#else
add_disk(disk);
#endif
@@ -1649,11 +1660,11 @@ zvol_os_create_minor(const char *name)
blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, zv->zv_zso->zvo_queue);
#endif
- ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL);
+ ASSERT0P(zv->zv_kstat.dk_kstats);
error = dataset_kstats_create(&zv->zv_kstat, zv->zv_objset);
if (error)
goto out_dmu_objset_disown;
- ASSERT3P(zv->zv_zilog, ==, NULL);
+ ASSERT0P(zv->zv_zilog);
zv->zv_zilog = zil_open(os, zvol_get_data, &zv->zv_kstat.dk_zil_sums);
if (spa_writeable(dmu_objset_spa(os))) {
if (zil_replay_disable)
@@ -1759,10 +1770,10 @@ zvol_init(void)
return (error);
}
- error = register_blkdev(zvol_major, ZVOL_DRIVER);
+ error = -register_blkdev(zvol_major, ZVOL_DRIVER);
if (error) {
printk(KERN_INFO "ZFS: register_blkdev() failed %d\n", error);
- return (error);
+ return (SET_ERROR(error));
}
if (zvol_blk_mq_queue_depth == 0) {
diff --git a/sys/contrib/openzfs/module/zfs/abd.c b/sys/contrib/openzfs/module/zfs/abd.c
index 826928e67350..bf9b13c30509 100644
--- a/sys/contrib/openzfs/module/zfs/abd.c
+++ b/sys/contrib/openzfs/module/zfs/abd.c
@@ -563,7 +563,7 @@ abd_get_offset_impl(abd_t *abd, abd_t *sabd, size_t off, size_t size)
left -= csize;
off = 0;
}
- ASSERT3U(left, ==, 0);
+ ASSERT0(left);
} else {
abd = abd_get_offset_scatter(abd, sabd, off, size);
}
diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c
index 3483be64ec57..df41e3b49204 100644
--- a/sys/contrib/openzfs/module/zfs/arc.c
+++ b/sys/contrib/openzfs/module/zfs/arc.c
@@ -2239,8 +2239,8 @@ arc_evictable_space_increment(arc_buf_hdr_t *hdr, arc_state_t *state)
ASSERT(HDR_HAS_L1HDR(hdr));
if (GHOST_STATE(state)) {
- ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_buf);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
(void) zfs_refcount_add_many(&state->arcs_esize[type],
HDR_GET_LSIZE(hdr), hdr);
@@ -2278,8 +2278,8 @@ arc_evictable_space_decrement(arc_buf_hdr_t *hdr, arc_state_t *state)
ASSERT(HDR_HAS_L1HDR(hdr));
if (GHOST_STATE(state)) {
- ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_buf);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
(void) zfs_refcount_remove_many(&state->arcs_esize[type],
HDR_GET_LSIZE(hdr), hdr);
@@ -2319,7 +2319,7 @@ add_reference(arc_buf_hdr_t *hdr, const void *tag)
if (!HDR_EMPTY(hdr) && !MUTEX_HELD(HDR_LOCK(hdr))) {
ASSERT(state == arc_anon);
ASSERT(zfs_refcount_is_zero(&hdr->b_l1hdr.b_refcnt));
- ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_buf);
}
if ((zfs_refcount_add(&hdr->b_l1hdr.b_refcnt, tag) == 1) &&
@@ -2503,7 +2503,7 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *hdr)
(void) zfs_refcount_add_many(
&new_state->arcs_size[type],
HDR_GET_LSIZE(hdr), hdr);
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
} else {
@@ -2547,7 +2547,7 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *hdr)
if (update_old && old_state != arc_l2c_only) {
ASSERT(HDR_HAS_L1HDR(hdr));
if (GHOST_STATE(old_state)) {
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
/*
@@ -2758,7 +2758,7 @@ arc_buf_alloc_impl(arc_buf_hdr_t *hdr, spa_t *spa, const zbookmark_phys_t *zb,
VERIFY(hdr->b_type == ARC_BUFC_DATA ||
hdr->b_type == ARC_BUFC_METADATA);
ASSERT3P(ret, !=, NULL);
- ASSERT3P(*ret, ==, NULL);
+ ASSERT0P(*ret);
IMPLY(encrypted, compressed);
buf = *ret = kmem_cache_alloc(buf_cache, KM_PUSHPAGE);
@@ -2982,7 +2982,7 @@ static void
arc_share_buf(arc_buf_hdr_t *hdr, arc_buf_t *buf)
{
ASSERT(arc_can_share(hdr, buf));
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!ARC_BUF_ENCRYPTED(buf));
ASSERT(HDR_EMPTY_OR_LOCKED(hdr));
@@ -3201,14 +3201,14 @@ arc_hdr_alloc_abd(arc_buf_hdr_t *hdr, int alloc_flags)
if (alloc_rdata) {
size = HDR_GET_PSIZE(hdr);
- ASSERT3P(hdr->b_crypt_hdr.b_rabd, ==, NULL);
+ ASSERT0P(hdr->b_crypt_hdr.b_rabd);
hdr->b_crypt_hdr.b_rabd = arc_get_data_abd(hdr, size, hdr,
alloc_flags);
ASSERT3P(hdr->b_crypt_hdr.b_rabd, !=, NULL);
ARCSTAT_INCR(arcstat_raw_size, size);
} else {
size = arc_hdr_size(hdr);
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
hdr->b_l1hdr.b_pabd = arc_get_data_abd(hdr, size, hdr,
alloc_flags);
ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL);
@@ -3290,7 +3290,7 @@ arc_hdr_alloc(uint64_t spa, int32_t psize, int32_t lsize,
ASSERT(HDR_EMPTY(hdr));
#ifdef ZFS_DEBUG
- ASSERT3P(hdr->b_l1hdr.b_freeze_cksum, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_freeze_cksum);
#endif
HDR_SET_PSIZE(hdr, psize);
HDR_SET_LSIZE(hdr, lsize);
@@ -3351,12 +3351,12 @@ arc_hdr_realloc(arc_buf_hdr_t *hdr, kmem_cache_t *old, kmem_cache_t *new)
nhdr->b_l1hdr.b_state = arc_l2c_only;
/* Verify previous threads set to NULL before freeing */
- ASSERT3P(nhdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(nhdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
} else {
- ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_buf);
#ifdef ZFS_DEBUG
- ASSERT3P(hdr->b_l1hdr.b_freeze_cksum, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_freeze_cksum);
#endif
/*
@@ -3375,7 +3375,7 @@ arc_hdr_realloc(arc_buf_hdr_t *hdr, kmem_cache_t *old, kmem_cache_t *new)
* might try to be accessed, even though it was removed.
*/
VERIFY(!HDR_L2_WRITING(hdr));
- VERIFY3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ VERIFY0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
arc_hdr_clear_flags(nhdr, ARC_FLAG_HAS_L1HDR);
@@ -3698,12 +3698,12 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
arc_hdr_free_abd(hdr, B_TRUE);
}
- ASSERT3P(hdr->b_hash_next, ==, NULL);
+ ASSERT0P(hdr->b_hash_next);
if (HDR_HAS_L1HDR(hdr)) {
ASSERT(!multilist_link_active(&hdr->b_l1hdr.b_arc_node));
- ASSERT3P(hdr->b_l1hdr.b_acb, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_acb);
#ifdef ZFS_DEBUG
- ASSERT3P(hdr->b_l1hdr.b_freeze_cksum, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_freeze_cksum);
#endif
kmem_cache_free(hdr_full_cache, hdr);
} else {
@@ -3771,7 +3771,7 @@ arc_evict_hdr(arc_buf_hdr_t *hdr, uint64_t *real_evicted)
ASSERT(MUTEX_HELD(HDR_LOCK(hdr)));
ASSERT(HDR_HAS_L1HDR(hdr));
ASSERT(!HDR_IO_IN_PROGRESS(hdr));
- ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_buf);
ASSERT0(zfs_refcount_count(&hdr->b_l1hdr.b_refcnt));
*real_evicted = 0;
@@ -3796,7 +3796,7 @@ arc_evict_hdr(arc_buf_hdr_t *hdr, uint64_t *real_evicted)
DTRACE_PROBE1(arc__delete, arc_buf_hdr_t *, hdr);
if (HDR_HAS_L2HDR(hdr)) {
- ASSERT(hdr->b_l1hdr.b_pabd == NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
/*
* This buffer is cached on the 2nd Level ARC;
@@ -5554,7 +5554,7 @@ static void
arc_hdr_verify(arc_buf_hdr_t *hdr, blkptr_t *bp)
{
if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp)) {
- ASSERT3U(HDR_GET_PSIZE(hdr), ==, 0);
+ ASSERT0(HDR_GET_PSIZE(hdr));
ASSERT3U(arc_hdr_get_compress(hdr), ==, ZIO_COMPRESS_OFF);
} else {
if (HDR_COMPRESSION_ENABLED(hdr)) {
@@ -6132,14 +6132,14 @@ top:
}
if (GHOST_STATE(hdr->b_l1hdr.b_state)) {
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
ASSERT(!HDR_IO_IN_PROGRESS(hdr));
ASSERT0(zfs_refcount_count(
&hdr->b_l1hdr.b_refcnt));
- ASSERT3P(hdr->b_l1hdr.b_buf, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_buf);
#ifdef ZFS_DEBUG
- ASSERT3P(hdr->b_l1hdr.b_freeze_cksum, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_freeze_cksum);
#endif
} else if (HDR_IO_IN_PROGRESS(hdr)) {
/*
@@ -6233,7 +6233,7 @@ top:
acb->acb_nobuf = no_buf;
acb->acb_zb = *zb;
- ASSERT3P(hdr->b_l1hdr.b_acb, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_acb);
hdr->b_l1hdr.b_acb = acb;
if (HDR_HAS_L2HDR(hdr) &&
@@ -6717,7 +6717,7 @@ arc_release(arc_buf_t *buf, const void *tag)
nhdr = arc_hdr_alloc(spa, psize, lsize, protected,
compress, hdr->b_complevel, type);
- ASSERT3P(nhdr->b_l1hdr.b_buf, ==, NULL);
+ ASSERT0P(nhdr->b_l1hdr.b_buf);
ASSERT0(zfs_refcount_count(&nhdr->b_l1hdr.b_refcnt));
VERIFY3U(nhdr->b_type, ==, type);
ASSERT(!HDR_SHARED_DATA(nhdr));
@@ -6804,7 +6804,7 @@ arc_write_ready(zio_t *zio)
if (HDR_HAS_RABD(hdr))
arc_hdr_free_abd(hdr, B_TRUE);
}
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
ASSERT(!HDR_HAS_RABD(hdr));
ASSERT(!HDR_SHARED_DATA(hdr));
ASSERT(!arc_buf_is_shared(buf));
@@ -6948,7 +6948,7 @@ arc_write_done(zio_t *zio)
arc_buf_t *buf = callback->awcb_buf;
arc_buf_hdr_t *hdr = buf->b_hdr;
- ASSERT3P(hdr->b_l1hdr.b_acb, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_acb);
if (zio->io_error == 0) {
arc_hdr_verify(hdr, zio->io_bp);
@@ -6973,7 +6973,7 @@ arc_write_done(zio_t *zio)
arc_buf_hdr_t *exists;
kmutex_t *hash_lock;
- ASSERT3U(zio->io_error, ==, 0);
+ ASSERT0(zio->io_error);
arc_cksum_verify(buf);
@@ -6994,7 +6994,7 @@ arc_write_done(zio_t *zio)
arc_hdr_destroy(exists);
mutex_exit(hash_lock);
exists = buf_hash_insert(hdr, &hash_lock);
- ASSERT3P(exists, ==, NULL);
+ ASSERT0P(exists);
} else if (zio->io_flags & ZIO_FLAG_NOPWRITE) {
/* nopwrite */
ASSERT(zio->io_prop.zp_nopwrite);
@@ -7007,7 +7007,7 @@ arc_write_done(zio_t *zio)
ASSERT(ARC_BUF_LAST(hdr->b_l1hdr.b_buf));
ASSERT(hdr->b_l1hdr.b_state == arc_anon);
ASSERT(BP_GET_DEDUP(zio->io_bp));
- ASSERT(BP_GET_LEVEL(zio->io_bp) == 0);
+ ASSERT0(BP_GET_LEVEL(zio->io_bp));
}
}
arc_hdr_clear_flags(hdr, ARC_FLAG_IO_IN_PROGRESS);
@@ -7044,7 +7044,7 @@ arc_write(zio_t *pio, spa_t *spa, uint64_t txg,
ASSERT3P(done, !=, NULL);
ASSERT(!HDR_IO_ERROR(hdr));
ASSERT(!HDR_IO_IN_PROGRESS(hdr));
- ASSERT3P(hdr->b_l1hdr.b_acb, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_acb);
ASSERT3P(hdr->b_l1hdr.b_buf, !=, NULL);
if (uncached)
arc_hdr_set_flags(hdr, ARC_FLAG_UNCACHED);
@@ -7113,7 +7113,7 @@ arc_write(zio_t *pio, spa_t *spa, uint64_t txg,
arc_hdr_set_compress(hdr, ZIO_COMPRESS_OFF);
ASSERT(!arc_buf_is_shared(buf));
- ASSERT3P(hdr->b_l1hdr.b_pabd, ==, NULL);
+ ASSERT0P(hdr->b_l1hdr.b_pabd);
zio = zio_write(pio, spa, txg, bp,
abd_get_from_buf(buf->b_data, HDR_GET_LSIZE(hdr)),
diff --git a/sys/contrib/openzfs/module/zfs/bpobj.c b/sys/contrib/openzfs/module/zfs/bpobj.c
index 0a8a077edf63..ea9fbd036c6e 100644
--- a/sys/contrib/openzfs/module/zfs/bpobj.c
+++ b/sys/contrib/openzfs/module/zfs/bpobj.c
@@ -160,8 +160,8 @@ bpobj_open(bpobj_t *bpo, objset_t *os, uint64_t object)
memset(bpo, 0, sizeof (*bpo));
mutex_init(&bpo->bpo_lock, NULL, MUTEX_DEFAULT, NULL);
- ASSERT(bpo->bpo_dbuf == NULL);
- ASSERT(bpo->bpo_phys == NULL);
+ ASSERT0P(bpo->bpo_dbuf);
+ ASSERT0P(bpo->bpo_phys);
ASSERT(object != 0);
ASSERT3U(doi.doi_type, ==, DMU_OT_BPOBJ);
ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_BPOBJ_HDR);
@@ -478,7 +478,7 @@ bpobj_iterate_impl(bpobj_t *initial_bpo, bpobj_itor_t func, void *arg,
* We have unprocessed subobjs. Process the next one.
*/
ASSERT(bpo->bpo_havecomp);
- ASSERT3P(bpobj_size, ==, NULL);
+ ASSERT0P(bpobj_size);
/* Add the last subobj to stack. */
int64_t i = bpi->bpi_unprocessed_subobjs - 1;
diff --git a/sys/contrib/openzfs/module/zfs/btree.c b/sys/contrib/openzfs/module/zfs/btree.c
index aa282f711bc3..725b96a3b2c7 100644
--- a/sys/contrib/openzfs/module/zfs/btree.c
+++ b/sys/contrib/openzfs/module/zfs/btree.c
@@ -1110,7 +1110,7 @@ zfs_btree_add_idx(zfs_btree_t *tree, const void *value,
if (where->bti_node == NULL) {
ASSERT3U(tree->bt_num_elems, ==, 1);
ASSERT3S(tree->bt_height, ==, -1);
- ASSERT3P(tree->bt_root, ==, NULL);
+ ASSERT0P(tree->bt_root);
ASSERT0(where->bti_offset);
tree->bt_num_nodes++;
@@ -1947,7 +1947,7 @@ void
zfs_btree_destroy(zfs_btree_t *tree)
{
ASSERT0(tree->bt_num_elems);
- ASSERT3P(tree->bt_root, ==, NULL);
+ ASSERT0P(tree->bt_root);
}
/* Verify that every child of this node has the correct parent pointer. */
@@ -1969,10 +1969,10 @@ static void
zfs_btree_verify_pointers(zfs_btree_t *tree)
{
if (tree->bt_height == -1) {
- VERIFY3P(tree->bt_root, ==, NULL);
+ VERIFY0P(tree->bt_root);
return;
}
- VERIFY3P(tree->bt_root->bth_parent, ==, NULL);
+ VERIFY0P(tree->bt_root->bth_parent);
zfs_btree_verify_pointers_helper(tree, tree->bt_root);
}
diff --git a/sys/contrib/openzfs/module/zfs/dataset_kstats.c b/sys/contrib/openzfs/module/zfs/dataset_kstats.c
index d3baabd6169f..e5abcd2044cf 100644
--- a/sys/contrib/openzfs/module/zfs/dataset_kstats.c
+++ b/sys/contrib/openzfs/module/zfs/dataset_kstats.c
@@ -44,6 +44,7 @@ static dataset_kstat_values_t empty_dataset_kstats = {
{ "zil_commit_error_count", KSTAT_DATA_UINT64 },
{ "zil_commit_stall_count", KSTAT_DATA_UINT64 },
{ "zil_commit_suspend_count", KSTAT_DATA_UINT64 },
+ { "zil_commit_crash_count", KSTAT_DATA_UINT64 },
{ "zil_itx_count", KSTAT_DATA_UINT64 },
{ "zil_itx_indirect_count", KSTAT_DATA_UINT64 },
{ "zil_itx_indirect_bytes", KSTAT_DATA_UINT64 },
diff --git a/sys/contrib/openzfs/module/zfs/dbuf.c b/sys/contrib/openzfs/module/zfs/dbuf.c
index 432c99cec960..3d0f88b36336 100644
--- a/sys/contrib/openzfs/module/zfs/dbuf.c
+++ b/sys/contrib/openzfs/module/zfs/dbuf.c
@@ -523,7 +523,7 @@ dbuf_verify_user(dmu_buf_impl_t *db, dbvu_verify_type_t verify_type)
return;
/* Only data blocks support the attachment of user data. */
- ASSERT(db->db_level == 0);
+ ASSERT0(db->db_level);
/* Clients must resolve a dbuf before attaching user data. */
ASSERT(db->db.db_data != NULL);
@@ -1128,8 +1128,8 @@ dbuf_verify(dmu_buf_impl_t *db)
DB_DNODE_ENTER(db);
dn = DB_DNODE(db);
if (dn == NULL) {
- ASSERT(db->db_parent == NULL);
- ASSERT(db->db_blkptr == NULL);
+ ASSERT0P(db->db_parent);
+ ASSERT0P(db->db_blkptr);
} else {
ASSERT3U(db->db.db_object, ==, dn->dn_object);
ASSERT3P(db->db_objset, ==, dn->dn_objset);
@@ -1180,7 +1180,7 @@ dbuf_verify(dmu_buf_impl_t *db)
/* db is pointed to by the dnode */
/* ASSERT3U(db->db_blkid, <, dn->dn_nblkptr); */
if (DMU_OBJECT_IS_SPECIAL(db->db.db_object))
- ASSERT(db->db_parent == NULL);
+ ASSERT0P(db->db_parent);
else
ASSERT(db->db_parent != NULL);
if (db->db_blkid != DMU_SPILL_BLKID)
@@ -1219,7 +1219,7 @@ dbuf_verify(dmu_buf_impl_t *db)
int i;
for (i = 0; i < db->db.db_size >> 3; i++) {
- ASSERT(buf[i] == 0);
+ ASSERT0(buf[i]);
}
} else {
blkptr_t *bps = db->db.db_data;
@@ -1259,7 +1259,7 @@ dbuf_clear_data(dmu_buf_impl_t *db)
{
ASSERT(MUTEX_HELD(&db->db_mtx));
dbuf_evict_user(db);
- ASSERT3P(db->db_buf, ==, NULL);
+ ASSERT0P(db->db_buf);
db->db.db_data = NULL;
if (db->db_state != DB_NOFILL) {
db->db_state = DB_UNCACHED;
@@ -1384,13 +1384,13 @@ dbuf_read_done(zio_t *zio, const zbookmark_phys_t *zb, const blkptr_t *bp,
* All reads are synchronous, so we must have a hold on the dbuf
*/
ASSERT(zfs_refcount_count(&db->db_holds) > 0);
- ASSERT(db->db_buf == NULL);
- ASSERT(db->db.db_data == NULL);
+ ASSERT0P(db->db_buf);
+ ASSERT0P(db->db.db_data);
if (buf == NULL) {
/* i/o error */
ASSERT(zio == NULL || zio->io_error != 0);
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
- ASSERT3P(db->db_buf, ==, NULL);
+ ASSERT0P(db->db_buf);
db->db_state = DB_UNCACHED;
DTRACE_SET_STATE(db, "i/o error");
} else if (db->db_level == 0 && db->db_freed_in_flight) {
@@ -1584,7 +1584,7 @@ dbuf_read_impl(dmu_buf_impl_t *db, dnode_t *dn, zio_t *zio, dmu_flags_t flags,
ASSERT(!zfs_refcount_is_zero(&db->db_holds));
ASSERT(MUTEX_HELD(&db->db_mtx));
ASSERT(db->db_state == DB_UNCACHED || db->db_state == DB_NOFILL);
- ASSERT(db->db_buf == NULL);
+ ASSERT0P(db->db_buf);
ASSERT(db->db_parent == NULL ||
RW_LOCK_HELD(&db->db_parent->db_rwlock));
@@ -1682,7 +1682,7 @@ dbuf_fix_old_data(dmu_buf_impl_t *db, uint64_t txg)
ASSERT(MUTEX_HELD(&db->db_mtx));
ASSERT(db->db.db_data != NULL);
- ASSERT(db->db_level == 0);
+ ASSERT0(db->db_level);
ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT);
if (dr == NULL ||
@@ -1901,8 +1901,8 @@ dbuf_noread(dmu_buf_impl_t *db, dmu_flags_t flags)
while (db->db_state == DB_READ || db->db_state == DB_FILL)
cv_wait(&db->db_changed, &db->db_mtx);
if (db->db_state == DB_UNCACHED) {
- ASSERT(db->db_buf == NULL);
- ASSERT(db->db.db_data == NULL);
+ ASSERT0P(db->db_buf);
+ ASSERT0P(db->db.db_data);
dbuf_set_data(db, dbuf_alloc_arcbuf(db));
db->db_state = DB_FILL;
DTRACE_SET_STATE(db, "assigning filled buffer");
@@ -1929,7 +1929,7 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
* comes from dbuf_dirty() callers who must also hold a range lock.
*/
ASSERT(dr->dt.dl.dr_override_state != DR_IN_DMU_SYNC);
- ASSERT(db->db_level == 0);
+ ASSERT0(db->db_level);
if (db->db_blkid == DMU_BONUS_BLKID ||
dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN)
@@ -1994,7 +1994,7 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
mutex_enter(&dn->dn_dbufs_mtx);
db = avl_find(&dn->dn_dbufs, db_search, &where);
- ASSERT3P(db, ==, NULL);
+ ASSERT0P(db);
db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
@@ -2017,7 +2017,7 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
if (db->db_state == DB_UNCACHED ||
db->db_state == DB_NOFILL ||
db->db_state == DB_EVICTING) {
- ASSERT(db->db.db_data == NULL);
+ ASSERT0P(db->db.db_data);
mutex_exit(&db->db_mtx);
continue;
}
@@ -2896,8 +2896,8 @@ dmu_buf_will_clone_or_dio(dmu_buf_t *db_fake, dmu_tx_t *tx)
dbuf_clear_data(db);
}
- ASSERT3P(db->db_buf, ==, NULL);
- ASSERT3P(db->db.db_data, ==, NULL);
+ ASSERT0P(db->db_buf);
+ ASSERT0P(db->db.db_data);
db->db_state = DB_NOFILL;
DTRACE_SET_STATE(db,
@@ -2932,7 +2932,7 @@ dmu_buf_will_fill_flags(dmu_buf_t *db_fake, dmu_tx_t *tx, boolean_t canfail,
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
ASSERT(tx->tx_txg != 0);
- ASSERT(db->db_level == 0);
+ ASSERT0(db->db_level);
ASSERT(!zfs_refcount_is_zero(&db->db_holds));
ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT ||
@@ -3144,7 +3144,7 @@ dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx,
{
ASSERT(!zfs_refcount_is_zero(&db->db_holds));
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
- ASSERT(db->db_level == 0);
+ ASSERT0(db->db_level);
ASSERT3U(dbuf_is_metadata(db), ==, arc_is_metadata(buf));
ASSERT(buf != NULL);
ASSERT3U(arc_buf_lsize(buf), ==, db->db.db_size);
@@ -3209,7 +3209,7 @@ dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx,
VERIFY(!dbuf_undirty(db, tx));
db->db_state = DB_UNCACHED;
}
- ASSERT(db->db_buf == NULL);
+ ASSERT0P(db->db_buf);
dbuf_set_data(db, buf);
db->db_state = DB_FILL;
DTRACE_SET_STATE(db, "filling assigned arcbuf");
@@ -3269,7 +3269,7 @@ dbuf_destroy(dmu_buf_impl_t *db)
}
ASSERT(db->db_state == DB_UNCACHED || db->db_state == DB_NOFILL);
- ASSERT(db->db_data_pending == NULL);
+ ASSERT0P(db->db_data_pending);
ASSERT(list_is_empty(&db->db_dirty_records));
db->db_state = DB_EVICTING;
@@ -3321,11 +3321,11 @@ dbuf_destroy(dmu_buf_impl_t *db)
db->db_parent = NULL;
- ASSERT(db->db_buf == NULL);
- ASSERT(db->db.db_data == NULL);
- ASSERT(db->db_hash_next == NULL);
- ASSERT(db->db_blkptr == NULL);
- ASSERT(db->db_data_pending == NULL);
+ ASSERT0P(db->db_buf);
+ ASSERT0P(db->db.db_data);
+ ASSERT0P(db->db_hash_next);
+ ASSERT0P(db->db_blkptr);
+ ASSERT0P(db->db_data_pending);
ASSERT3U(db->db_caching_status, ==, DB_NO_CACHE);
ASSERT(!multilist_link_active(&db->db_cache_link));
@@ -3960,7 +3960,7 @@ dbuf_hold_impl(dnode_t *dn, uint8_t level, uint64_t blkid,
if (fail_uncached)
return (SET_ERROR(ENOENT));
- ASSERT3P(parent, ==, NULL);
+ ASSERT0P(parent);
err = dbuf_findbp(dn, level, blkid, fail_sparse, &parent, &bp);
if (fail_sparse) {
if (err == 0 && bp && BP_IS_HOLE(bp))
@@ -4064,7 +4064,7 @@ dbuf_create_bonus(dnode_t *dn)
{
ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock));
- ASSERT(dn->dn_bonus == NULL);
+ ASSERT0P(dn->dn_bonus);
dn->dn_bonus = dbuf_create(dn, 0, DMU_BONUS_BLKID, dn->dn_dbuf, NULL,
dbuf_hash(dn->dn_objset, dn->dn_object, 0, DMU_BONUS_BLKID));
dn->dn_bonus->db_pending_evict = FALSE;
@@ -4416,7 +4416,7 @@ dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db)
* inappropriate to hook it in (i.e., nlevels mismatch).
*/
ASSERT(db->db_blkid < dn->dn_phys->dn_nblkptr);
- ASSERT(db->db_parent == NULL);
+ ASSERT0P(db->db_parent);
db->db_parent = dn->dn_dbuf;
db->db_blkptr = &dn->dn_phys->dn_blkptr[db->db_blkid];
DBUF_VERIFY(db);
@@ -4477,7 +4477,7 @@ dbuf_prepare_encrypted_dnode_leaf(dbuf_dirty_record_t *dr)
ASSERT(MUTEX_HELD(&db->db_mtx));
ASSERT3U(db->db.db_object, ==, DMU_META_DNODE_OBJECT);
- ASSERT3U(db->db_level, ==, 0);
+ ASSERT0(db->db_level);
if (!db->db_objset->os_raw_receive && arc_is_encrypted(db->db_buf)) {
zbookmark_phys_t zb;
@@ -4588,7 +4588,7 @@ dbuf_sync_leaf_verify_bonus_dnode(dbuf_dirty_record_t *dr)
/* ensure that everything is zero after our data */
for (; datap_end < datap_max; datap_end++)
- ASSERT(*datap_end == 0);
+ ASSERT0(*datap_end);
#endif
}
@@ -4596,7 +4596,7 @@ static blkptr_t *
dbuf_lightweight_bp(dbuf_dirty_record_t *dr)
{
/* This must be a lightweight dirty record. */
- ASSERT3P(dr->dr_dbuf, ==, NULL);
+ ASSERT0P(dr->dr_dbuf);
dnode_t *dn = dr->dr_dnode;
if (dn->dn_phys->dn_nlevels == 1) {
@@ -4739,7 +4739,7 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
*/
if (db->db_state == DB_UNCACHED) {
/* This buffer has been freed since it was dirtied */
- ASSERT3P(db->db.db_data, ==, NULL);
+ ASSERT0P(db->db.db_data);
} else if (db->db_state == DB_FILL) {
/* This buffer was freed and is now being re-filled */
ASSERT(db->db.db_data != dr->dt.dl.dr_data);
@@ -4756,9 +4756,9 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
*/
dbuf_dirty_record_t *dr_head =
list_head(&db->db_dirty_records);
- ASSERT3P(db->db_buf, ==, NULL);
- ASSERT3P(db->db.db_data, ==, NULL);
- ASSERT3P(dr_head->dt.dl.dr_data, ==, NULL);
+ ASSERT0P(db->db_buf);
+ ASSERT0P(db->db.db_data);
+ ASSERT0P(dr_head->dt.dl.dr_data);
ASSERT3U(dr_head->dt.dl.dr_override_state, ==, DR_OVERRIDDEN);
} else {
ASSERT(db->db_state == DB_CACHED || db->db_state == DB_NOFILL);
diff --git a/sys/contrib/openzfs/module/zfs/ddt.c b/sys/contrib/openzfs/module/zfs/ddt.c
index e0b9fc3951ff..d6658375f810 100644
--- a/sys/contrib/openzfs/module/zfs/ddt.c
+++ b/sys/contrib/openzfs/module/zfs/ddt.c
@@ -397,7 +397,7 @@ ddt_object_create(ddt_t *ddt, ddt_type_t type, ddt_class_t class,
ddt_object_name(ddt, type, class, name);
- ASSERT3U(*objectp, ==, 0);
+ ASSERT0(*objectp);
VERIFY0(ddt_ops[type]->ddt_op_create(os, objectp, tx, prehash));
ASSERT3U(*objectp, !=, 0);
@@ -1011,7 +1011,7 @@ ddt_free(const ddt_t *ddt, ddt_entry_t *dde)
{
if (dde->dde_io != NULL) {
for (int p = 0; p < DDT_NPHYS(ddt); p++)
- ASSERT3P(dde->dde_io->dde_lead_zio[p], ==, NULL);
+ ASSERT0P(dde->dde_io->dde_lead_zio[p]);
if (dde->dde_io->dde_repair_abd != NULL)
abd_free(dde->dde_io->dde_repair_abd);
@@ -1421,7 +1421,7 @@ ddt_key_compare(const void *x1, const void *x2)
static void
ddt_create_dir(ddt_t *ddt, dmu_tx_t *tx)
{
- ASSERT3U(ddt->ddt_dir_object, ==, 0);
+ ASSERT0(ddt->ddt_dir_object);
ASSERT3U(ddt->ddt_version, ==, DDT_VERSION_FDT);
char name[DDT_NAMELEN];
@@ -2395,7 +2395,7 @@ ddt_sync(spa_t *spa, uint64_t txg)
* scan's root zio here so that we can wait for any scan IOs in
* addition to the regular ddt IOs.
*/
- ASSERT3P(scn->scn_zio_root, ==, NULL);
+ ASSERT0P(scn->scn_zio_root);
scn->scn_zio_root = rio;
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
diff --git a/sys/contrib/openzfs/module/zfs/ddt_log.c b/sys/contrib/openzfs/module/zfs/ddt_log.c
index dbd381aa9609..3d30e244c1f7 100644
--- a/sys/contrib/openzfs/module/zfs/ddt_log.c
+++ b/sys/contrib/openzfs/module/zfs/ddt_log.c
@@ -116,7 +116,7 @@ static void
ddt_log_create_one(ddt_t *ddt, ddt_log_t *ddl, uint_t n, dmu_tx_t *tx)
{
ASSERT3U(ddt->ddt_dir_object, >, 0);
- ASSERT3U(ddl->ddl_object, ==, 0);
+ ASSERT0(ddl->ddl_object);
char name[DDT_NAMELEN];
ddt_log_name(ddt, name, n);
@@ -194,7 +194,7 @@ void
ddt_log_begin(ddt_t *ddt, size_t nentries, dmu_tx_t *tx, ddt_log_update_t *dlu)
{
ASSERT3U(nentries, >, 0);
- ASSERT3P(dlu->dlu_dbp, ==, NULL);
+ ASSERT0P(dlu->dlu_dbp);
if (ddt->ddt_log_active->ddl_object == 0)
ddt_log_create(ddt, tx);
@@ -748,8 +748,8 @@ ddt_log_load(ddt_t *ddt)
void
ddt_log_alloc(ddt_t *ddt)
{
- ASSERT3P(ddt->ddt_log_active, ==, NULL);
- ASSERT3P(ddt->ddt_log_flushing, ==, NULL);
+ ASSERT0P(ddt->ddt_log_active);
+ ASSERT0P(ddt->ddt_log_flushing);
avl_create(&ddt->ddt_log[0].ddl_tree, ddt_key_compare,
sizeof (ddt_log_entry_t), offsetof(ddt_log_entry_t, ddle_node));
diff --git a/sys/contrib/openzfs/module/zfs/dmu.c b/sys/contrib/openzfs/module/zfs/dmu.c
index 296e58ef9cd8..f7f808d5b8f7 100644
--- a/sys/contrib/openzfs/module/zfs/dmu.c
+++ b/sys/contrib/openzfs/module/zfs/dmu.c
@@ -1343,7 +1343,7 @@ dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
if (size == 0)
return;
- VERIFY(0 == dmu_buf_hold_array(os, object, offset, size,
+ VERIFY0(dmu_buf_hold_array(os, object, offset, size,
FALSE, FTAG, &numbufs, &dbp));
for (i = 0; i < numbufs; i++) {
@@ -1872,7 +1872,7 @@ dmu_sync_ready(zio_t *zio, arc_buf_t *buf, void *varg)
*/
BP_SET_LSIZE(bp, db->db_size);
} else if (!BP_IS_EMBEDDED(bp)) {
- ASSERT(BP_GET_LEVEL(bp) == 0);
+ ASSERT0(BP_GET_LEVEL(bp));
BP_SET_FILL(bp, 1);
}
}
@@ -2405,7 +2405,7 @@ dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
}
}
} else if (wp & WP_NOFILL) {
- ASSERT(level == 0);
+ ASSERT0(level);
/*
* If we're writing preallocated blocks, we aren't actually
@@ -2865,7 +2865,7 @@ byteswap_uint64_array(void *vbuf, size_t size)
size_t count = size >> 3;
int i;
- ASSERT((size & 7) == 0);
+ ASSERT0((size & 7));
for (i = 0; i < count; i++)
buf[i] = BSWAP_64(buf[i]);
@@ -2878,7 +2878,7 @@ byteswap_uint32_array(void *vbuf, size_t size)
size_t count = size >> 2;
int i;
- ASSERT((size & 3) == 0);
+ ASSERT0((size & 3));
for (i = 0; i < count; i++)
buf[i] = BSWAP_32(buf[i]);
@@ -2891,7 +2891,7 @@ byteswap_uint16_array(void *vbuf, size_t size)
size_t count = size >> 1;
int i;
- ASSERT((size & 1) == 0);
+ ASSERT0((size & 1));
for (i = 0; i < count; i++)
buf[i] = BSWAP_16(buf[i]);
diff --git a/sys/contrib/openzfs/module/zfs/dmu_direct.c b/sys/contrib/openzfs/module/zfs/dmu_direct.c
index 930ff101eca3..d44c686088fc 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_direct.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_direct.c
@@ -95,9 +95,9 @@ dmu_write_direct_done(zio_t *zio)
abd_free(zio->io_abd);
mutex_enter(&db->db_mtx);
- ASSERT3P(db->db_buf, ==, NULL);
- ASSERT3P(dr->dt.dl.dr_data, ==, NULL);
- ASSERT3P(db->db.db_data, ==, NULL);
+ ASSERT0P(db->db_buf);
+ ASSERT0P(dr->dt.dl.dr_data);
+ ASSERT0P(db->db.db_data);
db->db_state = DB_UNCACHED;
mutex_exit(&db->db_mtx);
diff --git a/sys/contrib/openzfs/module/zfs/dmu_object.c b/sys/contrib/openzfs/module/zfs/dmu_object.c
index b4ff7d224cc9..207cc6d0e713 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_object.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_object.c
@@ -90,7 +90,7 @@ dmu_object_alloc_impl(objset_t *os, dmu_object_type_t ot, int blocksize,
if (allocated_dnode != NULL) {
ASSERT3P(tag, !=, NULL);
} else {
- ASSERT3P(tag, ==, NULL);
+ ASSERT0P(tag);
tag = FTAG;
}
diff --git a/sys/contrib/openzfs/module/zfs/dmu_objset.c b/sys/contrib/openzfs/module/zfs/dmu_objset.c
index c135f620800f..a77f338bdfd3 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_objset.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_objset.c
@@ -724,7 +724,7 @@ dmu_objset_from_ds(dsl_dataset_t *ds, objset_t **osp)
if (err == 0) {
mutex_enter(&ds->ds_lock);
- ASSERT(ds->ds_objset == NULL);
+ ASSERT0P(ds->ds_objset);
ds->ds_objset = os;
mutex_exit(&ds->ds_lock);
}
@@ -2226,7 +2226,7 @@ dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx)
rf |= DB_RF_HAVESTRUCT;
error = dmu_spill_hold_by_dnode(dn, rf,
FTAG, (dmu_buf_t **)&db);
- ASSERT(error == 0);
+ ASSERT0(error);
mutex_enter(&db->db_mtx);
data = (before) ? db->db.db_data :
dmu_objset_userquota_find_data(db, tx);
diff --git a/sys/contrib/openzfs/module/zfs/dmu_recv.c b/sys/contrib/openzfs/module/zfs/dmu_recv.c
index 73227b58c140..45c7af2bdcd2 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_recv.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_recv.c
@@ -866,7 +866,7 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
*/
if (dcp == NULL && drrb->drr_fromguid == 0 &&
drba->drba_origin == NULL) {
- ASSERT3P(dcp, ==, NULL);
+ ASSERT0P(dcp);
dcp = &dummy_dcp;
if (featureflags & DMU_BACKUP_FEATURE_RAW)
@@ -881,7 +881,7 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
if (drba->drba_cookie->drc_fromsnapobj != 0) {
VERIFY0(dsl_dataset_hold_obj(dp,
drba->drba_cookie->drc_fromsnapobj, FTAG, &snap));
- ASSERT3P(dcp, ==, NULL);
+ ASSERT0P(dcp);
}
if (drc->drc_heal) {
/* When healing we want to use the provided snapshot */
@@ -905,7 +905,7 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
if (drba->drba_origin != NULL) {
VERIFY0(dsl_dataset_hold(dp, drba->drba_origin,
FTAG, &origin));
- ASSERT3P(dcp, ==, NULL);
+ ASSERT0P(dcp);
}
/* Create new dataset. */
@@ -2792,7 +2792,7 @@ receive_read_payload_and_next_header(dmu_recv_cookie_t *drc, int len, void *buf)
drc->drc_rrd->bytes_read = drc->drc_bytes_read;
}
} else {
- ASSERT3P(buf, ==, NULL);
+ ASSERT0P(buf);
}
drc->drc_prev_cksum = drc->drc_cksum;
@@ -3450,7 +3450,7 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
break;
}
- ASSERT3P(drc->drc_rrd, ==, NULL);
+ ASSERT0P(drc->drc_rrd);
drc->drc_rrd = drc->drc_next_rrd;
drc->drc_next_rrd = NULL;
/* Allocates and loads header into drc->drc_next_rrd */
@@ -3468,7 +3468,7 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
drc->drc_rrd = NULL;
}
- ASSERT3P(drc->drc_rrd, ==, NULL);
+ ASSERT0P(drc->drc_rrd);
drc->drc_rrd = kmem_zalloc(sizeof (*drc->drc_rrd), KM_SLEEP);
drc->drc_rrd->eos_marker = B_TRUE;
bqueue_enqueue_flush(&rwa->q, drc->drc_rrd, 1);
diff --git a/sys/contrib/openzfs/module/zfs/dmu_redact.c b/sys/contrib/openzfs/module/zfs/dmu_redact.c
index 9226ac9e4b80..5a22ed71a5fe 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_redact.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_redact.c
@@ -1067,7 +1067,7 @@ dmu_redact_snap(const char *snapname, nvlist_t *redactnvl,
}
if (err != 0)
goto out;
- VERIFY3P(nvlist_next_nvpair(redactnvl, pair), ==, NULL);
+ VERIFY0P(nvlist_next_nvpair(redactnvl, pair));
boolean_t resuming = B_FALSE;
zfs_bookmark_phys_t bookmark;
diff --git a/sys/contrib/openzfs/module/zfs/dmu_send.c b/sys/contrib/openzfs/module/zfs/dmu_send.c
index deeba29e159a..8ecb99d5f57c 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_send.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_send.c
@@ -962,7 +962,7 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
char *data = NULL;
if (srdp->abd != NULL) {
data = abd_to_buf(srdp->abd);
- ASSERT3P(srdp->abuf, ==, NULL);
+ ASSERT0P(srdp->abuf);
} else if (srdp->abuf != NULL) {
data = srdp->abuf->b_data;
}
@@ -2514,7 +2514,7 @@ dmu_send_impl(struct dmu_send_params *dspp)
* list in the stream.
*/
if (dspp->numfromredactsnaps != NUM_SNAPS_NOT_REDACTED) {
- ASSERT3P(from_rl, ==, NULL);
+ ASSERT0P(from_rl);
fnvlist_add_uint64_array(nvl, BEGINNV_REDACT_FROM_SNAPS,
dspp->fromredactsnaps, (uint_t)dspp->numfromredactsnaps);
if (dspp->numfromredactsnaps > 0) {
@@ -2891,7 +2891,7 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok,
&fromds);
if (err != 0) {
- ASSERT3P(fromds, ==, NULL);
+ ASSERT0P(fromds);
} else {
/*
* We need to make a deep copy of the redact
diff --git a/sys/contrib/openzfs/module/zfs/dmu_tx.c b/sys/contrib/openzfs/module/zfs/dmu_tx.c
index d85d8b89423e..40c0b3402a05 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_tx.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_tx.c
@@ -126,7 +126,7 @@ dmu_tx_hold_dnode_impl(dmu_tx_t *tx, dnode_t *dn, enum dmu_tx_hold_type type,
* problem, but there's no way for it to happen (for
* now, at least).
*/
- ASSERT(dn->dn_assigned_txg == 0);
+ ASSERT0(dn->dn_assigned_txg);
dn->dn_assigned_txg = tx->tx_txg;
(void) zfs_refcount_add(&dn->dn_tx_holds, tx);
mutex_exit(&dn->dn_mtx);
@@ -443,7 +443,7 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
dnode_t *dn = txh->txh_dnode;
int err;
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
if (off >= (dn->dn_maxblkid + 1) * dn->dn_datablksz)
return;
@@ -607,7 +607,7 @@ dmu_tx_hold_zap_impl(dmu_tx_hold_t *txh, const char *name)
dnode_t *dn = txh->txh_dnode;
int err;
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
dmu_tx_count_dnode(txh);
@@ -681,7 +681,7 @@ dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
{
dmu_tx_hold_t *txh;
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
object, THT_BONUS, 0, 0);
@@ -706,7 +706,7 @@ dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
{
dmu_tx_hold_t *txh;
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
DMU_NEW_OBJECT, THT_SPACE, space, 0);
@@ -1232,7 +1232,7 @@ dmu_tx_assign(dmu_tx_t *tx, dmu_tx_flag_t flags)
{
int err;
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
ASSERT0(flags & ~(DMU_TX_WAIT | DMU_TX_NOTHROTTLE | DMU_TX_SUSPEND));
IMPLY(flags & DMU_TX_SUSPEND, flags & DMU_TX_WAIT);
ASSERT(!dsl_pool_sync_context(tx->tx_pool));
@@ -1328,7 +1328,7 @@ dmu_tx_wait(dmu_tx_t *tx)
dsl_pool_t *dp = tx->tx_pool;
hrtime_t before;
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
ASSERT(!dsl_pool_config_held(tx->tx_pool));
/*
@@ -1644,12 +1644,12 @@ dmu_tx_hold_sa(dmu_tx_t *tx, sa_handle_t *hdl, boolean_t may_grow)
dmu_tx_hold_zap(tx, sa->sa_layout_attr_obj, B_TRUE, NULL);
if (sa->sa_force_spill || may_grow || hdl->sa_spill) {
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
dmu_tx_hold_spill(tx, object);
} else {
DB_DNODE_ENTER(db);
if (DB_DNODE(db)->dn_have_spill) {
- ASSERT(tx->tx_txg == 0);
+ ASSERT0(tx->tx_txg);
dmu_tx_hold_spill(tx, object);
}
DB_DNODE_EXIT(db);
diff --git a/sys/contrib/openzfs/module/zfs/dnode.c b/sys/contrib/openzfs/module/zfs/dnode.c
index 451e1533efa0..963ff41232a3 100644
--- a/sys/contrib/openzfs/module/zfs/dnode.c
+++ b/sys/contrib/openzfs/module/zfs/dnode.c
@@ -214,7 +214,7 @@ dnode_dest(void *arg, void *unused)
for (int i = 0; i < TXG_SIZE; i++) {
ASSERT(!multilist_link_active(&dn->dn_dirty_link[i]));
- ASSERT3P(dn->dn_free_ranges[i], ==, NULL);
+ ASSERT0P(dn->dn_free_ranges[i]);
list_destroy(&dn->dn_dirty_records[i]);
ASSERT0(dn->dn_next_nblkptr[i]);
ASSERT0(dn->dn_next_nlevels[i]);
@@ -231,10 +231,10 @@ dnode_dest(void *arg, void *unused)
ASSERT0(dn->dn_assigned_txg);
ASSERT0(dn->dn_dirty_txg);
ASSERT0(dn->dn_dirtyctx);
- ASSERT3P(dn->dn_dirtyctx_firstset, ==, NULL);
- ASSERT3P(dn->dn_bonus, ==, NULL);
+ ASSERT0P(dn->dn_dirtyctx_firstset);
+ ASSERT0P(dn->dn_bonus);
ASSERT(!dn->dn_have_spill);
- ASSERT3P(dn->dn_zio, ==, NULL);
+ ASSERT0P(dn->dn_zio);
ASSERT0(dn->dn_oldused);
ASSERT0(dn->dn_oldflags);
ASSERT0(dn->dn_olduid);
@@ -318,7 +318,7 @@ dnode_kstats_update(kstat_t *ksp, int rw)
void
dnode_init(void)
{
- ASSERT(dnode_cache == NULL);
+ ASSERT0P(dnode_cache);
dnode_cache = kmem_cache_create("dnode_t", sizeof (dnode_t),
0, dnode_cons, dnode_dest, NULL, NULL, NULL, KMC_RECLAIMABLE);
kmem_cache_set_move(dnode_cache, dnode_move);
@@ -509,7 +509,7 @@ dnode_buf_byteswap(void *vbuf, size_t size)
int i = 0;
ASSERT3U(sizeof (dnode_phys_t), ==, (1<<DNODE_SHIFT));
- ASSERT((size & (sizeof (dnode_phys_t)-1)) == 0);
+ ASSERT0((size & (sizeof (dnode_phys_t)-1)));
while (i < size) {
dnode_phys_t *dnp = (void *)(((char *)vbuf) + i);
@@ -673,7 +673,7 @@ dnode_destroy(dnode_t *dn)
objset_t *os = dn->dn_objset;
boolean_t complete_os_eviction = B_FALSE;
- ASSERT((dn->dn_id_flags & DN_ID_NEW_EXIST) == 0);
+ ASSERT0((dn->dn_id_flags & DN_ID_NEW_EXIST));
mutex_enter(&os->os_lock);
POINTER_INVALIDATE(&dn->dn_objset);
@@ -780,7 +780,7 @@ dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
ASSERT0(dn->dn_next_maxblkid[i]);
ASSERT(!multilist_link_active(&dn->dn_dirty_link[i]));
ASSERT3P(list_head(&dn->dn_dirty_records[i]), ==, NULL);
- ASSERT3P(dn->dn_free_ranges[i], ==, NULL);
+ ASSERT0P(dn->dn_free_ranges[i]);
}
dn->dn_type = ot;
@@ -958,7 +958,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn)
ndn->dn_dirty_txg = odn->dn_dirty_txg;
ndn->dn_dirtyctx = odn->dn_dirtyctx;
ndn->dn_dirtyctx_firstset = odn->dn_dirtyctx_firstset;
- ASSERT(zfs_refcount_count(&odn->dn_tx_holds) == 0);
+ ASSERT0(zfs_refcount_count(&odn->dn_tx_holds));
zfs_refcount_transfer(&ndn->dn_holds, &odn->dn_holds);
ASSERT(avl_is_empty(&ndn->dn_dbufs));
avl_swap(&ndn->dn_dbufs, &odn->dn_dbufs);
@@ -2304,7 +2304,7 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx)
if ((off >> blkshift) > dn->dn_maxblkid)
return;
} else {
- ASSERT(dn->dn_maxblkid == 0);
+ ASSERT0(dn->dn_maxblkid);
if (off == 0 && len >= blksz) {
/*
* Freeing the whole block; fast-track this request.
@@ -2524,7 +2524,7 @@ dnode_diduse_space(dnode_t *dn, int64_t delta)
}
space += delta;
if (spa_version(dn->dn_objset->os_spa) < SPA_VERSION_DNODE_BYTES) {
- ASSERT((dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES) == 0);
+ ASSERT0((dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES));
ASSERT0(P2PHASE(space, 1<<DEV_BSHIFT));
dn->dn_phys->dn_used = space >> DEV_BSHIFT;
} else {
diff --git a/sys/contrib/openzfs/module/zfs/dnode_sync.c b/sys/contrib/openzfs/module/zfs/dnode_sync.c
index 4067f221f1bf..046ceddb3609 100644
--- a/sys/contrib/openzfs/module/zfs/dnode_sync.c
+++ b/sys/contrib/openzfs/module/zfs/dnode_sync.c
@@ -209,8 +209,8 @@ free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx)
rw_exit(&dn->dn_struct_rwlock);
if (err == ENOENT)
continue;
- ASSERT(err == 0);
- ASSERT(child->db_level == 0);
+ ASSERT0(err);
+ ASSERT0(child->db_level);
dr = dbuf_find_dirty_eq(child, txg);
/* data_old better be zeroed */
@@ -868,7 +868,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
dbuf_sync_list(list, dn->dn_phys->dn_nlevels - 1, tx);
if (!DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
- ASSERT3P(list_head(list), ==, NULL);
+ ASSERT0P(list_head(list));
dnode_rele(dn, (void *)(uintptr_t)tx->tx_txg);
}
diff --git a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
index fdc8b7b198f0..ee574c499f9f 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
@@ -243,7 +243,7 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp,
/* error is retval of the following if-cascade */
if (strchr(source, '@') != NULL) {
dsl_dataset_t *source_snap_ds;
- ASSERT3S(snapshot_namecheck(source, NULL, NULL), ==, 0);
+ ASSERT0(snapshot_namecheck(source, NULL, NULL));
error = dsl_dataset_hold(dp, source, FTAG, &source_snap_ds);
if (error == 0) {
VERIFY(source_snap_ds->ds_is_snapshot);
@@ -258,7 +258,7 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp,
}
} else if (strchr(source, '#') != NULL) {
zfs_bookmark_phys_t source_phys;
- ASSERT3S(bookmark_namecheck(source, NULL, NULL), ==, 0);
+ ASSERT0(bookmark_namecheck(source, NULL, NULL));
/*
* Source must exists and be an earlier point in newbm_ds's
* timeline (newbm_ds's origin may be a snap of source's ds)
@@ -501,7 +501,7 @@ dsl_bookmark_create_sync_impl_snap(const char *bookmark, const char *snapshot,
sizeof (uint64_t) * num_redact_snaps);
local_rl->rl_phys->rlp_num_snaps = num_redact_snaps;
if (bookmark_redacted) {
- ASSERT3P(redaction_list, ==, NULL);
+ ASSERT0P(redaction_list);
local_rl->rl_phys->rlp_last_blkid = UINT64_MAX;
local_rl->rl_phys->rlp_last_object = UINT64_MAX;
dsl_redaction_list_long_rele(local_rl, tag);
diff --git a/sys/contrib/openzfs/module/zfs/dsl_crypt.c b/sys/contrib/openzfs/module/zfs/dsl_crypt.c
index 6b6bb8d45b6b..f519b937edc0 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_crypt.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_crypt.c
@@ -534,7 +534,7 @@ out:
static void
dsl_crypto_key_free(dsl_crypto_key_t *dck)
{
- ASSERT(zfs_refcount_count(&dck->dck_holds) == 0);
+ ASSERT0(zfs_refcount_count(&dck->dck_holds));
/* destroy the zio_crypt_key_t */
zio_crypt_key_destroy(&dck->dck_key);
@@ -1912,7 +1912,7 @@ dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd,
/* clones always use their origin's wrapping key */
if (dsl_dir_is_clone(dd)) {
- ASSERT3P(dcp, ==, NULL);
+ ASSERT0P(dcp);
/*
* If this is an encrypted clone we just need to clone the
diff --git a/sys/contrib/openzfs/module/zfs/dsl_dataset.c b/sys/contrib/openzfs/module/zfs/dsl_dataset.c
index b767c9641419..420687480a76 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_dataset.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_dataset.c
@@ -450,7 +450,7 @@ dsl_dataset_evict_sync(void *dbu)
{
dsl_dataset_t *ds = dbu;
- ASSERT(ds->ds_owner == NULL);
+ ASSERT0P(ds->ds_owner);
unique_remove(ds->ds_fsid_guid);
}
@@ -460,7 +460,7 @@ dsl_dataset_evict_async(void *dbu)
{
dsl_dataset_t *ds = dbu;
- ASSERT(ds->ds_owner == NULL);
+ ASSERT0P(ds->ds_owner);
ds->ds_dbuf = NULL;
@@ -1187,7 +1187,7 @@ dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
ASSERT(origin == NULL || origin->ds_dir->dd_pool == dp);
ASSERT(origin == NULL || dsl_dataset_phys(origin)->ds_num_children > 0);
ASSERT(dmu_tx_is_syncing(tx));
- ASSERT(dsl_dir_phys(dd)->dd_head_dataset_obj == 0);
+ ASSERT0(dsl_dir_phys(dd)->dd_head_dataset_obj);
dsobj = dmu_object_alloc(mos, DMU_OT_DSL_DATASET, 0,
DMU_OT_DSL_DATASET, sizeof (dsl_dataset_phys_t), tx);
@@ -2112,7 +2112,7 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *rio, dmu_tx_t *tx)
{
ASSERT(dmu_tx_is_syncing(tx));
ASSERT(ds->ds_objset != NULL);
- ASSERT(dsl_dataset_phys(ds)->ds_next_snap_obj == 0);
+ ASSERT0(dsl_dataset_phys(ds)->ds_next_snap_obj);
/*
* in case we had to change ds_fsid_guid when we opened it,
@@ -4180,7 +4180,7 @@ dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
dsl_pool_t *dp = dmu_tx_pool(tx);
int64_t unused_refres_delta;
- ASSERT(clone->ds_reserved == 0);
+ ASSERT0(clone->ds_reserved);
/*
* NOTE: On DEBUG kernels there could be a race between this and
* the check function if spa_asize_inflation is adjusted...
diff --git a/sys/contrib/openzfs/module/zfs/dsl_deadlist.c b/sys/contrib/openzfs/module/zfs/dsl_deadlist.c
index 9ffc998ac173..475db3c89508 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_deadlist.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_deadlist.c
@@ -1037,7 +1037,7 @@ dsl_livelist_iterate(void *arg, const blkptr_t *bp, boolean_t bp_freed,
avl_tree_t *avl = lia->avl;
bplist_t *to_free = lia->to_free;
zthr_t *t = lia->t;
- ASSERT(tx == NULL);
+ ASSERT0P(tx);
if ((t != NULL) && (zthr_has_waiters(t) || zthr_iscancelled(t)))
return (SET_ERROR(EINTR));
diff --git a/sys/contrib/openzfs/module/zfs/dsl_deleg.c b/sys/contrib/openzfs/module/zfs/dsl_deleg.c
index c01a06e98340..fdd37b36e280 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_deleg.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_deleg.c
@@ -102,7 +102,7 @@ dsl_deleg_can_allow(char *ddname, nvlist_t *nvp, cred_t *cr)
nvlist_t *perms;
nvpair_t *permpair = NULL;
- VERIFY(nvpair_value_nvlist(whopair, &perms) == 0);
+ VERIFY0(nvpair_value_nvlist(whopair, &perms));
while ((permpair = nvlist_next_nvpair(perms, permpair))) {
const char *perm = nvpair_name(permpair);
@@ -189,8 +189,7 @@ dsl_deleg_set_sync(void *arg, dmu_tx_t *tx)
const char *perm = nvpair_name(permpair);
uint64_t n = 0;
- VERIFY(zap_update(mos, jumpobj,
- perm, 8, 1, &n, tx) == 0);
+ VERIFY0(zap_update(mos, jumpobj, perm, 8, 1, &n, tx));
spa_history_log_internal_dd(dd, "permission update", tx,
"%s %s", whokey, perm);
}
@@ -225,7 +224,7 @@ dsl_deleg_unset_sync(void *arg, dmu_tx_t *tx)
if (zap_lookup(mos, zapobj, whokey, 8,
1, &jumpobj) == 0) {
(void) zap_remove(mos, zapobj, whokey, tx);
- VERIFY(0 == zap_destroy(mos, jumpobj, tx));
+ VERIFY0(zap_destroy(mos, jumpobj, tx));
}
spa_history_log_internal_dd(dd, "permission who remove",
tx, "%s", whokey);
@@ -243,7 +242,7 @@ dsl_deleg_unset_sync(void *arg, dmu_tx_t *tx)
if (zap_count(mos, jumpobj, &n) == 0 && n == 0) {
(void) zap_remove(mos, zapobj,
whokey, tx);
- VERIFY(0 == zap_destroy(mos,
+ VERIFY0(zap_destroy(mos,
jumpobj, tx));
}
spa_history_log_internal_dd(dd, "permission remove", tx,
@@ -332,7 +331,7 @@ dsl_deleg_get(const char *ddname, nvlist_t **nvp)
basezc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
baseza = zap_attribute_alloc();
source = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
- VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP));
for (dd = startdd; dd != NULL; dd = dd->dd_parent) {
nvlist_t *sp_nvp;
@@ -706,7 +705,7 @@ copy_create_perms(dsl_dir_t *dd, uint64_t pzapobj,
ZFS_DELEG_LOCAL, &uid);
if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) == ENOENT) {
jumpobj = zap_create(mos, DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
- VERIFY(zap_add(mos, zapobj, whokey, 8, 1, &jumpobj, tx) == 0);
+ VERIFY0(zap_add(mos, zapobj, whokey, 8, 1, &jumpobj, tx));
}
za = zap_attribute_alloc();
@@ -716,8 +715,7 @@ copy_create_perms(dsl_dir_t *dd, uint64_t pzapobj,
uint64_t zero = 0;
ASSERT(za->za_integer_length == 8 && za->za_num_integers == 1);
- VERIFY(zap_update(mos, jumpobj, za->za_name,
- 8, 1, &zero, tx) == 0);
+ VERIFY0(zap_update(mos, jumpobj, za->za_name, 8, 1, &zero, tx));
}
zap_cursor_fini(&zc);
zap_attribute_free(za);
@@ -761,10 +759,10 @@ dsl_deleg_destroy(objset_t *mos, uint64_t zapobj, dmu_tx_t *tx)
zap_cursor_retrieve(&zc, za) == 0;
zap_cursor_advance(&zc)) {
ASSERT(za->za_integer_length == 8 && za->za_num_integers == 1);
- VERIFY(0 == zap_destroy(mos, za->za_first_integer, tx));
+ VERIFY0(zap_destroy(mos, za->za_first_integer, tx));
}
zap_cursor_fini(&zc);
- VERIFY(0 == zap_destroy(mos, zapobj, tx));
+ VERIFY0(zap_destroy(mos, zapobj, tx));
zap_attribute_free(za);
return (0);
}
diff --git a/sys/contrib/openzfs/module/zfs/dsl_destroy.c b/sys/contrib/openzfs/module/zfs/dsl_destroy.c
index fff49c97f4d2..ea01ee586f8b 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_destroy.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_destroy.c
@@ -350,7 +350,7 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
dsl_dataset_deactivate_feature(ds, f, tx);
}
if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
- ASSERT3P(ds->ds_prev, ==, NULL);
+ ASSERT0P(ds->ds_prev);
VERIFY0(dsl_dataset_hold_obj(dp,
dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &ds_prev));
after_branch_point =
@@ -465,7 +465,7 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
&used, &comp, &uncomp);
dsl_dataset_phys(ds_next)->ds_unique_bytes += used;
dsl_dataset_rele(ds_nextnext, FTAG);
- ASSERT3P(ds_next->ds_prev, ==, NULL);
+ ASSERT0P(ds_next->ds_prev);
/* Collapse range in this head. */
dsl_dataset_t *hds;
@@ -525,7 +525,7 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
/* remove from snapshot namespace */
dsl_dataset_t *ds_head;
- ASSERT(dsl_dataset_phys(ds)->ds_snapnames_zapobj == 0);
+ ASSERT0(dsl_dataset_phys(ds)->ds_snapnames_zapobj);
VERIFY0(dsl_dataset_hold_obj(dp,
dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj, FTAG, &ds_head));
VERIFY0(dsl_dataset_get_snapname(ds));
@@ -728,7 +728,7 @@ kill_blkptr(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
*/
dsl_free(ka->tx->tx_pool, ka->tx->tx_txg, bp);
} else {
- ASSERT(zilog == NULL);
+ ASSERT0P(zilog);
ASSERT3U(BP_GET_BIRTH(bp), >,
dsl_dataset_phys(ka->ds)->ds_prev_snap_txg);
(void) dsl_dataset_block_kill(ka->ds, bp, tx, B_FALSE);
diff --git a/sys/contrib/openzfs/module/zfs/dsl_dir.c b/sys/contrib/openzfs/module/zfs/dsl_dir.c
index f24cd2049533..6ce1890cfea1 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_dir.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_dir.c
@@ -151,8 +151,8 @@ dsl_dir_evict_async(void *dbu)
for (t = 0; t < TXG_SIZE; t++) {
ASSERT(!txg_list_member(&dp->dp_dirty_dirs, dd, t));
- ASSERT(dd->dd_tempreserved[t] == 0);
- ASSERT(dd->dd_space_towrite[t] == 0);
+ ASSERT0(dd->dd_tempreserved[t]);
+ ASSERT0(dd->dd_space_towrite[t]);
}
if (dd->dd_parent)
diff --git a/sys/contrib/openzfs/module/zfs/dsl_pool.c b/sys/contrib/openzfs/module/zfs/dsl_pool.c
index 4f1f66b835f2..f47822df8b53 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_pool.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_pool.c
@@ -522,8 +522,8 @@ dsl_pool_create(spa_t *spa, nvlist_t *zplprops __attribute__((unused)),
/* create and open the free_bplist */
obj = bpobj_alloc(dp->dp_meta_objset, SPA_OLD_MAXBLOCKSIZE, tx);
- VERIFY(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
- DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx) == 0);
+ VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+ DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx));
VERIFY0(bpobj_open(&dp->dp_free_bpobj,
dp->dp_meta_objset, obj));
}
@@ -1077,7 +1077,7 @@ upgrade_clones_cb(dsl_pool_t *dp, dsl_dataset_t *hds, void *arg)
dsl_dataset_phys(prev)->ds_num_children++;
if (dsl_dataset_phys(ds)->ds_next_snap_obj == 0) {
- ASSERT(ds->ds_prev == NULL);
+ ASSERT0P(ds->ds_prev);
VERIFY0(dsl_dataset_hold_obj(dp,
dsl_dataset_phys(ds)->ds_prev_snap_obj,
ds, &ds->ds_prev));
@@ -1173,7 +1173,7 @@ dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
dsl_dataset_t *ds;
ASSERT(dmu_tx_is_syncing(tx));
- ASSERT(dp->dp_origin_snap == NULL);
+ ASSERT0P(dp->dp_origin_snap);
ASSERT(rrw_held(&dp->dp_config_rwlock, RW_WRITER));
/* create the origin dir, ds, & snap-ds */
@@ -1250,7 +1250,7 @@ dsl_pool_user_hold_create_obj(dsl_pool_t *dp, dmu_tx_t *tx)
{
objset_t *mos = dp->dp_meta_objset;
- ASSERT(dp->dp_tmp_userrefs_obj == 0);
+ ASSERT0(dp->dp_tmp_userrefs_obj);
ASSERT(dmu_tx_is_syncing(tx));
dp->dp_tmp_userrefs_obj = zap_create_link(mos, DMU_OT_USERREFS,
diff --git a/sys/contrib/openzfs/module/zfs/dsl_prop.c b/sys/contrib/openzfs/module/zfs/dsl_prop.c
index b76f22df61e2..51f624da5689 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_prop.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_prop.c
@@ -815,7 +815,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
*/
err = zap_update(mos, zapobj, recvdstr,
intsz, numints, value, tx);
- ASSERT(err == 0);
+ ASSERT0(err);
break;
case (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED):
/*
@@ -1166,7 +1166,7 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
if (nvlist_exists(nv, propname))
continue;
- VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP));
if (za->za_integer_length == 1) {
/*
* String property
@@ -1179,8 +1179,7 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
kmem_free(tmp, za->za_num_integers);
break;
}
- VERIFY(nvlist_add_string(propval, ZPROP_VALUE,
- tmp) == 0);
+ VERIFY0(nvlist_add_string(propval, ZPROP_VALUE, tmp));
kmem_free(tmp, za->za_num_integers);
} else {
/*
@@ -1191,8 +1190,8 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
za->za_first_integer);
}
- VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, source) == 0);
- VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
+ VERIFY0(nvlist_add_string(propval, ZPROP_SOURCE, source));
+ VERIFY0(nvlist_add_nvlist(nv, propname, propval));
nvlist_free(propval);
}
zap_cursor_fini(&zc);
@@ -1215,7 +1214,7 @@ dsl_prop_get_all_ds(dsl_dataset_t *ds, nvlist_t **nvp,
int err = 0;
char setpoint[ZFS_MAX_DATASET_NAME_LEN];
- VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP));
if (ds->ds_is_snapshot)
flags |= DSL_PROP_GET_SNAPSHOT;
@@ -1333,18 +1332,18 @@ dsl_prop_nvlist_add_uint64(nvlist_t *nv, zfs_prop_t prop, uint64_t value)
uint64_t default_value;
if (nvlist_lookup_nvlist(nv, propname, &propval) == 0) {
- VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
+ VERIFY0(nvlist_add_uint64(propval, ZPROP_VALUE, value));
return;
}
- VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
- VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
+ VERIFY0(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP));
+ VERIFY0(nvlist_add_uint64(propval, ZPROP_VALUE, value));
/* Indicate the default source if we can. */
if (dodefault(prop, 8, 1, &default_value) == 0 &&
value == default_value) {
- VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, "") == 0);
+ VERIFY0(nvlist_add_string(propval, ZPROP_SOURCE, ""));
}
- VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
+ VERIFY0(nvlist_add_nvlist(nv, propname, propval));
nvlist_free(propval);
}
@@ -1355,13 +1354,13 @@ dsl_prop_nvlist_add_string(nvlist_t *nv, zfs_prop_t prop, const char *value)
const char *propname = zfs_prop_to_name(prop);
if (nvlist_lookup_nvlist(nv, propname, &propval) == 0) {
- VERIFY(nvlist_add_string(propval, ZPROP_VALUE, value) == 0);
+ VERIFY0(nvlist_add_string(propval, ZPROP_VALUE, value));
return;
}
- VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
- VERIFY(nvlist_add_string(propval, ZPROP_VALUE, value) == 0);
- VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
+ VERIFY0(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP));
+ VERIFY0(nvlist_add_string(propval, ZPROP_VALUE, value));
+ VERIFY0(nvlist_add_nvlist(nv, propname, propval));
nvlist_free(propval);
}
diff --git a/sys/contrib/openzfs/module/zfs/dsl_scan.c b/sys/contrib/openzfs/module/zfs/dsl_scan.c
index 5052992d775c..fcd50c459d07 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_scan.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_scan.c
@@ -1784,7 +1784,7 @@ dsl_scan_zil_block(zilog_t *zilog, const blkptr_t *bp, void *arg,
SET_BOOKMARK(&zb, zh->zh_log.blk_cksum.zc_word[ZIL_ZC_OBJSET],
ZB_ZIL_OBJECT, ZB_ZIL_LEVEL, bp->blk_cksum.zc_word[ZIL_ZC_SEQ]);
- VERIFY(0 == scan_funcs[scn->scn_phys.scn_func](dp, bp, &zb));
+ VERIFY0(scan_funcs[scn->scn_phys.scn_func](dp, bp, &zb));
return (0);
}
@@ -1820,7 +1820,7 @@ dsl_scan_zil_record(zilog_t *zilog, const lr_t *lrc, void *arg,
lr->lr_foid, ZB_ZIL_LEVEL,
lr->lr_offset / BP_GET_LSIZE(bp));
- VERIFY(0 == scan_funcs[scn->scn_phys.scn_func](dp, bp, &zb));
+ VERIFY0(scan_funcs[scn->scn_phys.scn_func](dp, bp, &zb));
}
return (0);
}
@@ -5141,7 +5141,7 @@ dsl_scan_io_queue_vdev_xfer(vdev_t *svd, vdev_t *tvd)
mutex_enter(&svd->vdev_scan_io_queue_lock);
mutex_enter(&tvd->vdev_scan_io_queue_lock);
- VERIFY3P(tvd->vdev_scan_io_queue, ==, NULL);
+ VERIFY0P(tvd->vdev_scan_io_queue);
tvd->vdev_scan_io_queue = svd->vdev_scan_io_queue;
svd->vdev_scan_io_queue = NULL;
if (tvd->vdev_scan_io_queue != NULL)
diff --git a/sys/contrib/openzfs/module/zfs/dsl_userhold.c b/sys/contrib/openzfs/module/zfs/dsl_userhold.c
index 57c70e4ce3d2..f91b7a1eb69a 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_userhold.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_userhold.c
@@ -335,7 +335,7 @@ dsl_dataset_user_hold(nvlist_t *holds, minor_t cleanup_minor, nvlist_t *errlist)
dduha.dduha_holds = holds;
/* chkholds can have non-unique name */
- VERIFY(0 == nvlist_alloc(&dduha.dduha_chkholds, 0, KM_SLEEP));
+ VERIFY0(nvlist_alloc(&dduha.dduha_chkholds, 0, KM_SLEEP));
dduha.dduha_errlist = errlist;
dduha.dduha_minor = cleanup_minor;
diff --git a/sys/contrib/openzfs/module/zfs/fm.c b/sys/contrib/openzfs/module/zfs/fm.c
index a092817efedd..ae788b2310d8 100644
--- a/sys/contrib/openzfs/module/zfs/fm.c
+++ b/sys/contrib/openzfs/module/zfs/fm.c
@@ -337,7 +337,7 @@ zfs_zevent_next(zfs_zevent_t *ze, nvlist_t **event, uint64_t *event_size,
}
}
- VERIFY(nvlist_size(ev->ev_nvl, &size, NV_ENCODE_NATIVE) == 0);
+ VERIFY0(nvlist_size(ev->ev_nvl, &size, NV_ENCODE_NATIVE));
if (size > *event_size) {
*event_size = size;
error = ENOMEM;
diff --git a/sys/contrib/openzfs/module/zfs/metaslab.c b/sys/contrib/openzfs/module/zfs/metaslab.c
index 0e5f09b2724c..9f4399af56bd 100644
--- a/sys/contrib/openzfs/module/zfs/metaslab.c
+++ b/sys/contrib/openzfs/module/zfs/metaslab.c
@@ -391,7 +391,7 @@ static kstat_t *metaslab_ksp;
void
metaslab_stat_init(void)
{
- ASSERT(metaslab_alloc_trace_cache == NULL);
+ ASSERT0P(metaslab_alloc_trace_cache);
metaslab_alloc_trace_cache = kmem_cache_create(
"metaslab_alloc_trace_cache", sizeof (metaslab_alloc_trace_t),
0, NULL, NULL, NULL, NULL, NULL, 0);
@@ -456,16 +456,16 @@ metaslab_class_destroy(metaslab_class_t *mc)
{
spa_t *spa = mc->mc_spa;
- ASSERT(mc->mc_alloc == 0);
- ASSERT(mc->mc_deferred == 0);
- ASSERT(mc->mc_space == 0);
- ASSERT(mc->mc_dspace == 0);
+ ASSERT0(mc->mc_alloc);
+ ASSERT0(mc->mc_deferred);
+ ASSERT0(mc->mc_space);
+ ASSERT0(mc->mc_dspace);
for (int i = 0; i < spa->spa_alloc_count; i++) {
metaslab_class_allocator_t *mca = &mc->mc_allocator[i];
avl_destroy(&mca->mca_tree);
mutex_destroy(&mca->mca_lock);
- ASSERT(mca->mca_rotor == NULL);
+ ASSERT0P(mca->mca_rotor);
ASSERT0(mca->mca_reserved);
}
mutex_destroy(&mc->mc_lock);
@@ -1087,8 +1087,8 @@ metaslab_group_destroy(metaslab_group_t *mg)
{
spa_t *spa = mg->mg_class->mc_spa;
- ASSERT(mg->mg_prev == NULL);
- ASSERT(mg->mg_next == NULL);
+ ASSERT0P(mg->mg_prev);
+ ASSERT0P(mg->mg_next);
/*
* We may have gone below zero with the activation count
* either because we never activated in the first place or
@@ -1118,8 +1118,8 @@ metaslab_group_activate(metaslab_group_t *mg)
ASSERT3U(spa_config_held(spa, SCL_ALLOC, RW_WRITER), !=, 0);
- ASSERT(mg->mg_prev == NULL);
- ASSERT(mg->mg_next == NULL);
+ ASSERT0P(mg->mg_prev);
+ ASSERT0P(mg->mg_next);
ASSERT(mg->mg_activation_count <= 0);
if (++mg->mg_activation_count <= 0)
@@ -1164,8 +1164,8 @@ metaslab_group_passivate(metaslab_group_t *mg)
if (--mg->mg_activation_count != 0) {
for (int i = 0; i < spa->spa_alloc_count; i++)
ASSERT(mc->mc_allocator[i].mca_rotor != mg);
- ASSERT(mg->mg_prev == NULL);
- ASSERT(mg->mg_next == NULL);
+ ASSERT0P(mg->mg_prev);
+ ASSERT0P(mg->mg_next);
ASSERT(mg->mg_activation_count < 0);
return;
}
@@ -1345,7 +1345,7 @@ metaslab_group_histogram_remove(metaslab_group_t *mg, metaslab_t *msp)
static void
metaslab_group_add(metaslab_group_t *mg, metaslab_t *msp)
{
- ASSERT(msp->ms_group == NULL);
+ ASSERT0P(msp->ms_group);
mutex_enter(&mg->mg_lock);
msp->ms_group = mg;
msp->ms_weight = 0;
@@ -3017,7 +3017,7 @@ metaslab_fini(metaslab_t *msp)
metaslab_group_remove(mg, msp);
mutex_enter(&msp->ms_lock);
- VERIFY(msp->ms_group == NULL);
+ VERIFY0P(msp->ms_group);
/*
* If this metaslab hasn't been through metaslab_sync_done() yet its
@@ -5739,7 +5739,7 @@ metaslab_unalloc_dva(spa_t *spa, const dva_t *dva, uint64_t txg)
ASSERT(!vd->vdev_removing);
ASSERT(vdev_is_concrete(vd));
ASSERT0(vd->vdev_indirect_config.vic_mapping_object);
- ASSERT3P(vd->vdev_indirect_mapping, ==, NULL);
+ ASSERT0P(vd->vdev_indirect_mapping);
if (DVA_GET_GANG(dva))
size = vdev_gang_header_asize(vd);
@@ -5997,7 +5997,7 @@ metaslab_alloc_range(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
}
ASSERT(ndvas > 0 && ndvas <= spa_max_replication(spa));
- ASSERT(BP_GET_NDVAS(bp) == 0);
+ ASSERT0(BP_GET_NDVAS(bp));
ASSERT(hintbp == NULL || ndvas <= BP_GET_NDVAS(hintbp));
ASSERT3P(zal, !=, NULL);
@@ -6029,7 +6029,7 @@ metaslab_alloc_range(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
smallest_psize = MIN(cur_psize, smallest_psize);
}
}
- ASSERT(error == 0);
+ ASSERT0(error);
ASSERT(BP_GET_NDVAS(bp) == ndvas);
if (actual_psize)
*actual_psize = smallest_psize;
diff --git a/sys/contrib/openzfs/module/zfs/mmp.c b/sys/contrib/openzfs/module/zfs/mmp.c
index f3665d29b8b4..7db72b9b04b0 100644
--- a/sys/contrib/openzfs/module/zfs/mmp.c
+++ b/sys/contrib/openzfs/module/zfs/mmp.c
@@ -260,7 +260,7 @@ mmp_thread_stop(spa_t *spa)
zfs_dbgmsg("MMP thread stopped pool '%s' gethrtime %llu",
spa_name(spa), gethrtime());
- ASSERT(mmp->mmp_thread == NULL);
+ ASSERT0P(mmp->mmp_thread);
mmp->mmp_thread_exiting = 0;
}
diff --git a/sys/contrib/openzfs/module/zfs/range_tree.c b/sys/contrib/openzfs/module/zfs/range_tree.c
index fc2b17606bd2..ea2d2c7227c8 100644
--- a/sys/contrib/openzfs/module/zfs/range_tree.c
+++ b/sys/contrib/openzfs/module/zfs/range_tree.c
@@ -377,7 +377,7 @@ zfs_range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
return;
}
- ASSERT3P(rs, ==, NULL);
+ ASSERT0P(rs);
/*
* Determine whether or not we will have to merge with our neighbors.
@@ -867,7 +867,7 @@ zfs_range_tree_remove_xor_add_segment(uint64_t start, uint64_t end,
next = zfs_btree_next(&removefrom->rt_root, &where, &where);
}
- VERIFY3P(curr, ==, NULL);
+ VERIFY0P(curr);
if (start != end) {
VERIFY3U(start, <, end);
diff --git a/sys/contrib/openzfs/module/zfs/rrwlock.c b/sys/contrib/openzfs/module/zfs/rrwlock.c
index 8ee784619839..d0df39b93560 100644
--- a/sys/contrib/openzfs/module/zfs/rrwlock.c
+++ b/sys/contrib/openzfs/module/zfs/rrwlock.c
@@ -108,7 +108,7 @@ rrn_add(rrwlock_t *rrl, const void *tag)
rn->rn_rrl = rrl;
rn->rn_next = tsd_get(rrw_tsd_key);
rn->rn_tag = tag;
- VERIFY(tsd_set(rrw_tsd_key, rn) == 0);
+ VERIFY0(tsd_set(rrw_tsd_key, rn));
}
/*
@@ -129,7 +129,7 @@ rrn_find_and_remove(rrwlock_t *rrl, const void *tag)
if (prev)
prev->rn_next = rn->rn_next;
else
- VERIFY(tsd_set(rrw_tsd_key, rn->rn_next) == 0);
+ VERIFY0(tsd_set(rrw_tsd_key, rn->rn_next));
kmem_free(rn, sizeof (*rn));
return (B_TRUE);
}
@@ -155,7 +155,7 @@ rrw_destroy(rrwlock_t *rrl)
{
mutex_destroy(&rrl->rr_lock);
cv_destroy(&rrl->rr_cv);
- ASSERT(rrl->rr_writer == NULL);
+ ASSERT0P(rrl->rr_writer);
zfs_refcount_destroy(&rrl->rr_anon_rcount);
zfs_refcount_destroy(&rrl->rr_linked_rcount);
}
@@ -188,7 +188,7 @@ rrw_enter_read_impl(rrwlock_t *rrl, boolean_t prio, const void *tag)
} else {
(void) zfs_refcount_add(&rrl->rr_anon_rcount, tag);
}
- ASSERT(rrl->rr_writer == NULL);
+ ASSERT0P(rrl->rr_writer);
mutex_exit(&rrl->rr_lock);
}
diff --git a/sys/contrib/openzfs/module/zfs/sa.c b/sys/contrib/openzfs/module/zfs/sa.c
index 5db470ce6242..7ad25d4d85ba 100644
--- a/sys/contrib/openzfs/module/zfs/sa.c
+++ b/sys/contrib/openzfs/module/zfs/sa.c
@@ -304,7 +304,7 @@ sa_get_spill(sa_handle_t *hdl)
if (hdl->sa_spill == NULL) {
if ((rc = dmu_spill_hold_existing(hdl->sa_bonus, NULL,
&hdl->sa_spill)) == 0)
- VERIFY(0 == sa_build_index(hdl, SA_SPILL));
+ VERIFY0(sa_build_index(hdl, SA_SPILL));
} else {
rc = 0;
}
@@ -432,7 +432,7 @@ sa_add_layout_entry(objset_t *os, const sa_attr_type_t *attrs, int attr_count,
(void) snprintf(attr_name, sizeof (attr_name),
"%d", (int)lot_num);
- VERIFY(0 == zap_update(os, os->os_sa->sa_layout_attr_obj,
+ VERIFY0(zap_update(os, os->os_sa->sa_layout_attr_obj,
attr_name, 2, attr_count, attrs, tx));
}
@@ -505,7 +505,7 @@ sa_resize_spill(sa_handle_t *hdl, uint32_t size, dmu_tx_t *tx)
}
error = dbuf_spill_set_blksz(hdl->sa_spill, blocksize, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
return (error);
}
@@ -717,7 +717,7 @@ sa_build_layouts(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc, int attr_count,
if (BUF_SPACE_NEEDED(spill_used, spillhdrsize) >
hdl->sa_spill->db_size)
- VERIFY(0 == sa_resize_spill(hdl,
+ VERIFY0(sa_resize_spill(hdl,
BUF_SPACE_NEEDED(spill_used, spillhdrsize), tx));
}
@@ -791,7 +791,7 @@ sa_build_layouts(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc, int attr_count,
hdl->sa_bonus_tab = NULL;
}
if (!sa->sa_force_spill)
- VERIFY(0 == sa_build_index(hdl, SA_BONUS));
+ VERIFY0(sa_build_index(hdl, SA_BONUS));
if (hdl->sa_spill) {
sa_idx_tab_rele(hdl->sa_os, hdl->sa_spill_tab);
if (!spilling) {
@@ -801,10 +801,10 @@ sa_build_layouts(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc, int attr_count,
dmu_buf_rele(hdl->sa_spill, NULL);
hdl->sa_spill = NULL;
hdl->sa_spill_tab = NULL;
- VERIFY(0 == dmu_rm_spill(hdl->sa_os,
+ VERIFY0(dmu_rm_spill(hdl->sa_os,
sa_handle_object(hdl), tx));
} else {
- VERIFY(0 == sa_build_index(hdl, SA_SPILL));
+ VERIFY0(sa_build_index(hdl, SA_SPILL));
}
}
@@ -1733,10 +1733,10 @@ sa_add_projid(sa_handle_t *hdl, dmu_tx_t *tx, uint64_t projid)
NULL, dxattr_obj, dxattr_size);
}
- VERIFY(dmu_set_bonustype(db, DMU_OT_SA, tx) == 0);
- VERIFY(sa_replace_all_by_template_locked(hdl, attrs, count, tx) == 0);
+ VERIFY0(dmu_set_bonustype(db, DMU_OT_SA, tx));
+ VERIFY0(sa_replace_all_by_template_locked(hdl, attrs, count, tx));
if (znode_acl.z_acl_extern_obj) {
- VERIFY(0 == dmu_object_free(zfsvfs->z_os,
+ VERIFY0(dmu_object_free(zfsvfs->z_os,
znode_acl.z_acl_extern_obj, tx));
}
@@ -1858,7 +1858,7 @@ sa_attr_register_sync(sa_handle_t *hdl, dmu_tx_t *tx)
continue;
ATTR_ENCODE(attr_value, tb[i].sa_attr, tb[i].sa_length,
tb[i].sa_byteswap);
- VERIFY(0 == zap_update(hdl->sa_os, sa->sa_reg_attr_obj,
+ VERIFY0(zap_update(hdl->sa_os, sa->sa_reg_attr_obj,
tb[i].sa_name, 8, 1, &attr_value, tx));
tb[i].sa_registered = B_TRUE;
}
@@ -2013,7 +2013,7 @@ sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr,
* Only a variable-sized attribute can be
* replaced here, and its size must be changing.
*/
- ASSERT3U(reg_length, ==, 0);
+ ASSERT0(reg_length);
ASSERT3U(length, !=, buflen);
SA_ADD_BULK_ATTR(attr_desc, j, attr,
locator, datastart, buflen);
diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c
index 5ecb175fbd63..b3bb46da263b 100644
--- a/sys/contrib/openzfs/module/zfs/spa.c
+++ b/sys/contrib/openzfs/module/zfs/spa.c
@@ -426,10 +426,10 @@ spa_prop_add_user(nvlist_t *nvl, const char *propname, char *strval,
{
nvlist_t *propval;
- VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
- VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0);
- VERIFY(nvlist_add_string(propval, ZPROP_VALUE, strval) == 0);
- VERIFY(nvlist_add_nvlist(nvl, propname, propval) == 0);
+ VERIFY0(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP));
+ VERIFY0(nvlist_add_uint64(propval, ZPROP_SOURCE, src));
+ VERIFY0(nvlist_add_string(propval, ZPROP_VALUE, strval));
+ VERIFY0(nvlist_add_nvlist(nvl, propname, propval));
nvlist_free(propval);
}
@@ -965,7 +965,7 @@ spa_prop_set(spa_t *spa, nvlist_t *nvp)
uint64_t ver = 0;
if (prop == ZPOOL_PROP_VERSION) {
- VERIFY(nvpair_value_uint64(elem, &ver) == 0);
+ VERIFY0(nvpair_value_uint64(elem, &ver));
} else {
ASSERT(zpool_prop_feature(nvpair_name(elem)));
ver = SPA_VERSION_FEATURES;
@@ -1295,7 +1295,7 @@ spa_taskqs_fini(spa_t *spa, zio_type_t t, zio_taskq_type_t q)
spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q];
if (tqs->stqs_taskq == NULL) {
- ASSERT3U(tqs->stqs_count, ==, 0);
+ ASSERT0(tqs->stqs_count);
return;
}
@@ -1836,9 +1836,9 @@ static void
spa_deactivate(spa_t *spa)
{
ASSERT(spa->spa_sync_on == B_FALSE);
- ASSERT(spa->spa_dsl_pool == NULL);
- ASSERT(spa->spa_root_vdev == NULL);
- ASSERT(spa->spa_async_zio_root == NULL);
+ ASSERT0P(spa->spa_dsl_pool);
+ ASSERT0P(spa->spa_root_vdev);
+ ASSERT0P(spa->spa_async_zio_root);
ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
spa_evicting_os_wait(spa);
@@ -2021,7 +2021,7 @@ spa_unload_log_sm_flush_all(spa_t *spa)
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));
- ASSERT3U(spa->spa_log_flushall_txg, ==, 0);
+ ASSERT0(spa->spa_log_flushall_txg);
spa->spa_log_flushall_txg = dmu_tx_get_txg(tx);
dmu_tx_commit(tx);
@@ -2280,7 +2280,7 @@ spa_unload(spa_t *spa)
*/
if (spa->spa_root_vdev)
vdev_free(spa->spa_root_vdev);
- ASSERT(spa->spa_root_vdev == NULL);
+ ASSERT0P(spa->spa_root_vdev);
/*
* Close the dsl pool.
@@ -2418,8 +2418,8 @@ spa_load_spares(spa_t *spa)
spa->spa_spares.sav_vdevs = kmem_zalloc(nspares * sizeof (void *),
KM_SLEEP);
for (i = 0; i < spa->spa_spares.sav_count; i++) {
- VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0,
- VDEV_ALLOC_SPARE) == 0);
+ VERIFY0(spa_config_parse(spa, &vd, spares[i], NULL, 0,
+ VDEV_ALLOC_SPARE));
ASSERT(vd != NULL);
spa->spa_spares.sav_vdevs[i] = vd;
@@ -2546,8 +2546,8 @@ spa_load_l2cache(spa_t *spa)
/*
* Create new vdev
*/
- VERIFY(spa_config_parse(spa, &vd, l2cache[i], NULL, 0,
- VDEV_ALLOC_L2CACHE) == 0);
+ VERIFY0(spa_config_parse(spa, &vd, l2cache[i], NULL, 0,
+ VDEV_ALLOC_L2CACHE));
ASSERT(vd != NULL);
newvdevs[i] = vd;
@@ -2799,7 +2799,7 @@ spa_passivate_log(spa_t *spa)
vdev_t *tvd = rvd->vdev_child[c];
if (tvd->vdev_islog) {
- ASSERT3P(tvd->vdev_log_mg, ==, NULL);
+ ASSERT0P(tvd->vdev_log_mg);
metaslab_group_passivate(tvd->vdev_mg);
slog_found = B_TRUE;
}
@@ -2822,7 +2822,7 @@ spa_activate_log(spa_t *spa)
vdev_t *tvd = rvd->vdev_child[c];
if (tvd->vdev_islog) {
- ASSERT3P(tvd->vdev_log_mg, ==, NULL);
+ ASSERT0P(tvd->vdev_log_mg);
metaslab_group_activate(tvd->vdev_mg);
}
}
@@ -3259,7 +3259,7 @@ spa_livelist_delete_cb(void *arg, zthr_t *z)
static void
spa_start_livelist_destroy_thread(spa_t *spa)
{
- ASSERT3P(spa->spa_livelist_delete_zthr, ==, NULL);
+ ASSERT0P(spa->spa_livelist_delete_zthr);
spa->spa_livelist_delete_zthr =
zthr_create("z_livelist_destroy",
spa_livelist_delete_cb_check, spa_livelist_delete_cb, spa,
@@ -3275,7 +3275,7 @@ static int
livelist_track_new_cb(void *arg, const blkptr_t *bp, boolean_t bp_freed,
dmu_tx_t *tx)
{
- ASSERT(tx == NULL);
+ ASSERT0P(tx);
livelist_new_arg_t *lna = arg;
if (bp_freed) {
bplist_append(lna->frees, bp);
@@ -3469,7 +3469,7 @@ spa_start_livelist_condensing_thread(spa_t *spa)
spa->spa_to_condense.syncing = B_FALSE;
spa->spa_to_condense.cancelled = B_FALSE;
- ASSERT3P(spa->spa_livelist_condense_zthr, ==, NULL);
+ ASSERT0P(spa->spa_livelist_condense_zthr);
spa->spa_livelist_condense_zthr =
zthr_create("z_livelist_condense",
spa_livelist_condense_cb_check,
@@ -3486,7 +3486,7 @@ spa_spawn_aux_threads(spa_t *spa)
spa_start_livelist_destroy_thread(spa);
spa_start_livelist_condensing_thread(spa);
- ASSERT3P(spa->spa_checkpoint_discard_zthr, ==, NULL);
+ ASSERT0P(spa->spa_checkpoint_discard_zthr);
spa->spa_checkpoint_discard_zthr =
zthr_create("z_checkpoint_discard",
spa_checkpoint_discard_thread_check,
@@ -4091,11 +4091,11 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type)
nvlist_free(spa->spa_load_info);
spa->spa_load_info = fnvlist_alloc();
- ASSERT(spa->spa_comment == NULL);
+ ASSERT0P(spa->spa_comment);
if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
spa->spa_comment = spa_strdup(comment);
- ASSERT(spa->spa_compatibility == NULL);
+ ASSERT0P(spa->spa_compatibility);
if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMPATIBILITY,
&compatibility) == 0)
spa->spa_compatibility = spa_strdup(compatibility);
@@ -5913,7 +5913,7 @@ spa_load_best(spa_t *spa, spa_load_state_t state, uint64_t max_request,
nvlist_free(config);
if (state == SPA_LOAD_RECOVER) {
- ASSERT3P(loadinfo, ==, NULL);
+ ASSERT0P(loadinfo);
spa_import_progress_remove(spa_guid(spa));
return (rewind_error);
} else {
@@ -9091,7 +9091,7 @@ spa_vdev_setfru(spa_t *spa, uint64_t guid, const char *newfru)
int
spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t cmd)
{
- ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+ ASSERT0(spa_config_held(spa, SCL_ALL, RW_WRITER));
if (dsl_scan_resilvering(spa->spa_dsl_pool))
return (SET_ERROR(EBUSY));
@@ -9102,7 +9102,7 @@ spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t cmd)
int
spa_scan_stop(spa_t *spa)
{
- ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+ ASSERT0(spa_config_held(spa, SCL_ALL, RW_WRITER));
if (dsl_scan_resilvering(spa->spa_dsl_pool))
return (SET_ERROR(EBUSY));
@@ -9119,7 +9119,7 @@ int
spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
uint64_t txgend)
{
- ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
+ ASSERT0(spa_config_held(spa, SCL_ALL, RW_WRITER));
if (func >= POOL_SCAN_FUNCS || func == POOL_SCAN_NONE)
return (SET_ERROR(ENOTSUP));
@@ -9548,7 +9548,7 @@ spa_sync_frees(spa_t *spa, bplist_t *bpl, dmu_tx_t *tx)
{
zio_t *zio = zio_root(spa, NULL, NULL, 0);
bplist_iterate(bpl, spa_free_sync_cb, zio, tx);
- VERIFY(zio_wait(zio) == 0);
+ VERIFY0(zio_wait(zio));
}
/*
@@ -9587,7 +9587,7 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
size_t nvsize = 0;
dmu_buf_t *db;
- VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0);
+ VERIFY0(nvlist_size(nv, &nvsize, NV_ENCODE_XDR));
/*
* Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration
@@ -9597,15 +9597,15 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE);
packed = vmem_alloc(bufsize, KM_SLEEP);
- VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
- KM_SLEEP) == 0);
+ VERIFY0(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
+ KM_SLEEP));
memset(packed + nvsize, 0, bufsize - nvsize);
dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx);
vmem_free(packed, bufsize);
- VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db));
+ VERIFY0(dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db));
dmu_buf_will_dirty(db, tx);
*(uint64_t *)db->db_data = nvsize;
dmu_buf_rele(db, FTAG);
@@ -10541,7 +10541,7 @@ spa_sync_tq_create(spa_t *spa, const char *name)
{
kthread_t **kthreads;
- ASSERT(spa->spa_sync_tq == NULL);
+ ASSERT0P(spa->spa_sync_tq);
ASSERT3S(spa->spa_alloc_count, <=, boot_ncpus);
/*
diff --git a/sys/contrib/openzfs/module/zfs/spa_misc.c b/sys/contrib/openzfs/module/zfs/spa_misc.c
index 2eba8362a166..cce772eae598 100644
--- a/sys/contrib/openzfs/module/zfs/spa_misc.c
+++ b/sys/contrib/openzfs/module/zfs/spa_misc.c
@@ -471,9 +471,9 @@ spa_config_lock_destroy(spa_t *spa)
spa_config_lock_t *scl = &spa->spa_config_lock[i];
mutex_destroy(&scl->scl_lock);
cv_destroy(&scl->scl_cv);
- ASSERT(scl->scl_writer == NULL);
- ASSERT(scl->scl_write_wanted == 0);
- ASSERT(scl->scl_count == 0);
+ ASSERT0P(scl->scl_writer);
+ ASSERT0(scl->scl_write_wanted);
+ ASSERT0(scl->scl_count);
}
}
@@ -784,24 +784,23 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
dp->scd_path = altroot ? NULL : spa_strdup(spa_config_path);
list_insert_head(&spa->spa_config_list, dp);
- VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
- KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME, KM_SLEEP));
if (config != NULL) {
nvlist_t *features;
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
&features) == 0) {
- VERIFY(nvlist_dup(features, &spa->spa_label_features,
- 0) == 0);
+ VERIFY0(nvlist_dup(features,
+ &spa->spa_label_features, 0));
}
- VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
+ VERIFY0(nvlist_dup(config, &spa->spa_config, 0));
}
if (spa->spa_label_features == NULL) {
- VERIFY(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
- KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
+ KM_SLEEP));
}
spa->spa_min_ashift = INT_MAX;
diff --git a/sys/contrib/openzfs/module/zfs/spa_stats.c b/sys/contrib/openzfs/module/zfs/spa_stats.c
index 6d7cabcf766d..2c87122a0aa9 100644
--- a/sys/contrib/openzfs/module/zfs/spa_stats.c
+++ b/sys/contrib/openzfs/module/zfs/spa_stats.c
@@ -718,7 +718,7 @@ spa_mmp_history_set(spa_t *spa, uint64_t mmp_node_id, int io_error,
for (smh = list_tail(&shl->procfs_list.pl_list); smh != NULL;
smh = list_prev(&shl->procfs_list.pl_list, smh)) {
if (smh->mmp_node_id == mmp_node_id) {
- ASSERT(smh->io_error == 0);
+ ASSERT0(smh->io_error);
smh->io_error = io_error;
smh->duration = duration;
error = 0;
diff --git a/sys/contrib/openzfs/module/zfs/space_map.c b/sys/contrib/openzfs/module/zfs/space_map.c
index c429e0edd168..5f24963f2291 100644
--- a/sys/contrib/openzfs/module/zfs/space_map.c
+++ b/sys/contrib/openzfs/module/zfs/space_map.c
@@ -817,7 +817,7 @@ space_map_open(space_map_t **smp, objset_t *os, uint64_t object,
space_map_t *sm;
int error;
- ASSERT(*smp == NULL);
+ ASSERT0P(*smp);
ASSERT(os != NULL);
ASSERT(object != 0);
diff --git a/sys/contrib/openzfs/module/zfs/space_reftree.c b/sys/contrib/openzfs/module/zfs/space_reftree.c
index 9b2d5ed31dc9..889980e08c06 100644
--- a/sys/contrib/openzfs/module/zfs/space_reftree.c
+++ b/sys/contrib/openzfs/module/zfs/space_reftree.c
@@ -149,6 +149,6 @@ space_reftree_generate_map(avl_tree_t *t, zfs_range_tree_t *rt, int64_t minref)
}
}
}
- ASSERT(refcnt == 0);
+ ASSERT0(refcnt);
ASSERT(start == -1ULL);
}
diff --git a/sys/contrib/openzfs/module/zfs/vdev.c b/sys/contrib/openzfs/module/zfs/vdev.c
index 70b14fb9b2c8..9cf35e379000 100644
--- a/sys/contrib/openzfs/module/zfs/vdev.c
+++ b/sys/contrib/openzfs/module/zfs/vdev.c
@@ -554,7 +554,7 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd)
vdev_t **newchild;
ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
- ASSERT(cvd->vdev_parent == NULL);
+ ASSERT0P(cvd->vdev_parent);
cvd->vdev_parent = pvd;
@@ -578,7 +578,7 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd)
pvd->vdev_nonrot &= cvd->vdev_nonrot;
cvd->vdev_top = (pvd->vdev_top ? pvd->vdev_top: cvd);
- ASSERT(cvd->vdev_top->vdev_parent->vdev_parent == NULL);
+ ASSERT0P(cvd->vdev_top->vdev_parent->vdev_parent);
/*
* Walk up all ancestors to update guid sum.
@@ -1101,10 +1101,10 @@ vdev_free(vdev_t *vd)
{
spa_t *spa = vd->vdev_spa;
- ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
- ASSERT3P(vd->vdev_trim_thread, ==, NULL);
- ASSERT3P(vd->vdev_autotrim_thread, ==, NULL);
- ASSERT3P(vd->vdev_rebuild_thread, ==, NULL);
+ ASSERT0P(vd->vdev_initialize_thread);
+ ASSERT0P(vd->vdev_trim_thread);
+ ASSERT0P(vd->vdev_autotrim_thread);
+ ASSERT0P(vd->vdev_rebuild_thread);
/*
* Scan queues are normally destroyed at the end of a scan. If the
@@ -1133,7 +1133,7 @@ vdev_free(vdev_t *vd)
for (int c = 0; c < vd->vdev_children; c++)
vdev_free(vd->vdev_child[c]);
- ASSERT(vd->vdev_child == NULL);
+ ASSERT0P(vd->vdev_child);
ASSERT(vd->vdev_guid_sum == vd->vdev_guid);
if (vd->vdev_ops->vdev_op_fini != NULL)
@@ -1162,7 +1162,7 @@ vdev_free(vdev_t *vd)
*/
vdev_remove_child(vd->vdev_parent, vd);
- ASSERT(vd->vdev_parent == NULL);
+ ASSERT0P(vd->vdev_parent);
ASSERT(!list_link_active(&vd->vdev_leaf_node));
/*
@@ -1309,9 +1309,9 @@ vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
ASSERT0(tvd->vdev_indirect_config.vic_births_object);
ASSERT0(tvd->vdev_indirect_config.vic_mapping_object);
ASSERT3U(tvd->vdev_indirect_config.vic_prev_indirect_vdev, ==, -1ULL);
- ASSERT3P(tvd->vdev_indirect_mapping, ==, NULL);
- ASSERT3P(tvd->vdev_indirect_births, ==, NULL);
- ASSERT3P(tvd->vdev_obsolete_sm, ==, NULL);
+ ASSERT0P(tvd->vdev_indirect_mapping);
+ ASSERT0P(tvd->vdev_indirect_births);
+ ASSERT0P(tvd->vdev_obsolete_sm);
ASSERT0(tvd->vdev_noalloc);
ASSERT0(tvd->vdev_removing);
ASSERT0(tvd->vdev_rebuilding);
@@ -1464,7 +1464,7 @@ vdev_remove_parent(vdev_t *cvd)
if (cvd == cvd->vdev_top)
vdev_top_transfer(mvd, cvd);
- ASSERT(mvd->vdev_children == 0);
+ ASSERT0(mvd->vdev_children);
vdev_free(mvd);
}
@@ -2134,14 +2134,14 @@ vdev_open(vdev_t *vd)
* faulted, bail out of the open.
*/
if (!vd->vdev_removed && vd->vdev_faulted) {
- ASSERT(vd->vdev_children == 0);
+ ASSERT0(vd->vdev_children);
ASSERT(vd->vdev_label_aux == VDEV_AUX_ERR_EXCEEDED ||
vd->vdev_label_aux == VDEV_AUX_EXTERNAL);
vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED,
vd->vdev_label_aux);
return (SET_ERROR(ENXIO));
} else if (vd->vdev_offline) {
- ASSERT(vd->vdev_children == 0);
+ ASSERT0(vd->vdev_children);
vdev_set_state(vd, B_TRUE, VDEV_STATE_OFFLINE, VDEV_AUX_NONE);
return (SET_ERROR(ENXIO));
}
@@ -2197,7 +2197,7 @@ vdev_open(vdev_t *vd)
* the vdev is accessible. If we're faulted, bail.
*/
if (vd->vdev_faulted) {
- ASSERT(vd->vdev_children == 0);
+ ASSERT0(vd->vdev_children);
ASSERT(vd->vdev_label_aux == VDEV_AUX_ERR_EXCEEDED ||
vd->vdev_label_aux == VDEV_AUX_EXTERNAL);
vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED,
@@ -2206,7 +2206,7 @@ vdev_open(vdev_t *vd)
}
if (vd->vdev_degraded) {
- ASSERT(vd->vdev_children == 0);
+ ASSERT0(vd->vdev_children);
vdev_set_state(vd, B_TRUE, VDEV_STATE_DEGRADED,
VDEV_AUX_ERR_EXCEEDED);
} else {
@@ -3945,7 +3945,7 @@ vdev_load(vdev_t *vd)
if (error == 0 && checkpoint_sm_obj != 0) {
objset_t *mos = spa_meta_objset(vd->vdev_spa);
ASSERT(vd->vdev_asize != 0);
- ASSERT3P(vd->vdev_checkpoint_sm, ==, NULL);
+ ASSERT0P(vd->vdev_checkpoint_sm);
error = space_map_open(&vd->vdev_checkpoint_sm,
mos, checkpoint_sm_obj, 0, vd->vdev_asize,
@@ -3993,7 +3993,7 @@ vdev_load(vdev_t *vd)
if (error == 0 && obsolete_sm_object != 0) {
objset_t *mos = vd->vdev_spa->spa_meta_objset;
ASSERT(vd->vdev_asize != 0);
- ASSERT3P(vd->vdev_obsolete_sm, ==, NULL);
+ ASSERT0P(vd->vdev_obsolete_sm);
if ((error = space_map_open(&vd->vdev_obsolete_sm, mos,
obsolete_sm_object, 0, vd->vdev_asize, 0))) {
@@ -4521,7 +4521,7 @@ top:
/*
* Prevent any future allocations.
*/
- ASSERT3P(tvd->vdev_log_mg, ==, NULL);
+ ASSERT0P(tvd->vdev_log_mg);
metaslab_group_passivate(mg);
(void) spa_vdev_state_exit(spa, vd, 0);
@@ -5194,7 +5194,7 @@ vdev_stat_update(zio_t *zio, uint64_t psize)
int64_t
vdev_deflated_space(vdev_t *vd, int64_t space)
{
- ASSERT((space & (SPA_MINBLOCKSIZE-1)) == 0);
+ ASSERT0((space & (SPA_MINBLOCKSIZE-1)));
ASSERT(vd->vdev_deflate_ratio != 0 || vd->vdev_isl2cache);
return ((space >> SPA_MINBLOCKSHIFT) * vd->vdev_deflate_ratio);
@@ -5286,8 +5286,8 @@ vdev_config_dirty(vdev_t *vd)
if (nvlist_lookup_nvlist_array(sav->sav_config,
ZPOOL_CONFIG_L2CACHE, &aux, &naux) != 0) {
- VERIFY(nvlist_lookup_nvlist_array(sav->sav_config,
- ZPOOL_CONFIG_SPARES, &aux, &naux) == 0);
+ VERIFY0(nvlist_lookup_nvlist_array(sav->sav_config,
+ ZPOOL_CONFIG_SPARES, &aux, &naux));
}
ASSERT(c < naux);
@@ -5675,7 +5675,7 @@ vdev_expand(vdev_t *vd, uint64_t txg)
(vd->vdev_asize >> vd->vdev_ms_shift) > vd->vdev_ms_count &&
vdev_is_concrete(vd)) {
vdev_metaslab_group_create(vd);
- VERIFY(vdev_metaslab_init(vd, txg) == 0);
+ VERIFY0(vdev_metaslab_init(vd, txg));
vdev_config_dirty(vd);
}
}
diff --git a/sys/contrib/openzfs/module/zfs/vdev_draid.c b/sys/contrib/openzfs/module/zfs/vdev_draid.c
index feec5fd3ce17..a05289102af2 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_draid.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_draid.c
@@ -477,7 +477,7 @@ vdev_draid_generate_perms(const draid_map_t *map, uint8_t **permsp)
VERIFY3U(map->dm_children, <=, VDEV_DRAID_MAX_CHILDREN);
VERIFY3U(map->dm_seed, !=, 0);
VERIFY3U(map->dm_nperms, !=, 0);
- VERIFY3P(map->dm_perms, ==, NULL);
+ VERIFY0P(map->dm_perms);
#ifdef _KERNEL
/*
@@ -590,7 +590,7 @@ vdev_draid_psize_to_asize(vdev_t *vd, uint64_t psize, uint64_t txg)
uint64_t asize = (rows * vdc->vdc_groupwidth) << ashift;
ASSERT3U(asize, !=, 0);
- ASSERT3U(asize % (vdc->vdc_groupwidth), ==, 0);
+ ASSERT0(asize % (vdc->vdc_groupwidth));
return (asize);
}
@@ -704,7 +704,7 @@ vdev_draid_map_alloc_scrub(zio_t *zio, uint64_t abd_offset, raidz_row_t *rr)
uint64_t skip_off = 0;
ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
- ASSERT3P(rr->rr_abd_empty, ==, NULL);
+ ASSERT0P(rr->rr_abd_empty);
if (rr->rr_nempty > 0) {
rr->rr_abd_empty = abd_alloc_linear(rr->rr_nempty * skip_size,
@@ -793,7 +793,7 @@ vdev_draid_map_alloc_empty(zio_t *zio, raidz_row_t *rr)
uint64_t skip_off = 0;
ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
- ASSERT3P(rr->rr_abd_empty, ==, NULL);
+ ASSERT0P(rr->rr_abd_empty);
if (rr->rr_nempty > 0) {
rr->rr_abd_empty = abd_alloc_linear(rr->rr_nempty * skip_size,
@@ -807,7 +807,7 @@ vdev_draid_map_alloc_empty(zio_t *zio, raidz_row_t *rr)
/* empty data column (small read), add a skip sector */
ASSERT3U(skip_size, ==, parity_size);
ASSERT3U(rr->rr_nempty, !=, 0);
- ASSERT3P(rc->rc_abd, ==, NULL);
+ ASSERT0P(rc->rc_abd);
rc->rc_abd = abd_get_offset_size(rr->rr_abd_empty,
skip_off, skip_size);
skip_off += skip_size;
@@ -1623,7 +1623,7 @@ vdev_draid_rebuild_asize(vdev_t *vd, uint64_t start, uint64_t asize,
SPA_MAXBLOCKSIZE);
ASSERT3U(vdev_draid_get_astart(vd, start), ==, start);
- ASSERT3U(asize % (vdc->vdc_groupwidth << ashift), ==, 0);
+ ASSERT0(asize % (vdc->vdc_groupwidth << ashift));
/* Chunks must evenly span all data columns in the group. */
psize = (((psize >> ashift) / ndata) * ndata) << ashift;
@@ -1634,7 +1634,7 @@ vdev_draid_rebuild_asize(vdev_t *vd, uint64_t start, uint64_t asize,
uint64_t left = vdev_draid_group_to_offset(vd, group + 1) - start;
chunk_size = MIN(chunk_size, left);
- ASSERT3U(chunk_size % (vdc->vdc_groupwidth << ashift), ==, 0);
+ ASSERT0(chunk_size % (vdc->vdc_groupwidth << ashift));
ASSERT3U(vdev_draid_offset_to_group(vd, start), ==,
vdev_draid_offset_to_group(vd, start + chunk_size - 1));
@@ -2272,7 +2272,7 @@ vdev_draid_init(spa_t *spa, nvlist_t *nv, void **tsd)
ASSERT3U(vdc->vdc_groupwidth, <=, vdc->vdc_ndisks);
ASSERT3U(vdc->vdc_groupsz, >=, 2 * VDEV_DRAID_ROWHEIGHT);
ASSERT3U(vdc->vdc_devslicesz, >=, VDEV_DRAID_ROWHEIGHT);
- ASSERT3U(vdc->vdc_devslicesz % VDEV_DRAID_ROWHEIGHT, ==, 0);
+ ASSERT0(vdc->vdc_devslicesz % VDEV_DRAID_ROWHEIGHT);
ASSERT3U((vdc->vdc_groupwidth * vdc->vdc_ngroups) %
vdc->vdc_ndisks, ==, 0);
diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect.c b/sys/contrib/openzfs/module/zfs/vdev_indirect.c
index 9fc71fa0e03e..7538f471e63c 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_indirect.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_indirect.c
@@ -792,7 +792,7 @@ spa_condense_indirect_start_sync(vdev_t *vd, dmu_tx_t *tx)
DMU_POOL_CONDENSING_INDIRECT, sizeof (uint64_t),
sizeof (*scip) / sizeof (uint64_t), scip, tx));
- ASSERT3P(spa->spa_condensing_indirect, ==, NULL);
+ ASSERT0P(spa->spa_condensing_indirect);
spa->spa_condensing_indirect = spa_condensing_indirect_create(spa);
zfs_dbgmsg("starting condense of vdev %llu in txg %llu: "
@@ -882,7 +882,7 @@ spa_condense_fini(spa_t *spa)
void
spa_start_indirect_condensing_thread(spa_t *spa)
{
- ASSERT3P(spa->spa_condense_zthr, ==, NULL);
+ ASSERT0P(spa->spa_condense_zthr);
spa->spa_condense_zthr = zthr_create("z_indirect_condense",
spa_condense_indirect_thread_check,
spa_condense_indirect_thread, spa, minclsyspri);
@@ -1504,7 +1504,7 @@ vdev_indirect_splits_checksum_validate(indirect_vsd_t *iv, zio_t *zio)
is != NULL; is = list_next(&iv->iv_splits, is)) {
ASSERT3P(is->is_good_child->ic_data, !=, NULL);
- ASSERT3P(is->is_good_child->ic_duplicate, ==, NULL);
+ ASSERT0P(is->is_good_child->ic_duplicate);
abd_copy_off(zio->io_abd, is->is_good_child->ic_data,
is->is_split_offset, 0, is->is_size);
diff --git a/sys/contrib/openzfs/module/zfs/vdev_initialize.c b/sys/contrib/openzfs/module/zfs/vdev_initialize.c
index 9243c76e810d..27188c46e561 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_initialize.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_initialize.c
@@ -632,7 +632,7 @@ vdev_initialize(vdev_t *vd)
ASSERT(MUTEX_HELD(&vd->vdev_initialize_lock));
ASSERT(vd->vdev_ops->vdev_op_leaf);
ASSERT(vdev_is_concrete(vd));
- ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
+ ASSERT0P(vd->vdev_initialize_thread);
ASSERT(!vd->vdev_detached);
ASSERT(!vd->vdev_initialize_exit_wanted);
ASSERT(!vd->vdev_top->vdev_removing);
@@ -653,7 +653,7 @@ vdev_uninitialize(vdev_t *vd)
ASSERT(MUTEX_HELD(&vd->vdev_initialize_lock));
ASSERT(vd->vdev_ops->vdev_op_leaf);
ASSERT(vdev_is_concrete(vd));
- ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
+ ASSERT0P(vd->vdev_initialize_thread);
ASSERT(!vd->vdev_detached);
ASSERT(!vd->vdev_initialize_exit_wanted);
ASSERT(!vd->vdev_top->vdev_removing);
@@ -672,7 +672,7 @@ vdev_initialize_stop_wait_impl(vdev_t *vd)
while (vd->vdev_initialize_thread != NULL)
cv_wait(&vd->vdev_initialize_cv, &vd->vdev_initialize_lock);
- ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
+ ASSERT0P(vd->vdev_initialize_thread);
vd->vdev_initialize_exit_wanted = B_FALSE;
}
diff --git a/sys/contrib/openzfs/module/zfs/vdev_label.c b/sys/contrib/openzfs/module/zfs/vdev_label.c
index 6baa6236aac2..c44f654b0261 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_label.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_label.c
@@ -163,7 +163,7 @@ uint64_t
vdev_label_offset(uint64_t psize, int l, uint64_t offset)
{
ASSERT(offset < sizeof (vdev_label_t));
- ASSERT(P2PHASE_TYPED(psize, sizeof (vdev_label_t), uint64_t) == 0);
+ ASSERT0(P2PHASE_TYPED(psize, sizeof (vdev_label_t), uint64_t));
return (offset + l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
0 : psize - VDEV_LABELS * sizeof (vdev_label_t)));
@@ -768,12 +768,12 @@ vdev_top_config_generate(spa_t *spa, nvlist_t *config)
}
if (idx) {
- VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_HOLE_ARRAY,
- array, idx) == 0);
+ VERIFY0(nvlist_add_uint64_array(config,
+ ZPOOL_CONFIG_HOLE_ARRAY, array, idx));
}
- VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_VDEV_CHILDREN,
- rvd->vdev_children) == 0);
+ VERIFY0(nvlist_add_uint64(config, ZPOOL_CONFIG_VDEV_CHILDREN,
+ rvd->vdev_children));
kmem_free(array, rvd->vdev_children * sizeof (uint64_t));
}
@@ -1189,8 +1189,8 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
* vdev uses as described above, and automatically expires if we
* fail.
*/
- VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_CREATE_TXG,
- crtxg) == 0);
+ VERIFY0(nvlist_add_uint64(label, ZPOOL_CONFIG_CREATE_TXG,
+ crtxg));
}
buf = vp->vp_nvlist;
diff --git a/sys/contrib/openzfs/module/zfs/vdev_queue.c b/sys/contrib/openzfs/module/zfs/vdev_queue.c
index aa41f7066036..c12713b107bf 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_queue.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_queue.c
@@ -780,7 +780,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
if (dio->io_flags & ZIO_FLAG_NODATA) {
/* allocate a buffer for a write gap */
ASSERT3U(dio->io_type, ==, ZIO_TYPE_WRITE);
- ASSERT3P(dio->io_abd, ==, NULL);
+ ASSERT0P(dio->io_abd);
abd_gang_add(aio->io_abd,
abd_get_zeros(dio->io_size), B_TRUE);
} else {
diff --git a/sys/contrib/openzfs/module/zfs/vdev_raidz.c b/sys/contrib/openzfs/module/zfs/vdev_raidz.c
index 210cdcab1ecc..b597d6daefde 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_raidz.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_raidz.c
@@ -412,7 +412,7 @@ vdev_raidz_map_free(raidz_map_t *rm)
rm->rm_nphys_cols);
}
- ASSERT3P(rm->rm_lr, ==, NULL);
+ ASSERT0P(rm->rm_lr);
kmem_free(rm, offsetof(raidz_map_t, rm_row[rm->rm_nrows]));
}
@@ -2431,7 +2431,7 @@ raidz_start_skip_writes(zio_t *zio)
vdev_t *cvd = vd->vdev_child[rc->rc_devidx];
if (rc->rc_size != 0)
continue;
- ASSERT3P(rc->rc_abd, ==, NULL);
+ ASSERT0P(rc->rc_abd);
ASSERT3U(rc->rc_offset, <,
cvd->vdev_psize - VDEV_LABEL_END_SIZE);
@@ -3363,7 +3363,7 @@ vdev_raidz_io_done_reconstruct_known_missing(zio_t *zio, raidz_map_t *rm,
* also have been fewer parity errors than parity
* columns or, again, we wouldn't be in this code path.
*/
- ASSERT(parity_untried == 0);
+ ASSERT0(parity_untried);
ASSERT(parity_errors < rr->rr_firstdatacol);
/*
@@ -4743,7 +4743,7 @@ spa_raidz_expand_thread(void *arg, zthr_t *zthr)
void
spa_start_raidz_expansion_thread(spa_t *spa)
{
- ASSERT3P(spa->spa_raidz_expand_zthr, ==, NULL);
+ ASSERT0P(spa->spa_raidz_expand_zthr);
spa->spa_raidz_expand_zthr = zthr_create("raidz_expand",
spa_raidz_expand_thread_check, spa_raidz_expand_thread,
spa, defclsyspri);
diff --git a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
index cf259788ccf4..47b3b9921abe 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
@@ -256,7 +256,7 @@ vdev_rebuild_initiate_sync(void *arg, dmu_tx_t *tx)
"vdev_id=%llu vdev_guid=%llu started",
(u_longlong_t)vd->vdev_id, (u_longlong_t)vd->vdev_guid);
- ASSERT3P(vd->vdev_rebuild_thread, ==, NULL);
+ ASSERT0P(vd->vdev_rebuild_thread);
vd->vdev_rebuild_thread = thread_create(NULL, 0,
vdev_rebuild_thread, vd, 0, &p0, TS_RUN, maxclsyspri);
@@ -413,7 +413,7 @@ vdev_rebuild_reset_sync(void *arg, dmu_tx_t *tx)
mutex_enter(&vd->vdev_rebuild_lock);
ASSERT(vrp->vrp_rebuild_state == VDEV_REBUILD_ACTIVE);
- ASSERT3P(vd->vdev_rebuild_thread, ==, NULL);
+ ASSERT0P(vd->vdev_rebuild_thread);
vrp->vrp_last_offset = 0;
vrp->vrp_min_txg = 0;
diff --git a/sys/contrib/openzfs/module/zfs/vdev_removal.c b/sys/contrib/openzfs/module/zfs/vdev_removal.c
index 3887be4bd548..2f7a739da241 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_removal.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_removal.c
@@ -344,10 +344,10 @@ spa_vdev_remove_aux(nvlist_t *config, const char *name, nvlist_t **dev,
for (int i = 0, j = 0; i < count; i++) {
if (dev[i] == dev_to_remove)
continue;
- VERIFY(nvlist_dup(dev[i], &newdev[j++], KM_SLEEP) == 0);
+ VERIFY0(nvlist_dup(dev[i], &newdev[j++], KM_SLEEP));
}
- VERIFY(nvlist_remove(config, name, DATA_TYPE_NVLIST_ARRAY) == 0);
+ VERIFY0(nvlist_remove(config, name, DATA_TYPE_NVLIST_ARRAY));
fnvlist_add_nvlist_array(config, name, (const nvlist_t * const *)newdev,
count - 1);
@@ -423,7 +423,7 @@ vdev_remove_initiate_sync(void *arg, dmu_tx_t *tx)
svr = spa_vdev_removal_create(vd);
ASSERT(vd->vdev_removing);
- ASSERT3P(vd->vdev_indirect_mapping, ==, NULL);
+ ASSERT0P(vd->vdev_indirect_mapping);
spa_feature_incr(spa, SPA_FEATURE_DEVICE_REMOVAL, tx);
if (spa_feature_is_enabled(spa, SPA_FEATURE_OBSOLETE_COUNTS)) {
@@ -529,7 +529,7 @@ vdev_remove_initiate_sync(void *arg, dmu_tx_t *tx)
* but in any case only when there are outstanding free i/os, which
* there are not).
*/
- ASSERT3P(spa->spa_vdev_removal, ==, NULL);
+ ASSERT0P(spa->spa_vdev_removal);
spa->spa_vdev_removal = svr;
svr->svr_thread = thread_create(NULL, 0,
spa_vdev_remove_thread, spa, 0, &p0, TS_RUN, minclsyspri);
@@ -1362,11 +1362,11 @@ vdev_remove_complete(spa_t *spa)
txg_wait_synced(spa->spa_dsl_pool, 0);
txg = spa_vdev_enter(spa);
vdev_t *vd = vdev_lookup_top(spa, spa->spa_vdev_removal->svr_vdev_id);
- ASSERT3P(vd->vdev_initialize_thread, ==, NULL);
- ASSERT3P(vd->vdev_trim_thread, ==, NULL);
- ASSERT3P(vd->vdev_autotrim_thread, ==, NULL);
+ ASSERT0P(vd->vdev_initialize_thread);
+ ASSERT0P(vd->vdev_trim_thread);
+ ASSERT0P(vd->vdev_autotrim_thread);
vdev_rebuild_stop_wait(vd);
- ASSERT3P(vd->vdev_rebuild_thread, ==, NULL);
+ ASSERT0P(vd->vdev_rebuild_thread);
sysevent_t *ev = spa_event_create(spa, vd, NULL,
ESC_ZFS_VDEV_REMOVE_DEV);
@@ -1868,7 +1868,7 @@ spa_vdev_remove_cancel_sync(void *arg, dmu_tx_t *tx)
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
objset_t *mos = spa->spa_meta_objset;
- ASSERT3P(svr->svr_thread, ==, NULL);
+ ASSERT0P(svr->svr_thread);
spa_feature_decr(spa, SPA_FEATURE_DEVICE_REMOVAL, tx);
@@ -2076,7 +2076,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg)
ASSERT(vd->vdev_islog);
ASSERT(vd == vd->vdev_top);
- ASSERT3P(vd->vdev_log_mg, ==, NULL);
+ ASSERT0P(vd->vdev_log_mg);
ASSERT(MUTEX_HELD(&spa_namespace_lock));
/*
@@ -2112,7 +2112,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg)
if (error != 0) {
metaslab_group_activate(mg);
- ASSERT3P(vd->vdev_log_mg, ==, NULL);
+ ASSERT0P(vd->vdev_log_mg);
return (error);
}
ASSERT0(vd->vdev_stat.vs_alloc);
diff --git a/sys/contrib/openzfs/module/zfs/vdev_trim.c b/sys/contrib/openzfs/module/zfs/vdev_trim.c
index fc8d5b8e9a8a..eee18b367909 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_trim.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_trim.c
@@ -1010,7 +1010,7 @@ vdev_trim(vdev_t *vd, uint64_t rate, boolean_t partial, boolean_t secure)
ASSERT(MUTEX_HELD(&vd->vdev_trim_lock));
ASSERT(vd->vdev_ops->vdev_op_leaf);
ASSERT(vdev_is_concrete(vd));
- ASSERT3P(vd->vdev_trim_thread, ==, NULL);
+ ASSERT0P(vd->vdev_trim_thread);
ASSERT(!vd->vdev_detached);
ASSERT(!vd->vdev_trim_exit_wanted);
ASSERT(!vd->vdev_top->vdev_removing);
@@ -1032,7 +1032,7 @@ vdev_trim_stop_wait_impl(vdev_t *vd)
while (vd->vdev_trim_thread != NULL)
cv_wait(&vd->vdev_trim_cv, &vd->vdev_trim_lock);
- ASSERT3P(vd->vdev_trim_thread, ==, NULL);
+ ASSERT0P(vd->vdev_trim_thread);
vd->vdev_trim_exit_wanted = B_FALSE;
}
@@ -1539,7 +1539,7 @@ vdev_autotrim_stop_wait(vdev_t *tvd)
cv_wait(&tvd->vdev_autotrim_cv,
&tvd->vdev_autotrim_lock);
- ASSERT3P(tvd->vdev_autotrim_thread, ==, NULL);
+ ASSERT0P(tvd->vdev_autotrim_thread);
tvd->vdev_autotrim_exit_wanted = B_FALSE;
}
mutex_exit(&tvd->vdev_autotrim_lock);
@@ -1712,7 +1712,7 @@ vdev_trim_l2arc(spa_t *spa)
mutex_enter(&vd->vdev_trim_lock);
ASSERT(vd->vdev_ops->vdev_op_leaf);
ASSERT(vdev_is_concrete(vd));
- ASSERT3P(vd->vdev_trim_thread, ==, NULL);
+ ASSERT0P(vd->vdev_trim_thread);
ASSERT(!vd->vdev_detached);
ASSERT(!vd->vdev_trim_exit_wanted);
ASSERT(!vd->vdev_top->vdev_removing);
diff --git a/sys/contrib/openzfs/module/zfs/zap.c b/sys/contrib/openzfs/module/zfs/zap.c
index 0896690c97e3..3e4e997798a3 100644
--- a/sys/contrib/openzfs/module/zfs/zap.c
+++ b/sys/contrib/openzfs/module/zfs/zap.c
@@ -921,7 +921,7 @@ fzap_add_cd(zap_name_t *zn,
ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
ASSERT(!zap->zap_ismicro);
- ASSERT(fzap_check(zn, integer_size, num_integers) == 0);
+ ASSERT0(fzap_check(zn, integer_size, num_integers));
err = zap_deref_leaf(zap, zn->zn_hash, tx, RW_WRITER, &l);
if (err != 0)
@@ -1386,7 +1386,7 @@ again:
}
err = zap_entry_read_name(zap, &zeh,
za->za_name_len, za->za_name);
- ASSERT(err == 0);
+ ASSERT0(err);
za->za_normalization_conflict =
zap_entry_normalization_conflict(&zeh,
@@ -1546,7 +1546,7 @@ zap_shrink(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
boolean_t trunc = B_FALSE;
int err = 0;
- ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nentries, ==, 0);
+ ASSERT0(zap_leaf_phys(l)->l_hdr.lh_nentries);
ASSERT3U(prefix_len, <=, zap_f_phys(zap)->zap_ptrtbl.zt_shift);
ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
ASSERT3U(ZAP_HASH_IDX(hash, prefix_len), ==, prefix);
@@ -1564,7 +1564,7 @@ zap_shrink(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
uint64_t sl_hash = ZAP_PREFIX_HASH(sl_prefix, prefix_len);
int slbit = prefix & 1;
- ASSERT3U(zap_leaf_phys(l)->l_hdr.lh_nentries, ==, 0);
+ ASSERT0(zap_leaf_phys(l)->l_hdr.lh_nentries);
/*
* Check if there is a sibling by reading ptrtbl ptrs.
diff --git a/sys/contrib/openzfs/module/zfs/zap_micro.c b/sys/contrib/openzfs/module/zfs/zap_micro.c
index 411b1a9db5ab..ea4e3117a8b9 100644
--- a/sys/contrib/openzfs/module/zfs/zap_micro.c
+++ b/sys/contrib/openzfs/module/zfs/zap_micro.c
@@ -346,7 +346,7 @@ zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints)
{
zap_name_t *zn = kmem_cache_alloc(zap_name_cache, KM_SLEEP);
- ASSERT(zap->zap_normflags == 0);
+ ASSERT0(zap->zap_normflags);
zn->zn_zap = zap;
zn->zn_key_intlen = sizeof (*key);
zn->zn_key_orig = zn->zn_key_norm = key;
@@ -1876,7 +1876,7 @@ zap_cursor_serialize(zap_cursor_t *zc)
return (-1ULL);
if (zc->zc_zap == NULL)
return (zc->zc_serialized);
- ASSERT((zc->zc_hash & zap_maxcd(zc->zc_zap)) == 0);
+ ASSERT0((zc->zc_hash & zap_maxcd(zc->zc_zap)));
ASSERT(zc->zc_cd < zap_maxcd(zc->zc_zap));
/*
@@ -1911,7 +1911,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
* we must add to the existing zc_cd, which may already
* be 1 due to the zap_cursor_advance.
*/
- ASSERT(zc->zc_hash == 0);
+ ASSERT0(zc->zc_hash);
hb = zap_hashbits(zc->zc_zap);
zc->zc_hash = zc->zc_serialized << (64 - hb);
zc->zc_cd += zc->zc_serialized >> hb;
diff --git a/sys/contrib/openzfs/module/zfs/zcp.c b/sys/contrib/openzfs/module/zfs/zcp.c
index 9aecf67fd256..c6684f453e95 100644
--- a/sys/contrib/openzfs/module/zfs/zcp.c
+++ b/sys/contrib/openzfs/module/zfs/zcp.c
@@ -765,7 +765,7 @@ zcp_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
return (NULL);
}
(void) memcpy(luabuf, ptr, osize);
- VERIFY3P(zcp_lua_alloc(ud, ptr, osize, 0), ==, NULL);
+ VERIFY0P(zcp_lua_alloc(ud, ptr, osize, 0));
return (luabuf);
}
}
diff --git a/sys/contrib/openzfs/module/zfs/zfeature.c b/sys/contrib/openzfs/module/zfs/zfeature.c
index 7dfe00d42a08..0816ea134bf3 100644
--- a/sys/contrib/openzfs/module/zfs/zfeature.c
+++ b/sys/contrib/openzfs/module/zfs/zfeature.c
@@ -210,8 +210,8 @@ spa_features_check(spa_t *spa, boolean_t for_write,
za->za_name, 1, MAXPATHLEN, buf) == 0)
desc = buf;
- VERIFY(nvlist_add_string(unsup_feat,
- za->za_name, desc) == 0);
+ VERIFY0(nvlist_add_string(unsup_feat,
+ za->za_name, desc));
}
}
}
diff --git a/sys/contrib/openzfs/module/zfs/zfs_fuid.c b/sys/contrib/openzfs/module/zfs/zfs_fuid.c
index 10a6d289fbf8..2af1efe82e62 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_fuid.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_fuid.c
@@ -112,8 +112,7 @@ zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
uint64_t fuid_size;
ASSERT(fuid_obj != 0);
- VERIFY(0 == dmu_bonus_hold(os, fuid_obj,
- FTAG, &db));
+ VERIFY0(dmu_bonus_hold(os, fuid_obj, FTAG, &db));
fuid_size = *(uint64_t *)db->db_data;
dmu_buf_rele(db, FTAG);
@@ -125,22 +124,21 @@ zfs_fuid_table_load(objset_t *os, uint64_t fuid_obj, avl_tree_t *idx_tree,
int i;
packed = kmem_alloc(fuid_size, KM_SLEEP);
- VERIFY(dmu_read(os, fuid_obj, 0,
- fuid_size, packed, DMU_READ_PREFETCH) == 0);
- VERIFY(nvlist_unpack(packed, fuid_size,
- &nvp, 0) == 0);
- VERIFY(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
- &fuidnvp, &count) == 0);
+ VERIFY0(dmu_read(os, fuid_obj, 0,
+ fuid_size, packed, DMU_READ_PREFETCH));
+ VERIFY0(nvlist_unpack(packed, fuid_size, &nvp, 0));
+ VERIFY0(nvlist_lookup_nvlist_array(nvp, FUID_NVP_ARRAY,
+ &fuidnvp, &count));
for (i = 0; i != count; i++) {
fuid_domain_t *domnode;
const char *domain;
uint64_t idx;
- VERIFY(nvlist_lookup_string(fuidnvp[i], FUID_DOMAIN,
- &domain) == 0);
- VERIFY(nvlist_lookup_uint64(fuidnvp[i], FUID_IDX,
- &idx) == 0);
+ VERIFY0(nvlist_lookup_string(fuidnvp[i], FUID_DOMAIN,
+ &domain));
+ VERIFY0(nvlist_lookup_uint64(fuidnvp[i], FUID_IDX,
+ &idx));
domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
@@ -246,35 +244,33 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
&zfsvfs->z_fuid_obj, tx) == 0);
}
- VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP));
numnodes = avl_numnodes(&zfsvfs->z_fuid_idx);
fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP);
for (i = 0, domnode = avl_first(&zfsvfs->z_fuid_domain); domnode; i++,
domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode)) {
- VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0);
- VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
- domnode->f_idx) == 0);
- VERIFY(nvlist_add_uint64(fuids[i], FUID_OFFSET, 0) == 0);
- VERIFY(nvlist_add_string(fuids[i], FUID_DOMAIN,
- domnode->f_ksid->kd_name) == 0);
+ VERIFY0(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP));
+ VERIFY0(nvlist_add_uint64(fuids[i], FUID_IDX,
+ domnode->f_idx));
+ VERIFY0(nvlist_add_uint64(fuids[i], FUID_OFFSET, 0));
+ VERIFY0(nvlist_add_string(fuids[i], FUID_DOMAIN,
+ domnode->f_ksid->kd_name));
}
fnvlist_add_nvlist_array(nvp, FUID_NVP_ARRAY,
(const nvlist_t * const *)fuids, numnodes);
for (i = 0; i != numnodes; i++)
nvlist_free(fuids[i]);
kmem_free(fuids, numnodes * sizeof (void *));
- VERIFY(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR) == 0);
+ VERIFY0(nvlist_size(nvp, &nvsize, NV_ENCODE_XDR));
packed = kmem_alloc(nvsize, KM_SLEEP);
- VERIFY(nvlist_pack(nvp, &packed, &nvsize,
- NV_ENCODE_XDR, KM_SLEEP) == 0);
+ VERIFY0(nvlist_pack(nvp, &packed, &nvsize, NV_ENCODE_XDR, KM_SLEEP));
nvlist_free(nvp);
zfsvfs->z_fuid_size = nvsize;
dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
zfsvfs->z_fuid_size, packed, tx);
kmem_free(packed, zfsvfs->z_fuid_size);
- VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
- FTAG, &db));
+ VERIFY0(dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj, FTAG, &db));
dmu_buf_will_dirty(db, tx);
*(uint64_t *)db->db_data = zfsvfs->z_fuid_size;
dmu_buf_rele(db, FTAG);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
index dcb71229f96a..121b966b9864 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
@@ -1493,7 +1493,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
goto pool_props_bad;
(void) nvlist_remove_all(props, ZPOOL_HIDDEN_ARGS);
- VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP));
error = zfs_fill_zplprops_root(version, rootprops,
zplprops, NULL);
if (error != 0)
@@ -2245,7 +2245,7 @@ nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop)
*/
if ((error = zfs_get_zplprop(os, prop, &value)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0);
+ VERIFY0(nvlist_add_uint64(props, zfs_prop_to_name(prop), value));
return (0);
}
@@ -2280,7 +2280,7 @@ zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
dmu_objset_type(os) == DMU_OST_ZFS) {
nvlist_t *nv;
- VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP));
if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 &&
(err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 &&
(err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 &&
@@ -2483,7 +2483,7 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
nvlist_t *attrs;
- VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
+ VERIFY0(nvpair_value_nvlist(pair, &attrs));
if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
&pair) != 0)
return (SET_ERROR(EINVAL));
@@ -2538,9 +2538,8 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
nvlist_t *attrs;
- VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
- VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
- &pair) == 0);
+ VERIFY0(nvpair_value_nvlist(pair, &attrs));
+ VERIFY0(nvlist_lookup_nvpair(attrs, ZPROP_VALUE, &pair));
}
/* all special properties are numeric except for keylocation */
@@ -2932,14 +2931,14 @@ props_skip(nvlist_t *props, nvlist_t *skipped, nvlist_t **newprops)
{
nvpair_t *pair;
- VERIFY(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP));
pair = NULL;
while ((pair = nvlist_next_nvpair(props, pair)) != NULL) {
if (nvlist_exists(skipped, nvpair_name(pair)))
continue;
- VERIFY(nvlist_add_nvpair(*newprops, pair) == 0);
+ VERIFY0(nvlist_add_nvpair(*newprops, pair));
}
}
@@ -3064,11 +3063,11 @@ zfs_ioc_inherit_prop(zfs_cmd_t *zc)
switch (type) {
case PROP_TYPE_STRING:
- VERIFY(0 == nvlist_add_string(dummy, propname, ""));
+ VERIFY0(nvlist_add_string(dummy, propname, ""));
break;
case PROP_TYPE_NUMBER:
case PROP_TYPE_INDEX:
- VERIFY(0 == nvlist_add_uint64(dummy, propname, 0));
+ VERIFY0(nvlist_add_uint64(dummy, propname, 0));
break;
default:
err = SET_ERROR(EINVAL);
@@ -3454,14 +3453,14 @@ zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
/*
* Put the version in the zplprops
*/
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_VERSION), zplver));
if (norm == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm));
/*
* If we're normalizing, names must always be valid UTF-8 strings.
@@ -3471,55 +3470,55 @@ zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
if (u8 == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8));
if (sense == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_CASE, &sense)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_CASE), sense));
if (duq == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_DEFAULTUSERQUOTA, &duq)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_DEFAULTUSERQUOTA), duq) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_DEFAULTUSERQUOTA), duq));
if (dgq == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_DEFAULTGROUPQUOTA,
&dgq)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_DEFAULTGROUPQUOTA), dgq) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_DEFAULTGROUPQUOTA), dgq));
if (dpq == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_DEFAULTPROJECTQUOTA,
&dpq)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_DEFAULTPROJECTQUOTA), dpq) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_DEFAULTPROJECTQUOTA), dpq));
if (duoq == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_DEFAULTUSEROBJQUOTA,
&duoq)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_DEFAULTUSEROBJQUOTA), duoq) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_DEFAULTUSEROBJQUOTA), duoq));
if (dgoq == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_DEFAULTGROUPOBJQUOTA,
&dgoq)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_DEFAULTGROUPOBJQUOTA), dgoq) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_DEFAULTGROUPOBJQUOTA), dgoq));
if (dpoq == ZFS_PROP_UNDEFINED &&
(error = zfs_get_zplprop(os, ZFS_PROP_DEFAULTPROJECTOBJQUOTA,
&dpoq)) != 0)
return (error);
- VERIFY(nvlist_add_uint64(zplprops,
- zfs_prop_to_name(ZFS_PROP_DEFAULTPROJECTOBJQUOTA), dpoq) == 0);
+ VERIFY0(nvlist_add_uint64(zplprops,
+ zfs_prop_to_name(ZFS_PROP_DEFAULTPROJECTOBJQUOTA), dpoq));
if (is_ci)
*is_ci = (sense == ZFS_CASE_INSENSITIVE);
@@ -3668,8 +3667,8 @@ zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
* file system creation, so go figure them out
* now.
*/
- VERIFY(nvlist_alloc(&zct.zct_zplprops,
- NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&zct.zct_zplprops,
+ NV_UNIQUE_NAME, KM_SLEEP));
error = zfs_fill_zplprops(fsname, nvprops,
zct.zct_zplprops, &is_insensitive);
if (error != 0) {
@@ -4916,9 +4915,8 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
* format.
*/
nvlist_t *attrs;
- VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
- VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
- &pair) == 0);
+ VERIFY0(nvpair_value_nvlist(pair, &attrs));
+ VERIFY0(nvlist_lookup_nvpair(attrs, ZPROP_VALUE, &pair));
}
/*
@@ -5103,7 +5101,7 @@ zfs_check_clearable(const char *dataset, nvlist_t *props, nvlist_t **errlist)
if (props == NULL)
return (0);
- VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP));
zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
(void) strlcpy(zc->zc_name, dataset, sizeof (zc->zc_name));
@@ -5115,9 +5113,8 @@ zfs_check_clearable(const char *dataset, nvlist_t *props, nvlist_t **errlist)
sizeof (zc->zc_value));
if ((err = zfs_check_settable(dataset, pair, CRED())) != 0 ||
(err = zfs_secpolicy_inherit_prop(zc, NULL, CRED())) != 0) {
- VERIFY(nvlist_remove_nvpair(props, pair) == 0);
- VERIFY(nvlist_add_int32(errors,
- zc->zc_value, err) == 0);
+ VERIFY0(nvlist_remove_nvpair(props, pair));
+ VERIFY0(nvlist_add_int32(errors, zc->zc_value, err));
}
pair = next_pair;
}
@@ -5127,7 +5124,7 @@ zfs_check_clearable(const char *dataset, nvlist_t *props, nvlist_t **errlist)
nvlist_free(errors);
errors = NULL;
} else {
- VERIFY(nvpair_value_int32(pair, &rv) == 0);
+ VERIFY0(nvpair_value_int32(pair, &rv));
}
if (errlist == NULL)
@@ -5144,16 +5141,14 @@ propval_equals(nvpair_t *p1, nvpair_t *p2)
if (nvpair_type(p1) == DATA_TYPE_NVLIST) {
/* dsl_prop_get_all_impl() format */
nvlist_t *attrs;
- VERIFY(nvpair_value_nvlist(p1, &attrs) == 0);
- VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
- &p1) == 0);
+ VERIFY0(nvpair_value_nvlist(p1, &attrs));
+ VERIFY0(nvlist_lookup_nvpair(attrs, ZPROP_VALUE, &p1));
}
if (nvpair_type(p2) == DATA_TYPE_NVLIST) {
nvlist_t *attrs;
- VERIFY(nvpair_value_nvlist(p2, &attrs) == 0);
- VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
- &p2) == 0);
+ VERIFY0(nvpair_value_nvlist(p2, &attrs));
+ VERIFY0(nvlist_lookup_nvpair(attrs, ZPROP_VALUE, &p2));
}
if (nvpair_type(p1) != nvpair_type(p2))
@@ -5162,14 +5157,14 @@ propval_equals(nvpair_t *p1, nvpair_t *p2)
if (nvpair_type(p1) == DATA_TYPE_STRING) {
const char *valstr1, *valstr2;
- VERIFY(nvpair_value_string(p1, &valstr1) == 0);
- VERIFY(nvpair_value_string(p2, &valstr2) == 0);
+ VERIFY0(nvpair_value_string(p1, &valstr1));
+ VERIFY0(nvpair_value_string(p2, &valstr2));
return (strcmp(valstr1, valstr2) == 0);
} else {
uint64_t intval1, intval2;
- VERIFY(nvpair_value_uint64(p1, &intval1) == 0);
- VERIFY(nvpair_value_uint64(p2, &intval2) == 0);
+ VERIFY0(nvpair_value_uint64(p1, &intval1));
+ VERIFY0(nvpair_value_uint64(p2, &intval2));
return (intval1 == intval2);
}
}
@@ -5237,7 +5232,7 @@ extract_delay_props(nvlist_t *props)
};
int i;
- VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
+ VERIFY0(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP));
for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
nvp = nvlist_next_nvpair(props, nvp)) {
@@ -5253,8 +5248,8 @@ extract_delay_props(nvlist_t *props)
}
if (delayable[i] != 0) {
tmp = nvlist_prev_nvpair(props, nvp);
- VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
- VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
+ VERIFY0(nvlist_add_nvpair(delayprops, nvp));
+ VERIFY0(nvlist_remove_nvpair(props, nvp));
nvp = tmp;
}
}
@@ -5485,15 +5480,15 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, const char *origin,
* using ASSERT() will be just like a VERIFY.
*/
if (recv_delayprops != NULL) {
- ASSERT(nvlist_merge(recvprops, recv_delayprops, 0) == 0);
+ ASSERT0(nvlist_merge(recvprops, recv_delayprops, 0));
nvlist_free(recv_delayprops);
}
if (local_delayprops != NULL) {
- ASSERT(nvlist_merge(localprops, local_delayprops, 0) == 0);
+ ASSERT0(nvlist_merge(localprops, local_delayprops, 0));
nvlist_free(local_delayprops);
}
if (inherited_delayprops != NULL) {
- ASSERT(nvlist_merge(localprops, inherited_delayprops, 0) == 0);
+ ASSERT0(nvlist_merge(localprops, inherited_delayprops, 0));
nvlist_free(inherited_delayprops);
}
*read_bytes = off - noff;
@@ -7342,8 +7337,8 @@ zfs_ioctl_register_legacy(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
ASSERT3U(ioc, <, ZFS_IOC_LAST);
- ASSERT3P(vec->zvec_legacy_func, ==, NULL);
- ASSERT3P(vec->zvec_func, ==, NULL);
+ ASSERT0P(vec->zvec_legacy_func);
+ ASSERT0P(vec->zvec_func);
vec->zvec_legacy_func = func;
vec->zvec_secpolicy = secpolicy;
@@ -7366,8 +7361,8 @@ zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
ASSERT3U(ioc, <, ZFS_IOC_LAST);
- ASSERT3P(vec->zvec_legacy_func, ==, NULL);
- ASSERT3P(vec->zvec_func, ==, NULL);
+ ASSERT0P(vec->zvec_legacy_func);
+ ASSERT0P(vec->zvec_func);
/* if we are logging, the name must be valid */
ASSERT(!allow_log || namecheck != NO_NAME);
@@ -8148,7 +8143,7 @@ zfsdev_ioctl_common(uint_t vecnum, zfs_cmd_t *zc, int flag)
spa_t *spa;
nvlist_t *lognv = NULL;
- ASSERT(vec->zvec_legacy_func == NULL);
+ ASSERT0P(vec->zvec_legacy_func);
/*
* Add the innvl to the lognv before calling the func,
diff --git a/sys/contrib/openzfs/module/zfs/zfs_log.c b/sys/contrib/openzfs/module/zfs/zfs_log.c
index 2f61ecfd9b3b..ea17e049279f 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_log.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_log.c
@@ -620,7 +620,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
if (zil_replaying(zilog, tx) || zp->z_unlinked ||
zfs_xattr_owner_unlinked(zp)) {
if (callback != NULL)
- callback(callback_data);
+ callback(callback_data, 0);
return;
}
@@ -663,7 +663,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
DMU_KEEP_CACHING);
DB_DNODE_EXIT(db);
if (err != 0) {
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
itx = zil_itx_create(txtype, sizeof (*lr));
lr = (lr_write_t *)&itx->itx_lr;
wr_state = WR_NEED_COPY;
diff --git a/sys/contrib/openzfs/module/zfs/zfs_quota.c b/sys/contrib/openzfs/module/zfs/zfs_quota.c
index b8fe512d4f09..2e91ccc27d6d 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_quota.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_quota.c
@@ -374,7 +374,7 @@ zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
if (*objp == 0) {
*objp = zap_create(zfsvfs->z_os, DMU_OT_USERGROUP_QUOTA,
DMU_OT_NONE, 0, tx);
- VERIFY(0 == zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
+ VERIFY0(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
zfs_userquota_prop_prefixes[type], 8, 1, objp, tx));
}
mutex_exit(&zfsvfs->z_lock);
@@ -386,7 +386,7 @@ zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
} else {
err = zap_update(zfsvfs->z_os, *objp, buf, 8, 1, &quota, tx);
}
- ASSERT(err == 0);
+ ASSERT0(err);
if (fuid_dirtied)
zfs_fuid_sync(zfsvfs, tx);
dmu_tx_commit(tx);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_rlock.c b/sys/contrib/openzfs/module/zfs/zfs_rlock.c
index 53eb3ef1b66e..4035baff77d6 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_rlock.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_rlock.c
@@ -666,7 +666,7 @@ zfs_rangelock_reduce(zfs_locked_range_t *lr, uint64_t off, uint64_t len)
/* Ensure there are no other locks */
ASSERT3U(avl_numnodes(&rl->rl_tree), ==, 1);
- ASSERT3U(lr->lr_offset, ==, 0);
+ ASSERT0(lr->lr_offset);
ASSERT3U(lr->lr_type, ==, RL_WRITER);
ASSERT(!lr->lr_proxy);
ASSERT3U(lr->lr_length, ==, UINT64_MAX);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_sa.c b/sys/contrib/openzfs/module/zfs/zfs_sa.c
index 59b6ae4e4203..8b4fc6fd7fbd 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_sa.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_sa.c
@@ -169,7 +169,7 @@ zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
ASSERT(MUTEX_HELD(&zp->z_lock));
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
if (zp->z_is_sa)
- VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs),
+ VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs),
&xoap->xoa_av_scanstamp,
sizeof (xoap->xoa_av_scanstamp), tx));
else {
@@ -181,12 +181,12 @@ zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
len = sizeof (xoap->xoa_av_scanstamp) +
ZFS_OLD_ZNODE_PHYS_SIZE;
if (len > doi.doi_bonus_size)
- VERIFY(dmu_set_bonus(db, len, tx) == 0);
+ VERIFY0(dmu_set_bonus(db, len, tx));
(void) memcpy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp));
zp->z_pflags |= ZFS_BONUS_SCANSTAMP;
- VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs),
+ VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs),
&zp->z_pflags, sizeof (uint64_t), tx));
}
}
@@ -286,7 +286,7 @@ zfs_sa_set_xattr(znode_t *zp, const char *name, const void *value, size_t vsize)
dmu_tx_commit(tx);
if (logsaxattr && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ error = zil_commit(zilog, 0);
}
out_free:
vmem_free(obj, size);
@@ -427,11 +427,10 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP;
}
- VERIFY(dmu_set_bonustype(db, DMU_OT_SA, tx) == 0);
- VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs,
- count, tx) == 0);
+ VERIFY0(dmu_set_bonustype(db, DMU_OT_SA, tx));
+ VERIFY0(sa_replace_all_by_template_locked(hdl, sa_attrs, count, tx));
if (znode_acl.z_acl_extern_obj)
- VERIFY(0 == dmu_object_free(zfsvfs->z_os,
+ VERIFY0(dmu_object_free(zfsvfs->z_os,
znode_acl.z_acl_extern_obj, tx));
zp->z_is_sa = B_TRUE;
diff --git a/sys/contrib/openzfs/module/zfs/zfs_vnops.c b/sys/contrib/openzfs/module/zfs/zfs_vnops.c
index 74aa91a4f2eb..7bb9ba57c69e 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_vnops.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_vnops.c
@@ -27,6 +27,7 @@
* Copyright 2017 Nexenta Systems, Inc.
* Copyright (c) 2021, 2022 by Pawel Jakub Dawidek
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
+ * Copyright (c) 2025, Klara, Inc.
*/
/* Portions Copyright 2007 Jeremy Teo */
@@ -116,7 +117,7 @@ zfs_fsync(znode_t *zp, int syncflag, cred_t *cr)
if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
return (error);
- zil_commit(zfsvfs->z_log, zp->z_id);
+ error = zil_commit(zfsvfs->z_log, zp->z_id);
zfs_exit(zfsvfs, FTAG);
}
return (error);
@@ -375,8 +376,13 @@ zfs_read(struct znode *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
frsync = !!(ioflag & FRSYNC);
#endif
if (zfsvfs->z_log &&
- (frsync || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS))
- zil_commit(zfsvfs->z_log, zp->z_id);
+ (frsync || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)) {
+ error = zil_commit(zfsvfs->z_log, zp->z_id);
+ if (error != 0) {
+ zfs_exit(zfsvfs, FTAG);
+ return (error);
+ }
+ }
/*
* Lock the range against changes.
@@ -1074,8 +1080,13 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
return (error);
}
- if (commit)
- zil_commit(zilog, zp->z_id);
+ if (commit) {
+ error = zil_commit(zilog, zp->z_id);
+ if (error != 0) {
+ zfs_exit(zfsvfs, FTAG);
+ return (error);
+ }
+ }
int64_t nwritten = start_resid - zfs_uio_resid(uio);
dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, nwritten);
@@ -1260,8 +1271,8 @@ zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag, cred_t *cr)
zilog = zfsvfs->z_log;
error = zfs_setacl(zp, vsecp, skipaclchk, cr);
- if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
- zil_commit(zilog, 0);
+ if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ error = zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1946,7 +1957,7 @@ unlock:
ZFS_ACCESSTIME_STAMP(inzfsvfs, inzp);
if (outos->os_sync == ZFS_SYNC_ALWAYS) {
- zil_commit(zilog, outzp->z_id);
+ error = zil_commit(zilog, outzp->z_id);
}
*inoffp += done;
diff --git a/sys/contrib/openzfs/module/zfs/zil.c b/sys/contrib/openzfs/module/zfs/zil.c
index 6e4f84257407..31b59c55f17b 100644
--- a/sys/contrib/openzfs/module/zfs/zil.c
+++ b/sys/contrib/openzfs/module/zfs/zil.c
@@ -24,6 +24,7 @@
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright (c) 2018 Datto Inc.
+ * Copyright (c) 2025, Klara, Inc.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -103,6 +104,7 @@ static zil_kstat_values_t zil_stats = {
{ "zil_commit_error_count", KSTAT_DATA_UINT64 },
{ "zil_commit_stall_count", KSTAT_DATA_UINT64 },
{ "zil_commit_suspend_count", KSTAT_DATA_UINT64 },
+ { "zil_commit_crash_count", KSTAT_DATA_UINT64 },
{ "zil_itx_count", KSTAT_DATA_UINT64 },
{ "zil_itx_indirect_count", KSTAT_DATA_UINT64 },
{ "zil_itx_indirect_bytes", KSTAT_DATA_UINT64 },
@@ -145,7 +147,7 @@ static uint64_t zil_slog_bulk = 64 * 1024 * 1024;
static kmem_cache_t *zil_lwb_cache;
static kmem_cache_t *zil_zcw_cache;
-static void zil_lwb_commit(zilog_t *zilog, lwb_t *lwb, itx_t *itx);
+static int zil_lwb_commit(zilog_t *zilog, lwb_t *lwb, itx_t *itx);
static itx_t *zil_itx_clone(itx_t *oitx);
static uint64_t zil_max_waste_space(zilog_t *zilog);
@@ -367,6 +369,7 @@ zil_sums_init(zil_sums_t *zs)
wmsum_init(&zs->zil_commit_error_count, 0);
wmsum_init(&zs->zil_commit_stall_count, 0);
wmsum_init(&zs->zil_commit_suspend_count, 0);
+ wmsum_init(&zs->zil_commit_crash_count, 0);
wmsum_init(&zs->zil_itx_count, 0);
wmsum_init(&zs->zil_itx_indirect_count, 0);
wmsum_init(&zs->zil_itx_indirect_bytes, 0);
@@ -392,6 +395,7 @@ zil_sums_fini(zil_sums_t *zs)
wmsum_fini(&zs->zil_commit_error_count);
wmsum_fini(&zs->zil_commit_stall_count);
wmsum_fini(&zs->zil_commit_suspend_count);
+ wmsum_fini(&zs->zil_commit_crash_count);
wmsum_fini(&zs->zil_itx_count);
wmsum_fini(&zs->zil_itx_indirect_count);
wmsum_fini(&zs->zil_itx_indirect_bytes);
@@ -422,6 +426,8 @@ zil_kstat_values_update(zil_kstat_values_t *zs, zil_sums_t *zil_sums)
wmsum_value(&zil_sums->zil_commit_stall_count);
zs->zil_commit_suspend_count.value.ui64 =
wmsum_value(&zil_sums->zil_commit_suspend_count);
+ zs->zil_commit_crash_count.value.ui64 =
+ wmsum_value(&zil_sums->zil_commit_crash_count);
zs->zil_itx_count.value.ui64 =
wmsum_value(&zil_sums->zil_itx_count);
zs->zil_itx_indirect_count.value.ui64 =
@@ -864,9 +870,9 @@ zil_free_lwb(zilog_t *zilog, lwb_t *lwb)
ASSERT(MUTEX_HELD(&zilog->zl_lock));
ASSERT(lwb->lwb_state == LWB_STATE_NEW ||
lwb->lwb_state == LWB_STATE_FLUSH_DONE);
- ASSERT3P(lwb->lwb_child_zio, ==, NULL);
- ASSERT3P(lwb->lwb_write_zio, ==, NULL);
- ASSERT3P(lwb->lwb_root_zio, ==, NULL);
+ ASSERT0P(lwb->lwb_child_zio);
+ ASSERT0P(lwb->lwb_write_zio);
+ ASSERT0P(lwb->lwb_root_zio);
ASSERT3U(lwb->lwb_alloc_txg, <=, spa_syncing_txg(zilog->zl_spa));
ASSERT3U(lwb->lwb_max_txg, <=, spa_syncing_txg(zilog->zl_spa));
VERIFY(list_is_empty(&lwb->lwb_itxs));
@@ -991,8 +997,8 @@ zil_create(zilog_t *zilog)
*/
txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
- ASSERT(zh->zh_claim_txg == 0);
- ASSERT(zh->zh_replay_seq == 0);
+ ASSERT0(zh->zh_claim_txg);
+ ASSERT0(zh->zh_replay_seq);
blk = zh->zh_log;
@@ -1104,7 +1110,7 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
zilog->zl_keep_first = keep_first;
if (!list_is_empty(&zilog->zl_lwb_list)) {
- ASSERT(zh->zh_claim_txg == 0);
+ ASSERT0(zh->zh_claim_txg);
VERIFY(!keep_first);
while ((lwb = list_remove_head(&zilog->zl_lwb_list)) != NULL) {
if (lwb->lwb_buf != NULL)
@@ -1250,7 +1256,7 @@ zil_check_log_chain(dsl_pool_t *dp, dsl_dataset_t *ds, void *tx)
blkptr_t *bp;
int error;
- ASSERT(tx == NULL);
+ ASSERT0P(tx);
error = dmu_objset_from_ds(ds, &os);
if (error != 0) {
@@ -1351,7 +1357,7 @@ zil_commit_waiter_link_lwb(zil_commit_waiter_t *zcw, lwb_t *lwb)
ASSERT(!list_link_active(&zcw->zcw_node));
list_insert_tail(&lwb->lwb_waiters, zcw);
- ASSERT3P(zcw->zcw_lwb, ==, NULL);
+ ASSERT0P(zcw->zcw_lwb);
zcw->zcw_lwb = lwb;
}
@@ -1365,7 +1371,7 @@ zil_commit_waiter_link_nolwb(zil_commit_waiter_t *zcw, list_t *nolwb)
{
ASSERT(!list_link_active(&zcw->zcw_node));
list_insert_tail(nolwb, zcw);
- ASSERT3P(zcw->zcw_lwb, ==, NULL);
+ ASSERT0P(zcw->zcw_lwb);
}
void
@@ -1482,7 +1488,7 @@ zil_lwb_flush_vdevs_done(zio_t *zio)
}
while ((itx = list_remove_head(&lwb->lwb_itxs)) != NULL)
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
mutex_enter(&zcw->zcw_lock);
@@ -1895,7 +1901,7 @@ zil_lwb_write_close(zilog_t *zilog, lwb_t *lwb, lwb_state_t state)
/*
* Finalize previously closed block and issue the write zio.
*/
-static void
+static int
zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
{
spa_t *spa = zilog->zl_spa;
@@ -1909,8 +1915,13 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
/* Actually fill the lwb with the data. */
for (itx_t *itx = list_head(&lwb->lwb_itxs); itx;
- itx = list_next(&lwb->lwb_itxs, itx))
- zil_lwb_commit(zilog, lwb, itx);
+ itx = list_next(&lwb->lwb_itxs, itx)) {
+ error = zil_lwb_commit(zilog, lwb, itx);
+ if (error != 0) {
+ ASSERT3U(error, ==, ESHUTDOWN);
+ return (error);
+ }
+ }
lwb->lwb_nused = lwb->lwb_nfilled;
ASSERT3U(lwb->lwb_nused, <=, lwb->lwb_nmax);
@@ -1928,7 +1939,7 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
lwb->lwb_state = LWB_STATE_READY;
if (BP_IS_HOLE(&lwb->lwb_blk) && lwb->lwb_error == 0) {
mutex_exit(&zilog->zl_lock);
- return;
+ return (0);
}
mutex_exit(&zilog->zl_lock);
@@ -2065,6 +2076,8 @@ next_lwb:
lwb = nlwb;
if (lwb)
goto next_lwb;
+
+ return (0);
}
/*
@@ -2308,11 +2321,13 @@ cont:
return (lwb);
}
+static void zil_crash(zilog_t *zilog);
+
/*
* Fill the actual transaction data into the lwb, following zil_lwb_assign().
* Does not require locking.
*/
-static void
+static int
zil_lwb_commit(zilog_t *zilog, lwb_t *lwb, itx_t *itx)
{
lr_t *lr, *lrb;
@@ -2324,7 +2339,7 @@ zil_lwb_commit(zilog_t *zilog, lwb_t *lwb, itx_t *itx)
lrw = (lr_write_t *)lr;
if (lr->lrc_txtype == TX_COMMIT)
- return;
+ return (0);
reclen = lr->lrc_reclen;
dlen = zil_itx_data_size(itx);
@@ -2410,16 +2425,35 @@ zil_lwb_commit(zilog_t *zilog, lwb_t *lwb, itx_t *itx)
". Falling back to txg_wait_synced().",
error);
zfs_fallthrough;
- case EIO:
- txg_wait_synced(zilog->zl_dmu_pool,
- lr->lrc_txg);
+ case EIO: {
+ int error = txg_wait_synced_flags(
+ zilog->zl_dmu_pool,
+ lr->lrc_txg, TXG_WAIT_SUSPEND);
+ if (error != 0) {
+ ASSERT3U(error, ==, ESHUTDOWN);
+ /*
+ * zil_lwb_commit() is called from a
+ * loop over a list of itxs at the
+ * top of zil_lwb_write_issue(), which
+ * itself is called from a loop over a
+ * list of lwbs in various places.
+ * zil_crash() will free those itxs
+ * and sometimes the lwbs, so they
+ * are invalid when zil_crash() returns.
+ * Callers must pretty much abort
+ * immediately.
+ */
+ zil_crash(zilog);
+ return (error);
+ }
zfs_fallthrough;
+ }
case ENOENT:
zfs_fallthrough;
case EEXIST:
zfs_fallthrough;
case EALREADY:
- return;
+ return (0);
}
}
}
@@ -2427,6 +2461,8 @@ zil_lwb_commit(zilog_t *zilog, lwb_t *lwb, itx_t *itx)
lwb->lwb_nfilled += reclen + dlen;
ASSERT3S(lwb->lwb_nfilled, <=, lwb->lwb_nused);
ASSERT0(P2PHASE(lwb->lwb_nfilled, sizeof (uint64_t)));
+
+ return (0);
}
itx_t *
@@ -2468,7 +2504,7 @@ zil_itx_clone(itx_t *oitx)
}
void
-zil_itx_destroy(itx_t *itx)
+zil_itx_destroy(itx_t *itx, int err)
{
ASSERT3U(itx->itx_size, >=, sizeof (itx_t));
ASSERT3U(itx->itx_lr.lrc_reclen, ==,
@@ -2477,7 +2513,7 @@ zil_itx_destroy(itx_t *itx)
IMPLY(itx->itx_callback != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT);
if (itx->itx_callback != NULL)
- itx->itx_callback(itx->itx_callback_data);
+ itx->itx_callback(itx->itx_callback_data, err);
zio_data_buf_free(itx, itx->itx_size);
}
@@ -2520,7 +2556,7 @@ zil_itxg_clean(void *arg)
if (itx->itx_lr.lrc_txtype == TX_COMMIT)
zil_commit_waiter_skip(itx->itx_private);
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
}
cookie = NULL;
@@ -2530,7 +2566,7 @@ zil_itxg_clean(void *arg)
while ((itx = list_remove_head(list)) != NULL) {
/* commit itxs should never be on the async lists. */
ASSERT3U(itx->itx_lr.lrc_txtype, !=, TX_COMMIT);
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
}
list_destroy(list);
kmem_free(ian, sizeof (itx_async_node_t));
@@ -2592,7 +2628,7 @@ zil_remove_async(zilog_t *zilog, uint64_t oid)
while ((itx = list_remove_head(&clean_list)) != NULL) {
/* commit itxs should never be on the async lists. */
ASSERT3U(itx->itx_lr.lrc_txtype, !=, TX_COMMIT);
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
}
list_destroy(&clean_list);
}
@@ -2677,6 +2713,67 @@ zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx)
}
/*
+ * Post-crash cleanup. This is called from zil_clean() because it needs to
+ * do cleanup after every txg until the ZIL is restarted, and zilog_dirty()
+ * can arrange that easily, unlike zil_sync() which is more complicated to
+ * get a call to without actual dirty data.
+ */
+static void
+zil_crash_clean(zilog_t *zilog, uint64_t synced_txg)
+{
+ ASSERT(MUTEX_HELD(&zilog->zl_lock));
+ ASSERT3U(zilog->zl_restart_txg, >, 0);
+
+ /* Clean up anything on the crash list from earlier txgs */
+ lwb_t *lwb;
+ while ((lwb = list_head(&zilog->zl_lwb_crash_list)) != NULL) {
+ if (lwb->lwb_alloc_txg >= synced_txg ||
+ lwb->lwb_max_txg >= synced_txg) {
+ /*
+ * This lwb was allocated or updated on this txg, or
+ * in the future. We stop processing here, to avoid
+ * the strange situation of freeing a ZIL block on
+ * on the same or earlier txg than what it was
+ * allocated for.
+ *
+ * We'll take care of it on the next txg.
+ */
+ break;
+ }
+
+ /* This LWB is from the past, so we can clean it up now. */
+ list_remove(&zilog->zl_lwb_crash_list, lwb);
+ if (lwb->lwb_buf != NULL)
+ zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
+ if (!BP_IS_HOLE(&lwb->lwb_blk))
+ /*
+ * Free on the next txg, since zil_clean() is called
+ * once synced_txg has already been completed.
+ */
+ zio_free(zilog->zl_spa, synced_txg+1, &lwb->lwb_blk);
+ zil_free_lwb(zilog, lwb);
+ }
+
+ if (zilog->zl_restart_txg > synced_txg) {
+ /*
+ * Not reached the restart txg yet, so mark the ZIL dirty for
+ * the next txg and we'll consider it all again then.
+ */
+ zilog_dirty(zilog, synced_txg+1);
+ return;
+ }
+
+ /*
+ * Reached the restart txg, so we can allow new calls to zil_commit().
+ * All ZIL txgs have long past so there should be no IO waiting.
+ */
+ ASSERT(list_is_empty(&zilog->zl_lwb_list));
+ ASSERT(list_is_empty(&zilog->zl_lwb_crash_list));
+
+ zilog->zl_restart_txg = 0;
+}
+
+/*
* If there are any in-memory intent log transactions which have now been
* synced then start up a taskq to free them. We should only do this after we
* have written out the uberblocks (i.e. txg has been committed) so that
@@ -2691,6 +2788,15 @@ zil_clean(zilog_t *zilog, uint64_t synced_txg)
ASSERT3U(synced_txg, <, ZILTEST_TXG);
+ /* Do cleanup and restart after crash. */
+ if (zilog->zl_restart_txg > 0) {
+ mutex_enter(&zilog->zl_lock);
+ /* Make sure we didn't lose a race. */
+ if (zilog->zl_restart_txg > 0)
+ zil_crash_clean(zilog, synced_txg);
+ mutex_exit(&zilog->zl_lock);
+ }
+
mutex_enter(&itxg->itxg_lock);
if (itxg->itxg_itxs == NULL || itxg->itxg_txg == ZILTEST_TXG) {
mutex_exit(&itxg->itxg_lock);
@@ -2883,13 +2989,13 @@ zil_prune_commit_list(zilog_t *zilog)
mutex_exit(&zilog->zl_lock);
list_remove(&zilog->zl_itx_commit_list, itx);
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
}
IMPLY(itx != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT);
}
-static void
+static int
zil_commit_writer_stall(zilog_t *zilog)
{
/*
@@ -2914,8 +3020,22 @@ zil_commit_writer_stall(zilog_t *zilog)
*/
ASSERT(MUTEX_HELD(&zilog->zl_issuer_lock));
ZIL_STAT_BUMP(zilog, zil_commit_stall_count);
- txg_wait_synced(zilog->zl_dmu_pool, 0);
+
+ int err = txg_wait_synced_flags(zilog->zl_dmu_pool, 0,
+ TXG_WAIT_SUSPEND);
+ if (err != 0) {
+ ASSERT3U(err, ==, ESHUTDOWN);
+ zil_crash(zilog);
+ }
+
+ /*
+ * Either zil_sync() has been called to wait for and clean up any
+ * in-flight LWBs, or zil_crash() has emptied out the list and arranged
+ * for them to be cleaned up later.
+ */
ASSERT(list_is_empty(&zilog->zl_lwb_list));
+
+ return (err);
}
static void
@@ -3082,7 +3202,7 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
} else {
ASSERT3S(lrc->lrc_txtype, !=, TX_COMMIT);
zilog->zl_cur_left -= zil_itx_full_size(itx);
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
}
}
@@ -3093,9 +3213,14 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
* the ZIL write pipeline; see the comment within
* zil_commit_writer_stall() for more details.
*/
- while ((lwb = list_remove_head(ilwbs)) != NULL)
- zil_lwb_write_issue(zilog, lwb);
- zil_commit_writer_stall(zilog);
+ int err = 0;
+ while ((lwb = list_remove_head(ilwbs)) != NULL) {
+ err = zil_lwb_write_issue(zilog, lwb);
+ if (err != 0)
+ break;
+ }
+ if (err == 0)
+ err = zil_commit_writer_stall(zilog);
/*
* Additionally, we have to signal and mark the "nolwb"
@@ -3113,7 +3238,7 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
* the itx's callback if one exists for the itx.
*/
while ((itx = list_remove_head(&nolwb_itxs)) != NULL)
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
} else {
ASSERT(list_is_empty(&nolwb_waiters));
ASSERT3P(lwb, !=, NULL);
@@ -3169,9 +3294,15 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
list_insert_tail(ilwbs, lwb);
lwb = zil_lwb_write_close(zilog, lwb, LWB_STATE_NEW);
if (lwb == NULL) {
- while ((lwb = list_remove_head(ilwbs)) != NULL)
- zil_lwb_write_issue(zilog, lwb);
- zil_commit_writer_stall(zilog);
+ int err = 0;
+ while ((lwb =
+ list_remove_head(ilwbs)) != NULL) {
+ err = zil_lwb_write_issue(zilog, lwb);
+ if (err != 0)
+ break;
+ }
+ if (err == 0)
+ zil_commit_writer_stall(zilog);
}
}
}
@@ -3230,10 +3361,23 @@ zil_commit_writer(zilog_t *zilog, zil_commit_waiter_t *zcw)
zil_prune_commit_list(zilog);
zil_process_commit_list(zilog, zcw, &ilwbs);
+ /*
+ * If the ZIL failed somewhere inside zil_process_commit_list(), it's
+ * will be because a fallback to txg_wait_sync_flags() happened at some
+ * point (eg zil_commit_writer_stall()). All cases should issue and
+ * empty ilwbs, so there will be nothing to in the issue loop below.
+ * That's why we don't have to plumb the error value back from
+ * zil_process_commit_list(), and don't have to skip it.
+ */
+ IMPLY(zilog->zl_restart_txg > 0, list_is_empty(&ilwbs));
+
out:
mutex_exit(&zilog->zl_issuer_lock);
- while ((lwb = list_remove_head(&ilwbs)) != NULL)
- zil_lwb_write_issue(zilog, lwb);
+ int err = 0;
+ while ((lwb = list_remove_head(&ilwbs)) != NULL) {
+ if (err == 0)
+ err = zil_lwb_write_issue(zilog, lwb);
+ }
list_destroy(&ilwbs);
return (wtxg);
}
@@ -3489,7 +3633,7 @@ static void
zil_free_commit_waiter(zil_commit_waiter_t *zcw)
{
ASSERT(!list_link_active(&zcw->zcw_node));
- ASSERT3P(zcw->zcw_lwb, ==, NULL);
+ ASSERT0P(zcw->zcw_lwb);
ASSERT3B(zcw->zcw_done, ==, B_TRUE);
mutex_destroy(&zcw->zcw_lock);
cv_destroy(&zcw->zcw_cv);
@@ -3526,6 +3670,96 @@ zil_commit_itx_assign(zilog_t *zilog, zil_commit_waiter_t *zcw)
}
/*
+ * Crash the ZIL. This is something like suspending, but abandons the ZIL
+ * without further IO until the wanted txg completes. No effort is made to
+ * close the on-disk chain or do any other on-disk work, as the pool may
+ * have suspended. zil_sync() will handle cleanup as normal and restart the
+ * ZIL once enough txgs have passed.
+ */
+static void
+zil_crash(zilog_t *zilog)
+{
+ mutex_enter(&zilog->zl_lock);
+
+ uint64_t txg = spa_syncing_txg(zilog->zl_spa);
+ uint64_t restart_txg =
+ spa_syncing_txg(zilog->zl_spa) + TXG_CONCURRENT_STATES;
+
+ if (zilog->zl_restart_txg > 0) {
+ /*
+ * If the ZIL is already crashed, it's almost certainly because
+ * we lost a race involving multiple callers from
+ * zil_commit_impl().
+ */
+
+ /*
+ * This sanity check is to support my understanding that in the
+ * event of multiple callers to zil_crash(), only one of them
+ * can possibly be in the codepath to issue lwbs; the rest
+ * should be calling from zil_commit_impl() after their waiters
+ * have completed. As I understand it, a second thread trying
+ * to issue will eventually wait on zl_issuer_lock, and then
+ * have no work to do and leave.
+ *
+ * If more lwbs had been created an issued between zil_crash()
+ * calls, then we probably just need to take those too, add
+ * them to the crash list and clean them up, but it complicates
+ * this function and I don't think it can happend.
+ */
+ ASSERT(list_is_empty(&zilog->zl_lwb_list));
+
+ mutex_exit(&zilog->zl_lock);
+ return;
+ }
+
+ zilog->zl_restart_txg = restart_txg;
+
+ /*
+ * Capture any live LWBs. Depending on the state of the pool they may
+ * represent in-flight IO that won't return for some time, and we want
+ * to make sure they don't get in the way of normal ZIL operation.
+ */
+ ASSERT(list_is_empty(&zilog->zl_lwb_crash_list));
+ list_move_tail(&zilog->zl_lwb_crash_list, &zilog->zl_lwb_list);
+
+ /*
+ * Run through the LWB list; erroring all itxes and signalling error
+ * to all waiters.
+ */
+ for (lwb_t *lwb = list_head(&zilog->zl_lwb_crash_list); lwb != NULL;
+ lwb = list_next(&zilog->zl_lwb_crash_list, lwb)) {
+ itx_t *itx;
+ while ((itx = list_remove_head(&lwb->lwb_itxs)) != NULL)
+ zil_itx_destroy(itx, EIO);
+
+ zil_commit_waiter_t *zcw;
+ while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
+ mutex_enter(&zcw->zcw_lock);
+ zcw->zcw_lwb = NULL;
+ zcw->zcw_zio_error = EIO;
+ zcw->zcw_done = B_TRUE;
+ cv_broadcast(&zcw->zcw_cv);
+ mutex_exit(&zcw->zcw_lock);
+ }
+ }
+
+ /*
+ * Zero the ZIL header bp after the ZIL restarts. We'll free it in
+ * zil_clean() when we clean up the lwbs.
+ */
+ zil_header_t *zh = zil_header_in_syncing_context(zilog);
+ BP_ZERO(&zh->zh_log);
+
+ /*
+ * Mark this ZIL dirty on the next txg, so that zil_clean() will be
+ * called for cleanup.
+ */
+ zilog_dirty(zilog, txg+1);
+
+ mutex_exit(&zilog->zl_lock);
+}
+
+/*
* Commit ZFS Intent Log transactions (itxs) to stable storage.
*
* When writing ZIL transactions to the on-disk representation of the
@@ -3640,9 +3874,17 @@ zil_commit_itx_assign(zilog_t *zilog, zil_commit_waiter_t *zcw)
* but the order in which they complete will be the same order in
* which they were created.
*/
-void
+static int zil_commit_impl(zilog_t *zilog, uint64_t foid);
+
+int
zil_commit(zilog_t *zilog, uint64_t foid)
{
+ return (zil_commit_flags(zilog, foid, ZIL_COMMIT_FAILMODE));
+}
+
+int
+zil_commit_flags(zilog_t *zilog, uint64_t foid, zil_commit_flag_t flags)
+{
/*
* We should never attempt to call zil_commit on a snapshot for
* a couple of reasons:
@@ -3659,7 +3901,7 @@ zil_commit(zilog_t *zilog, uint64_t foid)
ASSERT3B(dmu_objset_is_snapshot(zilog->zl_os), ==, B_FALSE);
if (zilog->zl_sync == ZFS_SYNC_DISABLED)
- return;
+ return (0);
if (!spa_writeable(zilog->zl_spa)) {
/*
@@ -3670,10 +3912,23 @@ zil_commit(zilog_t *zilog, uint64_t foid)
* verifying that truth before we return to the caller.
*/
ASSERT(list_is_empty(&zilog->zl_lwb_list));
- ASSERT3P(zilog->zl_last_lwb_opened, ==, NULL);
+ ASSERT0P(zilog->zl_last_lwb_opened);
for (int i = 0; i < TXG_SIZE; i++)
- ASSERT3P(zilog->zl_itxg[i].itxg_itxs, ==, NULL);
- return;
+ ASSERT0P(zilog->zl_itxg[i].itxg_itxs);
+ return (0);
+ }
+
+ int err = 0;
+
+ /*
+ * If the ZIL crashed, bypass it entirely, and rely on txg_wait_sync()
+ * to get the data out to disk.
+ */
+ if (zilog->zl_restart_txg > 0) {
+ ZIL_STAT_BUMP(zilog, zil_commit_crash_count);
+ err = txg_wait_synced_flags(zilog->zl_dmu_pool, 0,
+ TXG_WAIT_SUSPEND);
+ goto out;
}
/*
@@ -3685,14 +3940,43 @@ zil_commit(zilog_t *zilog, uint64_t foid)
*/
if (zilog->zl_suspend > 0) {
ZIL_STAT_BUMP(zilog, zil_commit_suspend_count);
- txg_wait_synced(zilog->zl_dmu_pool, 0);
- return;
+ err = txg_wait_synced_flags(zilog->zl_dmu_pool, 0,
+ TXG_WAIT_SUSPEND);
+ if (err != 0) {
+ ASSERT3U(err, ==, ESHUTDOWN);
+ zil_crash(zilog);
+ }
+ goto out;
}
- zil_commit_impl(zilog, foid);
+ err = zil_commit_impl(zilog, foid);
+
+out:
+ if (err == 0)
+ return (0);
+
+ /*
+ * The ZIL write failed and the pool is suspended. There's nothing else
+ * we can do except return or block.
+ */
+ ASSERT3U(err, ==, ESHUTDOWN);
+
+ /*
+ * Return error if failmode=continue or caller will handle directly.
+ */
+ if (!(flags & ZIL_COMMIT_FAILMODE) ||
+ spa_get_failmode(zilog->zl_spa) == ZIO_FAILURE_MODE_CONTINUE)
+ return (SET_ERROR(EIO));
+
+ /*
+ * Block until the pool returns. We assume that the data will make
+ * it out to disk in the end, and so return success.
+ */
+ txg_wait_synced(zilog->zl_dmu_pool, 0);
+ return (0);
}
-void
+static int
zil_commit_impl(zilog_t *zilog, uint64_t foid)
{
ZIL_STAT_BUMP(zilog, zil_commit_count);
@@ -3729,6 +4013,7 @@ zil_commit_impl(zilog_t *zilog, uint64_t foid)
uint64_t wtxg = zil_commit_writer(zilog, zcw);
zil_commit_waiter(zilog, zcw);
+ int err = 0;
if (zcw->zcw_zio_error != 0) {
/*
* If there was an error writing out the ZIL blocks that
@@ -3741,13 +4026,29 @@ zil_commit_impl(zilog_t *zilog, uint64_t foid)
ZIL_STAT_BUMP(zilog, zil_commit_error_count);
DTRACE_PROBE2(zil__commit__io__error,
zilog_t *, zilog, zil_commit_waiter_t *, zcw);
- txg_wait_synced(zilog->zl_dmu_pool, 0);
+ err = txg_wait_synced_flags(zilog->zl_dmu_pool, 0,
+ TXG_WAIT_SUSPEND);
} else if (wtxg != 0) {
ZIL_STAT_BUMP(zilog, zil_commit_suspend_count);
- txg_wait_synced(zilog->zl_dmu_pool, wtxg);
+ err = txg_wait_synced_flags(zilog->zl_dmu_pool, wtxg,
+ TXG_WAIT_SUSPEND);
}
zil_free_commit_waiter(zcw);
+
+ if (err == 0)
+ return (0);
+
+ /*
+ * ZIL write failed and pool failed in the fallback to
+ * txg_wait_synced_flags(). Right now we have no idea if the data is on
+ * disk and the pool is probably suspended so we have no idea when it's
+ * coming back. All we can do is shut down and return error to the
+ * caller.
+ */
+ ASSERT3U(err, ==, ESHUTDOWN);
+ zil_crash(zilog);
+ return (err);
}
/*
@@ -3773,7 +4074,7 @@ zil_sync(zilog_t *zilog, dmu_tx_t *tx)
mutex_enter(&zilog->zl_lock);
- ASSERT(zilog->zl_stop_sync == 0);
+ ASSERT0(zilog->zl_stop_sync);
if (*replayed_seq != 0) {
ASSERT(zh->zh_replay_seq < *replayed_seq);
@@ -3943,6 +4244,8 @@ zil_alloc(objset_t *os, zil_header_t *zh_phys)
list_create(&zilog->zl_lwb_list, sizeof (lwb_t),
offsetof(lwb_t, lwb_node));
+ list_create(&zilog->zl_lwb_crash_list, sizeof (lwb_t),
+ offsetof(lwb_t, lwb_node));
list_create(&zilog->zl_itx_commit_list, sizeof (itx_t),
offsetof(itx_t, itx_node));
@@ -3967,9 +4270,12 @@ zil_free(zilog_t *zilog)
ASSERT0(zilog->zl_suspend);
ASSERT0(zilog->zl_suspending);
+ ASSERT0(zilog->zl_restart_txg);
ASSERT(list_is_empty(&zilog->zl_lwb_list));
list_destroy(&zilog->zl_lwb_list);
+ ASSERT(list_is_empty(&zilog->zl_lwb_crash_list));
+ list_destroy(&zilog->zl_lwb_crash_list);
ASSERT(list_is_empty(&zilog->zl_itx_commit_list));
list_destroy(&zilog->zl_itx_commit_list);
@@ -4005,8 +4311,8 @@ zil_open(objset_t *os, zil_get_data_t *get_data, zil_sums_t *zil_sums)
{
zilog_t *zilog = dmu_objset_zil(os);
- ASSERT3P(zilog->zl_get_data, ==, NULL);
- ASSERT3P(zilog->zl_last_lwb_opened, ==, NULL);
+ ASSERT0P(zilog->zl_get_data);
+ ASSERT0P(zilog->zl_last_lwb_opened);
ASSERT(list_is_empty(&zilog->zl_lwb_list));
zilog->zl_get_data = get_data;
@@ -4025,7 +4331,8 @@ zil_close(zilog_t *zilog)
uint64_t txg;
if (!dmu_objset_is_snapshot(zilog->zl_os)) {
- zil_commit(zilog, 0);
+ if (zil_commit_flags(zilog, 0, ZIL_COMMIT_NOW) != 0)
+ txg_wait_synced(zilog->zl_dmu_pool, 0);
} else {
ASSERT(list_is_empty(&zilog->zl_lwb_list));
ASSERT0(zilog->zl_dirty_max_txg);
@@ -4126,6 +4433,17 @@ zil_suspend(const char *osname, void **cookiep)
return (SET_ERROR(EBUSY));
}
+ if (zilog->zl_restart_txg > 0) {
+ /*
+ * ZIL crashed. It effectively _is_ suspended, but callers
+ * are usually trying to make sure it's empty on-disk, which
+ * we can't guarantee right now.
+ */
+ mutex_exit(&zilog->zl_lock);
+ dmu_objset_rele(os, suspend_tag);
+ return (SET_ERROR(EBUSY));
+ }
+
/*
* Don't put a long hold in the cases where we can avoid it. This
* is when there is no cookie so we are doing a suspend & resume
@@ -4158,6 +4476,11 @@ zil_suspend(const char *osname, void **cookiep)
zil_resume(os);
else
*cookiep = os;
+
+ if (zilog->zl_restart_txg > 0)
+ /* ZIL crashed while we were waiting. */
+ return (SET_ERROR(EBUSY));
+
return (0);
}
@@ -4199,17 +4522,34 @@ zil_suspend(const char *osname, void **cookiep)
* would just call txg_wait_synced(), because zl_suspend is set.
* txg_wait_synced() doesn't wait for these lwb's to be
* LWB_STATE_FLUSH_DONE before returning.
+ *
+ * However, zil_commit_impl() itself can return an error if any of the
+ * lwbs fail, or the pool suspends in the fallback
+ * txg_wait_sync_flushed(), which affects what we do next, so we
+ * capture that error.
*/
- zil_commit_impl(zilog, 0);
+ error = zil_commit_impl(zilog, 0);
+ if (error == ESHUTDOWN)
+ /* zil_commit_impl() has called zil_crash() already */
+ error = SET_ERROR(EBUSY);
/*
* Now that we've ensured all lwb's are LWB_STATE_FLUSH_DONE, we
* use txg_wait_synced() to ensure the data from the zilog has
* migrated to the main pool before calling zil_destroy().
*/
- txg_wait_synced(zilog->zl_dmu_pool, 0);
+ if (error == 0) {
+ error = txg_wait_synced_flags(zilog->zl_dmu_pool, 0,
+ TXG_WAIT_SUSPEND);
+ if (error != 0) {
+ ASSERT3U(error, ==, ESHUTDOWN);
+ zil_crash(zilog);
+ error = SET_ERROR(EBUSY);
+ }
+ }
- zil_destroy(zilog, B_FALSE);
+ if (error == 0)
+ zil_destroy(zilog, B_FALSE);
mutex_enter(&zilog->zl_lock);
zilog->zl_suspending = B_FALSE;
@@ -4223,7 +4563,8 @@ zil_suspend(const char *osname, void **cookiep)
zil_resume(os);
else
*cookiep = os;
- return (0);
+
+ return (error);
}
void
@@ -4386,7 +4727,7 @@ zil_replay(objset_t *os, void *arg,
zilog->zl_replay = B_TRUE;
zilog->zl_replay_time = ddi_get_lbolt();
- ASSERT(zilog->zl_replay_blks == 0);
+ ASSERT0(zilog->zl_replay_blks);
(void) zil_parse(zilog, zil_incr_blks, zil_replay_log_record, &zr,
zh->zh_claim_txg, B_TRUE);
vmem_free(zr.zr_lr, 2 * SPA_MAXBLOCKSIZE);
diff --git a/sys/contrib/openzfs/module/zfs/zio.c b/sys/contrib/openzfs/module/zfs/zio.c
index 218aec6093e2..3f0ddb63249d 100644
--- a/sys/contrib/openzfs/module/zfs/zio.c
+++ b/sys/contrib/openzfs/module/zfs/zio.c
@@ -339,8 +339,8 @@ zio_fini(void)
}
for (size_t i = 0; i < n; i++) {
- VERIFY3P(zio_buf_cache[i], ==, NULL);
- VERIFY3P(zio_data_buf_cache[i], ==, NULL);
+ VERIFY0P(zio_buf_cache[i]);
+ VERIFY0P(zio_data_buf_cache[i]);
}
if (zio_ksp != NULL) {
@@ -771,7 +771,7 @@ zio_add_child_impl(zio_t *pio, zio_t *cio, boolean_t first)
else
mutex_enter(&cio->io_lock);
- ASSERT(pio->io_state[ZIO_WAIT_DONE] == 0);
+ ASSERT0(pio->io_state[ZIO_WAIT_DONE]);
uint64_t *countp = pio->io_children[cio->io_child_type];
for (int w = 0; w < ZIO_WAIT_TYPES; w++)
@@ -821,7 +821,7 @@ zio_wait_for_children(zio_t *zio, uint8_t childbits, enum zio_wait_type wait)
boolean_t waiting = B_FALSE;
mutex_enter(&zio->io_lock);
- ASSERT(zio->io_stall == NULL);
+ ASSERT0P(zio->io_stall);
for (int c = 0; c < ZIO_CHILD_TYPES; c++) {
if (!(ZIO_CHILD_BIT_IS_SET(childbits, c)))
continue;
@@ -955,8 +955,8 @@ zio_create(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
zio_t *zio;
IMPLY(type != ZIO_TYPE_TRIM, psize <= SPA_MAXBLOCKSIZE);
- ASSERT(P2PHASE(psize, SPA_MINBLOCKSIZE) == 0);
- ASSERT(P2PHASE(offset, SPA_MINBLOCKSIZE) == 0);
+ ASSERT0(P2PHASE(psize, SPA_MINBLOCKSIZE));
+ ASSERT0(P2PHASE(offset, SPA_MINBLOCKSIZE));
ASSERT(!vd || spa_config_held(spa, SCL_STATE_ALL, RW_READER));
ASSERT(!bp || !(flags & ZIO_FLAG_CONFIG_WRITER));
@@ -1451,7 +1451,7 @@ zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp)
metaslab_check_free(spa, bp);
bplist_append(&spa->spa_free_bplist[txg & TXG_MASK], bp);
} else {
- VERIFY3P(zio_free_sync(NULL, spa, txg, bp, 0), ==, NULL);
+ VERIFY0P(zio_free_sync(NULL, spa, txg, bp, 0));
}
}
@@ -1559,7 +1559,7 @@ zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
{
zio_t *zio;
- ASSERT(vd->vdev_children == 0);
+ ASSERT0(vd->vdev_children);
ASSERT(!labels || offset + size <= VDEV_LABEL_START_SIZE ||
offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE);
ASSERT3U(offset + size, <=, vd->vdev_psize);
@@ -1580,7 +1580,7 @@ zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
{
zio_t *zio;
- ASSERT(vd->vdev_children == 0);
+ ASSERT0(vd->vdev_children);
ASSERT(!labels || offset + size <= VDEV_LABEL_START_SIZE ||
offset >= vd->vdev_psize - VDEV_LABEL_END_SIZE);
ASSERT3U(offset + size, <=, vd->vdev_psize);
@@ -1747,7 +1747,7 @@ zio_flush(zio_t *pio, vdev_t *vd)
void
zio_shrink(zio_t *zio, uint64_t size)
{
- ASSERT3P(zio->io_executor, ==, NULL);
+ ASSERT0P(zio->io_executor);
ASSERT3U(zio->io_orig_size, ==, zio->io_size);
ASSERT3U(size, <=, zio->io_size);
@@ -1941,7 +1941,7 @@ zio_write_compress(zio_t *zio)
}
ASSERT(zio->io_child_type != ZIO_CHILD_DDT);
- ASSERT(zio->io_bp_override == NULL);
+ ASSERT0P(zio->io_bp_override);
if (!BP_IS_HOLE(bp) && BP_GET_BIRTH(bp) == zio->io_txg) {
/*
@@ -2436,7 +2436,7 @@ __zio_execute(zio_t *zio)
ASSERT(!MUTEX_HELD(&zio->io_lock));
ASSERT(ISP2(stage));
- ASSERT(zio->io_stall == NULL);
+ ASSERT0P(zio->io_stall);
do {
stage <<= 1;
@@ -2509,7 +2509,7 @@ zio_wait(zio_t *zio)
int error;
ASSERT3S(zio->io_stage, ==, ZIO_STAGE_OPEN);
- ASSERT3P(zio->io_executor, ==, NULL);
+ ASSERT0P(zio->io_executor);
zio->io_waiter = curthread;
ASSERT0(zio->io_queued_timestamp);
@@ -2551,7 +2551,7 @@ zio_nowait(zio_t *zio)
if (zio == NULL)
return;
- ASSERT3P(zio->io_executor, ==, NULL);
+ ASSERT0P(zio->io_executor);
if (zio->io_child_type == ZIO_CHILD_LOGICAL &&
list_is_empty(&zio->io_parent_list)) {
@@ -2590,8 +2590,8 @@ zio_reexecute(void *arg)
ASSERT(pio->io_child_type == ZIO_CHILD_LOGICAL);
ASSERT(pio->io_orig_stage == ZIO_STAGE_OPEN);
- ASSERT(pio->io_gang_leader == NULL);
- ASSERT(pio->io_gang_tree == NULL);
+ ASSERT0P(pio->io_gang_leader);
+ ASSERT0P(pio->io_gang_tree);
mutex_enter(&pio->io_lock);
pio->io_flags = pio->io_orig_flags;
@@ -2689,7 +2689,7 @@ zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason)
ASSERT(!(zio->io_flags & ZIO_FLAG_GODFATHER));
ASSERT(zio != spa->spa_suspend_zio_root);
ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
- ASSERT(zio_unique_parent(zio) == NULL);
+ ASSERT0P(zio_unique_parent(zio));
ASSERT(zio->io_stage == ZIO_STAGE_DONE);
zio_add_child(spa->spa_suspend_zio_root, zio);
}
@@ -2908,7 +2908,7 @@ zio_gang_node_alloc(zio_gang_node_t **gnpp, uint64_t gangblocksize)
{
zio_gang_node_t *gn;
- ASSERT(*gnpp == NULL);
+ ASSERT0P(*gnpp);
gn = kmem_zalloc(sizeof (*gn) +
(gbh_nblkptrs(gangblocksize) * sizeof (gn)), KM_SLEEP);
@@ -2925,7 +2925,7 @@ zio_gang_node_free(zio_gang_node_t **gnpp)
zio_gang_node_t *gn = *gnpp;
for (int g = 0; g < gbh_nblkptrs(gn->gn_allocsize); g++)
- ASSERT(gn->gn_child[g] == NULL);
+ ASSERT0P(gn->gn_child[g]);
zio_buf_free(gn->gn_gbh, gn->gn_allocsize);
kmem_free(gn, sizeof (*gn) +
@@ -3362,11 +3362,11 @@ zio_nop_write(zio_t *zio)
zio_prop_t *zp = &zio->io_prop;
ASSERT(BP_IS_HOLE(bp));
- ASSERT(BP_GET_LEVEL(bp) == 0);
+ ASSERT0(BP_GET_LEVEL(bp));
ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
ASSERT(zp->zp_nopwrite);
ASSERT(!zp->zp_dedup);
- ASSERT(zio->io_bp_override == NULL);
+ ASSERT0P(zio->io_bp_override);
ASSERT(IO_IS_ALLOCATING(zio));
/*
@@ -3495,7 +3495,7 @@ zio_ddt_read_start(zio_t *zio)
ddt_univ_phys_t *ddp = dde->dde_phys;
blkptr_t blk;
- ASSERT(zio->io_vsd == NULL);
+ ASSERT0P(zio->io_vsd);
zio->io_vsd = dde;
if (v_self == DDT_PHYS_NONE)
@@ -3560,7 +3560,7 @@ zio_ddt_read_done(zio_t *zio)
zio->io_vsd = NULL;
}
- ASSERT(zio->io_vsd == NULL);
+ ASSERT0P(zio->io_vsd);
return (zio);
}
@@ -4415,7 +4415,7 @@ static void
zio_dva_unallocate(zio_t *zio, zio_gang_node_t *gn, blkptr_t *bp)
{
ASSERT(BP_GET_BIRTH(bp) == zio->io_txg || BP_IS_HOLE(bp));
- ASSERT(zio->io_bp_override == NULL);
+ ASSERT0P(zio->io_bp_override);
if (!BP_IS_HOLE(bp)) {
metaslab_free(zio->io_spa, bp, BP_GET_BIRTH(bp), B_TRUE);
@@ -4559,8 +4559,8 @@ zio_vdev_io_start(zio_t *zio)
zio->io_delay = 0;
- ASSERT(zio->io_error == 0);
- ASSERT(zio->io_child_error[ZIO_CHILD_VDEV] == 0);
+ ASSERT0(zio->io_error);
+ ASSERT0(zio->io_child_error[ZIO_CHILD_VDEV]);
if (vd == NULL) {
if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER))
@@ -4751,7 +4751,7 @@ zio_vdev_io_done(zio_t *zio)
ops->vdev_op_io_done(zio);
if (unexpected_error && vd->vdev_remove_wanted == B_FALSE)
- VERIFY(vdev_probe(vd, zio) == NULL);
+ VERIFY0P(vdev_probe(vd, zio));
return (zio);
}
@@ -4903,7 +4903,7 @@ void
zio_vdev_io_reissue(zio_t *zio)
{
ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_START);
- ASSERT(zio->io_error == 0);
+ ASSERT0(zio->io_error);
zio->io_stage >>= 1;
}
@@ -4920,7 +4920,7 @@ void
zio_vdev_io_bypass(zio_t *zio)
{
ASSERT(zio->io_stage == ZIO_STAGE_VDEV_IO_START);
- ASSERT(zio->io_error == 0);
+ ASSERT0(zio->io_error);
zio->io_flags |= ZIO_FLAG_IO_BYPASS;
zio->io_stage = ZIO_STAGE_VDEV_IO_ASSESS >> 1;
@@ -5298,7 +5298,7 @@ zio_ready(zio_t *zio)
ASSERT(IO_IS_ALLOCATING(zio));
ASSERT(BP_GET_BIRTH(bp) == zio->io_txg ||
BP_IS_HOLE(bp) || (zio->io_flags & ZIO_FLAG_NOPWRITE));
- ASSERT(zio->io_children[ZIO_CHILD_GANG][ZIO_WAIT_READY] == 0);
+ ASSERT0(zio->io_children[ZIO_CHILD_GANG][ZIO_WAIT_READY]);
zio->io_ready(zio);
}
@@ -5448,7 +5448,7 @@ zio_done(zio_t *zio)
for (int c = 0; c < ZIO_CHILD_TYPES; c++)
for (int w = 0; w < ZIO_WAIT_TYPES; w++)
- ASSERT(zio->io_children[c][w] == 0);
+ ASSERT0(zio->io_children[c][w]);
if (zio->io_bp != NULL && !BP_IS_EMBEDDED(zio->io_bp)) {
ASSERT(memcmp(zio->io_bp, &zio->io_bp_copy,
diff --git a/sys/contrib/openzfs/module/zfs/zio_checksum.c b/sys/contrib/openzfs/module/zfs/zio_checksum.c
index 63d0c6dadd46..1d0646a61185 100644
--- a/sys/contrib/openzfs/module/zfs/zio_checksum.c
+++ b/sys/contrib/openzfs/module/zfs/zio_checksum.c
@@ -215,7 +215,7 @@ zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
spa_feature_t
zio_checksum_to_feature(enum zio_checksum cksum)
{
- VERIFY((cksum & ~ZIO_CHECKSUM_MASK) == 0);
+ VERIFY0((cksum & ~ZIO_CHECKSUM_MASK));
switch (cksum) {
case ZIO_CHECKSUM_BLAKE3:
diff --git a/sys/contrib/openzfs/module/zfs/zio_compress.c b/sys/contrib/openzfs/module/zfs/zio_compress.c
index 9f0ac1b63146..89ceeb58ad91 100644
--- a/sys/contrib/openzfs/module/zfs/zio_compress.c
+++ b/sys/contrib/openzfs/module/zfs/zio_compress.c
@@ -38,12 +38,6 @@
#include <sys/zstd/zstd.h>
/*
- * If nonzero, every 1/X decompression attempts will fail, simulating
- * an undetected memory error.
- */
-static unsigned long zio_decompress_fail_fraction = 0;
-
-/*
* Compression vectors.
*/
zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS] = {
@@ -171,15 +165,6 @@ zio_decompress_data(enum zio_compress c, abd_t *src, abd_t *dst,
else
err = ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level);
- /*
- * Decompression shouldn't fail, because we've already verified
- * the checksum. However, for extra protection (e.g. against bitflips
- * in non-ECC RAM), we handle this error (and test it).
- */
- if (zio_decompress_fail_fraction != 0 &&
- random_in_range(zio_decompress_fail_fraction) == 0)
- err = SET_ERROR(EINVAL);
-
return (err);
}
diff --git a/sys/contrib/openzfs/module/zfs/zio_inject.c b/sys/contrib/openzfs/module/zfs/zio_inject.c
index df7b01ba879e..981a1be4847c 100644
--- a/sys/contrib/openzfs/module/zfs/zio_inject.c
+++ b/sys/contrib/openzfs/module/zfs/zio_inject.c
@@ -1119,7 +1119,7 @@ zio_clear_fault(int id)
kmem_free(handler->zi_lanes, sizeof (*handler->zi_lanes) *
handler->zi_record.zi_nlanes);
} else {
- ASSERT3P(handler->zi_lanes, ==, NULL);
+ ASSERT0P(handler->zi_lanes);
}
if (handler->zi_spa_name != NULL)
diff --git a/sys/contrib/openzfs/module/zfs/zrlock.c b/sys/contrib/openzfs/module/zfs/zrlock.c
index 3c0f1b7bbbc1..09c110945c97 100644
--- a/sys/contrib/openzfs/module/zfs/zrlock.c
+++ b/sys/contrib/openzfs/module/zfs/zrlock.c
@@ -129,7 +129,7 @@ zrl_tryenter(zrlock_t *zrl)
(uint32_t *)&zrl->zr_refcount, 0, ZRL_LOCKED);
if (cas == 0) {
#ifdef ZFS_DEBUG
- ASSERT3P(zrl->zr_owner, ==, NULL);
+ ASSERT0P(zrl->zr_owner);
zrl->zr_owner = curthread;
#endif
return (1);
diff --git a/sys/contrib/openzfs/module/zfs/zthr.c b/sys/contrib/openzfs/module/zfs/zthr.c
index 597a510528ea..d245ce4946e0 100644
--- a/sys/contrib/openzfs/module/zfs/zthr.c
+++ b/sys/contrib/openzfs/module/zfs/zthr.c
@@ -316,7 +316,7 @@ zthr_destroy(zthr_t *t)
{
ASSERT(!MUTEX_HELD(&t->zthr_state_lock));
ASSERT(!MUTEX_HELD(&t->zthr_request_lock));
- VERIFY3P(t->zthr_thread, ==, NULL);
+ VERIFY0P(t->zthr_thread);
mutex_destroy(&t->zthr_request_lock);
mutex_destroy(&t->zthr_state_lock);
cv_destroy(&t->zthr_cv);
diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c
index 7e264f308cf2..29f51e230a37 100644
--- a/sys/contrib/openzfs/module/zfs/zvol.c
+++ b/sys/contrib/openzfs/module/zfs/zvol.c
@@ -215,8 +215,8 @@ zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
int error;
uint64_t volblocksize, volsize;
- VERIFY(nvlist_lookup_uint64(nvprops,
- zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) == 0);
+ VERIFY0(nvlist_lookup_uint64(nvprops,
+ zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize));
if (nvlist_lookup_uint64(nvprops,
zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), &volblocksize) != 0)
volblocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
@@ -225,21 +225,20 @@ zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
* These properties must be removed from the list so the generic
* property setting step won't apply to them.
*/
- VERIFY(nvlist_remove_all(nvprops,
- zfs_prop_to_name(ZFS_PROP_VOLSIZE)) == 0);
+ VERIFY0(nvlist_remove_all(nvprops, zfs_prop_to_name(ZFS_PROP_VOLSIZE)));
(void) nvlist_remove_all(nvprops,
zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE));
error = dmu_object_claim(os, ZVOL_OBJ, DMU_OT_ZVOL, volblocksize,
DMU_OT_NONE, 0, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
error = zap_create_claim(os, ZVOL_ZAP_OBJ, DMU_OT_ZVOL_PROP,
DMU_OT_NONE, 0, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx);
- ASSERT(error == 0);
+ ASSERT0(error);
}
/*
@@ -254,7 +253,7 @@ zvol_get_stats(objset_t *os, nvlist_t *nv)
error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &val);
if (error)
- return (SET_ERROR(error));
+ return (error);
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_VOLSIZE, val);
doi = kmem_alloc(sizeof (dmu_object_info_t), KM_SLEEP);
@@ -267,7 +266,7 @@ zvol_get_stats(objset_t *os, nvlist_t *nv)
kmem_free(doi, sizeof (dmu_object_info_t));
- return (SET_ERROR(error));
+ return (error);
}
/*
@@ -305,7 +304,7 @@ zvol_update_volsize(uint64_t volsize, objset_t *os)
error = dmu_tx_assign(tx, DMU_TX_WAIT);
if (error) {
dmu_tx_abort(tx);
- return (SET_ERROR(error));
+ return (error);
}
txg = dmu_tx_get_txg(tx);
@@ -337,7 +336,7 @@ zvol_set_volsize(const char *name, uint64_t volsize)
error = dsl_prop_get_integer(name,
zfs_prop_to_name(ZFS_PROP_READONLY), &readonly, NULL);
if (error != 0)
- return (SET_ERROR(error));
+ return (error);
if (readonly)
return (SET_ERROR(EROFS));
@@ -353,7 +352,7 @@ zvol_set_volsize(const char *name, uint64_t volsize)
FTAG, &os)) != 0) {
if (zv != NULL)
mutex_exit(&zv->zv_state_lock);
- return (SET_ERROR(error));
+ return (error);
}
owned = B_TRUE;
if (zv != NULL)
@@ -390,7 +389,7 @@ out:
if (error == 0 && zv != NULL)
zvol_os_update_volsize(zv, volsize);
- return (SET_ERROR(error));
+ return (error);
}
/*
@@ -401,7 +400,7 @@ zvol_set_volthreading(const char *name, boolean_t value)
{
zvol_state_t *zv = zvol_find_by_name(name, RW_NONE);
if (zv == NULL)
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
zv->zv_threading = value;
mutex_exit(&zv->zv_state_lock);
return (0);
@@ -450,8 +449,10 @@ zvol_check_volblocksize(const char *name, uint64_t volblocksize)
* We don't allow setting the property above 1MB,
* unless the tunable has been changed.
*/
- if (volblocksize > zfs_max_recordsize)
+ if (volblocksize > zfs_max_recordsize) {
+ spa_close(spa, FTAG);
return (SET_ERROR(EDOM));
+ }
spa_close(spa, FTAG);
}
@@ -618,7 +619,7 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
dmu_tx_t *tx;
blkptr_t *bps;
size_t maxblocks;
- int error = EINVAL;
+ int error = 0;
rw_enter(&zv_dst->zv_suspend_lock, RW_READER);
if (zv_dst->zv_zilog == NULL) {
@@ -644,23 +645,22 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
*/
if (!spa_feature_is_enabled(dmu_objset_spa(outos),
SPA_FEATURE_BLOCK_CLONING)) {
- error = EOPNOTSUPP;
+ error = SET_ERROR(EOPNOTSUPP);
goto out;
}
if (dmu_objset_spa(inos) != dmu_objset_spa(outos)) {
- error = EXDEV;
+ error = SET_ERROR(EXDEV);
goto out;
}
if (inos->os_encrypted != outos->os_encrypted) {
- error = EXDEV;
+ error = SET_ERROR(EXDEV);
goto out;
}
if (zv_src->zv_volblocksize != zv_dst->zv_volblocksize) {
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
goto out;
}
if (inoff >= zv_src->zv_volsize || outoff >= zv_dst->zv_volsize) {
- error = 0;
goto out;
}
@@ -671,17 +671,15 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
len = zv_src->zv_volsize - inoff;
if (len > zv_dst->zv_volsize - outoff)
len = zv_dst->zv_volsize - outoff;
- if (len == 0) {
- error = 0;
+ if (len == 0)
goto out;
- }
/*
* No overlapping if we are cloning within the same file
*/
if (zv_src == zv_dst) {
if (inoff < outoff + len && outoff < inoff + len) {
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
goto out;
}
}
@@ -691,7 +689,7 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
*/
if ((inoff % zv_src->zv_volblocksize) != 0 ||
(outoff % zv_dst->zv_volblocksize) != 0) {
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
goto out;
}
@@ -699,7 +697,7 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
* Length must be multiple of block size
*/
if ((len % zv_src->zv_volblocksize) != 0) {
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
goto out;
}
@@ -771,13 +769,13 @@ zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst,
zfs_rangelock_exit(outlr);
zfs_rangelock_exit(inlr);
if (error == 0 && zv_dst->zv_objset->os_sync == ZFS_SYNC_ALWAYS) {
- zil_commit(zilog_dst, ZVOL_OBJ);
+ error = zil_commit(zilog_dst, ZVOL_OBJ);
}
out:
if (zv_src != zv_dst)
rw_exit(&zv_src->zv_suspend_lock);
rw_exit(&zv_dst->zv_suspend_lock);
- return (SET_ERROR(error));
+ return (error);
}
/*
@@ -897,7 +895,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
if (wr_state == WR_COPIED &&
dmu_read_by_dnode(zv->zv_dn, offset, len, lr + 1,
DMU_READ_NO_PREFETCH | DMU_KEEP_CACHING) != 0) {
- zil_itx_destroy(itx);
+ zil_itx_destroy(itx, 0);
itx = zil_itx_create(TX_WRITE, sizeof (*lr));
lr = (lr_write_t *)&itx->itx_lr;
wr_state = WR_NEED_COPY;
@@ -916,7 +914,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
itx->itx_private = zv;
- (void) zil_itx_assign(zilog, itx, tx);
+ zil_itx_assign(zilog, itx, tx);
offset += len;
size -= len;
@@ -1026,7 +1024,7 @@ zvol_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
zvol_get_done(zgd, error);
- return (SET_ERROR(error));
+ return (error);
}
/*
@@ -1071,15 +1069,15 @@ zvol_setup_zv(zvol_state_t *zv)
error = dsl_prop_get_integer(zv->zv_name, "readonly", &ro, NULL);
if (error)
- return (SET_ERROR(error));
+ return (error);
error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
if (error)
- return (SET_ERROR(error));
+ return (error);
error = dnode_hold(os, ZVOL_OBJ, zv, &zv->zv_dn);
if (error)
- return (SET_ERROR(error));
+ return (error);
zvol_os_set_capacity(zv, volsize >> 9);
zv->zv_volsize = volsize;
@@ -1121,7 +1119,7 @@ zvol_shutdown_zv(zvol_state_t *zv)
*/
if (zv->zv_flags & ZVOL_WRITTEN_TO)
txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0);
- (void) dmu_objset_evict_dbufs(zv->zv_objset);
+ dmu_objset_evict_dbufs(zv->zv_objset);
}
/*
@@ -1198,7 +1196,7 @@ zvol_resume(zvol_state_t *zv)
if (zv->zv_flags & ZVOL_REMOVING)
cv_broadcast(&zv->zv_removing_cv);
- return (SET_ERROR(error));
+ return (error);
}
int
@@ -1214,7 +1212,7 @@ zvol_first_open(zvol_state_t *zv, boolean_t readonly)
boolean_t ro = (readonly || (strchr(zv->zv_name, '@') != NULL));
error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, ro, B_TRUE, zv, &os);
if (error)
- return (SET_ERROR(error));
+ return (error);
zv->zv_objset = os;
@@ -1440,41 +1438,32 @@ zvol_task_update_status(zvol_task_t *task, uint64_t total, uint64_t done,
}
}
-static const char *
-zvol_task_op_msg(zvol_async_op_t op)
-{
- switch (op) {
- case ZVOL_ASYNC_CREATE_MINORS:
- return ("create");
- case ZVOL_ASYNC_REMOVE_MINORS:
- return ("remove");
- case ZVOL_ASYNC_RENAME_MINORS:
- return ("rename");
- case ZVOL_ASYNC_SET_SNAPDEV:
- case ZVOL_ASYNC_SET_VOLMODE:
- return ("set property");
- default:
- return ("unknown");
- }
-
- __builtin_unreachable();
- return (NULL);
-}
-
static void
zvol_task_report_status(zvol_task_t *task)
{
+#ifdef ZFS_DEBUG
+ static const char *const msg[] = {
+ "create",
+ "remove",
+ "rename",
+ "set snapdev",
+ "set volmode",
+ "unknown",
+ };
if (task->zt_status == 0)
return;
+ zvol_async_op_t op = MIN(task->zt_op, ZVOL_ASYNC_MAX);
if (task->zt_error) {
dprintf("The %s minors zvol task was not ok, last error %d\n",
- zvol_task_op_msg(task->zt_op), task->zt_error);
+ msg[op], task->zt_error);
} else {
- dprintf("The %s minors zvol task was not ok\n",
- zvol_task_op_msg(task->zt_op));
+ dprintf("The %s minors zvol task was not ok\n", msg[op]);
}
+#else
+ (void) task;
+#endif
}
/*
@@ -1733,7 +1722,7 @@ zvol_remove_minor_impl(const char *name)
if (zv == NULL) {
rw_exit(&zvol_state_lock);
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
}
ASSERT(MUTEX_HELD(&zv->zv_state_lock));
@@ -2212,7 +2201,7 @@ zvol_fini_impl(void)
rw_destroy(&zvol_state_lock);
if (ztqs->tqs_taskq == NULL) {
- ASSERT3U(ztqs->tqs_cnt, ==, 0);
+ ASSERT0(ztqs->tqs_cnt);
} else {
for (uint_t i = 0; i < ztqs->tqs_cnt; i++) {
ASSERT3P(ztqs->tqs_taskq[i], !=, NULL);
diff --git a/sys/contrib/openzfs/rpm/generic/zfs.spec.in b/sys/contrib/openzfs/rpm/generic/zfs.spec.in
index dddc0a6c8f02..1ce668e7b86d 100644
--- a/sys/contrib/openzfs/rpm/generic/zfs.spec.in
+++ b/sys/contrib/openzfs/rpm/generic/zfs.spec.in
@@ -506,7 +506,6 @@ systemctl --system daemon-reload >/dev/null || true
# Core utilities
%{_sbindir}/*
%{_bindir}/raidz_test
-%{_sbindir}/zgenhostid
%{_bindir}/zvol_wait
# Optional Python 3 scripts
%{_bindir}/arc_summary
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index 9fad8946f4f3..131845f5ed40 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -725,7 +725,11 @@ tests = ['fadvise_willneed']
tags = ['functional', 'fadvise']
[tests/functional/failmode]
-tests = ['failmode_dmu_tx_wait', 'failmode_dmu_tx_continue']
+tests = ['failmode_dmu_tx_wait', 'failmode_dmu_tx_continue',
+ 'failmode_fsync_wait', 'failmode_fsync_continue',
+ 'failmode_msync_wait', 'failmode_msync_continue',
+ 'failmode_osync_wait', 'failmode_osync_continue',
+ 'failmode_syncalways_wait', 'failmode_syncalways_continue']
tags = ['functional', 'failmode']
[tests/functional/fallocate]
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore b/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
index 1cd90024e94d..62f1684acfb4 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
@@ -28,6 +28,7 @@
/mmap_seek
/mmap_sync
/mmapwrite
+/mmap_write_sync
/nvlist_to_lua
/randfree_file
/randwritecomp
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
index d5448055a1e1..85c3cf3c35a8 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
@@ -74,7 +74,7 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/mkbusy %D%/mkfile %D%/mkfiles %D%/mktree
scripts_zfs_tests_bin_PROGRAMS += \
%D%/mmap_exec %D%/mmap_ftruncate %D%/mmap_seek \
- %D%/mmap_sync %D%/mmapwrite %D%/readmmap
+ %D%/mmap_sync %D%/mmapwrite %D%/readmmap %D%/mmap_write_sync
%C%_mmapwrite_LDADD = -lpthread
if WANT_MMAP_LIBAIO
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c
index e7b80d01efaa..f8948a61833d 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c
@@ -207,7 +207,7 @@ insert_find_remove(zfs_btree_t *bt, char *why)
"Found removed value (%llu)\n", *p);
return (1);
}
- ASSERT3S(zfs_btree_numnodes(bt), ==, 0);
+ ASSERT0(zfs_btree_numnodes(bt));
zfs_btree_verify(bt);
return (0);
@@ -279,7 +279,7 @@ drain_tree(zfs_btree_t *bt, char *why)
node = avl_last(&avl);
ASSERT3U(node->data, ==, *(uint64_t *)zfs_btree_last(bt, NULL));
}
- ASSERT3S(zfs_btree_numnodes(bt), ==, 0);
+ ASSERT0(zfs_btree_numnodes(bt));
void *avl_cookie = NULL;
while ((node = avl_destroy_nodes(&avl, &avl_cookie)) != NULL)
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_write_sync.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_write_sync.c
new file mode 100644
index 000000000000..ad5e37f24960
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_write_sync.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: CDDL-1.0
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or https://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2025, Klara, Inc.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#define PAGES (8)
+
+int
+main(int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <filename>\n", argv[0]);
+ exit(1);
+ }
+
+ long page_size = sysconf(_SC_PAGESIZE);
+ if (page_size < 0) {
+ perror("sysconf");
+ exit(2);
+ }
+ size_t map_size = page_size * PAGES;
+
+ int fd = open(argv[1], O_CREAT|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
+ if (fd < 0) {
+ perror("open");
+ exit(2);
+ }
+
+ if (ftruncate(fd, map_size) < 0) {
+ perror("ftruncate");
+ close(fd);
+ exit(2);
+ }
+
+ uint64_t *p =
+ mmap(NULL, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (p == MAP_FAILED) {
+ perror("mmap");
+ close(fd);
+ exit(2);
+ }
+
+ for (int i = 0; i < (map_size / sizeof (uint64_t)); i++)
+ p[i] = 0x0123456789abcdef;
+
+ if (msync(p, map_size, MS_SYNC) < 0) {
+ perror("msync");
+ munmap(p, map_size);
+ close(fd);
+ exit(3);
+ }
+
+ munmap(p, map_size);
+ close(fd);
+ exit(0);
+}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
index bbaa8665ecc8..884a99d785bc 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
+++ b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
@@ -210,6 +210,7 @@ export ZFSTEST_FILES='badsend
mmap_seek
mmap_sync
mmapwrite
+ mmap_write_sync
nvlist_to_lua
randfree_file
randwritecomp
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
index c2542287c1d7..b8b8bbe45a42 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
@@ -276,6 +276,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/direct/dio.kshlib \
functional/events/events.cfg \
functional/events/events_common.kshlib \
+ functional/failmode/failmode.kshlib \
functional/fault/fault.cfg \
functional/gang_blocks/gang_blocks.kshlib \
functional/grow/grow.cfg \
@@ -1541,6 +1542,14 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/failmode/cleanup.ksh \
functional/failmode/failmode_dmu_tx_wait.ksh \
functional/failmode/failmode_dmu_tx_continue.ksh \
+ functional/failmode/failmode_fsync_wait.ksh \
+ functional/failmode/failmode_fsync_continue.ksh \
+ functional/failmode/failmode_msync_wait.ksh \
+ functional/failmode/failmode_msync_continue.ksh \
+ functional/failmode/failmode_osync_wait.ksh \
+ functional/failmode/failmode_osync_continue.ksh \
+ functional/failmode/failmode_syncalways_wait.ksh \
+ functional/failmode/failmode_syncalways_continue.ksh \
functional/failmode/setup.ksh \
functional/fallocate/cleanup.ksh \
functional/fallocate/fallocate_prealloc.ksh \
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode.kshlib
new file mode 100644
index 000000000000..d0b7404557ab
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode.kshlib
@@ -0,0 +1,149 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+typeset -A failmode_sync_helper_cmd=(
+ ["fsync"]='dd if=/dev/urandom of=DATAFILE bs=128k count=1 conv=fsync'
+ ["msync"]='mmap_write_sync DATAFILE'
+ ["osync"]='dd if=/dev/urandom of=DATAFILE bs=128k count=1 oflag=sync'
+ ["syncalways"]='dd if=/dev/urandom of=DATAFILE bs=128k count=1'
+)
+
+typeset -A failmode_sync_helper_dsopts=(
+ ["syncalways"]="-o sync=always"
+)
+
+function failmode_sync_cleanup
+{
+ zinject -c all || true
+ zpool clear $TESTPOOL || true
+ destroy_pool $TESTPOOL
+}
+
+#
+# failmode_sync_test <failmode> <helper>
+#
+# run a failmode sync test:
+# - failmode: wait|continue
+# - helper: fsync|msync|osync|syncalways
+#
+function failmode_sync_test
+{
+ typeset failmode=$1
+ typeset helper=$2
+
+ # we'll need two disks, one for the main pool, one for the log
+ read -r DISK1 DISK2 _ <<<"$DISKS"
+
+ # file to write to the pool
+ typeset datafile="/$TESTPOOL/$TESTFS/datafile"
+
+ # create a single-disk pool with a separate log and the wanted failmode
+ log_must zpool create \
+ -f -o failmode=$failmode $TESTPOOL $DISK1 log $DISK2
+
+ # create the test dataset. we bias the ZIL towards the log device to
+ # try to ensure that the sync write never involves the main device
+ log_must zfs create \
+ -o recordsize=128k -o logbias=latency \
+ ${failmode_sync_helper_dsopts[$helper]} \
+ $TESTPOOL/$TESTFS
+
+ # create the target file. the ZIL head structure is created on first
+ # use, and does a full txg wait to finish, which we want to avoid
+ log_must dd if=/dev/zero of=$datafile bs=128k count=1 conv=fsync
+ log_must zpool sync
+
+ # inject errors. writes will fail, as will the followup probes
+ zinject -d $DISK1 -e io -T write $TESTPOOL
+ zinject -d $DISK1 -e nxio -T probe $TESTPOOL
+ zinject -d $DISK2 -e io -T write $TESTPOOL
+ zinject -d $DISK2 -e nxio -T probe $TESTPOOL
+
+ # run the helper program in the background. the pool should immediately
+ # suspend, and the sync op block or fail based on the failmode
+ typeset helper_cmd=${failmode_sync_helper_cmd[$helper]/DATAFILE/$datafile}
+ log_note "running failmode sync helper: $helper_cmd"
+ $helper_cmd &
+ typeset -i pid=$!
+
+ # should only take a moment, but give it a chance
+ log_note "waiting for pool to suspend"
+ typeset -i tries=10
+ until [[ $(kstat_pool $TESTPOOL state) == "SUSPENDED" ]] ; do
+ if ((tries-- == 0)); then
+ log_fail "pool didn't suspend"
+ fi
+ sleep 1
+ done
+
+ # zil_commit() should have noticed the suspend by now
+ typeset -i zilerr=$(kstat zil.zil_commit_error_count)
+
+ # see if the helper program blocked
+ typeset -i blocked
+ if kill -0 $pid ; then
+ blocked=1
+ log_note "$helper: blocked in the kernel"
+ else
+ blocked=0
+ log_note "$helper: exited while pool suspended"
+ fi
+
+ # bring the pool back online
+ zinject -c all
+ zpool clear $TESTPOOL
+
+ # program definitely exited now, get its return code
+ wait $pid
+ typeset -i rc=$?
+
+ failmode_sync_cleanup
+
+ log_note "$helper: zilerr=$zilerr blocked=$blocked rc=$rc"
+
+ # confirm expected results for the failmode
+ if [[ $failmode = "wait" ]] ; then
+ # - the ZIL saw an error, and fell back to a txg sync
+ # - sync op blocked when the pool suspended
+ # - after resume, sync op succeeded, helper returned success
+ log_must test $zilerr -ne 0
+ log_must test $blocked -eq 1
+ log_must test $rc -eq 0
+ elif [[ $failmode = "continue" ]] ; then
+ # confirm expected results:
+ # - the ZIL saw an error, and fell back to a txg sync
+ # - helper exited when the pool suspended
+ # - sync op returned an error, so helper returned failure
+ log_must test $zilerr -ne 0
+ log_must test $blocked -eq 0
+ log_must test $rc -ne 0
+ else
+ log_fail "impossible failmode: $failmode"
+ fi
+}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_continue.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_continue.ksh
new file mode 100755
index 000000000000..7b145d3a2b4c
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_continue.ksh
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="fsync() returns when pool suspends with failmode=continue"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test continue fsync
+log_pass $desc
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_wait.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_wait.ksh
new file mode 100755
index 000000000000..677d226b5481
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_fsync_wait.ksh
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="fsync() blocks when pool suspends with failmode=wait"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test wait fsync
+log_pass $desc
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_continue.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_continue.ksh
new file mode 100755
index 000000000000..0c79ee15a1ba
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_continue.ksh
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="msync() returns when pool suspends with failmode=continue"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test continue msync
+log_pass $desc
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_wait.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_wait.ksh
new file mode 100755
index 000000000000..a59d8cc50d61
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_msync_wait.ksh
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="msync() blocks when pool suspends with failmode=wait"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test wait msync
+log_pass $desc
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_continue.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_continue.ksh
new file mode 100755
index 000000000000..c4fa0c8f042c
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_continue.ksh
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="O_SYNC returns when pool suspends with failmode=continue"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test continue osync
+log_pass $desc
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_wait.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_wait.ksh
new file mode 100755
index 000000000000..5f65cf92ad33
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_osync_wait.ksh
@@ -0,0 +1,37 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="O_SYNC blocks when pool suspends with failmode=wait"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test wait osync
+log_pass $desc
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_continue.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_continue.ksh
new file mode 100755
index 000000000000..b80d776224a0
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_continue.ksh
@@ -0,0 +1,37 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="write()+sync=always returns when pool suspends with failmode=continue"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test continue syncalways
+log_pass $desc
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_wait.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_wait.ksh
new file mode 100755
index 000000000000..4fcb167b5c77
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/failmode/failmode_syncalways_wait.ksh
@@ -0,0 +1,37 @@
+#!/bin/ksh -p
+# SPDX-License-Identifier: CDDL-1.0
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or https://opensource.org/licenses/CDDL-1.0.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2025, Klara, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/failmode/failmode.kshlib
+
+typeset desc="write()+sync=always blocks when pool suspends with failmode=wait"
+
+log_assert $desc
+log_onexit failmode_sync_cleanup
+log_must failmode_sync_test wait syncalways
+log_pass $desc
+
diff --git a/sys/dev/amdgpio/amdgpio.c b/sys/dev/amdgpio/amdgpio.c
index f39006d95805..2bd455c612b8 100644
--- a/sys/dev/amdgpio/amdgpio.c
+++ b/sys/dev/amdgpio/amdgpio.c
@@ -408,12 +408,13 @@ amdgpio_attach(device_t dev)
GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
device_printf(dev, "could not attach gpiobus\n");
goto err_bus;
}
+ bus_attach_children(dev);
return (0);
err_bus:
diff --git a/sys/dev/bhnd/cores/chipc/chipc_gpio.c b/sys/dev/bhnd/cores/chipc/chipc_gpio.c
index a110bdda5fa7..429de0fc1fd8 100644
--- a/sys/dev/bhnd/cores/chipc/chipc_gpio.c
+++ b/sys/dev/bhnd/cores/chipc/chipc_gpio.c
@@ -173,11 +173,13 @@ chipc_gpio_attach(device_t dev)
if (CC_GPIO_QUIRK(sc, NO_GPIOC)) {
sc->gpiobus = NULL;
} else {
- if ((sc->gpiobus = gpiobus_attach_bus(dev)) == NULL) {
+ if ((sc->gpiobus = gpiobus_add_bus(dev)) == NULL) {
device_printf(dev, "failed to attach gpiobus\n");
error = ENXIO;
goto failed;
}
+
+ bus_attach_children(dev);
}
/* Register as the bus GPIO provider */
diff --git a/sys/dev/ftgpio/ftgpio.c b/sys/dev/ftgpio/ftgpio.c
index 7acfdd5b900e..68787b54bb16 100644
--- a/sys/dev/ftgpio/ftgpio.c
+++ b/sys/dev/ftgpio/ftgpio.c
@@ -398,12 +398,13 @@ ftgpio_attach(device_t dev)
FTGPIO_VERBOSE_PRINTF(sc->dev, "groups GPIO1..GPIO6 enabled\n");
GPIO_UNLOCK(sc);
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
GPIO_LOCK_DESTROY(sc);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/gpio/acpi_gpiobus.c b/sys/dev/gpio/acpi_gpiobus.c
index 94f4e5771266..170f23615416 100644
--- a/sys/dev/gpio/acpi_gpiobus.c
+++ b/sys/dev/gpio/acpi_gpiobus.c
@@ -383,7 +383,8 @@ acpi_gpiobus_detach(device_t dev)
}
static int
-acpi_gpiobus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+acpi_gpiobus_read_ivar(device_t dev, device_t child, int which,
+ uintptr_t *result)
{
struct acpi_gpiobus_ivar *devi = device_get_ivars(child);
diff --git a/sys/dev/gpio/bytgpio.c b/sys/dev/gpio/bytgpio.c
index f7b2a73ec6cb..5d685c155a03 100644
--- a/sys/dev/gpio/bytgpio.c
+++ b/sys/dev/gpio/bytgpio.c
@@ -608,7 +608,7 @@ bytgpio_attach(device_t dev)
sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK;
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
BYTGPIO_LOCK_DESTROY(sc);
bus_release_resource(dev, SYS_RES_MEMORY,
@@ -616,6 +616,7 @@ bytgpio_attach(device_t dev)
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
error:
diff --git a/sys/dev/gpio/chvgpio.c b/sys/dev/gpio/chvgpio.c
index 199ad4d6f373..3273aad9242b 100644
--- a/sys/dev/gpio/chvgpio.c
+++ b/sys/dev/gpio/chvgpio.c
@@ -441,7 +441,7 @@ chvgpio_attach(device_t dev)
bus_write_4(sc->sc_mem_res, CHVGPIO_INTERRUPT_MASK, 0);
bus_write_4(sc->sc_mem_res, CHVGPIO_INTERRUPT_STATUS, 0xffff);
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
CHVGPIO_LOCK_DESTROY(sc);
bus_release_resource(dev, SYS_RES_MEMORY,
@@ -451,6 +451,7 @@ chvgpio_attach(device_t dev)
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/gpio/dwgpio/dwgpio.c b/sys/dev/gpio/dwgpio/dwgpio.c
index 5acb99ca591e..3908113d5fd4 100644
--- a/sys/dev/gpio/dwgpio/dwgpio.c
+++ b/sys/dev/gpio/dwgpio/dwgpio.c
@@ -167,12 +167,13 @@ dwgpio_attach(device_t dev)
snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
"dwgpio%d.%d", device_get_unit(dev), i);
}
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index 764bcb7e6ee8..c25c41f43042 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -330,24 +330,6 @@ gpiobus_add_bus(device_t dev)
return (busdev);
}
-/*
- * Attach a gpiobus child.
- * Note that the controller is expected
- * to be fully initialized at this point.
- */
-device_t
-gpiobus_attach_bus(device_t dev)
-{
- device_t busdev;
-
- busdev = gpiobus_add_bus(dev);
- if (busdev == NULL)
- return (NULL);
-
- bus_attach_children(dev);
- return (busdev);
-}
-
int
gpiobus_detach_bus(device_t dev)
{
diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h
index 7f504236a774..0528efe45525 100644
--- a/sys/dev/gpio/gpiobusvar.h
+++ b/sys/dev/gpio/gpiobusvar.h
@@ -171,7 +171,6 @@ struct resource *gpio_alloc_intr_resource(device_t consumer_dev, int *rid,
int gpio_check_flags(uint32_t, uint32_t);
device_t gpiobus_add_bus(device_t);
-device_t gpiobus_attach_bus(device_t);
int gpiobus_detach_bus(device_t);
#endif /* __GPIOBUS_H__ */
diff --git a/sys/dev/gpio/pl061.c b/sys/dev/gpio/pl061.c
index 87d4310a6396..32109e5982bc 100644
--- a/sys/dev/gpio/pl061.c
+++ b/sys/dev/gpio/pl061.c
@@ -495,13 +495,14 @@ pl061_attach(device_t dev)
goto free_isrc;
}
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
device_printf(dev, "couldn't attach gpio bus\n");
PL061_LOCK_DESTROY(sc);
goto free_isrc;
}
+ bus_attach_children(dev);
return (0);
free_isrc:
diff --git a/sys/dev/gpio/qoriq_gpio.c b/sys/dev/gpio/qoriq_gpio.c
index 8b44cd256c79..d11868a23751 100644
--- a/sys/dev/gpio/qoriq_gpio.c
+++ b/sys/dev/gpio/qoriq_gpio.c
@@ -379,12 +379,13 @@ qoriq_gpio_attach(device_t dev)
OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
qoriq_gpio_detach(dev);
return (ENOMEM);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/iicbus/gpio/pcf8574.c b/sys/dev/iicbus/gpio/pcf8574.c
index ab6e2bc07d1f..bf60dec67557 100644
--- a/sys/dev/iicbus/gpio/pcf8574.c
+++ b/sys/dev/iicbus/gpio/pcf8574.c
@@ -142,12 +142,13 @@ pcf8574_attach(device_t dev)
(void)pcf8574_write(sc, 0xff);
sx_init(&sc->lock, "pcf8574");
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "Could not create busdev child\n");
sx_destroy(&sc->lock);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
@@ -158,9 +159,7 @@ pcf8574_detach(device_t dev)
sc = device_get_softc(dev);
- if (sc->busdev != NULL)
- gpiobus_detach_bus(sc->busdev);
-
+ gpiobus_detach_bus(dev);
sx_destroy(&sc->lock);
return (0);
}
diff --git a/sys/dev/iicbus/gpio/tca64xx.c b/sys/dev/iicbus/gpio/tca64xx.c
index cd011ae9be75..ab8fedd3f8fd 100644
--- a/sys/dev/iicbus/gpio/tca64xx.c
+++ b/sys/dev/iicbus/gpio/tca64xx.c
@@ -262,7 +262,7 @@ tca64xx_attach(device_t dev)
mtx_init(&sc->mtx, "tca64xx gpio", "gpio", MTX_DEF);
OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "Could not create busdev child\n");
return (ENXIO);
@@ -281,6 +281,7 @@ tca64xx_attach(device_t dev)
}
#endif
+ bus_attach_children(dev);
return (0);
}
@@ -291,9 +292,7 @@ tca64xx_detach(device_t dev)
sc = device_get_softc(dev);
- if (sc->busdev != NULL)
- gpiobus_detach_bus(sc->busdev);
-
+ gpiobus_detach_bus(dev);
mtx_destroy(&sc->mtx);
return (0);
diff --git a/sys/dev/nctgpio/nctgpio.c b/sys/dev/nctgpio/nctgpio.c
index 75ea1fbdba17..ddc2ceef7dfb 100644
--- a/sys/dev/nctgpio/nctgpio.c
+++ b/sys/dev/nctgpio/nctgpio.c
@@ -1258,13 +1258,14 @@ nct_attach(device_t dev)
GPIO_UNLOCK(sc);
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "failed to attach to gpiobus\n");
GPIO_LOCK_DESTROY(sc);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/p2sb/lewisburg_gpio.c b/sys/dev/p2sb/lewisburg_gpio.c
index b45d7767602c..3be777ab9524 100644
--- a/sys/dev/p2sb/lewisburg_gpio.c
+++ b/sys/dev/p2sb/lewisburg_gpio.c
@@ -217,10 +217,11 @@ lbggpio_attach(device_t dev)
}
/* support gpio */
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL)
return (ENXIO);
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/qcom_tlmm/qcom_tlmm_ipq4018.c b/sys/dev/qcom_tlmm/qcom_tlmm_ipq4018.c
index 2d390cd449af..50f54b896748 100644
--- a/sys/dev/qcom_tlmm/qcom_tlmm_ipq4018.c
+++ b/sys/dev/qcom_tlmm/qcom_tlmm_ipq4018.c
@@ -346,13 +346,14 @@ qcom_tlmm_ipq4018_attach(device_t dev)
fdt_pinctrl_register(dev, NULL);
fdt_pinctrl_configure_by_name(dev, "default");
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "%s: failed to attach bus\n", __func__);
qcom_tlmm_ipq4018_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/rccgpio/rccgpio.c b/sys/dev/rccgpio/rccgpio.c
index b2b775b879ad..dafd0b511fa9 100644
--- a/sys/dev/rccgpio/rccgpio.c
+++ b/sys/dev/rccgpio/rccgpio.c
@@ -308,7 +308,7 @@ rcc_gpio_attach(device_t dev)
RCC_WRITE(sc, RCC_GPIO_GP_LVL, sc->sc_output);
/* Attach the gpiobus. */
- sc->sc_busdev = gpiobus_attach_bus(dev);
+ sc->sc_busdev = gpiobus_add_bus(dev);
if (sc->sc_busdev == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_io_rid,
sc->sc_io_res);
@@ -316,6 +316,7 @@ rcc_gpio_attach(device_t dev)
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/dev/uart/uart_cpu_acpi.c b/sys/dev/uart/uart_cpu_acpi.c
index 7382c47a8db6..da77603f0093 100644
--- a/sys/dev/uart/uart_cpu_acpi.c
+++ b/sys/dev/uart/uart_cpu_acpi.c
@@ -44,23 +44,15 @@
#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/actables.h>
-static struct acpi_uart_compat_data *
+static struct acpi_spcr_compat_data *
uart_cpu_acpi_scan(uint8_t interface_type)
{
- struct acpi_uart_compat_data **cd, *curcd;
+ struct acpi_spcr_compat_data **cd, *curcd;
int i;
- SET_FOREACH(cd, uart_acpi_class_and_device_set) {
+ SET_FOREACH(cd, uart_acpi_spcr_class_set) {
curcd = *cd;
- for (i = 0; curcd[i].cd_hid != NULL; i++) {
- if (curcd[i].cd_port_subtype == interface_type)
- return (&curcd[i]);
- }
- }
-
- SET_FOREACH(cd, uart_acpi_class_set) {
- curcd = *cd;
- for (i = 0; curcd[i].cd_hid != NULL; i++) {
+ for (i = 0; curcd[i].cd_class != NULL; i++) {
if (curcd[i].cd_port_subtype == interface_type)
return (&curcd[i]);
}
@@ -143,7 +135,7 @@ uart_cpu_acpi_spcr(int devtype, struct uart_devinfo *di)
{
vm_paddr_t spcr_physaddr;
ACPI_TABLE_SPCR *spcr;
- struct acpi_uart_compat_data *cd;
+ struct acpi_spcr_compat_data *cd;
struct uart_class *class;
int error = ENXIO;
@@ -237,7 +229,7 @@ uart_cpu_acpi_dbg2(struct uart_devinfo *di)
ACPI_TABLE_DBG2 *dbg2;
ACPI_DBG2_DEVICE *dbg2_dev;
ACPI_GENERIC_ADDRESS *base_address;
- struct acpi_uart_compat_data *cd;
+ struct acpi_spcr_compat_data *cd;
struct uart_class *class;
int error;
bool found;
diff --git a/sys/dev/uart/uart_cpu_acpi.h b/sys/dev/uart/uart_cpu_acpi.h
index 94329e1f1349..218f643c7621 100644
--- a/sys/dev/uart/uart_cpu_acpi.h
+++ b/sys/dev/uart/uart_cpu_acpi.h
@@ -35,11 +35,18 @@
struct uart_class;
+struct acpi_spcr_compat_data {
+ struct uart_class *cd_class;
+ uint16_t cd_port_subtype;
+};
+SET_DECLARE(uart_acpi_spcr_class_set, struct acpi_spcr_compat_data);
+#define UART_ACPI_SPCR_CLASS(data) \
+ DATA_SET(uart_acpi_spcr_class_set, data)
+
struct acpi_uart_compat_data {
const char *cd_hid;
struct uart_class *cd_class;
- uint16_t cd_port_subtype;
int cd_regshft;
int cd_regiowidth;
int cd_rclk;
@@ -56,14 +63,6 @@ SET_DECLARE(uart_acpi_class_and_device_set, struct acpi_uart_compat_data);
#define UART_ACPI_CLASS_AND_DEVICE(data) \
DATA_SET(uart_acpi_class_and_device_set, data)
-/*
- * If your UART driver implements uart_class and custom device layer,
- * then use UART_ACPI_CLASS for its declaration
- */
-SET_DECLARE(uart_acpi_class_set, struct acpi_uart_compat_data);
-#define UART_ACPI_CLASS(data) \
- DATA_SET(uart_acpi_class_set, data)
-
/* Try to initialize UART device from ACPI tables */
int uart_cpu_acpi_setup(int devtype, struct uart_devinfo *di);
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 0f19ede6d9df..c38d50e54ad8 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -492,24 +492,32 @@ UART_CLASS(uart_ns8250_class);
* XXX -- refactor out ACPI and FDT ifdefs
*/
#ifdef DEV_ACPI
+static struct acpi_spcr_compat_data acpi_spcr_compat_data[] = {
+ { &uart_ns8250_class, ACPI_DBG2_16550_COMPATIBLE },
+ { &uart_ns8250_class, ACPI_DBG2_16550_SUBSET },
+ { &uart_ns8250_class, ACPI_DBG2_16550_WITH_GAS },
+ { NULL, 0 },
+};
+UART_ACPI_SPCR_CLASS(acpi_spcr_compat_data);
+
static struct acpi_uart_compat_data acpi_compat_data[] = {
- {"AMD0020", &uart_ns8250_class, 0, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"},
- {"AMDI0020", &uart_ns8250_class, 0, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"},
- {"APMC0D08", &uart_ns8250_class, ACPI_DBG2_16550_COMPATIBLE, 2, 4, 0, 0, "APM compatible UART"},
- {"MRVL0001", &uart_ns8250_class, ACPI_DBG2_16550_SUBSET, 2, 0, 200000000, UART_F_BUSY_DETECT, "Marvell / Synopsys Designware UART"},
- {"SCX0006", &uart_ns8250_class, 0, 2, 0, 62500000, UART_F_BUSY_DETECT, "SynQuacer / Synopsys Designware UART"},
- {"HISI0031", &uart_ns8250_class, 0, 2, 0, 200000000, UART_F_BUSY_DETECT, "HiSilicon / Synopsys Designware UART"},
- {"INTC1006", &uart_ns8250_class, 0, 2, 0, 25000000, 0, "Intel ARM64 UART"},
- {"NXP0018", &uart_ns8250_class, 0, 0, 0, 350000000, UART_F_BUSY_DETECT, "NXP / Synopsys Designware UART"},
- {"PNP0500", &uart_ns8250_class, 0, 0, 0, 0, 0, "Standard PC COM port"},
- {"PNP0501", &uart_ns8250_class, 0, 0, 0, 0, 0, "16550A-compatible COM port"},
- {"PNP0502", &uart_ns8250_class, 0, 0, 0, 0, 0, "Multiport serial device (non-intelligent 16550)"},
- {"PNP0510", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"},
- {"PNP0511", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"},
- {"WACF004", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet PC Screen"},
- {"WACF00E", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet PC Screen 00e"},
- {"FUJ02E5", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet at FuS Lifebook T"},
- {NULL, NULL, 0, 0 , 0, 0, 0, NULL},
+ {"AMD0020", &uart_ns8250_class, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"},
+ {"AMDI0020", &uart_ns8250_class, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"},
+ {"APMC0D08", &uart_ns8250_class, 2, 4, 0, 0, "APM compatible UART"},
+ {"MRVL0001", &uart_ns8250_class, 2, 0, 200000000, UART_F_BUSY_DETECT, "Marvell / Synopsys Designware UART"},
+ {"SCX0006", &uart_ns8250_class, 2, 0, 62500000, UART_F_BUSY_DETECT, "SynQuacer / Synopsys Designware UART"},
+ {"HISI0031", &uart_ns8250_class, 2, 0, 200000000, UART_F_BUSY_DETECT, "HiSilicon / Synopsys Designware UART"},
+ {"INTC1006", &uart_ns8250_class, 2, 0, 25000000, 0, "Intel ARM64 UART"},
+ {"NXP0018", &uart_ns8250_class, 0, 0, 350000000, UART_F_BUSY_DETECT, "NXP / Synopsys Designware UART"},
+ {"PNP0500", &uart_ns8250_class, 0, 0, 0, 0, "Standard PC COM port"},
+ {"PNP0501", &uart_ns8250_class, 0, 0, 0, 0, "16550A-compatible COM port"},
+ {"PNP0502", &uart_ns8250_class, 0, 0, 0, 0, "Multiport serial device (non-intelligent 16550)"},
+ {"PNP0510", &uart_ns8250_class, 0, 0, 0, 0, "Generic IRDA-compatible device"},
+ {"PNP0511", &uart_ns8250_class, 0, 0, 0, 0, "Generic IRDA-compatible device"},
+ {"WACF004", &uart_ns8250_class, 0, 0, 0, 0, "Wacom Tablet PC Screen"},
+ {"WACF00E", &uart_ns8250_class, 0, 0, 0, 0, "Wacom Tablet PC Screen 00e"},
+ {"FUJ02E5", &uart_ns8250_class, 0, 0, 0, 0, "Wacom Tablet at FuS Lifebook T"},
+ {NULL, NULL, 0 , 0, 0, 0, NULL},
};
UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data);
#endif
diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c
index a0d5a5b1c7e2..6afc693cd347 100644
--- a/sys/dev/uart/uart_dev_pl011.c
+++ b/sys/dev/uart/uart_dev_pl011.c
@@ -391,11 +391,19 @@ UART_FDT_CLASS_AND_DEVICE(fdt_compat_data);
#endif
#ifdef DEV_ACPI
+static struct acpi_spcr_compat_data acpi_spcr_compat_data[] = {
+ { &uart_pl011_class, ACPI_DBG2_ARM_PL011 },
+ { &uart_pl011_class, ACPI_DBG2_ARM_SBSA_GENERIC },
+ { &uart_pl011_class, ACPI_DBG2_ARM_SBSA_32BIT },
+ { NULL, 0 },
+};
+UART_ACPI_SPCR_CLASS(acpi_spcr_compat_data);
+
static struct acpi_uart_compat_data acpi_compat_data[] = {
- {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_PL011, 2, 0, 0, 0, "uart pl011"},
- {"ARMHB000", &uart_pl011_class, ACPI_DBG2_ARM_SBSA_GENERIC, 2, 0, 0, 0, "uart pl011"},
- {"ARMHB000", &uart_pl011_class, ACPI_DBG2_ARM_SBSA_32BIT, 2, 0, 0, 0, "uart pl011"},
- {NULL, NULL, 0, 0, 0, 0, 0, NULL},
+ {"ARMH0011", &uart_pl011_class, 2, 0, 0, 0, "uart pl011"},
+ {"ARMHB000", &uart_pl011_class, 2, 0, 0, 0, "uart pl011"},
+ {"ARMHB000", &uart_pl011_class, 2, 0, 0, 0, "uart pl011"},
+ {NULL, NULL, 0, 0, 0, 0, NULL},
};
UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data);
#endif
diff --git a/sys/dev/usb/misc/cp2112.c b/sys/dev/usb/misc/cp2112.c
index d4776ca342cb..201a3ec51ce4 100644
--- a/sys/dev/usb/misc/cp2112.c
+++ b/sys/dev/usb/misc/cp2112.c
@@ -708,11 +708,12 @@ cp2112gpio_attach(device_t dev)
}
}
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
- device_printf(dev, "gpiobus_attach_bus failed\n");
+ device_printf(dev, "gpiobus_add_bus failed\n");
goto detach;
}
+ bus_attach_children(dev);
return (0);
detach:
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 0ae3b94bef89..1e4e8506790f 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -239,6 +239,7 @@ static bool nfscl_use_gss[NFSV42_NPROCS] = {
true,
true,
true,
+ true,
};
/*
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 67e33193ecec..7f5b29ca2085 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -187,7 +187,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = {
{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Read Plus */
{ 0, 1, 0, 0, LK_SHARED, 1, 0 }, /* Seek */
{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Write Same */
- { 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 }, /* Clone */
+ { 2, 1, 1, 0, LK_SHARED, 1, 0 }, /* Clone */
{ 0, 1, 0, 0, LK_SHARED, 1, 1 }, /* Getxattr */
{ 0, 1, 1, 1, LK_EXCLUSIVE, 1, 1 }, /* Setxattr */
{ 0, 1, 0, 0, LK_SHARED, 1, 1 }, /* Listxattrs */
@@ -219,7 +219,7 @@ NFSD_VNET_DEFINE_STATIC(u_char *, nfsrv_dnsname) = NULL;
static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
+ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
/* local functions */
static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
@@ -310,6 +310,7 @@ static struct {
{ NFSV4OP_LAYOUTERROR, 1, "LayoutError", 11, },
{ NFSV4OP_VERIFY, 3, "AppendWrite", 11, },
{ NFSV4OP_OPENATTR, 3, "OpenAttr", 8, },
+ { NFSV4OP_SAVEFH, 5, "Clone", 5, },
};
/*
@@ -319,7 +320,7 @@ static int nfs_bigrequest[NFSV42_NPROCS] = {
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 1, 0
+ 0, 1, 0, 0
};
/*
@@ -648,7 +649,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap,
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL,
- false, false, false);
+ false, false, false, 0);
break;
}
}
@@ -1302,7 +1303,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
struct nfsv3_pathconf *pc, struct statfs *sbp, struct nfsstatfs *sfp,
struct nfsfsinfo *fsp, NFSACL_T *aclp, int compare, int *retcmpp,
u_int32_t *leasep, u_int32_t *rderrp, bool *has_namedattrp,
- NFSPROC_T *p, struct ucred *cred)
+ uint32_t *clone_blksizep, NFSPROC_T *p, struct ucred *cred)
{
u_int32_t *tl;
int i = 0, j, k, l = 0, m, bitpos, attrsum = 0;
@@ -1437,6 +1438,13 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
NFSCLRBIT_ATTRBIT(&checkattrbits,
NFSATTRBIT_SYSTEM);
}
+ /* Some filesystems do not support block cloning */
+ if (vp == NULL || VOP_PATHCONF(vp,
+ _PC_CLONE_BLKSIZE, &has_pathconf) != 0)
+ has_pathconf = 0;
+ if (has_pathconf == 0)
+ NFSCLRBIT_ATTRBIT(&checkattrbits,
+ NFSATTRBIT_CLONEBLKSIZE);
if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits)
|| retnotsup)
*retcmpp = NFSERR_NOTSAME;
@@ -2374,6 +2382,23 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
if (compare && !(*retcmpp) && i != nfs_srvmaxio)
*retcmpp = NFSERR_NOTSAME;
break;
+ case NFSATTRBIT_CLONEBLKSIZE:
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+ if (compare) {
+ if (!(*retcmpp)) {
+ if (vp == NULL || VOP_PATHCONF(vp,
+ _PC_CLONE_BLKSIZE, &has_pathconf)
+ != 0)
+ has_pathconf = 0;
+ if (has_pathconf !=
+ fxdr_unsigned(uint32_t, *tl))
+ *retcmpp = NFSERR_NOTSAME;
+ }
+ } else if (clone_blksizep != NULL) {
+ *clone_blksizep = fxdr_unsigned(uint32_t, *tl);
+ }
+ attrsum += NFSX_UNSIGNED;
+ break;
case NFSATTRBIT_CHANGEATTRTYPE:
NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
if (compare) {
@@ -2648,7 +2673,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram,
int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
struct statfs *pnfssf, bool xattrsupp, bool has_hiddensystem,
- bool has_namedattr)
+ bool has_namedattr, uint32_t clone_blksize)
{
int bitpos, retnum = 0;
u_int32_t *tl;
@@ -2771,6 +2796,9 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN);
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM);
}
+ if (clone_blksize == 0)
+ NFSCLRBIT_ATTRBIT(&attrbits,
+ NFSATTRBIT_CLONEBLKSIZE);
retnum += nfsrv_putattrbit(nd, &attrbits);
break;
case NFSATTRBIT_TYPE:
@@ -3249,6 +3277,11 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
}
retnum += NFSX_UNSIGNED;
break;
+ case NFSATTRBIT_CLONEBLKSIZE:
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(clone_blksize);
+ retnum += NFSX_UNSIGNED;
+ break;
default:
printf("EEK! Bad V4 attribute bitpos=%d\n", bitpos);
}
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 54f60a753c50..61083ecf2d66 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -286,6 +286,8 @@ int nfsrvd_deallocate(struct nfsrv_descript *, int,
vnode_t, struct nfsexstuff *);
int nfsrvd_copy_file_range(struct nfsrv_descript *, int,
vnode_t, vnode_t, struct nfsexstuff *, struct nfsexstuff *);
+int nfsrvd_clone(struct nfsrv_descript *, int,
+ vnode_t, vnode_t, struct nfsexstuff *, struct nfsexstuff *);
int nfsrvd_seek(struct nfsrv_descript *, int,
vnode_t, struct nfsexstuff *);
int nfsrvd_getxattr(struct nfsrv_descript *, int,
@@ -341,7 +343,8 @@ int nfsv4_loadattr(struct nfsrv_descript *, vnode_t,
struct nfsvattr *, struct nfsfh **, fhandle_t *, int,
struct nfsv3_pathconf *, struct statfs *, struct nfsstatfs *,
struct nfsfsinfo *, NFSACL_T *,
- int, int *, u_int32_t *, u_int32_t *, bool *, NFSPROC_T *, struct ucred *);
+ int, int *, u_int32_t *, u_int32_t *, bool *, uint32_t *, NFSPROC_T *,
+ struct ucred *);
int nfsv4_lock(struct nfsv4lock *, int, int *, struct mtx *, struct mount *);
void nfsv4_unlock(struct nfsv4lock *, int);
void nfsv4_relref(struct nfsv4lock *);
@@ -397,7 +400,7 @@ void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int,
int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
struct vattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *,
NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *, bool, bool,
- bool);
+ bool, uint32_t);
void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
struct mbuf *nfsrv_adj(struct mbuf *, int, int);
void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
@@ -517,10 +520,10 @@ int nfsrpc_lock(struct nfsrv_descript *, struct nfsmount *, vnode_t,
u_int8_t *, int, struct nfscllockowner *, int, int, u_int64_t,
u_int64_t, short, struct ucred *, NFSPROC_T *, int);
int nfsrpc_statfs(vnode_t, struct nfsstatfs *, struct nfsfsinfo *, uint32_t *,
- struct ucred *, NFSPROC_T *, struct nfsvattr *, int *);
+ uint32_t *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *);
int nfsrpc_fsinfo(vnode_t, struct nfsfsinfo *, struct ucred *,
NFSPROC_T *, struct nfsvattr *, int *);
-int nfsrpc_pathconf(vnode_t, struct nfsv3_pathconf *, bool *,
+int nfsrpc_pathconf(vnode_t, struct nfsv3_pathconf *, bool *, uint32_t *,
struct ucred *, NFSPROC_T *, struct nfsvattr *, int *);
int nfsrpc_renew(struct nfsclclient *, struct nfsclds *, struct ucred *,
NFSPROC_T *);
@@ -562,6 +565,8 @@ int nfsrpc_deallocate(vnode_t, off_t, off_t, struct nfsvattr *, int *,
int nfsrpc_copy_file_range(vnode_t, off_t *, vnode_t, off_t *, size_t *,
unsigned int, int *, struct nfsvattr *, int *, struct nfsvattr *,
struct ucred *, bool, bool *);
+int nfsrpc_clone(vnode_t, off_t *, vnode_t, off_t *, size_t *, bool,
+ int *, struct nfsvattr *, int *, struct nfsvattr *, struct ucred *);
int nfsrpc_seek(vnode_t, off_t *, bool *, int, struct ucred *,
struct nfsvattr *, int *);
int nfsrpc_getextattr(vnode_t, const char *, struct uio *, ssize_t *,
@@ -668,7 +673,7 @@ int nfscl_nget(mount_t, vnode_t, struct nfsfh *,
NFSPROC_T *nfscl_getparent(NFSPROC_T *);
void nfscl_start_renewthread(struct nfsclclient *);
void nfscl_loadsbinfo(struct nfsmount *, struct nfsstatfs *, void *);
-void nfscl_loadfsinfo (struct nfsmount *, struct nfsfsinfo *);
+void nfscl_loadfsinfo(struct nfsmount *, struct nfsfsinfo *, uint32_t);
void nfscl_delegreturn(struct nfscldeleg *, int, struct nfsmount *,
struct ucred *, NFSPROC_T *);
void nfsrvd_cbinit(int);
@@ -737,7 +742,7 @@ int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct nfsrv_descript *,
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, bool, bool,
- bool);
+ bool, uint32_t);
int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
NFSACL_T *, NFSPROC_T *);
int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index c30b46261df0..bd6107187966 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -442,10 +442,13 @@
/* Do a NFSv4 Openattr. */
#define NFSPROC_OPENATTR 70
+/* Do a NFSv4.2 Clone. */
+#define NFSPROC_CLONE 71
+
/*
* Must be defined as one higher than the last NFSv4.2 Proc# above.
*/
-#define NFSV42_NPROCS 71
+#define NFSV42_NPROCS 72
/* Value of NFSV42_NPROCS for old nfsstats structure. (Always 69) */
#define NFSV42_OLDNPROCS 69
@@ -477,7 +480,7 @@ struct nfsstatsv1 {
uint64_t readlink_bios;
uint64_t biocache_readdirs;
uint64_t readdir_bios;
- uint64_t rpccnt[NFSV42_NPROCS + 9];
+ uint64_t rpccnt[NFSV42_NPROCS + 8];
uint64_t rpcretries;
uint64_t srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
uint64_t srvlayouts;
diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h
index cb5a80e8df73..d628108bdc1a 100644
--- a/sys/fs/nfs/nfsproto.h
+++ b/sys/fs/nfs/nfsproto.h
@@ -411,10 +411,13 @@
/* Do a NFSv4 Openattr. */
#define NFSPROC_OPENATTR 70
+/* Do a NFSv4.2 Clone. */
+#define NFSPROC_CLONE 71
+
/*
* Must be defined as one higher than the last NFSv4.2 Proc# above.
*/
-#define NFSV42_NPROCS 71
+#define NFSV42_NPROCS 72
/* Value of NFSV42_NPROCS for old nfsstats structure. (Always 69) */
#define NFSV42_OLDNPROCS 69
@@ -1194,6 +1197,7 @@ struct nfsv3_sattr {
NFSATTRBM_LAYOUTBLKSIZE | \
NFSATTRBM_LAYOUTALIGNMENT | \
NFSATTRBM_SUPPATTREXCLCREAT | \
+ NFSATTRBM_CLONEBLKSIZE | \
NFSATTRBM_CHANGEATTRTYPE | \
NFSATTRBM_XATTRSUPPORT)
@@ -1242,7 +1246,8 @@ struct nfsv3_sattr {
* NFSATTRBIT_NFSV42 - Attributes only supported by NFSv4.2.
*/
#define NFSATTRBIT_NFSV42_2 \
- (NFSATTRBM_CHANGEATTRTYPE | \
+ (NFSATTRBM_CLONEBLKSIZE | \
+ NFSATTRBM_CHANGEATTRTYPE | \
NFSATTRBM_XATTRSUPPORT | \
NFSATTRBM_MODEUMASK)
@@ -1415,7 +1420,7 @@ struct nfsv3_sattr {
/*
* NFSGETATTRBIT_STATFS2 - bits 64<->95
*/
-#define NFSGETATTRBIT_STATFS2 0
+#define NFSGETATTRBIT_STATFS2 (NFSATTRBM_CLONEBLKSIZE)
/*
* Set of attributes for the equivalent of an nfsv3 pathconf rpc.
@@ -1438,7 +1443,7 @@ struct nfsv3_sattr {
/*
* NFSGETATTRBIT_PATHCONF2 - bits 64<->95
*/
-#define NFSGETATTRBIT_PATHCONF2 0
+#define NFSGETATTRBIT_PATHCONF2 (NFSATTRBM_CLONEBLKSIZE)
/*
* Sets of attributes required by readdir and readdirplus.
diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c
index bca0bdcd0df1..05963074e53d 100644
--- a/sys/fs/nfsclient/nfs_clcomsubs.c
+++ b/sys/fs/nfsclient/nfs_clcomsubs.c
@@ -272,7 +272,7 @@ nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
if (nd->nd_flag & ND_NFSV4) {
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL,
NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
- NULL);
+ NULL, NULL);
} else if (nd->nd_flag & ND_NFSV3) {
NFSM_DISSECT(fp, struct nfs_fattr *, NFSX_V3FATTR);
nap->na_type = nfsv34tov_type(fp->fa_type);
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index b25d967982a1..704aeeeabdf2 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -828,7 +828,7 @@ nfscl_wcc_data(struct nfsrv_descript *nd, struct vnode *vp,
== (ND_NFSV4 | ND_V4WCCATTR)) {
error = nfsv4_loadattr(nd, NULL, &nfsva, NULL,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (error)
return (error);
/*
@@ -963,7 +963,8 @@ nfscl_loadsbinfo(struct nfsmount *nmp, struct nfsstatfs *sfp, void *statfs)
* Use the fsinfo stuff to update the mount point.
*/
void
-nfscl_loadfsinfo(struct nfsmount *nmp, struct nfsfsinfo *fsp)
+nfscl_loadfsinfo(struct nfsmount *nmp, struct nfsfsinfo *fsp,
+ uint32_t clone_blksize)
{
if ((nmp->nm_wsize == 0 || fsp->fs_wtpref < nmp->nm_wsize) &&
@@ -1003,6 +1004,14 @@ nfscl_loadfsinfo(struct nfsmount *nmp, struct nfsfsinfo *fsp)
fsp->fs_maxfilesize < nmp->nm_maxfilesize)
nmp->nm_maxfilesize = fsp->fs_maxfilesize;
nmp->nm_mountp->mnt_stat.f_iosize = newnfs_iosize(nmp);
+
+ /*
+ * Although ZFS reports a clone_blksize of 16Mbytes,
+ * 128Kbytes usually works, so set it to that.
+ */
+ if (clone_blksize > 128 * 1024)
+ clone_blksize = 128 * 1024;
+ nmp->nm_cloneblksize = clone_blksize;
nmp->nm_state |= NFSSTA_GOTFSINFO;
}
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 920fcf7b8c61..4ec621de2eff 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -225,6 +225,9 @@ static int nfsrpc_layoutgetres(struct nfsmount *, vnode_t, uint8_t *,
static int nfsrpc_copyrpc(vnode_t, off_t, vnode_t, off_t, size_t *,
nfsv4stateid_t *, nfsv4stateid_t *, struct nfsvattr *, int *,
struct nfsvattr *, int *, bool, int *, struct ucred *, NFSPROC_T *);
+static int nfsrpc_clonerpc(vnode_t, off_t, vnode_t, off_t, size_t *, bool,
+ nfsv4stateid_t *, nfsv4stateid_t *, struct nfsvattr *, int *,
+ struct nfsvattr *, int *, struct ucred *, NFSPROC_T *);
static int nfsrpc_seekrpc(vnode_t, off_t *, nfsv4stateid_t *, bool *,
int, struct nfsvattr *, int *, struct ucred *);
static struct mbuf *nfsm_split(struct mbuf *, uint64_t);
@@ -696,7 +699,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
("nfsrpc_openrpc: Getattr repstat"));
error = nfsv4_loadattr(nd, NULL, &nfsva, NULL,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, NULL, NULL, p, cred);
+ NULL, NULL, NULL, NULL, NULL, p, cred);
if (error)
goto nfsmout;
}
@@ -1355,7 +1358,7 @@ nfsrpc_getattrnovp(struct nfsmount *nmp, u_int8_t *fhp, int fhlen, int syscred,
if ((nd->nd_flag & ND_NFSV4) != 0)
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0, NULL, leasep, NULL,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
else
error = nfsm_loadattr(nd, nap);
} else
@@ -3597,7 +3600,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
nfsva.na_mntonfileno = UINT64_MAX;
error = nfsv4_loadattr(nd, NULL, &nfsva, NULL,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, NULL, NULL, p, cred);
+ NULL, NULL, NULL, NULL, NULL, p, cred);
if (error) {
dotdotfileid = dotfileid;
} else if (gotmnton) {
@@ -3847,7 +3850,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
nfsva.na_mntonfileno = UINT64_MAX;
error = nfsv4_loadattr(nd, NULL, &nfsva, NULL,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, &rderr, NULL, p, cred);
+ NULL, NULL, &rderr, NULL, NULL, p, cred);
if (error)
goto nfsmout;
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
@@ -4072,7 +4075,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
nfsva.na_mntonfileno = UINT64_MAX;
error = nfsv4_loadattr(nd, NULL, &nfsva, NULL,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, NULL, NULL, p, cred);
+ NULL, NULL, NULL, NULL, NULL, p, cred);
if (error) {
dotdotfileid = dotfileid;
} else if (gotmnton) {
@@ -4346,7 +4349,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
nfsva.na_mntonfileno = 0xffffffff;
error = nfsv4_loadattr(nd, NULL, &nfsva, &nfhp,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, &rderr, NULL, p, cred);
+ NULL, NULL, &rderr, NULL, NULL, p, cred);
if (error)
goto nfsmout;
}
@@ -4981,8 +4984,8 @@ nfsmout:
*/
int
nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struct nfsfsinfo *fsp,
- uint32_t *leasep, struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap,
- int *attrflagp)
+ uint32_t *leasep, uint32_t *cloneblksizep, struct ucred *cred, NFSPROC_T *p,
+ struct nfsvattr *nap, int *attrflagp)
{
u_int32_t *tl = NULL;
struct nfsrv_descript nfsd, *nd = &nfsd;
@@ -4991,6 +4994,8 @@ nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struct nfsfsinfo *fsp,
int error;
*attrflagp = 0;
+ if (cloneblksizep != NULL)
+ *cloneblksizep = 0;
nmp = VFSTONFS(vp->v_mount);
if (NFSHASNFSV4(nmp)) {
/*
@@ -5009,7 +5014,7 @@ nfsrpc_statfs(vnode_t vp, struct nfsstatfs *sbp, struct nfsfsinfo *fsp,
if (nd->nd_repstat == 0) {
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0,
NULL, NULL, sbp, fsp, NULL, 0, NULL, leasep, NULL,
- NULL, p, cred);
+ NULL, cloneblksizep, p, cred);
if (!error) {
nmp->nm_fsid[0] = nap->na_filesid[0];
nmp->nm_fsid[1] = nap->na_filesid[1];
@@ -5063,7 +5068,8 @@ nfsmout:
*/
int
nfsrpc_pathconf(vnode_t vp, struct nfsv3_pathconf *pc, bool *has_namedattrp,
- struct ucred *cred, NFSPROC_T *p, struct nfsvattr *nap, int *attrflagp)
+ uint32_t *clone_blksizep, struct ucred *cred, NFSPROC_T *p,
+ struct nfsvattr *nap, int *attrflagp)
{
struct nfsrv_descript nfsd, *nd = &nfsd;
struct nfsmount *nmp;
@@ -5074,6 +5080,7 @@ nfsrpc_pathconf(vnode_t vp, struct nfsv3_pathconf *pc, bool *has_namedattrp,
*has_namedattrp = false;
*attrflagp = 0;
+ *clone_blksizep = 0;
nmp = VFSTONFS(vp->v_mount);
if (NFSHASNFSV4(nmp)) {
np = VTONFS(vp);
@@ -5100,7 +5107,7 @@ nfsrpc_pathconf(vnode_t vp, struct nfsv3_pathconf *pc, bool *has_namedattrp,
if (nd->nd_repstat == 0) {
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0,
pc, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL,
- has_namedattrp, p, cred);
+ has_namedattrp, clone_blksizep, p, cred);
if (!error)
*attrflagp = 1;
} else {
@@ -5395,7 +5402,8 @@ nfsrpc_getacl(vnode_t vp, struct ucred *cred, NFSPROC_T *p, struct acl *aclp)
return (error);
if (!nd->nd_repstat)
error = nfsv4_loadattr(nd, vp, NULL, NULL, NULL, 0, NULL,
- NULL, NULL, NULL, aclp, 0, NULL, NULL, NULL, NULL, p, cred);
+ NULL, NULL, NULL, aclp, 0, NULL, NULL, NULL, NULL, NULL, p,
+ cred);
else
error = nd->nd_repstat;
m_freem(nd->nd_mrep);
@@ -5437,7 +5445,7 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, aclp, NULL, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL, false, false,
- false);
+ false, 0);
error = nfscl_request(nd, vp, p, cred);
if (error)
return (error);
@@ -8496,7 +8504,7 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp,
if (*++tl == 0) {
error = nfsv4_loadattr(nd, NULL, &nfsva, NULL,
NULL, 0, NULL, NULL, NULL, NULL, NULL, 0,
- NULL, NULL, NULL, NULL, p, cred);
+ NULL, NULL, NULL, NULL, NULL, p, cred);
if (error != 0)
goto nfsmout;
if (ndp != NULL) {
@@ -9168,6 +9176,199 @@ nfsmout:
}
/*
+ * nfs clone operation.
+ */
+int
+nfsrpc_clone(vnode_t invp, off_t *inoffp, vnode_t outvp,
+ off_t *outoffp, size_t *lenp, bool toeof, int *inattrflagp,
+ struct nfsvattr *innap, int *outattrflagp, struct nfsvattr *outnap,
+ struct ucred *cred)
+{
+ int error, expireret = 0, retrycnt;
+ uint32_t clidrev = 0;
+ struct nfsmount *nmp = VFSTONFS(invp->v_mount);
+ struct nfsfh *innfhp = NULL, *outnfhp = NULL;
+ nfsv4stateid_t instateid, outstateid;
+ void *inlckp, *outlckp;
+
+ if (nmp->nm_clp != NULL)
+ clidrev = nmp->nm_clp->nfsc_clientidrev;
+ innfhp = VTONFS(invp)->n_fhp;
+ outnfhp = VTONFS(outvp)->n_fhp;
+ retrycnt = 0;
+ do {
+ /* Get both stateids. */
+ inlckp = NULL;
+ nfscl_getstateid(invp, innfhp->nfh_fh, innfhp->nfh_len,
+ NFSV4OPEN_ACCESSREAD, 0, NULL, curthread, &instateid,
+ &inlckp);
+ outlckp = NULL;
+ nfscl_getstateid(outvp, outnfhp->nfh_fh, outnfhp->nfh_len,
+ NFSV4OPEN_ACCESSWRITE, 0, NULL, curthread, &outstateid,
+ &outlckp);
+
+ error = nfsrpc_clonerpc(invp, *inoffp, outvp, *outoffp, lenp,
+ toeof, &instateid, &outstateid, innap, inattrflagp, outnap,
+ outattrflagp, cred, curthread);
+ if (error == 0) {
+ *inoffp += *lenp;
+ *outoffp += *lenp;
+ } else if (error == NFSERR_STALESTATEID)
+ nfscl_initiate_recovery(nmp->nm_clp);
+ if (inlckp != NULL)
+ nfscl_lockderef(inlckp);
+ if (outlckp != NULL)
+ nfscl_lockderef(outlckp);
+ if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
+ error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
+ error == NFSERR_OLDSTATEID || error == NFSERR_BADSESSION) {
+ (void) nfs_catnap(PZERO, error, "nfs_cfr");
+ } else if ((error == NFSERR_EXPIRED || (!NFSHASINT(nmp) &&
+ error == NFSERR_BADSTATEID)) && clidrev != 0) {
+ expireret = nfscl_hasexpired(nmp->nm_clp, clidrev,
+ curthread);
+ } else if (error == NFSERR_BADSTATEID && NFSHASINT(nmp)) {
+ error = EIO;
+ }
+ retrycnt++;
+ } while (error == NFSERR_GRACE || error == NFSERR_DELAY ||
+ error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION ||
+ error == NFSERR_STALEDONTRECOVER ||
+ (error == NFSERR_OLDSTATEID && retrycnt < 20) ||
+ ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID) &&
+ expireret == 0 && clidrev != 0 && retrycnt < 4));
+ if (error != 0 && (retrycnt >= 4 ||
+ error == NFSERR_STALESTATEID || error == NFSERR_BADSESSION ||
+ error == NFSERR_STALEDONTRECOVER))
+ error = EIO;
+ return (error);
+}
+
+/*
+ * The clone RPC.
+ */
+static int
+nfsrpc_clonerpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff,
+ size_t *lenp, bool toeof, nfsv4stateid_t *instateidp,
+ nfsv4stateid_t *outstateidp, struct nfsvattr *innap, int *inattrflagp,
+ struct nfsvattr *outnap, int *outattrflagp, struct ucred *cred,
+ NFSPROC_T *p)
+{
+ uint32_t *tl, *opcntp;
+ int error;
+ struct nfsrv_descript nfsd;
+ struct nfsrv_descript *nd = &nfsd;
+ struct nfsmount *nmp;
+ nfsattrbit_t attrbits;
+ struct vattr va;
+ uint64_t len;
+
+ nmp = VFSTONFS(invp->v_mount);
+ *inattrflagp = *outattrflagp = 0;
+ len = *lenp;
+ if (len == 0)
+ return (0);
+ if (toeof)
+ len = 0;
+ nfscl_reqstart(nd, NFSPROC_CLONE, nmp, VTONFS(invp)->n_fhp->nfh_fh,
+ VTONFS(invp)->n_fhp->nfh_len, &opcntp, NULL, 0, 0, cred);
+ /*
+ * First do a Setattr of atime to the server's clock
+ * time. The FreeBSD "collective" was of the opinion
+ * that setting atime was necessary for this syscall.
+ * Do the Setattr before the Clone, so that it can be
+ * handled well if the server replies NFSERR_DELAY to
+ * the Setattr operation.
+ */
+ if ((nmp->nm_mountp->mnt_flag & MNT_NOATIME) == 0) {
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(NFSV4OP_SETATTR);
+ nfsm_stateidtom(nd, instateidp, NFSSTATEID_PUTSTATEID);
+ VATTR_NULL(&va);
+ va.va_atime.tv_sec = va.va_atime.tv_nsec = 0;
+ va.va_vaflags = VA_UTIMES_NULL;
+ nfscl_fillsattr(nd, &va, invp, 0, 0);
+ /* Bump opcnt from 7 to 8. */
+ *opcntp = txdr_unsigned(8);
+ }
+
+ /* Now Getattr the invp attributes. */
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(NFSV4OP_GETATTR);
+ NFSGETATTR_ATTRBIT(&attrbits);
+ nfsrv_putattrbit(nd, &attrbits);
+
+ /* Set outvp. */
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(NFSV4OP_PUTFH);
+ (void)nfsm_fhtom(nmp, nd, VTONFS(outvp)->n_fhp->nfh_fh,
+ VTONFS(outvp)->n_fhp->nfh_len, 0);
+
+ /* Do the Clone. */
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ *tl = txdr_unsigned(NFSV4OP_CLONE);
+ nfsm_stateidtom(nd, instateidp, NFSSTATEID_PUTSTATEID);
+ nfsm_stateidtom(nd, outstateidp, NFSSTATEID_PUTSTATEID);
+ NFSM_BUILD(tl, uint32_t *, 3 * NFSX_HYPER + NFSX_UNSIGNED);
+ txdr_hyper(inoff, tl); tl += 2;
+ txdr_hyper(outoff, tl); tl += 2;
+ txdr_hyper(len, tl); tl += 2;
+
+ /* Get the outvp attributes. */
+ *tl = txdr_unsigned(NFSV4OP_GETATTR);
+ NFSWRITEGETATTR_ATTRBIT(&attrbits);
+ nfsrv_putattrbit(nd, &attrbits);
+
+ error = nfscl_request(nd, invp, p, cred);
+ if (error != 0)
+ return (error);
+ /* Skip over the Setattr reply. */
+ if ((nd->nd_flag & ND_NOMOREDATA) == 0 &&
+ (nmp->nm_mountp->mnt_flag & MNT_NOATIME) == 0) {
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ if (*(tl + 1) == 0) {
+ error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL);
+ if (error != 0)
+ goto nfsmout;
+ } else
+ nd->nd_flag |= ND_NOMOREDATA;
+ }
+ if ((nd->nd_flag & ND_NOMOREDATA) == 0) {
+ /* Get the input file's attributes. */
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ if (*(tl + 1) == 0) {
+ error = nfsm_loadattr(nd, innap);
+ if (error != 0)
+ goto nfsmout;
+ *inattrflagp = 1;
+ } else
+ nd->nd_flag |= ND_NOMOREDATA;
+ }
+ /* Skip over return stat for PutFH. */
+ if ((nd->nd_flag & ND_NOMOREDATA) == 0) {
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ if (*++tl != 0)
+ nd->nd_flag |= ND_NOMOREDATA;
+ }
+ /* Skip over return stat for Clone. */
+ if ((nd->nd_flag & ND_NOMOREDATA) == 0)
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ if (nd->nd_repstat == 0) {
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ error = nfsm_loadattr(nd, outnap);
+ if (error == 0)
+ *outattrflagp = NFS_LATTR_NOSHRINK;
+ } else {
+ *lenp = 0;
+ }
+ if (error == 0)
+ error = nd->nd_repstat;
+nfsmout:
+ m_freem(nd->nd_mrep);
+ return (error);
+}
+
+/*
* Seek operation.
*/
int
@@ -9724,13 +9925,13 @@ nfscl_statfs(struct vnode *vp, struct ucred *cred, NFSPROC_T *td)
struct nfsstatfs sb;
struct mount *mp;
struct nfsmount *nmp;
- uint32_t lease;
+ uint32_t clone_blksize, lease;
int attrflag, error;
mp = vp->v_mount;
nmp = VFSTONFS(mp);
- error = nfsrpc_statfs(vp, &sb, &fs, &lease, cred, td, &nfsva,
- &attrflag);
+ error = nfsrpc_statfs(vp, &sb, &fs, &lease, &clone_blksize, cred, td,
+ &nfsva, &attrflag);
if (attrflag != 0)
(void) nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
if (error == 0) {
@@ -9739,7 +9940,7 @@ nfscl_statfs(struct vnode *vp, struct ucred *cred, NFSPROC_T *td)
nmp->nm_clp->nfsc_renew = NFSCL_RENEW(lease);
NFSUNLOCKCLSTATE();
mtx_lock(&nmp->nm_mtx);
- nfscl_loadfsinfo(nmp, &fs);
+ nfscl_loadfsinfo(nmp, &fs, clone_blksize);
nfscl_loadsbinfo(nmp, &sb, &mp->mnt_stat);
mp->mnt_stat.f_iosize = newnfs_iosize(nmp);
mtx_unlock(&nmp->nm_mtx);
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 99a781640c53..aa9d01fc4632 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3701,7 +3701,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
if (!error)
(void) nfsv4_fillattr(nd, NULL, NULL, NULL, &va,
NULL, 0, &rattrbits, NULL, p, 0, 0, 0, 0,
- (uint64_t)0, NULL, false, false, false);
+ (uint64_t)0, NULL, false, false, false, 0);
break;
case NFSV4OP_CBRECALL:
NFSCL_DEBUG(4, "cbrecall\n");
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 0bd05c03885b..5ea7eab07632 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -292,8 +292,10 @@ nfs_statfs(struct mount *mp, struct statfs *sbp)
int error = 0, attrflag, gotfsinfo = 0, ret;
struct nfsnode *np;
char *fakefh;
+ uint32_t clone_blksize;
td = curthread;
+ clone_blksize = 0;
error = vfs_busy(mp, MBF_NOWAIT);
if (error)
@@ -337,8 +339,8 @@ nfs_statfs(struct mount *mp, struct statfs *sbp)
} else
mtx_unlock(&nmp->nm_mtx);
if (!error)
- error = nfsrpc_statfs(vp, &sb, &fs, NULL, td->td_ucred, td,
- &nfsva, &attrflag);
+ error = nfsrpc_statfs(vp, &sb, &fs, NULL, &clone_blksize,
+ td->td_ucred, td, &nfsva, &attrflag);
if ((nmp->nm_privflag & NFSMNTP_FAKEROOTFH) != 0 &&
error == NFSERR_WRONGSEC) {
/* Cannot get new stats, so return what is in mnt_stat. */
@@ -375,7 +377,7 @@ nfs_statfs(struct mount *mp, struct statfs *sbp)
if (!error) {
mtx_lock(&nmp->nm_mtx);
if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
- nfscl_loadfsinfo(nmp, &fs);
+ nfscl_loadfsinfo(nmp, &fs, clone_blksize);
nfscl_loadsbinfo(nmp, &sb, sbp);
sbp->f_iosize = newnfs_iosize(nmp);
mtx_unlock(&nmp->nm_mtx);
@@ -408,7 +410,7 @@ ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
if (attrflag)
(void) nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
mtx_lock(&nmp->nm_mtx);
- nfscl_loadfsinfo(nmp, &fs);
+ nfscl_loadfsinfo(nmp, &fs, 0);
mtx_unlock(&nmp->nm_mtx);
}
return (error);
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index fa451887e73e..6824ee6ef13d 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -4027,31 +4027,51 @@ nfs_copy_file_range(struct vop_copy_file_range_args *ap)
struct vattr va, *vap;
struct uio io;
struct nfsmount *nmp;
+ struct nfsnode *np;
size_t len, len2;
ssize_t r;
int error, inattrflag, outattrflag, ret, ret2, invp_lock;
off_t inoff, outoff;
- bool consecutive, must_commit, tryoutcred;
+ bool consecutive, must_commit, onevp, toeof, tryclone, tryoutcred;
+ bool mustclone;
/*
* NFSv4.2 Copy is not permitted for infile == outfile.
+ * The NFSv4.2 Clone operation does work on non-overlapping
+ * byte ranges in the same file, but only if offsets
+ * (and len if not to EOF) are aligned properly.
* TODO: copy_file_range() between multiple NFS mountpoints
+ * --> This is not possible now, since each mount appears to
+ * the NFSv4.n server as a separate client.
*/
- if (invp == outvp || invp->v_mount != outvp->v_mount) {
+ if ((invp == outvp && (ap->a_flags & COPY_FILE_RANGE_CLONE) == 0) ||
+ (invp != outvp && invp->v_mount != outvp->v_mount)) {
generic_copy:
return (ENOSYS);
}
-
- invp_lock = LK_SHARED;
+ if (invp == outvp) {
+ onevp = true;
+ invp_lock = LK_EXCLUSIVE;
+ } else {
+ onevp = false;
+ invp_lock = LK_SHARED;
+ }
+ mustclone = false;
+ if (onevp || (ap->a_flags & COPY_FILE_RANGE_CLONE) != 0)
+ mustclone = true;
relock:
+ inoff = *ap->a_inoffp;
+ outoff = *ap->a_outoffp;
- /* Lock both vnodes, avoiding risk of deadlock. */
+ /* Lock vnode(s), avoiding risk of deadlock. */
do {
mp = NULL;
error = vn_start_write(outvp, &mp, V_WAIT);
if (error == 0) {
error = vn_lock(outvp, LK_EXCLUSIVE);
if (error == 0) {
+ if (onevp)
+ break;
error = vn_lock(invp, invp_lock | LK_NOWAIT);
if (error == 0)
break;
@@ -4071,16 +4091,24 @@ relock:
return (error);
/*
- * More reasons to avoid nfs copy: not NFSv4.2, or explicitly
- * disabled.
+ * More reasons to avoid nfs copy/clone: not NFSv4.2, explicitly
+ * disabled or requires cloning and unable to clone.
+ * Only clone if the clone_blksize attribute is supported
+ * and the clone_blksize is greater than 0.
+ * Alignment of offsets and length will be checked later.
*/
nmp = VFSTONFS(invp->v_mount);
+ np = VTONFS(invp);
mtx_lock(&nmp->nm_mtx);
+ if ((nmp->nm_privflag & NFSMNTP_NOCOPY) != 0)
+ mustclone = true;
if (!NFSHASNFSV4(nmp) || nmp->nm_minorvers < NFSV42_MINORVERSION ||
- (nmp->nm_privflag & NFSMNTP_NOCOPY) != 0) {
+ (mustclone && (!NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,
+ NFSATTRBIT_CLONEBLKSIZE) || nmp->nm_cloneblksize == 0))) {
mtx_unlock(&nmp->nm_mtx);
VOP_UNLOCK(invp);
- VOP_UNLOCK(outvp);
+ if (!onevp)
+ VOP_UNLOCK(outvp); /* For onevp, same as invp. */
if (mp != NULL)
vn_finished_write(mp);
goto generic_copy;
@@ -4111,6 +4139,8 @@ relock:
invp_obj = invp->v_object;
if (invp_obj != NULL && vm_object_mightbedirty(invp_obj)) {
if (invp_lock != LK_EXCLUSIVE) {
+ KASSERT(!onevp, ("nfs_copy_file_range: "
+ "invp_lock LK_SHARED for onevp"));
invp_lock = LK_EXCLUSIVE;
VOP_UNLOCK(invp);
VOP_UNLOCK(outvp);
@@ -4134,10 +4164,10 @@ relock:
else
consecutive = false;
mtx_unlock(&nmp->nm_mtx);
- inoff = *ap->a_inoffp;
- outoff = *ap->a_outoffp;
tryoutcred = true;
must_commit = false;
+ toeof = false;
+
if (error == 0) {
vap = &VTONFS(invp)->n_vattr.na_vattr;
error = VOP_GETATTR(invp, vap, ap->a_incred);
@@ -4169,29 +4199,63 @@ relock:
if (error == 0 && ret != 0)
error = ret;
}
- } else if (inoff + len > vap->va_size)
+ } else if (inoff + len >= vap->va_size) {
+ toeof = true;
*ap->a_lenp = len = vap->va_size - inoff;
+ }
} else
error = 0;
}
/*
+ * For cloning, the offsets must be clone blksize aligned and
+ * the len must be blksize aligned unless it goes to EOF on
+ * the input file.
+ */
+ tryclone = false;
+ if (len > 0) {
+ if (error == 0 && NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,
+ NFSATTRBIT_CLONEBLKSIZE) && nmp->nm_cloneblksize != 0 &&
+ (inoff % nmp->nm_cloneblksize) == 0 &&
+ (outoff % nmp->nm_cloneblksize) == 0 &&
+ (toeof || (len % nmp->nm_cloneblksize) == 0))
+ tryclone = true;
+ else if (mustclone)
+ error = ENOSYS;
+ }
+
+ /*
* len will be set to 0 upon a successful Copy RPC.
- * As such, this only loops when the Copy RPC needs to be retried.
+ * As such, this only loops when the Copy/Clone RPC needs to be retried.
*/
while (len > 0 && error == 0) {
inattrflag = outattrflag = 0;
len2 = len;
- if (tryoutcred)
- error = nfsrpc_copy_file_range(invp, ap->a_inoffp,
- outvp, ap->a_outoffp, &len2, ap->a_flags,
- &inattrflag, &innfsva, &outattrflag, &outnfsva,
- ap->a_outcred, consecutive, &must_commit);
- else
- error = nfsrpc_copy_file_range(invp, ap->a_inoffp,
- outvp, ap->a_outoffp, &len2, ap->a_flags,
- &inattrflag, &innfsva, &outattrflag, &outnfsva,
- ap->a_incred, consecutive, &must_commit);
+ if (tryclone) {
+ if (tryoutcred)
+ error = nfsrpc_clone(invp, ap->a_inoffp, outvp,
+ ap->a_outoffp, &len2, toeof, &inattrflag,
+ &innfsva, &outattrflag, &outnfsva,
+ ap->a_outcred);
+ else
+ error = nfsrpc_clone(invp, ap->a_inoffp, outvp,
+ ap->a_outoffp, &len2, toeof, &inattrflag,
+ &innfsva, &outattrflag, &outnfsva,
+ ap->a_incred);
+ } else {
+ if (tryoutcred)
+ error = nfsrpc_copy_file_range(invp,
+ ap->a_inoffp, outvp, ap->a_outoffp, &len2,
+ ap->a_flags, &inattrflag, &innfsva,
+ &outattrflag, &outnfsva,
+ ap->a_outcred, consecutive, &must_commit);
+ else
+ error = nfsrpc_copy_file_range(invp,
+ ap->a_inoffp, outvp, ap->a_outoffp, &len2,
+ ap->a_flags, &inattrflag, &innfsva,
+ &outattrflag, &outnfsva,
+ ap->a_incred, consecutive, &must_commit);
+ }
if (inattrflag != 0)
ret = nfscl_loadattrcache(&invp, &innfsva, NULL, 0, 1);
if (outattrflag != 0)
@@ -4230,6 +4294,13 @@ relock:
/* Try again with incred. */
tryoutcred = false;
error = 0;
+ } else if (tryclone && error != 0) {
+ if (mustclone) {
+ error = ENOSYS;
+ } else {
+ tryclone = false;
+ error = 0;
+ }
}
if (error == NFSERR_STALEWRITEVERF) {
/*
@@ -4243,11 +4314,12 @@ relock:
}
}
VOP_UNLOCK(invp);
- VOP_UNLOCK(outvp);
+ if (!onevp)
+ VOP_UNLOCK(outvp); /* For onevp, same as invp. */
if (mp != NULL)
vn_finished_write(mp);
if (error == NFSERR_NOTSUPP || error == NFSERR_OFFLOADNOREQS ||
- error == NFSERR_ACCES) {
+ error == NFSERR_ACCES || error == ENOSYS) {
/*
* Unlike the NFSv4.2 Copy, vn_generic_copy_file_range() can
* use a_incred for the read and a_outcred for the write, so
@@ -4255,7 +4327,7 @@ relock:
* For NFSERR_NOTSUPP and NFSERR_OFFLOADNOREQS, the Copy can
* never succeed, so disable it.
*/
- if (error != NFSERR_ACCES) {
+ if (error != NFSERR_ACCES && error != ENOSYS) {
/* Can never do Copy on this mount. */
mtx_lock(&nmp->nm_mtx);
nmp->nm_privflag |= NFSMNTP_NOCOPY;
@@ -4596,6 +4668,7 @@ nfs_pathconf(struct vop_pathconf_args *ap)
struct nfsmount *nmp;
struct thread *td = curthread;
off_t off;
+ uint32_t clone_blksize;
bool eof, has_namedattr, named_enabled;
int attrflag, error;
struct nfsnode *np;
@@ -4604,19 +4677,22 @@ nfs_pathconf(struct vop_pathconf_args *ap)
np = VTONFS(vp);
named_enabled = false;
has_namedattr = false;
+ clone_blksize = 0;
if ((NFS_ISV34(vp) && (ap->a_name == _PC_LINK_MAX ||
ap->a_name == _PC_NAME_MAX || ap->a_name == _PC_CHOWN_RESTRICTED ||
ap->a_name == _PC_NO_TRUNC)) ||
(NFS_ISV4(vp) && (ap->a_name == _PC_ACL_NFS4 ||
- ap->a_name == _PC_HAS_NAMEDATTR))) {
+ ap->a_name == _PC_HAS_NAMEDATTR ||
+ ap->a_name == _PC_CLONE_BLKSIZE))) {
/*
* Since only the above 4 a_names are returned by the NFSv3
* Pathconf RPC, there is no point in doing it for others.
* For NFSv4, the Pathconf RPC (actually a Getattr Op.) can
- * be used for _PC_ACL_NFS4 and _PC_HAS_NAMEDATTR as well.
+ * be used for _PC_ACL_NFS4, _PC_HAS_NAMEDATTR and
+ * _PC_CLONE_BLKSIZE as well.
*/
- error = nfsrpc_pathconf(vp, &pc, &has_namedattr, td->td_ucred,
- td, &nfsva, &attrflag);
+ error = nfsrpc_pathconf(vp, &pc, &has_namedattr, &clone_blksize,
+ td->td_ucred, td, &nfsva, &attrflag);
if (attrflag != 0)
(void) nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
if (error != 0)
@@ -4771,6 +4847,9 @@ nfs_pathconf(struct vop_pathconf_args *ap)
else
*ap->a_retval = 0;
break;
+ case _PC_CLONE_BLKSIZE:
+ *ap->a_retval = clone_blksize;
+ break;
default:
error = vop_stdpathconf(ap);
diff --git a/sys/fs/nfsclient/nfsmount.h b/sys/fs/nfsclient/nfsmount.h
index 37b84a015dab..ef876dd30e59 100644
--- a/sys/fs/nfsclient/nfsmount.h
+++ b/sys/fs/nfsclient/nfsmount.h
@@ -87,6 +87,7 @@ struct nfsmount {
/* unclipped, wraps to 0 */
struct __rpc_client *nm_aconn[NFS_MAXNCONN - 1]; /* Additional nconn */
/* Locked via nm_sockreq.nr_mtx */
+ uint32_t nm_cloneblksize; /* Block cloning alignment */
u_int16_t nm_krbnamelen; /* Krb5 host principal, if any */
u_int16_t nm_dirpathlen; /* and mount dirpath, for V4 */
u_int16_t nm_srvkrbnamelen; /* and the server's target name */
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 8c427c66c156..496cac263fa0 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2113,7 +2113,8 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
struct nfsvattr *nvap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp,
struct ucred *cred, struct thread *p, int isdgram, int reterr,
int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
- bool xattrsupp, bool has_hiddensystem, bool has_namedattr)
+ bool xattrsupp, bool has_hiddensystem, bool has_namedattr,
+ uint32_t clone_blksize)
{
struct statfs *sf;
int error;
@@ -2130,9 +2131,11 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
sf = NULL;
}
}
+
error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root,
- mounted_on_fileno, sf, xattrsupp, has_hiddensystem, has_namedattr);
+ mounted_on_fileno, sf, xattrsupp, has_hiddensystem, has_namedattr,
+ clone_blksize);
free(sf, M_TEMP);
NFSEXITCODE2(0, nd);
return (error);
@@ -2441,7 +2444,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
struct vnode *vp, struct nfsexstuff *exp)
{
struct dirent *dp;
- u_int32_t *tl;
+ uint32_t clone_blksize, *tl;
int dirlen;
char *cpos, *cend, *rbuf;
struct vnode *nvp;
@@ -2943,6 +2946,7 @@ again:
xattrsupp = false;
has_hiddensystem = false;
has_namedattr = false;
+ clone_blksize = 0;
if (nvp != NULL) {
supports_nfsv4acls =
nfs_supportsnfsv4acls(nvp);
@@ -2966,6 +2970,11 @@ again:
&pathval) != 0)
pathval = 0;
has_namedattr = pathval > 0;
+ pathval = 0;
+ if (VOP_PATHCONF(nvp, _PC_CLONE_BLKSIZE,
+ &pathval) != 0)
+ pathval = 0;
+ clone_blksize = pathval;
NFSVOPUNLOCK(nvp);
} else
supports_nfsv4acls = 0;
@@ -2986,14 +2995,16 @@ again:
nd->nd_cred, p, isdgram, 0,
supports_nfsv4acls, at_root,
mounted_on_fileno, xattrsupp,
- has_hiddensystem, has_namedattr);
+ has_hiddensystem, has_namedattr,
+ clone_blksize);
} else {
dirlen += nfsvno_fillattr(nd, new_mp,
nvp, nvap, &nfh, r, &attrbits,
nd->nd_cred, p, isdgram, 0,
supports_nfsv4acls, at_root,
mounted_on_fileno, xattrsupp,
- has_hiddensystem, has_namedattr);
+ has_hiddensystem, has_namedattr,
+ clone_blksize);
}
if (nvp != NULL)
vrele(nvp);
@@ -5690,7 +5701,8 @@ nfsrv_writedsdorpc(struct nfsmount *nmp, fhandle_t *fhp, off_t off, int len,
if ((nd->nd_flag & (ND_NOMOREDATA | ND_NFSV4 | ND_V4WCCATTR)) ==
(ND_NFSV4 | ND_V4WCCATTR)) {
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL, NULL,
- NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL);
NFSD_DEBUG(4, "nfsrv_writedsdorpc: wcc attr=%d\n", error);
if (error != 0)
goto nfsmout;
@@ -5721,7 +5733,8 @@ nfsrv_writedsdorpc(struct nfsmount *nmp, fhandle_t *fhp, off_t off, int len,
if (error == 0) {
NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL, NULL,
- NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL);
}
NFSD_DEBUG(4, "nfsrv_writedsdorpc: aft loadattr=%d\n", error);
nfsmout:
@@ -5887,7 +5900,8 @@ nfsrv_allocatedsdorpc(struct nfsmount *nmp, fhandle_t *fhp, off_t off,
if (nd->nd_repstat == 0) {
NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL, NULL,
- NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL);
} else
error = nd->nd_repstat;
NFSD_DEBUG(4, "nfsrv_allocatedsdorpc: aft loadattr=%d\n", error);
@@ -6054,7 +6068,8 @@ nfsrv_deallocatedsdorpc(struct nfsmount *nmp, fhandle_t *fhp, off_t off,
if ((nd->nd_flag & (ND_NOMOREDATA | ND_NFSV4 | ND_V4WCCATTR)) ==
(ND_NFSV4 | ND_V4WCCATTR)) {
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL, NULL,
- NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL);
NFSD_DEBUG(4, "nfsrv_deallocatedsdorpc: wcc attr=%d\n", error);
if (error != 0)
goto nfsmout;
@@ -6068,7 +6083,8 @@ nfsrv_deallocatedsdorpc(struct nfsmount *nmp, fhandle_t *fhp, off_t off,
if (nd->nd_repstat == 0) {
NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, NULL, NULL,
- NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL);
} else
error = nd->nd_repstat;
NFSD_DEBUG(4, "nfsrv_deallocatedsdorpc: aft loadattr=%d\n", error);
@@ -6216,7 +6232,8 @@ nfsrv_setattrdsdorpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p,
if ((nd->nd_flag & (ND_NOMOREDATA | ND_NFSV4 | ND_V4WCCATTR)) ==
(ND_NFSV4 | ND_V4WCCATTR)) {
error = nfsv4_loadattr(nd, NULL, dsnap, NULL, NULL, 0, NULL,
- NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL);
NFSD_DEBUG(4, "nfsrv_setattrdsdorpc: wcc attr=%d\n", error);
if (error != 0)
goto nfsmout;
@@ -6241,7 +6258,7 @@ nfsrv_setattrdsdorpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p,
NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
error = nfsv4_loadattr(nd, NULL, dsnap, NULL, NULL, 0, NULL,
NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
- NULL);
+ NULL, NULL);
}
NFSD_DEBUG(4, "nfsrv_setattrdsdorpc: aft setattr loadattr=%d\n", error);
nfsmout:
@@ -6386,7 +6403,7 @@ nfsrv_setacldsdorpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p,
* the same type (VREG).
*/
nfsv4_fillattr(nd, NULL, vp, aclp, NULL, NULL, 0, &attrbits, NULL,
- NULL, 0, 0, 0, 0, 0, NULL, false, false, false);
+ NULL, 0, 0, 0, 0, 0, NULL, false, false, false, 0);
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
if (error != 0) {
@@ -6530,7 +6547,7 @@ nfsrv_getattrdsrpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p,
if (nd->nd_repstat == 0) {
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
/*
* We can only save the updated values in the extended
* attribute if the vp is exclusively locked.
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index 9eebcda548c6..a881968b03be 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -253,6 +253,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
size_t atsiz;
long pathval;
bool has_hiddensystem, has_namedattr, xattrsupp;
+ uint32_t clone_blksize;
if (nd->nd_repstat)
goto out;
@@ -330,6 +331,11 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
&pathval) != 0)
pathval = 0;
has_namedattr = pathval > 0;
+ pathval = 0;
+ if (VOP_PATHCONF(vp, _PC_CLONE_BLKSIZE,
+ &pathval) != 0)
+ pathval = 0;
+ clone_blksize = pathval;
mp = vp->v_mount;
if (nfsrv_enable_crossmntpt != 0 &&
vp->v_type == VDIR &&
@@ -365,7 +371,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
isdgram, 1, supports_nfsv4acls,
at_root, mounted_on_fileno,
xattrsupp, has_hiddensystem,
- has_namedattr);
+ has_namedattr, clone_blksize);
vfs_unbusy(mp);
}
vrele(vp);
@@ -4347,7 +4353,7 @@ nfsrvd_verify(struct nfsrv_descript *nd, int isdgram,
if (!nd->nd_repstat) {
nfsvno_getfs(&fs, isdgram);
error = nfsv4_loadattr(nd, vp, &nva, NULL, &fh, fhsize, NULL,
- sf, NULL, &fs, NULL, 1, &ret, NULL, NULL, NULL, p,
+ sf, NULL, &fs, NULL, 1, &ret, NULL, NULL, NULL, NULL, p,
nd->nd_cred);
if (!error) {
if (nd->nd_procnum == NFSV4OP_NVERIFY) {
@@ -6011,6 +6017,212 @@ nfsmout:
}
/*
+ * nfs clone service
+ */
+int
+nfsrvd_clone(struct nfsrv_descript *nd, __unused int isdgram,
+ vnode_t vp, vnode_t tovp, struct nfsexstuff *exp, struct nfsexstuff *toexp)
+{
+ uint32_t *tl;
+ struct nfsvattr at;
+ int error = 0, ret;
+ off_t inoff, outoff;
+ uint64_t len;
+ size_t xfer;
+ struct nfsstate inst, outst, *instp = &inst, *outstp = &outst;
+ struct nfslock inlo, outlo, *inlop = &inlo, *outlop = &outlo;
+ nfsquad_t clientid;
+ nfsv4stateid_t stateid;
+ nfsattrbit_t attrbits;
+ void *rl_rcookie, *rl_wcookie;
+ long pathval;
+
+ rl_rcookie = rl_wcookie = NULL;
+ pathval = 0;
+ if (nfsrv_maxcopyrange == 0 || nfsrv_devidcnt > 0 ||
+ VOP_PATHCONF(vp, _PC_CLONE_BLKSIZE, &pathval) != 0 ||
+ pathval == 0) {
+ /*
+ * For a pNFS server, reply NFSERR_NOTSUPP so that the client
+ * will not do the clone and will do I/O on the DS(s).
+ * If vfs.nfsd.maxcopyrange set to 0, disable Clone.
+ */
+ nd->nd_repstat = NFSERR_NOTSUPP;
+ goto nfsmout;
+ }
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_STATEID + 3 * NFSX_HYPER);
+ instp->ls_flags = (NFSLCK_CHECK | NFSLCK_READACCESS);
+ inlop->lo_flags = NFSLCK_READ;
+ instp->ls_ownerlen = 0;
+ instp->ls_op = NULL;
+ instp->ls_uid = nd->nd_cred->cr_uid;
+ instp->ls_stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
+ clientid.lval[0] = instp->ls_stateid.other[0] = *tl++;
+ clientid.lval[1] = instp->ls_stateid.other[1] = *tl++;
+ if ((nd->nd_flag & ND_IMPLIEDCLID) != 0)
+ clientid.qval = nd->nd_clientid.qval;
+ instp->ls_stateid.other[2] = *tl++;
+ outstp->ls_flags = (NFSLCK_CHECK | NFSLCK_WRITEACCESS);
+ outlop->lo_flags = NFSLCK_WRITE;
+ outstp->ls_ownerlen = 0;
+ outstp->ls_op = NULL;
+ outstp->ls_uid = nd->nd_cred->cr_uid;
+ outstp->ls_stateid.seqid = fxdr_unsigned(uint32_t, *tl++);
+ outstp->ls_stateid.other[0] = *tl++;
+ outstp->ls_stateid.other[1] = *tl++;
+ outstp->ls_stateid.other[2] = *tl++;
+ inoff = fxdr_hyper(tl); tl += 2;
+ inlop->lo_first = inoff;
+ outoff = fxdr_hyper(tl); tl += 2;
+ outlop->lo_first = outoff;
+ len = fxdr_hyper(tl);
+ if (len == 0) {
+ /* len == 0 means to EOF. */
+ inlop->lo_end = OFF_MAX;
+ outlop->lo_end = OFF_MAX;
+ } else {
+ inlop->lo_end = inlop->lo_first + len;
+ outlop->lo_end = outlop->lo_first + len;
+ }
+
+ if ((inoff > OFF_MAX || outoff > OFF_MAX ||
+ inlop->lo_end > OFF_MAX || outlop->lo_end > OFF_MAX ||
+ inlop->lo_end < inlop->lo_first || outlop->lo_end <
+ outlop->lo_first))
+ nd->nd_repstat = NFSERR_INVAL;
+
+ if (nd->nd_repstat == 0 && vp->v_type != VREG)
+ nd->nd_repstat = NFSERR_WRONGTYPE;
+
+ /* Check permissions for the input file. */
+ NFSZERO_ATTRBIT(&attrbits);
+ NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_OWNER);
+ ret = nfsvno_getattr(vp, &at, nd, curthread, 1, &attrbits);
+ if (nd->nd_repstat == 0)
+ nd->nd_repstat = ret;
+ if (nd->nd_repstat == 0 && (at.na_uid != nd->nd_cred->cr_uid ||
+ NFSVNO_EXSTRICTACCESS(exp)))
+ nd->nd_repstat = nfsvno_accchk(vp, VREAD, nd->nd_cred, exp,
+ curthread, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED,
+ NULL);
+ if (nd->nd_repstat == 0)
+ nd->nd_repstat = nfsrv_lockctrl(vp, &instp, &inlop, NULL,
+ clientid, &stateid, exp, nd, curthread);
+ if (vp != tovp) {
+ NFSVOPUNLOCK(vp);
+ if (nd->nd_repstat != 0)
+ goto out;
+
+ error = NFSVOPLOCK(tovp, LK_SHARED);
+ if (error != 0)
+ goto out;
+ pathval = 0;
+ if (VOP_PATHCONF(tovp, _PC_CLONE_BLKSIZE, &pathval) != 0 ||
+ pathval == 0)
+ nd->nd_repstat = NFSERR_NOTSUPP;
+ else if (tovp->v_type != VREG)
+ nd->nd_repstat = NFSERR_WRONGTYPE;
+ }
+
+ /* For the output file, we only need the Owner attribute. */
+ ret = nfsvno_getattr(tovp, &at, nd, curthread, 1, &attrbits);
+ if (nd->nd_repstat == 0)
+ nd->nd_repstat = ret;
+ if (nd->nd_repstat == 0 && (at.na_uid != nd->nd_cred->cr_uid ||
+ NFSVNO_EXSTRICTACCESS(exp)))
+ nd->nd_repstat = nfsvno_accchk(tovp, VWRITE, nd->nd_cred, toexp,
+ curthread, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED,
+ NULL);
+ if (nd->nd_repstat == 0)
+ nd->nd_repstat = nfsrv_lockctrl(tovp, &outstp, &outlop, NULL,
+ clientid, &stateid, toexp, nd, curthread);
+ NFSVOPUNLOCK(tovp);
+
+ /* Range lock the byte ranges for both invp and outvp. */
+ if (nd->nd_repstat == 0) {
+ for (;;) {
+ if (len == 0)
+ rl_wcookie = vn_rangelock_wlock(tovp, outoff,
+ OFF_MAX);
+ else
+ rl_wcookie = vn_rangelock_wlock(tovp, outoff,
+ outoff + len);
+ if (vp != tovp) {
+ if (len == 0)
+ rl_rcookie = vn_rangelock_tryrlock(vp,
+ inoff, OFF_MAX);
+ else
+ rl_rcookie = vn_rangelock_tryrlock(vp,
+ inoff, inoff + len);
+ if (rl_rcookie != NULL)
+ break;
+ } else {
+ rl_rcookie = NULL;
+ break;
+ }
+ vn_rangelock_unlock(tovp, rl_wcookie);
+ if (len == 0)
+ rl_rcookie = vn_rangelock_rlock(vp, inoff,
+ OFF_MAX);
+ else
+ rl_rcookie = vn_rangelock_rlock(vp, inoff,
+ inoff + len);
+ vn_rangelock_unlock(vp, rl_rcookie);
+ }
+
+ error = NFSVOPLOCK(vp, LK_SHARED);
+ if (error == 0) {
+ ret = nfsvno_getattr(vp, &at, nd, curthread, 1, NULL);
+ if (ret == 0) {
+ /*
+ * Since invp is range locked, na_size should
+ * not change.
+ */
+ if (len == 0 && at.na_size > inoff)
+ len = SSIZE_MAX; /* To EOF. */
+ else if (inoff + len > at.na_size)
+ nd->nd_repstat = NFSERR_INVAL;
+ }
+ NFSVOPUNLOCK(vp);
+ if (ret != 0 && nd->nd_repstat == 0)
+ nd->nd_repstat = ret;
+ } else if (nd->nd_repstat == 0)
+ nd->nd_repstat = error;
+ }
+
+ /*
+ * Do the actual copy to an upper limit of vfs.nfsd.maxcopyrange.
+ * This size limit can be set to limit the time a copy RPC will
+ * take.
+ */
+ xfer = len;
+ if (nd->nd_repstat == 0) {
+ nd->nd_repstat = vn_copy_file_range(vp, &inoff, tovp, &outoff,
+ &xfer, COPY_FILE_RANGE_CLONE, nd->nd_cred, nd->nd_cred,
+ NULL);
+ if (nd->nd_repstat == ENOSYS)
+ nd->nd_repstat = NFSERR_INVAL;
+ }
+
+ /* Unlock the ranges. */
+ if (rl_rcookie != NULL)
+ vn_rangelock_unlock(vp, rl_rcookie);
+ if (rl_wcookie != NULL)
+ vn_rangelock_unlock(tovp, rl_wcookie);
+
+out:
+ vrele(vp);
+ vrele(tovp);
+ NFSEXITCODE2(error, nd);
+ return (error);
+nfsmout:
+ vput(vp);
+ vrele(tovp);
+ NFSEXITCODE2(error, nd);
+ return (error);
+}
+
+/*
* nfs seek service
*/
int
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index d6832b4f74be..636c4735a131 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -371,7 +371,7 @@ int (*nfsrv4_ops2[NFSV42_NOPS])(struct nfsrv_descript *,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
- (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
+ nfsrvd_clone,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0,
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 2e27817389dd..36e3ce7b7142 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -4675,7 +4675,7 @@ errout:
} else if (error == 0 && procnum == NFSV4OP_CBGETATTR)
error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL,
- NULL, p, NULL);
+ NULL, NULL, p, NULL);
m_freem(nd->nd_mrep);
}
NFSLOCKSTATE();
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 85fe48ddd466..eb1327f7f2de 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -1160,7 +1160,8 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR)
return (EINVAL);
- if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0)
+ if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC |
+ O_CLOFORK)) != 0)
return (EINVAL);
largepage = (shmflags & SHM_LARGEPAGE) != 0;
diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h
index 6561d62b5e26..c79c9eaa1a5f 100644
--- a/sys/modules/zfs/zfs_config.h
+++ b/sys/modules/zfs/zfs_config.h
@@ -830,7 +830,7 @@
/* #undef ZFS_DEVICE_MINOR */
/* Define the project alias string. */
-#define ZFS_META_ALIAS "zfs-2.3.99-515-FreeBSD_g8302b6e32"
+#define ZFS_META_ALIAS "zfs-2.3.99-539-FreeBSD_g1d0b94c4e"
/* Define the project author. */
#define ZFS_META_AUTHOR "OpenZFS"
@@ -860,7 +860,7 @@
#define ZFS_META_NAME "zfs"
/* Define the project release. */
-#define ZFS_META_RELEASE "515-FreeBSD_g8302b6e32"
+#define ZFS_META_RELEASE "539-FreeBSD_g1d0b94c4e"
/* Define the project version. */
#define ZFS_META_VERSION "2.3.99"
diff --git a/sys/modules/zfs/zfs_gitrev.h b/sys/modules/zfs/zfs_gitrev.h
index 2f1ffe504350..20fd58c620b5 100644
--- a/sys/modules/zfs/zfs_gitrev.h
+++ b/sys/modules/zfs/zfs_gitrev.h
@@ -1 +1 @@
-#define ZFS_META_GITREV "zfs-2.3.99-515-g8302b6e32"
+#define ZFS_META_GITREV "zfs-2.3.99-539-g1d0b94c4e"
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 2eca81d54f99..6638c90882aa 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -2890,51 +2890,6 @@ iflib_rxd_pkt_get(iflib_rxq_t rxq, if_rxd_info_t ri)
return (m);
}
-#if defined(INET6) || defined(INET)
-static void
-iflib_get_ip_forwarding(struct lro_ctrl *lc, bool *v4, bool *v6)
-{
- CURVNET_SET(if_getvnet(lc->ifp));
-#if defined(INET6)
- *v6 = V_ip6_forwarding;
-#endif
-#if defined(INET)
- *v4 = V_ipforwarding;
-#endif
- CURVNET_RESTORE();
-}
-
-/*
- * Returns true if it's possible this packet could be LROed.
- * if it returns false, it is guaranteed that tcp_lro_rx()
- * would not return zero.
- */
-static bool
-iflib_check_lro_possible(struct mbuf *m, bool v4_forwarding, bool v6_forwarding)
-{
- struct ether_header *eh;
-
- eh = mtod(m, struct ether_header *);
- switch (eh->ether_type) {
-#if defined(INET6)
- case htons(ETHERTYPE_IPV6):
- return (!v6_forwarding);
-#endif
-#if defined(INET)
- case htons(ETHERTYPE_IP):
- return (!v4_forwarding);
-#endif
- }
-
- return (false);
-}
-#else
-static void
-iflib_get_ip_forwarding(struct lro_ctrl *lc __unused, bool *v4 __unused, bool *v6 __unused)
-{
-}
-#endif
-
static void
_task_fn_rx_watchdog(void *context)
{
@@ -2956,18 +2911,16 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
int err, budget_left, rx_bytes, rx_pkts;
iflib_fl_t fl;
int lro_enabled;
- bool v4_forwarding, v6_forwarding, lro_possible;
uint8_t retval = 0;
/*
* XXX early demux data packets so that if_input processing only handles
* acks in interrupt context
*/
- struct mbuf *m, *mh, *mt, *mf;
+ struct mbuf *m, *mh, *mt;
NET_EPOCH_ASSERT();
- lro_possible = v4_forwarding = v6_forwarding = false;
ifp = ctx->ifc_ifp;
mh = mt = NULL;
MPASS(budget > 0);
@@ -2983,6 +2936,8 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
return (retval);
}
+ lro_enabled = (if_getcapenable(ifp) & IFCAP_LRO);
+
/* pfil needs the vnet to be set */
CURVNET_SET_QUIET(if_getvnet(ifp));
for (budget_left = budget; budget_left > 0 && avail > 0;) {
@@ -3027,7 +2982,17 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
if (__predict_false(m == NULL))
continue;
- /* imm_pkt: -- cxgb */
+#ifndef __NO_STRICT_ALIGNMENT
+ if (!IP_ALIGNED(m) && (m = iflib_fixup_rx(m)) == NULL)
+ continue;
+#endif
+#if defined(INET6) || defined(INET)
+ if (lro_enabled) {
+ tcp_lro_queue_mbuf(&rxq->ifr_lc, m);
+ continue;
+ }
+#endif
+
if (mh == NULL)
mh = mt = m;
else {
@@ -3040,49 +3005,8 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
for (i = 0, fl = &rxq->ifr_fl[0]; i < sctx->isc_nfl; i++, fl++)
retval |= iflib_fl_refill_all(ctx, fl);
- lro_enabled = (if_getcapenable(ifp) & IFCAP_LRO);
- if (lro_enabled)
- iflib_get_ip_forwarding(&rxq->ifr_lc, &v4_forwarding, &v6_forwarding);
- mt = mf = NULL;
- while (mh != NULL) {
- m = mh;
- mh = mh->m_nextpkt;
- m->m_nextpkt = NULL;
-#ifndef __NO_STRICT_ALIGNMENT
- if (!IP_ALIGNED(m) && (m = iflib_fixup_rx(m)) == NULL)
- continue;
-#endif
-#if defined(INET6) || defined(INET)
- if (lro_enabled) {
- if (!lro_possible) {
- lro_possible = iflib_check_lro_possible(m, v4_forwarding, v6_forwarding);
- if (lro_possible && mf != NULL) {
- if_input(ifp, mf);
- DBG_COUNTER_INC(rx_if_input);
- mt = mf = NULL;
- }
- }
- if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC | CSUM_L4_VALID)) ==
- (CSUM_L4_CALC | CSUM_L4_VALID)) {
- if (lro_possible && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0)
- continue;
- }
- }
-#endif
- if (lro_possible) {
- if_input(ifp, m);
- DBG_COUNTER_INC(rx_if_input);
- continue;
- }
-
- if (mf == NULL)
- mf = m;
- if (mt != NULL)
- mt->m_nextpkt = m;
- mt = m;
- }
- if (mf != NULL) {
- if_input(ifp, mf);
+ if (mh != NULL) {
+ if_input(ifp, mh);
DBG_COUNTER_INC(rx_if_input);
}
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
index 7845b682f3e4..2ca5b3433e47 100644
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -713,9 +713,6 @@ void icmp6_redirect_input(struct mbuf *, int);
void icmp6_redirect_output(struct mbuf *, struct nhop_object *);
int icmp6_ratelimit(const struct in6_addr *, const int, const int);
-struct ip6ctlparam;
-void icmp6_mtudisc_update(struct ip6ctlparam *, int);
-
/* XXX: is this the right place for these macros? */
#define icmp6_ifstat_inc(ifp, tag) \
do { \
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index d392cbe09950..6492495dc583 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -609,7 +609,6 @@ tcp_input_with_port(struct mbuf **mp, int *offp, int proto, uint16_t port)
int tlen = 0, off;
int drop_hdrlen;
int thflags;
- int rstreason = 0; /* For badport_bandlim accounting purposes */
int lookupflag;
uint8_t iptos;
struct m_tag *fwd_tag = NULL;
@@ -905,23 +904,22 @@ findpcb:
* XXX MRT Send RST using which routing table?
*/
if (inp == NULL) {
- if (rstreason != 0) {
+ if ((lookupflag & INPLOOKUP_WILDCARD) == 0) {
/* We came here after second (safety) lookup. */
- MPASS((lookupflag & INPLOOKUP_WILDCARD) == 0);
- goto dropwithreset;
- }
- /*
- * Log communication attempts to ports that are not
- * in use.
- */
- if ((V_tcp_log_in_vain == 1 && (thflags & TH_SYN)) ||
- V_tcp_log_in_vain == 2) {
- if ((s = tcp_log_vain(NULL, th, (void *)ip, ip6)))
+ MPASS(!closed_port);
+ } else {
+ /*
+ * Log communication attempts to ports that are not
+ * in use.
+ */
+ if (((V_tcp_log_in_vain == 1 && (thflags & TH_SYN)) ||
+ V_tcp_log_in_vain == 2) &&
+ (s = tcp_log_vain(NULL, th, (void *)ip, ip6))) {
log(LOG_INFO, "%s; %s: Connection attempt "
"to closed port\n", s, __func__);
+ }
+ closed_port = true;
}
- rstreason = BANDLIM_TCP_RST;
- closed_port = true;
goto dropwithreset;
}
INP_LOCK_ASSERT(inp);
@@ -1012,13 +1010,11 @@ findpcb:
* down or it is in the CLOSED state. Either way we drop the
* segment and send an appropriate response.
*/
- rstreason = BANDLIM_TCP_RST;
closed_port = true;
goto dropwithreset;
}
if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) {
- rstreason = BANDLIM_TCP_RST;
closed_port = true;
goto dropwithreset;
}
@@ -1102,7 +1098,8 @@ findpcb:
* don't want to sent RST for the second ACK,
* so we perform second lookup without wildcard
* match, hoping to find the new socket. If
- * the ACK is stray indeed, rstreason would
+ * the ACK is stray indeed, the missing
+ * INPLOOKUP_WILDCARD flag in lookupflag would
* hint the above code that the lookup was a
* second attempt.
*
@@ -1110,7 +1107,6 @@ findpcb:
* of the failure cause.
*/
INP_WUNLOCK(inp);
- rstreason = BANDLIM_TCP_RST;
lookupflag &= ~INPLOOKUP_WILDCARD;
goto findpcb;
}
@@ -1134,7 +1130,6 @@ tfo_socket_result:
V_tcp_sc_rst_sock_fail ?
"sending RST" : "try again");
if (V_tcp_sc_rst_sock_fail) {
- rstreason = BANDLIM_TCP_RST;
goto dropwithreset;
} else
goto dropunlock;
@@ -1201,7 +1196,6 @@ tfo_socket_result:
s, __func__);
syncache_badack(&inc, port); /* XXX: Not needed! */
TCPSTAT_INC(tcps_badsyn);
- rstreason = BANDLIM_TCP_RST;
goto dropwithreset;
}
/*
@@ -1277,7 +1271,6 @@ tfo_socket_result:
"Connection attempt to deprecated "
"IPv6 address rejected\n",
s, __func__);
- rstreason = BANDLIM_TCP_RST;
goto dropwithreset;
}
}
@@ -1398,8 +1391,7 @@ dropwithreset:
* When blackholing do not respond with a RST but
* completely ignore the segment and drop it.
*/
- if (rstreason == BANDLIM_TCP_RST &&
- ((!closed_port && V_blackhole == 3) ||
+ if (((!closed_port && V_blackhole == 3) ||
(closed_port &&
((V_blackhole == 1 && (thflags & TH_SYN)) || V_blackhole > 1))) &&
(V_blackhole_local || (
@@ -1414,7 +1406,7 @@ dropwithreset:
)))
goto dropunlock;
TCP_PROBE5(receive, NULL, tp, m, tp, th);
- tcp_dropwithreset(m, th, tp, tlen, rstreason);
+ tcp_dropwithreset(m, th, tp, tlen);
m = NULL; /* mbuf chain got consumed. */
dropunlock:
@@ -1523,7 +1515,7 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
uint16_t thflags;
int acked, ourfinisacked, needoutput = 0;
sackstatus_t sack_changed;
- int rstreason, todrop, win, incforsyn = 0;
+ int todrop, win, incforsyn = 0;
uint32_t tiwin;
uint16_t nsegs;
char *s;
@@ -1568,7 +1560,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
*/
if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) {
- rstreason = BANDLIM_TCP_RST;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
@@ -1984,7 +1975,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
if ((thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->snd_una) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
- rstreason = BANDLIM_TCP_RST;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
@@ -1997,7 +1987,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
* FIN, or a RST.
*/
if ((thflags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) {
- rstreason = BANDLIM_TCP_RST;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
} else if (thflags & TH_SYN) {
@@ -2264,7 +2253,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
* for the "LAND" DoS attack.
*/
if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) {
- rstreason = BANDLIM_TCP_RST;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
@@ -2346,7 +2334,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST);
tp = tcp_close(tp);
TCPSTAT_INC(tcps_rcvafterclose);
- rstreason = BANDLIM_TCP_RST;
goto dropwithreset;
}
@@ -3443,7 +3430,6 @@ dropafterack:
if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) &&
(SEQ_GT(tp->snd_una, th->th_ack) ||
SEQ_GT(th->th_ack, tp->snd_max)) ) {
- rstreason = BANDLIM_TCP_RST;
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
goto dropwithreset;
}
@@ -3455,11 +3441,10 @@ dropafterack:
return;
dropwithreset:
+ tcp_dropwithreset(m, th, NULL, tlen);
if (tp != NULL) {
- tcp_dropwithreset(m, th, tp, tlen, rstreason);
INP_WUNLOCK(inp);
- } else
- tcp_dropwithreset(m, th, NULL, tlen, rstreason);
+ }
return;
drop:
@@ -3479,8 +3464,7 @@ drop:
* tp may be NULL.
*/
void
-tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
- int tlen, int rstreason)
+tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int tlen)
{
#ifdef INET
struct ip *ip;
@@ -3520,7 +3504,7 @@ tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp,
#endif
/* Perform bandwidth limiting. */
- if (badport_bandlim(rstreason) < 0)
+ if (badport_bandlim(BANDLIM_TCP_RST) < 0)
goto drop;
/* tcp_respond consumes the mbuf chain. */
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index f2960ab9c636..fed259f4d8e1 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -7863,7 +7863,7 @@ nothing_left:
/* tcp_close will kill the inp pre-log the Reset */
tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST);
tp = tcp_close(tp);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
BBR_STAT_INC(bbr_dropped_af_data);
return (1);
}
@@ -8763,7 +8763,7 @@ bbr_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so,
(SEQ_LEQ(th->th_ack, tp->iss) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
if ((thflags & (TH_ACK | TH_RST)) == (TH_ACK | TH_RST)) {
@@ -8965,7 +8965,7 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
(SEQ_LEQ(th->th_ack, tp->snd_una) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
if (tp->t_flags & TF_FASTOPEN) {
@@ -8977,7 +8977,7 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if ((thflags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
} else if (thflags & TH_SYN) {
/* non-initial SYN is ignored */
@@ -9010,7 +9010,7 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if (SEQ_LT(th->th_seq, tp->irs)) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
@@ -9288,7 +9288,7 @@ bbr_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -9385,7 +9385,7 @@ bbr_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -9405,7 +9405,7 @@ close_now:
tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST);
tp = tcp_close(tp);
KMOD_TCPSTAT_INC(tcps_rcvafterclose);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, (*tlen));
+ ctf_do_dropwithreset(m, tp, th, *tlen);
return (1);
}
if (sbavail(&so->so_snd) == 0)
@@ -9535,7 +9535,7 @@ bbr_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -9637,7 +9637,7 @@ bbr_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -9739,7 +9739,7 @@ bbr_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -9848,7 +9848,7 @@ bbr_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -11510,7 +11510,7 @@ bbr_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
if (tiwin > bbr->r_ctl.rc_high_rwnd)
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 2dfcad84ad99..71dd4de6baf9 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -12038,7 +12038,7 @@ rack_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so,
/* tcp_close will kill the inp pre-log the Reset */
tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST);
tp = tcp_close(tp);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
}
@@ -12876,7 +12876,7 @@ rack_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so,
(SEQ_LEQ(th->th_ack, tp->iss) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
if ((thflags & (TH_ACK | TH_RST)) == (TH_ACK | TH_RST)) {
@@ -13090,7 +13090,7 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
(SEQ_LEQ(th->th_ack, tp->snd_una) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
if (tp->t_flags & TF_FASTOPEN) {
@@ -13103,7 +13103,7 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if ((thflags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
} else if (thflags & TH_SYN) {
/* non-initial SYN is ignored */
@@ -13137,7 +13137,7 @@ rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if (SEQ_LT(th->th_seq, tp->irs)) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return (1);
}
if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
@@ -13400,7 +13400,7 @@ rack_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (sbavail(&so->so_snd)) {
if (ctf_progress_timeout_check(tp, true)) {
rack_log_progress_event(rack, tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -13496,7 +13496,7 @@ rack_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (ctf_progress_timeout_check(tp, true)) {
rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr,
tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -13518,7 +13518,7 @@ rack_check_data_after_close(struct mbuf *m,
tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST);
tp = tcp_close(tp);
KMOD_TCPSTAT_INC(tcps_rcvafterclose);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, (*tlen));
+ ctf_do_dropwithreset(m, tp, th, *tlen);
return (1);
}
if (sbavail(&so->so_snd) == 0)
@@ -13646,7 +13646,7 @@ rack_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (ctf_progress_timeout_check(tp, true)) {
rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr,
tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -13747,7 +13747,7 @@ rack_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (ctf_progress_timeout_check(tp, true)) {
rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr,
tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -13849,7 +13849,7 @@ rack_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (ctf_progress_timeout_check(tp, true)) {
rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr,
tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -13953,7 +13953,7 @@ rack_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (ctf_progress_timeout_check(tp, true)) {
rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr,
tp, tick, PROGRESS_DROP, __LINE__);
- ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset_conn(m, tp, th, tlen);
return (1);
}
}
@@ -16653,7 +16653,7 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) {
tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT);
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
#ifdef TCP_ACCOUNTING
sched_unpin();
#endif
diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.c b/sys/netinet/tcp_stacks/rack_bbr_common.c
index fb013d3d17f0..fc12672a45f7 100644
--- a/sys/netinet/tcp_stacks/rack_bbr_common.c
+++ b/sys/netinet/tcp_stacks/rack_bbr_common.c
@@ -507,9 +507,9 @@ ctf_flight_size(struct tcpcb *tp, uint32_t rc_sacked)
void
ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th,
- int32_t rstreason, int32_t tlen)
+ int32_t tlen)
{
- tcp_dropwithreset(m, th, tp, tlen, rstreason);
+ tcp_dropwithreset(m, th, tp, tlen);
if (tp != NULL)
INP_WUNLOCK(tptoinpcb(tp));
}
@@ -670,7 +670,7 @@ ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t
(SEQ_GT(tp->snd_una, th->th_ack) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
*ret_val = 1;
- ctf_do_dropwithreset(m, tp, th, BANDLIM_TCP_RST, tlen);
+ ctf_do_dropwithreset(m, tp, th, tlen);
return;
} else
*ret_val = 0;
@@ -864,10 +864,10 @@ ctf_calc_rwin(struct socket *so, struct tcpcb *tp)
void
ctf_do_dropwithreset_conn(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th,
- int32_t rstreason, int32_t tlen)
+ int32_t tlen)
{
- tcp_dropwithreset(m, th, tp, tlen, rstreason);
+ tcp_dropwithreset(m, th, tp, tlen);
tp = tcp_drop(tp, ETIMEDOUT);
if (tp)
INP_WUNLOCK(tptoinpcb(tp));
diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.h b/sys/netinet/tcp_stacks/rack_bbr_common.h
index 6a8a056d89b0..cd33cb8ce50b 100644
--- a/sys/netinet/tcp_stacks/rack_bbr_common.h
+++ b/sys/netinet/tcp_stacks/rack_bbr_common.h
@@ -101,7 +101,7 @@ ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp,
void
ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp,
- struct tcphdr *th, int32_t rstreason, int32_t tlen);
+ struct tcphdr *th, int32_t tlen);
void
ctf_do_drop(struct mbuf *m, struct tcpcb *tp);
@@ -125,7 +125,7 @@ ctf_calc_rwin(struct socket *so, struct tcpcb *tp);
void
ctf_do_dropwithreset_conn(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th,
- int32_t rstreason, int32_t tlen);
+ int32_t tlen);
uint32_t
ctf_fixed_maxseg(struct tcpcb *tp);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 1fce7c591639..2e039ebbfdd2 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -3205,7 +3205,7 @@ tcp6_next_pmtu(const struct icmp6_hdr *icmp6)
* small, set to the min.
*/
if (mtu < IPV6_MMTU)
- mtu = IPV6_MMTU - 8; /* XXXNP: what is the adjustment for? */
+ mtu = IPV6_MMTU;
return (mtu);
}
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index c095fc8f7765..ce63fcf9ffc0 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -101,7 +101,7 @@ sysctl_net_inet_tcp_nolocaltimewait(SYSCTL_HANDLER_ARGS)
if (error == 0 && req->newptr) {
V_nolocaltimewait = new;
gone_in(16, "net.inet.tcp.nolocaltimewait is obsolete."
- " Use net.inet.tcp.local_msl instead.\n");
+ " Use net.inet.tcp.msl_local instead.\n");
}
return (error);
}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index b90f65e83cb1..53856bae9a66 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1379,8 +1379,7 @@ int tcp_reass(struct tcpcb *, struct tcphdr *, tcp_seq *, int *,
void tcp_reass_global_init(void);
void tcp_reass_flush(struct tcpcb *);
void tcp_dooptions(struct tcpopt *, u_char *, int, int);
-void tcp_dropwithreset(struct mbuf *, struct tcphdr *,
- struct tcpcb *, int, int);
+void tcp_dropwithreset(struct mbuf *, struct tcphdr *, struct tcpcb *, int);
void tcp_pulloutofband(struct socket *,
struct tcphdr *, struct mbuf *, int);
void tcp_xmit_timer(struct tcpcb *, int);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index df8f293f9426..2f2f9abf1c83 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -654,7 +654,11 @@ udp_input(struct mbuf **mp, int *offp, int proto)
else
UDP_PROBE(receive, NULL, NULL, ip, NULL, uh);
UDPSTAT_INC(udps_noport);
- if (m->m_flags & (M_BCAST | M_MCAST)) {
+ if (m->m_flags & M_MCAST) {
+ UDPSTAT_INC(udps_noportmcast);
+ goto badunlocked;
+ }
+ if (m->m_flags & M_BCAST) {
UDPSTAT_INC(udps_noportbcast);
goto badunlocked;
}
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index d89515d7eda5..f98381499b2d 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -159,6 +159,7 @@ static int ni6_addrs(struct icmp6_nodeinfo *, struct mbuf *,
static int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
struct ifnet *, int);
static int icmp6_notify_error(struct mbuf **, int, int);
+static void icmp6_mtudisc_update(struct ip6ctlparam *ip6cp);
/*
* Kernel module interface for updating icmp6stat. The argument is an index
@@ -1115,7 +1116,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len)
if (icmp6type == ICMP6_PACKET_TOO_BIG) {
notifymtu = ntohl(icmp6->icmp6_mtu);
ip6cp.ip6c_cmdarg = (void *)&notifymtu;
- icmp6_mtudisc_update(&ip6cp, 1); /*XXX*/
+ icmp6_mtudisc_update(&ip6cp);
}
if (ip6_ctlprotox[nxt] != NULL)
@@ -1130,47 +1131,18 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len)
return (-1);
}
-void
-icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated)
+static void
+icmp6_mtudisc_update(struct ip6ctlparam *ip6cp)
{
struct in6_addr *dst = &ip6cp->ip6c_finaldst->sin6_addr;
struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6;
- struct mbuf *m = ip6cp->ip6c_m; /* will be necessary for scope issue */
+ struct mbuf *m = ip6cp->ip6c_m;
u_int mtu = ntohl(icmp6->icmp6_mtu);
struct in_conninfo inc;
uint32_t max_mtu;
-#if 0
- /*
- * RFC2460 section 5, last paragraph.
- * even though minimum link MTU for IPv6 is IPV6_MMTU,
- * we may see ICMPv6 too big with mtu < IPV6_MMTU
- * due to packet translator in the middle.
- * see ip6_output() and ip6_getpmtu() "alwaysfrag" case for
- * special handling.
- */
if (mtu < IPV6_MMTU)
return;
-#endif
-
- /*
- * we reject ICMPv6 too big with abnormally small value.
- * XXX what is the good definition of "abnormally small"?
- */
- if (mtu < sizeof(struct ip6_hdr) + sizeof(struct ip6_frag) + 8)
- return;
-
- if (!validated)
- return;
-
- /*
- * In case the suggested mtu is less than IPV6_MMTU, we
- * only need to remember that it was for above mentioned
- * "alwaysfrag" case.
- * Try to be as close to the spec as possible.
- */
- if (mtu < IPV6_MMTU)
- mtu = IPV6_MMTU - 8;
bzero(&inc, sizeof(inc));
inc.inc_fibnum = M_GETFIB(m);
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index ed71c58fffbe..6299ce6e146b 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -145,11 +145,10 @@ static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
struct ip6_frag **);
static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
-static int ip6_getpmtu(struct route_in6 *, int,
- struct ifnet *, const struct in6_addr *, u_long *, int *, u_int,
- u_int);
-static int ip6_calcmtu(struct ifnet *, const struct in6_addr *, u_long,
- u_long *, int *, u_int);
+static void ip6_getpmtu(struct route_in6 *, int,
+ struct ifnet *, const struct in6_addr *, u_long *, u_int, u_int);
+static void ip6_calcmtu(struct ifnet *, const struct in6_addr *, u_long,
+ u_long *, u_int);
static int ip6_getpmtu_ctl(u_int, const struct in6_addr *, u_long *);
static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
@@ -418,7 +417,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
int vlan_pcp = -1;
struct in6_ifaddr *ia = NULL;
u_long mtu;
- int alwaysfrag, dontfrag;
+ int dontfrag;
u_int32_t optlen, plen = 0, unfragpartlen;
struct ip6_exthdrs exthdrs;
struct in6_addr src0, dst0;
@@ -939,12 +938,10 @@ nonh6lookup:
*ifpp = ifp;
/* Determine path MTU. */
- if ((error = ip6_getpmtu(ro_pmtu, ro != ro_pmtu, ifp, &ip6->ip6_dst,
- &mtu, &alwaysfrag, fibnum, *nexthdrp)) != 0)
- goto bad;
- KASSERT(mtu > 0, ("%s:%d: mtu %ld, ro_pmtu %p ro %p ifp %p "
- "alwaysfrag %d fibnum %u\n", __func__, __LINE__, mtu, ro_pmtu, ro,
- ifp, alwaysfrag, fibnum));
+ ip6_getpmtu(ro_pmtu, ro != ro_pmtu, ifp, &ip6->ip6_dst, &mtu, fibnum,
+ *nexthdrp);
+ KASSERT(mtu > 0, ("%s:%d: mtu %ld, ro_pmtu %p ro %p ifp %p fibnum %u",
+ __func__, __LINE__, mtu, ro_pmtu, ro, ifp, fibnum));
/*
* The caller of this function may specify to use the minimum MTU
@@ -1121,20 +1118,13 @@ passout:
* Send the packet to the outgoing interface.
* If necessary, do IPv6 fragmentation before sending.
*
- * The logic here is rather complex:
- * 1: normal case (dontfrag == 0, alwaysfrag == 0)
+ * 1: normal case (dontfrag == 0)
* 1-a: send as is if tlen <= path mtu
* 1-b: fragment if tlen > path mtu
*
* 2: if user asks us not to fragment (dontfrag == 1)
* 2-a: send as is if tlen <= interface mtu
* 2-b: error if tlen > interface mtu
- *
- * 3: if we always need to attach fragment header (alwaysfrag == 1)
- * always fragment
- *
- * 4: if dontfrag == 1 && alwaysfrag == 1
- * error, as we cannot handle this conflicting request.
*/
sw_csum = m->m_pkthdr.csum_flags;
if (!hdrsplit) {
@@ -1157,14 +1147,9 @@ passout:
dontfrag = 1;
else
dontfrag = 0;
- if (dontfrag && alwaysfrag) { /* Case 4. */
- /* Conflicting request - can't transmit. */
- error = EMSGSIZE;
- goto bad;
- }
if (dontfrag && tlen > IN6_LINKMTU(ifp) && !tso) { /* Case 2-b. */
/*
- * Even if the DONTFRAG option is specified, we cannot send the
+ * If the DONTFRAG option is specified, we cannot send the
* packet when the data length is larger than the MTU of the
* outgoing interface.
* Notify the error by sending IPV6_PATHMTU ancillary data if
@@ -1178,7 +1163,7 @@ passout:
}
/* Transmit packet without fragmentation. */
- if (dontfrag || (!alwaysfrag && tlen <= mtu)) { /* Cases 1-a and 2-a. */
+ if (dontfrag || tlen <= mtu) { /* Cases 1-a and 2-a. */
struct in6_ifaddr *ia6;
ip6 = mtod(m, struct ip6_hdr *);
@@ -1194,7 +1179,7 @@ passout:
goto done;
}
- /* Try to fragment the packet. Cases 1-b and 3. */
+ /* Try to fragment the packet. Case 1-b. */
if (mtu < IPV6_MMTU) {
/* Path MTU cannot be less than IPV6_MMTU. */
error = EMSGSIZE;
@@ -1478,9 +1463,10 @@ ip6_getpmtu_ctl(u_int fibnum, const struct in6_addr *dst, u_long *mtup)
NET_EPOCH_ENTER(et);
nh = fib6_lookup(fibnum, &kdst, scopeid, NHR_NONE, 0);
- if (nh != NULL)
- error = ip6_calcmtu(nh->nh_ifp, dst, nh->nh_mtu, mtup, NULL, 0);
- else
+ if (nh != NULL) {
+ ip6_calcmtu(nh->nh_ifp, dst, nh->nh_mtu, mtup, 0);
+ error = 0;
+ } else
error = EHOSTUNREACH;
NET_EPOCH_EXIT(et);
@@ -1494,13 +1480,12 @@ ip6_getpmtu_ctl(u_int fibnum, const struct in6_addr *dst, u_long *mtup)
* inside @ro_pmtu to avoid subsequent route lookups after packet
* filter processing.
*
- * Stores mtu and always-frag value into @mtup and @alwaysfragp.
- * Returns 0 on success.
+ * Stores mtu into @mtup.
*/
-static int
+static void
ip6_getpmtu(struct route_in6 *ro_pmtu, int do_lookup,
struct ifnet *ifp, const struct in6_addr *dst, u_long *mtup,
- int *alwaysfragp, u_int fibnum, u_int proto)
+ u_int fibnum, u_int proto)
{
struct nhop_object *nh;
struct in6_addr kdst;
@@ -1544,65 +1529,41 @@ ip6_getpmtu(struct route_in6 *ro_pmtu, int do_lookup,
if (ro_pmtu != NULL && ro_pmtu->ro_nh != NULL)
mtu = ro_pmtu->ro_nh->nh_mtu;
- return (ip6_calcmtu(ifp, dst, mtu, mtup, alwaysfragp, proto));
+ ip6_calcmtu(ifp, dst, mtu, mtup, proto);
}
/*
* Calculate MTU based on transmit @ifp, route mtu @rt_mtu and
* hostcache data for @dst.
- * Stores mtu and always-frag value into @mtup and @alwaysfragp.
- *
- * Returns 0 on success.
+ * Stores mtu into @mtup.
*/
-static int
+static void
ip6_calcmtu(struct ifnet *ifp, const struct in6_addr *dst, u_long rt_mtu,
- u_long *mtup, int *alwaysfragp, u_int proto)
+ u_long *mtup, u_int proto)
{
u_long mtu = 0;
- int alwaysfrag = 0;
- int error = 0;
if (rt_mtu > 0) {
- u_int32_t ifmtu;
- struct in_conninfo inc;
-
- bzero(&inc, sizeof(inc));
- inc.inc_flags |= INC_ISIPV6;
- inc.inc6_faddr = *dst;
-
- ifmtu = IN6_LINKMTU(ifp);
+ /* Skip the hostcache if the protocol handles PMTU changes. */
+ if (proto != IPPROTO_TCP && proto != IPPROTO_SCTP) {
+ struct in_conninfo inc = {
+ .inc_flags = INC_ISIPV6,
+ .inc6_faddr = *dst,
+ };
- /* TCP is known to react to pmtu changes so skip hc */
- if (proto != IPPROTO_TCP)
mtu = tcp_hc_getmtu(&inc);
+ }
if (mtu)
mtu = min(mtu, rt_mtu);
else
mtu = rt_mtu;
- if (mtu == 0)
- mtu = ifmtu;
- else if (mtu < IPV6_MMTU) {
- /*
- * RFC2460 section 5, last paragraph:
- * if we record ICMPv6 too big message with
- * mtu < IPV6_MMTU, transmit packets sized IPV6_MMTU
- * or smaller, with framgent header attached.
- * (fragment header is needed regardless from the
- * packet size, for translators to identify packets)
- */
- alwaysfrag = 1;
- mtu = IPV6_MMTU;
- }
- } else if (ifp) {
+ }
+
+ if (mtu == 0)
mtu = IN6_LINKMTU(ifp);
- } else
- error = EHOSTUNREACH; /* XXX */
*mtup = mtu;
- if (alwaysfragp)
- *alwaysfragp = alwaysfrag;
- return (error);
}
/*
diff --git a/sys/powerpc/mpc85xx/mpc85xx_gpio.c b/sys/powerpc/mpc85xx/mpc85xx_gpio.c
index cb96d768adef..7353ed7bac7b 100644
--- a/sys/powerpc/mpc85xx/mpc85xx_gpio.c
+++ b/sys/powerpc/mpc85xx/mpc85xx_gpio.c
@@ -228,12 +228,13 @@ mpc85xx_gpio_attach(device_t dev)
OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
mpc85xx_gpio_detach(dev);
return (ENOMEM);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/riscv/sifive/sifive_gpio.c b/sys/riscv/sifive/sifive_gpio.c
index ef68d2b39da3..98bff2f72082 100644
--- a/sys/riscv/sifive/sifive_gpio.c
+++ b/sys/riscv/sifive/sifive_gpio.c
@@ -157,13 +157,14 @@ sfgpio_attach(device_t dev)
sc->gpio_pins[i].gp_name[GPIOMAXNAME - 1] = '\0';
}
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "Cannot attach gpiobus\n");
error = ENXIO;
goto fail;
}
+ bus_attach_children(dev);
return (0);
fail:
diff --git a/sys/riscv/starfive/jh7110_gpio.c b/sys/riscv/starfive/jh7110_gpio.c
index 452a3306b4a1..1ed7d9f42259 100644
--- a/sys/riscv/starfive/jh7110_gpio.c
+++ b/sys/riscv/starfive/jh7110_gpio.c
@@ -321,13 +321,14 @@ jh7110_gpio_attach(device_t dev)
JH7110_GPIO_WRITE(sc, GPIOE_1, 0);
JH7110_GPIO_WRITE(sc, GPIOEN, 1);
- sc->busdev = gpiobus_attach_bus(dev);
+ sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "Cannot attach gpiobus\n");
jh7110_gpio_detach(dev);
return (ENXIO);
}
+ bus_attach_children(dev);
return (0);
}
diff --git a/sys/sys/param.h b/sys/sys/param.h
index b9942c7bc2fd..c410a6ee666f 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -74,7 +74,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1500059
+#define __FreeBSD_version 1500060
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index 336e73f29835..9044b1e7e4f2 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -8,6 +8,7 @@ TESTSRC= ${SRCTOP}/contrib/netbsd-tests/kernel
TESTSDIR= ${TESTSBASE}/sys/kern
ATF_TESTS_C+= basic_signal
+ATF_TESTS_C+= copy_file_range
.if ${MACHINE_ARCH} != "i386" && ${MACHINE_ARCH} != "powerpc" && \
${MACHINE_ARCH} != "powerpcspe"
# No support for atomic_load_64 on i386 or (32-bit) powerpc
@@ -81,6 +82,7 @@ PROGS+= coredump_phnum_helper
PROGS+= pdeathsig_helper
PROGS+= sendfile_helper
+LIBADD.copy_file_range+= md
LIBADD.jail_lookup_root+= jail util
CFLAGS.sys_getrandom+= -I${SRCTOP}/sys/contrib/zstd/lib
LIBADD.sys_getrandom+= zstd
diff --git a/tests/sys/kern/copy_file_range.c b/tests/sys/kern/copy_file_range.c
new file mode 100644
index 000000000000..ca52eaf668e3
--- /dev/null
+++ b/tests/sys/kern/copy_file_range.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2025 Mark Johnston <markj@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+#include <sha256.h>
+
+/*
+ * Create a file with random data and size between 1B and 32MB. Return a file
+ * descriptor for the file.
+ */
+static int
+genfile(void)
+{
+ char buf[256], file[NAME_MAX];
+ size_t sz;
+ int fd;
+
+ sz = (random() % (32 * 1024 * 1024ul)) + 1;
+
+ snprintf(file, sizeof(file), "testfile.XXXXXX");
+ fd = mkstemp(file);
+ ATF_REQUIRE(fd != -1);
+
+ while (sz > 0) {
+ ssize_t n;
+ int error;
+
+ error = getentropy(buf, sizeof(buf));
+ ATF_REQUIRE(error == 0);
+ n = write(fd, buf, sizeof(buf) < sz ? sizeof(buf) : sz);
+ ATF_REQUIRE(n > 0);
+
+ sz -= n;
+ }
+
+ ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0);
+ return (fd);
+}
+
+/*
+ * Return true if the file data in the two file descriptors is the same,
+ * false otherwise.
+ */
+static bool
+cmpfile(int fd1, int fd2)
+{
+ struct stat st1, st2;
+ void *addr1, *addr2;
+ size_t sz;
+ int res;
+
+ ATF_REQUIRE(fstat(fd1, &st1) == 0);
+ ATF_REQUIRE(fstat(fd2, &st2) == 0);
+ if (st1.st_size != st2.st_size)
+ return (false);
+
+ sz = st1.st_size;
+ addr1 = mmap(NULL, sz, PROT_READ, MAP_PRIVATE, fd1, 0);
+ ATF_REQUIRE(addr1 != MAP_FAILED);
+ addr2 = mmap(NULL, sz, PROT_READ, MAP_PRIVATE, fd2, 0);
+ ATF_REQUIRE(addr2 != MAP_FAILED);
+
+ res = memcmp(addr1, addr2, sz);
+
+ ATF_REQUIRE(munmap(addr1, sz) == 0);
+ ATF_REQUIRE(munmap(addr2, sz) == 0);
+
+ return (res == 0);
+}
+
+/*
+ * Exercise a few error paths in the copy_file_range() syscall.
+ */
+ATF_TC_WITHOUT_HEAD(copy_file_range_invalid);
+ATF_TC_BODY(copy_file_range_invalid, tc)
+{
+ off_t off1, off2;
+ int fd1, fd2;
+
+ fd1 = genfile();
+ fd2 = genfile();
+
+ /* Can't copy a file to itself without explicit offsets. */
+ ATF_REQUIRE_ERRNO(EINVAL,
+ copy_file_range(fd1, NULL, fd1, NULL, SSIZE_MAX, 0) == -1);
+
+ /* When copying a file to itself, ranges cannot overlap. */
+ off1 = off2 = 0;
+ ATF_REQUIRE_ERRNO(EINVAL,
+ copy_file_range(fd1, &off1, fd1, &off2, 1, 0) == -1);
+
+ /* Negative offsets are not allowed. */
+ off1 = -1;
+ off2 = 0;
+ ATF_REQUIRE_ERRNO(EINVAL,
+ copy_file_range(fd1, &off1, fd2, &off2, 42, 0) == -1);
+ ATF_REQUIRE_ERRNO(EINVAL,
+ copy_file_range(fd2, &off2, fd1, &off1, 42, 0) == -1);
+}
+
+/*
+ * Make sure that copy_file_range() updates the file offsets passed to it.
+ */
+ATF_TC_WITHOUT_HEAD(copy_file_range_offset);
+ATF_TC_BODY(copy_file_range_offset, tc)
+{
+ struct stat sb;
+ off_t off1, off2;
+ ssize_t n;
+ int fd1, fd2;
+
+ off1 = off2 = 0;
+
+ fd1 = genfile();
+ fd2 = open("copy", O_RDWR | O_CREAT, 0644);
+ ATF_REQUIRE(fd2 != -1);
+
+ ATF_REQUIRE(fstat(fd1, &sb) == 0);
+
+ ATF_REQUIRE(lseek(fd1, 0, SEEK_CUR) == 0);
+ ATF_REQUIRE(lseek(fd2, 0, SEEK_CUR) == 0);
+
+ do {
+ off_t ooff1, ooff2;
+
+ ooff1 = off1;
+ ooff2 = off2;
+ n = copy_file_range(fd1, &off1, fd2, &off2, sb.st_size, 0);
+ ATF_REQUIRE(n >= 0);
+ ATF_REQUIRE_EQ(off1, ooff1 + n);
+ ATF_REQUIRE_EQ(off2, ooff2 + n);
+ } while (n != 0);
+
+ /* Offsets should have been adjusted by copy_file_range(). */
+ ATF_REQUIRE_EQ(off1, sb.st_size);
+ ATF_REQUIRE_EQ(off2, sb.st_size);
+ /* Seek offsets should have been left alone. */
+ ATF_REQUIRE(lseek(fd1, 0, SEEK_CUR) == 0);
+ ATF_REQUIRE(lseek(fd2, 0, SEEK_CUR) == 0);
+ /* Make sure the file contents are the same. */
+ ATF_REQUIRE_MSG(cmpfile(fd1, fd2), "file contents differ");
+
+ ATF_REQUIRE(close(fd1) == 0);
+ ATF_REQUIRE(close(fd2) == 0);
+}
+
+/*
+ * Make sure that copying to a larger file doesn't cause it to be truncated.
+ */
+ATF_TC_WITHOUT_HEAD(copy_file_range_truncate);
+ATF_TC_BODY(copy_file_range_truncate, tc)
+{
+ struct stat sb, sb1, sb2;
+ char digest1[65], digest2[65];
+ off_t off;
+ ssize_t n;
+ int fd1, fd2;
+
+ fd1 = genfile();
+ fd2 = genfile();
+
+ ATF_REQUIRE(fstat(fd1, &sb1) == 0);
+ ATF_REQUIRE(fstat(fd2, &sb2) == 0);
+
+ /* fd1 refers to the smaller file. */
+ if (sb1.st_size > sb2.st_size) {
+ int tmp;
+
+ tmp = fd1;
+ fd1 = fd2;
+ fd2 = tmp;
+ ATF_REQUIRE(fstat(fd1, &sb1) == 0);
+ ATF_REQUIRE(fstat(fd2, &sb2) == 0);
+ }
+
+ /*
+ * Compute a hash of the bytes in the larger file which lie beyond the
+ * length of the smaller file.
+ */
+ SHA256_FdChunk(fd2, digest1, sb1.st_size, sb2.st_size - sb1.st_size);
+ ATF_REQUIRE(lseek(fd2, 0, SEEK_SET) == 0);
+
+ do {
+ n = copy_file_range(fd1, NULL, fd2, NULL, SSIZE_MAX, 0);
+ ATF_REQUIRE(n >= 0);
+ } while (n != 0);
+
+ /* Validate file offsets after the copy. */
+ off = lseek(fd1, 0, SEEK_CUR);
+ ATF_REQUIRE(off == sb1.st_size);
+ off = lseek(fd2, 0, SEEK_CUR);
+ ATF_REQUIRE(off == sb1.st_size);
+
+ /* The larger file's size should remain the same. */
+ ATF_REQUIRE(fstat(fd2, &sb) == 0);
+ ATF_REQUIRE(sb.st_size == sb2.st_size);
+
+ /* The bytes beyond the end of the copy should be unchanged. */
+ SHA256_FdChunk(fd2, digest2, sb1.st_size, sb2.st_size - sb1.st_size);
+ ATF_REQUIRE_MSG(strcmp(digest1, digest2) == 0,
+ "trailing file contents differ after copy_file_range()");
+
+ /*
+ * Verify that the copy actually replicated bytes from the smaller file.
+ */
+ ATF_REQUIRE(ftruncate(fd2, sb1.st_size) == 0);
+ ATF_REQUIRE(cmpfile(fd1, fd2));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, copy_file_range_invalid);
+ ATF_TP_ADD_TC(tp, copy_file_range_offset);
+ ATF_TP_ADD_TC(tp, copy_file_range_truncate);
+
+ return (atf_no_error());
+}
diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh
index 65bace957f71..59ae8d92f4af 100755
--- a/tools/tools/nanobsd/defaults.sh
+++ b/tools/tools/nanobsd/defaults.sh
@@ -79,7 +79,12 @@ CONF_BUILD=' '
CONF_INSTALL=' '
# Options to put in make.conf during both build- & installworld.
-CONF_WORLD=' '
+CONF_WORLD='
+WITHOUT_DEBUG_FILES=true
+WITHOUT_LIB32=true
+WITHOUT_KERNEL_SYMBOLS=true
+WITHOUT_TESTS=true
+'
# Kernel config file to use
NANO_KERNEL=GENERIC
@@ -104,7 +109,7 @@ NANO_NEWFS="-b 4096 -f 512 -i 8192 -U"
NANO_DRIVE=ada0
# Target media size in 512 bytes sectors
-NANO_MEDIASIZE=2000000
+NANO_MEDIASIZE=4000000
# Number of code images on media (1 or 2)
NANO_IMAGES=2
diff --git a/usr.bin/last/last.c b/usr.bin/last/last.c
index 69848f359d79..2e6754abab8e 100644
--- a/usr.bin/last/last.c
+++ b/usr.bin/last/last.c
@@ -433,15 +433,15 @@ want(struct utmpx *bp)
return (YES);
break;
case HOST_TYPE:
- if (!strcasecmp(step->name, bp->ut_host))
+ if (strcasecmp(step->name, bp->ut_host) == 0)
return (YES);
break;
case TTY_TYPE:
- if (!strcmp(step->name, bp->ut_line))
+ if (strcmp(step->name, bp->ut_line) == 0)
return (YES);
break;
case USER_TYPE:
- if (!strcmp(step->name, bp->ut_user))
+ if (strcmp(step->name, bp->ut_user) == 0)
return (YES);
break;
}
@@ -478,7 +478,7 @@ hostconv(char *arg)
static char *hostdot, name[MAXHOSTNAMELEN];
char *argdot;
- if (!(argdot = strchr(arg, '.')))
+ if ((argdot = strchr(arg, '.')) == NULL)
return;
if (first) {
first = 0;
@@ -486,7 +486,7 @@ hostconv(char *arg)
xo_err(1, "gethostname");
hostdot = strchr(name, '.');
}
- if (hostdot && !strcasecmp(hostdot, argdot))
+ if (hostdot != NULL && strcasecmp(hostdot, argdot) == 0)
*argdot = '\0';
}
@@ -504,19 +504,16 @@ ttyconv(char *arg)
* a two character suffix.
*/
if (strlen(arg) == 2) {
- /* either 6 for "ttyxx" or 8 for "console" */
- if ((mval = malloc(8)) == NULL)
+ if (strcmp(arg, "co") == 0)
+ mval = strdup("console");
+ else
+ asprintf(&mval, "tty%s", arg);
+ if (mval == NULL)
xo_errx(1, "malloc failure");
- if (!strcmp(arg, "co"))
- (void)strcpy(mval, "console");
- else {
- (void)strcpy(mval, "tty");
- (void)strcpy(mval + 3, arg);
- }
return (mval);
}
- if (!strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1))
- return (arg + 5);
+ if (strncmp(arg, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+ return (arg + strlen(_PATH_DEV));
return (arg);
}
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 139ff9294fde..7014f02032c2 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -904,7 +904,7 @@ void
udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
{
struct udpstat udpstat;
- uint64_t delivered;
+ uint64_t delivered, noportbmcast;
#ifdef INET6
if (udp_done != 0)
@@ -937,8 +937,11 @@ udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
"{N:/with no checksum}\n");
p1a(udps_noport, "{:dropped-no-socket/%ju} "
"{N:/dropped due to no socket}\n");
- p(udps_noportbcast, "{:dropped-broadcast-multicast/%ju} "
- "{N:/broadcast\\/multicast datagram%s undelivered}\n");
+ noportbmcast = udpstat.udps_noportmcast + udpstat.udps_noportbcast;
+ if (noportbmcast || sflag <= 1)
+ xo_emit("\t{:dropped-broadcast-multicast/%ju} "
+ "{N:/broadcast\\/multicast datagram%s undelivered}\n",
+ (uintmax_t)noportbmcast, plural(noportbmcast));
p1a(udps_fullsock, "{:dropped-full-socket-buffer/%ju} "
"{N:/dropped due to full socket buffers}\n");
p1a(udpps_pcbhashmiss, "{:not-for-hashed-pcb/%ju} "
@@ -948,11 +951,10 @@ udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
udpstat.udps_badlen -
udpstat.udps_badsum -
udpstat.udps_noport -
- udpstat.udps_noportbcast -
udpstat.udps_fullsock;
if (delivered || sflag <= 1)
xo_emit("\t{:delivered-packets/%ju} {N:/delivered}\n",
- (uint64_t)delivered);
+ (uintmax_t)delivered);
p(udps_opackets, "{:output-packets/%ju} {N:/datagram%s output}\n");
/* the next statistic is cumulative in udps_noportbcast */
p(udps_filtermcast, "{:multicast-source-filter-matches/%ju} "
diff --git a/usr.bin/sockstat/Makefile b/usr.bin/sockstat/Makefile
index 7254511f21c6..c6e7a078162b 100644
--- a/usr.bin/sockstat/Makefile
+++ b/usr.bin/sockstat/Makefile
@@ -1,6 +1,7 @@
.include <src.opts.mk>
PROG= sockstat
+SRCS= main.c sockstat.c
LIBADD= jail xo
@@ -13,4 +14,7 @@ LIBADD+= cap_sysctl
CFLAGS+= -DWITH_CASPER
.endif
+HAS_TESTS=
+SUBDIR.${MK_TESTS}+= tests
+
.include <bsd.prog.mk>
diff --git a/usr.bin/sockstat/main.c b/usr.bin/sockstat/main.c
new file mode 100644
index 000000000000..b5e0248b743a
--- /dev/null
+++ b/usr.bin/sockstat/main.c
@@ -0,0 +1,1883 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2002 Dag-Erling Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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.
+ */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/sysctl.h>
+#include <sys/jail.h>
+#include <sys/user.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+
+#include <sys/un.h>
+#include <sys/unpcb.h>
+
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/sctp.h>
+#include <netinet/tcp.h>
+#define TCPSTATES /* load state names */
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_var.h>
+#include <arpa/inet.h>
+
+#include <capsicum_helpers.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <jail.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libxo/xo.h>
+
+#include <libcasper.h>
+#include <casper/cap_net.h>
+#include <casper/cap_netdb.h>
+#include <casper/cap_pwd.h>
+#include <casper/cap_sysctl.h>
+
+#include "sockstat.h"
+
+#define SOCKSTAT_XO_VERSION "1"
+#define sstosin(ss) ((struct sockaddr_in *)(ss))
+#define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
+#define sstosun(ss) ((struct sockaddr_un *)(ss))
+#define sstosa(ss) ((struct sockaddr *)(ss))
+
+static bool opt_4; /* Show IPv4 sockets */
+static bool opt_6; /* Show IPv6 sockets */
+static bool opt_A; /* Show kernel address of pcb */
+static bool opt_C; /* Show congestion control */
+static bool opt_c; /* Show connected sockets */
+static bool opt_f; /* Show FIB numbers */
+static bool opt_I; /* Show spliced socket addresses */
+static bool opt_i; /* Show inp_gencnt */
+static int opt_j; /* Show specified jail */
+static bool opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
+static bool opt_l; /* Show listening sockets */
+static bool opt_n; /* Don't resolve UIDs to user names */
+static bool opt_q; /* Don't show header */
+static bool opt_S; /* Show protocol stack if applicable */
+static bool opt_s; /* Show protocol state if applicable */
+static bool opt_U; /* Show remote UDP encapsulation port number */
+static bool opt_u; /* Show Unix domain sockets */
+static u_int opt_v; /* Verbose mode */
+static bool opt_w; /* Automatically size the columns */
+static bool is_xo_style_encoding;
+
+/*
+ * Default protocols to use if no -P was defined.
+ */
+static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
+static size_t default_numprotos = nitems(default_protos);
+
+static int *protos; /* protocols to use */
+static size_t numprotos; /* allocated size of protos[] */
+
+struct addr {
+ union {
+ struct sockaddr_storage address;
+ struct { /* unix(4) faddr */
+ kvaddr_t conn;
+ kvaddr_t firstref;
+ kvaddr_t nextref;
+ };
+ };
+ unsigned int encaps_port;
+ int state;
+ struct addr *next;
+};
+
+struct sock {
+ union {
+ RB_ENTRY(sock) socket_tree; /* tree of pcbs with socket */
+ SLIST_ENTRY(sock) socket_list; /* list of pcbs w/o socket */
+ };
+ RB_ENTRY(sock) pcb_tree;
+ kvaddr_t socket;
+ kvaddr_t pcb;
+ kvaddr_t splice_socket;
+ uint64_t inp_gencnt;
+ int shown;
+ int vflag;
+ int family;
+ int proto;
+ int state;
+ int fibnum;
+ const char *protoname;
+ char stack[TCP_FUNCTION_NAME_LEN_MAX];
+ char cc[TCP_CA_NAME_MAX];
+ struct addr *laddr;
+ struct addr *faddr;
+};
+
+static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
+static int64_t
+socket_compare(const struct sock *a, const struct sock *b)
+{
+ return ((int64_t)(a->socket/2 - b->socket/2));
+}
+RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
+
+static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
+static int64_t
+pcb_compare(const struct sock *a, const struct sock *b)
+{
+ return ((int64_t)(a->pcb/2 - b->pcb/2));
+}
+RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
+
+static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
+
+struct file {
+ RB_ENTRY(file) file_tree;
+ kvaddr_t xf_data;
+ pid_t xf_pid;
+ uid_t xf_uid;
+ int xf_fd;
+};
+
+static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
+static int64_t
+file_compare(const struct file *a, const struct file *b)
+{
+ return ((int64_t)(a->xf_data/2 - b->xf_data/2));
+}
+RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
+
+static struct file *files;
+static int nfiles;
+
+static cap_channel_t *capnet;
+static cap_channel_t *capnetdb;
+static cap_channel_t *capsysctl;
+static cap_channel_t *cappwd;
+
+static bool
+_check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
+{
+ if (received_size != expected_size) {
+ xo_warnx("%s size mismatch: expected %zd, received %zd",
+ struct_name, expected_size, received_size);
+ return false;
+ }
+ return true;
+}
+#define check_ksize(_sz, _struct) (_check_ksize(_sz, sizeof(_struct), #_struct))
+
+static void
+_enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
+{
+ if (received_size != expected_size) {
+ xo_errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
+ struct_name, expected_size, received_size);
+ }
+}
+#define enforce_ksize(_sz, _struct) (_enforce_ksize(_sz, sizeof(_struct), #_struct))
+
+static int
+get_proto_type(const char *proto)
+{
+ struct protoent *pent;
+
+ if (strlen(proto) == 0)
+ return (0);
+ if (capnetdb != NULL)
+ pent = cap_getprotobyname(capnetdb, proto);
+ else
+ pent = getprotobyname(proto);
+ if (pent == NULL) {
+ xo_warn("cap_getprotobyname");
+ return (-1);
+ }
+ return (pent->p_proto);
+}
+
+static void
+init_protos(int num)
+{
+ int proto_count = 0;
+
+ if (num > 0) {
+ proto_count = num;
+ } else {
+ /* Find the maximum number of possible protocols. */
+ while (getprotoent() != NULL)
+ proto_count++;
+ endprotoent();
+ }
+
+ if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
+ xo_err(1, "malloc");
+ numprotos = proto_count;
+}
+
+static int
+parse_protos(char *protospec)
+{
+ char *prot;
+ int proto_type, proto_index;
+
+ if (protospec == NULL)
+ return (-1);
+
+ init_protos(0);
+ proto_index = 0;
+ while ((prot = strsep(&protospec, ",")) != NULL) {
+ if (strlen(prot) == 0)
+ continue;
+ proto_type = get_proto_type(prot);
+ if (proto_type != -1)
+ protos[proto_index++] = proto_type;
+ }
+ numprotos = proto_index;
+ return (proto_index);
+}
+
+static void
+sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
+{
+ struct sockaddr_in *sin4;
+ struct sockaddr_in6 *sin6;
+
+ bzero(ss, sizeof(*ss));
+ switch (af) {
+ case AF_INET:
+ sin4 = sstosin(ss);
+ sin4->sin_len = sizeof(*sin4);
+ sin4->sin_family = af;
+ sin4->sin_port = port;
+ sin4->sin_addr = *(struct in_addr *)addr;
+ break;
+ case AF_INET6:
+ sin6 = sstosin6(ss);
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_family = af;
+ sin6->sin6_port = port;
+ sin6->sin6_addr = *(struct in6_addr *)addr;
+#define s6_addr16 __u6_addr.__u6_addr16
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ sin6->sin6_scope_id =
+ ntohs(sin6->sin6_addr.s6_addr16[1]);
+ sin6->sin6_addr.s6_addr16[1] = 0;
+ }
+ break;
+ default:
+ abort();
+ }
+}
+
+static void
+free_socket(struct sock *sock)
+{
+ struct addr *cur, *next;
+
+ cur = sock->laddr;
+ while (cur != NULL) {
+ next = cur->next;
+ free(cur);
+ cur = next;
+ }
+ cur = sock->faddr;
+ while (cur != NULL) {
+ next = cur->next;
+ free(cur);
+ cur = next;
+ }
+ free(sock);
+}
+
+static void
+gather_sctp(void)
+{
+ struct sock *sock;
+ struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
+ struct xsctp_inpcb *xinpcb;
+ struct xsctp_tcb *xstcb;
+ struct xsctp_raddr *xraddr;
+ struct xsctp_laddr *xladdr;
+ const char *varname;
+ size_t len, offset;
+ char *buf;
+ int vflag;
+ int no_stcb, local_all_loopback, foreign_all_loopback;
+
+ vflag = 0;
+ if (opt_4)
+ vflag |= INP_IPV4;
+ if (opt_6)
+ vflag |= INP_IPV6;
+
+ varname = "net.inet.sctp.assoclist";
+ if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
+ if (errno != ENOENT)
+ xo_err(1, "cap_sysctlbyname()");
+ return;
+ }
+ if ((buf = (char *)malloc(len)) == NULL) {
+ xo_err(1, "malloc()");
+ return;
+ }
+ if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
+ xo_err(1, "cap_sysctlbyname()");
+ free(buf);
+ return;
+ }
+ xinpcb = (struct xsctp_inpcb *)(void *)buf;
+ offset = sizeof(struct xsctp_inpcb);
+ while ((offset < len) && (xinpcb->last == 0)) {
+ if ((sock = calloc(1, sizeof *sock)) == NULL)
+ xo_err(1, "malloc()");
+ sock->socket = xinpcb->socket;
+ sock->proto = IPPROTO_SCTP;
+ sock->protoname = "sctp";
+ if (xinpcb->maxqlen == 0)
+ sock->state = SCTP_CLOSED;
+ else
+ sock->state = SCTP_LISTEN;
+ if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
+ sock->family = AF_INET6;
+ /*
+ * Currently there is no way to distinguish between
+ * IPv6 only sockets or dual family sockets.
+ * So mark it as dual socket.
+ */
+ sock->vflag = INP_IPV6 | INP_IPV4;
+ } else {
+ sock->family = AF_INET;
+ sock->vflag = INP_IPV4;
+ }
+ prev_laddr = NULL;
+ local_all_loopback = 1;
+ while (offset < len) {
+ xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
+ offset += sizeof(struct xsctp_laddr);
+ if (xladdr->last == 1)
+ break;
+ if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
+ xo_err(1, "malloc()");
+ switch (xladdr->address.sa.sa_family) {
+ case AF_INET:
+#define __IN_IS_ADDR_LOOPBACK(pina) \
+ ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+ if (!__IN_IS_ADDR_LOOPBACK(
+ &xladdr->address.sin.sin_addr))
+ local_all_loopback = 0;
+#undef __IN_IS_ADDR_LOOPBACK
+ sockaddr(&laddr->address, AF_INET,
+ &xladdr->address.sin.sin_addr,
+ htons(xinpcb->local_port));
+ break;
+ case AF_INET6:
+ if (!IN6_IS_ADDR_LOOPBACK(
+ &xladdr->address.sin6.sin6_addr))
+ local_all_loopback = 0;
+ sockaddr(&laddr->address, AF_INET6,
+ &xladdr->address.sin6.sin6_addr,
+ htons(xinpcb->local_port));
+ break;
+ default:
+ xo_errx(1, "address family %d not supported",
+ xladdr->address.sa.sa_family);
+ }
+ laddr->next = NULL;
+ if (prev_laddr == NULL)
+ sock->laddr = laddr;
+ else
+ prev_laddr->next = laddr;
+ prev_laddr = laddr;
+ }
+ if (sock->laddr == NULL) {
+ if ((sock->laddr =
+ calloc(1, sizeof(struct addr))) == NULL)
+ xo_err(1, "malloc()");
+ sock->laddr->address.ss_family = sock->family;
+ if (sock->family == AF_INET)
+ sock->laddr->address.ss_len =
+ sizeof(struct sockaddr_in);
+ else
+ sock->laddr->address.ss_len =
+ sizeof(struct sockaddr_in6);
+ local_all_loopback = 0;
+ }
+ if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
+ xo_err(1, "malloc()");
+ sock->faddr->address.ss_family = sock->family;
+ if (sock->family == AF_INET)
+ sock->faddr->address.ss_len =
+ sizeof(struct sockaddr_in);
+ else
+ sock->faddr->address.ss_len =
+ sizeof(struct sockaddr_in6);
+ no_stcb = 1;
+ while (offset < len) {
+ xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
+ offset += sizeof(struct xsctp_tcb);
+ if (no_stcb) {
+ if (opt_l && (sock->vflag & vflag) &&
+ (!opt_L || !local_all_loopback) &&
+ ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
+ (xstcb->last == 1))) {
+ RB_INSERT(socks_t, &socks, sock);
+ } else {
+ free_socket(sock);
+ }
+ }
+ if (xstcb->last == 1)
+ break;
+ no_stcb = 0;
+ if (opt_c) {
+ if ((sock = calloc(1, sizeof *sock)) == NULL)
+ xo_err(1, "malloc()");
+ sock->socket = xinpcb->socket;
+ sock->proto = IPPROTO_SCTP;
+ sock->protoname = "sctp";
+ sock->state = (int)xstcb->state;
+ if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
+ sock->family = AF_INET6;
+ /*
+ * Currently there is no way to distinguish
+ * between IPv6 only sockets or dual family
+ * sockets. So mark it as dual socket.
+ */
+ sock->vflag = INP_IPV6 | INP_IPV4;
+ } else {
+ sock->family = AF_INET;
+ sock->vflag = INP_IPV4;
+ }
+ }
+ prev_laddr = NULL;
+ local_all_loopback = 1;
+ while (offset < len) {
+ xladdr = (struct xsctp_laddr *)(void *)(buf +
+ offset);
+ offset += sizeof(struct xsctp_laddr);
+ if (xladdr->last == 1)
+ break;
+ if (!opt_c)
+ continue;
+ laddr = calloc(1, sizeof(struct addr));
+ if (laddr == NULL)
+ xo_err(1, "malloc()");
+ switch (xladdr->address.sa.sa_family) {
+ case AF_INET:
+#define __IN_IS_ADDR_LOOPBACK(pina) \
+ ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+ if (!__IN_IS_ADDR_LOOPBACK(
+ &xladdr->address.sin.sin_addr))
+ local_all_loopback = 0;
+#undef __IN_IS_ADDR_LOOPBACK
+ sockaddr(&laddr->address, AF_INET,
+ &xladdr->address.sin.sin_addr,
+ htons(xstcb->local_port));
+ break;
+ case AF_INET6:
+ if (!IN6_IS_ADDR_LOOPBACK(
+ &xladdr->address.sin6.sin6_addr))
+ local_all_loopback = 0;
+ sockaddr(&laddr->address, AF_INET6,
+ &xladdr->address.sin6.sin6_addr,
+ htons(xstcb->local_port));
+ break;
+ default:
+ xo_errx(1,
+ "address family %d not supported",
+ xladdr->address.sa.sa_family);
+ }
+ laddr->next = NULL;
+ if (prev_laddr == NULL)
+ sock->laddr = laddr;
+ else
+ prev_laddr->next = laddr;
+ prev_laddr = laddr;
+ }
+ prev_faddr = NULL;
+ foreign_all_loopback = 1;
+ while (offset < len) {
+ xraddr = (struct xsctp_raddr *)(void *)(buf +
+ offset);
+ offset += sizeof(struct xsctp_raddr);
+ if (xraddr->last == 1)
+ break;
+ if (!opt_c)
+ continue;
+ faddr = calloc(1, sizeof(struct addr));
+ if (faddr == NULL)
+ xo_err(1, "malloc()");
+ switch (xraddr->address.sa.sa_family) {
+ case AF_INET:
+#define __IN_IS_ADDR_LOOPBACK(pina) \
+ ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+ if (!__IN_IS_ADDR_LOOPBACK(
+ &xraddr->address.sin.sin_addr))
+ foreign_all_loopback = 0;
+#undef __IN_IS_ADDR_LOOPBACK
+ sockaddr(&faddr->address, AF_INET,
+ &xraddr->address.sin.sin_addr,
+ htons(xstcb->remote_port));
+ break;
+ case AF_INET6:
+ if (!IN6_IS_ADDR_LOOPBACK(
+ &xraddr->address.sin6.sin6_addr))
+ foreign_all_loopback = 0;
+ sockaddr(&faddr->address, AF_INET6,
+ &xraddr->address.sin6.sin6_addr,
+ htons(xstcb->remote_port));
+ break;
+ default:
+ xo_errx(1,
+ "address family %d not supported",
+ xraddr->address.sa.sa_family);
+ }
+ faddr->encaps_port = xraddr->encaps_port;
+ faddr->state = xraddr->state;
+ faddr->next = NULL;
+ if (prev_faddr == NULL)
+ sock->faddr = faddr;
+ else
+ prev_faddr->next = faddr;
+ prev_faddr = faddr;
+ }
+ if (opt_c) {
+ if ((sock->vflag & vflag) &&
+ (!opt_L ||
+ !(local_all_loopback ||
+ foreign_all_loopback))) {
+ RB_INSERT(socks_t, &socks, sock);
+ } else {
+ free_socket(sock);
+ }
+ }
+ }
+ xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
+ offset += sizeof(struct xsctp_inpcb);
+ }
+ free(buf);
+}
+
+static void
+gather_inet(int proto)
+{
+ struct xinpgen *xig, *exig;
+ struct xinpcb *xip;
+ struct xtcpcb *xtp = NULL;
+ struct xsocket *so;
+ struct sock *sock;
+ struct addr *laddr, *faddr;
+ const char *varname, *protoname;
+ size_t len, bufsize;
+ void *buf;
+ int retry, vflag;
+
+ vflag = 0;
+ if (opt_4)
+ vflag |= INP_IPV4;
+ if (opt_6)
+ vflag |= INP_IPV6;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ varname = "net.inet.tcp.pcblist";
+ protoname = "tcp";
+ break;
+ case IPPROTO_UDP:
+ varname = "net.inet.udp.pcblist";
+ protoname = "udp";
+ break;
+ case IPPROTO_DIVERT:
+ varname = "net.inet.divert.pcblist";
+ protoname = "div";
+ break;
+ default:
+ xo_errx(1, "protocol %d not supported", proto);
+ }
+
+ buf = NULL;
+ bufsize = 8192;
+ retry = 5;
+ do {
+ for (;;) {
+ if ((buf = realloc(buf, bufsize)) == NULL)
+ xo_err(1, "realloc()");
+ len = bufsize;
+ if (cap_sysctlbyname(capsysctl, varname, buf, &len,
+ NULL, 0) == 0)
+ break;
+ if (errno == ENOENT)
+ goto out;
+ if (errno != ENOMEM || len != bufsize)
+ xo_err(1, "cap_sysctlbyname()");
+ bufsize *= 2;
+ }
+ xig = (struct xinpgen *)buf;
+ exig = (struct xinpgen *)(void *)
+ ((char *)buf + len - sizeof *exig);
+ enforce_ksize(xig->xig_len, struct xinpgen);
+ enforce_ksize(exig->xig_len, struct xinpgen);
+ } while (xig->xig_gen != exig->xig_gen && retry--);
+
+ if (xig->xig_gen != exig->xig_gen && opt_v)
+ xo_warnx("warning: data may be inconsistent");
+
+ for (;;) {
+ xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
+ if (xig >= exig)
+ break;
+ switch (proto) {
+ case IPPROTO_TCP:
+ xtp = (struct xtcpcb *)xig;
+ xip = &xtp->xt_inp;
+ if (!check_ksize(xtp->xt_len, struct xtcpcb))
+ goto out;
+ protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
+ break;
+ case IPPROTO_UDP:
+ case IPPROTO_DIVERT:
+ xip = (struct xinpcb *)xig;
+ if (!check_ksize(xip->xi_len, struct xinpcb))
+ goto out;
+ break;
+ default:
+ xo_errx(1, "protocol %d not supported", proto);
+ }
+ so = &xip->xi_socket;
+ if ((xip->inp_vflag & vflag) == 0)
+ continue;
+ if (xip->inp_vflag & INP_IPV4) {
+ if ((xip->inp_fport == 0 && !opt_l) ||
+ (xip->inp_fport != 0 && !opt_c))
+ continue;
+#define __IN_IS_ADDR_LOOPBACK(pina) \
+ ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+ if (opt_L &&
+ (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
+ __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
+ continue;
+#undef __IN_IS_ADDR_LOOPBACK
+ } else if (xip->inp_vflag & INP_IPV6) {
+ if ((xip->inp_fport == 0 && !opt_l) ||
+ (xip->inp_fport != 0 && !opt_c))
+ continue;
+ if (opt_L &&
+ (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
+ IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
+ continue;
+ } else {
+ if (opt_v)
+ xo_warnx("invalid vflag 0x%x", xip->inp_vflag);
+ continue;
+ }
+ if ((sock = calloc(1, sizeof(*sock))) == NULL)
+ xo_err(1, "malloc()");
+ if ((laddr = calloc(1, sizeof *laddr)) == NULL)
+ xo_err(1, "malloc()");
+ if ((faddr = calloc(1, sizeof *faddr)) == NULL)
+ xo_err(1, "malloc()");
+ sock->socket = so->xso_so;
+ sock->pcb = so->so_pcb;
+ sock->splice_socket = so->so_splice_so;
+ sock->proto = proto;
+ sock->inp_gencnt = xip->inp_gencnt;
+ sock->fibnum = so->so_fibnum;
+ if (xip->inp_vflag & INP_IPV4) {
+ sock->family = AF_INET;
+ sockaddr(&laddr->address, sock->family,
+ &xip->inp_laddr, xip->inp_lport);
+ sockaddr(&faddr->address, sock->family,
+ &xip->inp_faddr, xip->inp_fport);
+ } else if (xip->inp_vflag & INP_IPV6) {
+ sock->family = AF_INET6;
+ sockaddr(&laddr->address, sock->family,
+ &xip->in6p_laddr, xip->inp_lport);
+ sockaddr(&faddr->address, sock->family,
+ &xip->in6p_faddr, xip->inp_fport);
+ }
+ if (proto == IPPROTO_TCP)
+ faddr->encaps_port = xtp->xt_encaps_port;
+ laddr->next = NULL;
+ faddr->next = NULL;
+ sock->laddr = laddr;
+ sock->faddr = faddr;
+ sock->vflag = xip->inp_vflag;
+ if (proto == IPPROTO_TCP) {
+ sock->state = xtp->t_state;
+ memcpy(sock->stack, xtp->xt_stack,
+ TCP_FUNCTION_NAME_LEN_MAX);
+ memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
+ }
+ sock->protoname = protoname;
+ if (sock->socket != 0)
+ RB_INSERT(socks_t, &socks, sock);
+ else
+ SLIST_INSERT_HEAD(&nosocks, sock, socket_list);
+ }
+out:
+ free(buf);
+}
+
+static void
+gather_unix(int proto)
+{
+ struct xunpgen *xug, *exug;
+ struct xunpcb *xup;
+ struct sock *sock;
+ struct addr *laddr, *faddr;
+ const char *varname, *protoname;
+ size_t len, bufsize;
+ void *buf;
+ int retry;
+
+ switch (proto) {
+ case SOCK_STREAM:
+ varname = "net.local.stream.pcblist";
+ protoname = "stream";
+ break;
+ case SOCK_DGRAM:
+ varname = "net.local.dgram.pcblist";
+ protoname = "dgram";
+ break;
+ case SOCK_SEQPACKET:
+ varname = "net.local.seqpacket.pcblist";
+ protoname = is_xo_style_encoding ? "seqpacket" : "seqpack";
+ break;
+ default:
+ abort();
+ }
+ buf = NULL;
+ bufsize = 8192;
+ retry = 5;
+ do {
+ for (;;) {
+ if ((buf = realloc(buf, bufsize)) == NULL)
+ xo_err(1, "realloc()");
+ len = bufsize;
+ if (cap_sysctlbyname(capsysctl, varname, buf, &len,
+ NULL, 0) == 0)
+ break;
+ if (errno != ENOMEM || len != bufsize)
+ xo_err(1, "cap_sysctlbyname()");
+ bufsize *= 2;
+ }
+ xug = (struct xunpgen *)buf;
+ exug = (struct xunpgen *)(void *)
+ ((char *)buf + len - sizeof(*exug));
+ if (!check_ksize(xug->xug_len, struct xunpgen) ||
+ !check_ksize(exug->xug_len, struct xunpgen))
+ goto out;
+ } while (xug->xug_gen != exug->xug_gen && retry--);
+
+ if (xug->xug_gen != exug->xug_gen && opt_v)
+ xo_warnx("warning: data may be inconsistent");
+
+ for (;;) {
+ xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
+ if (xug >= exug)
+ break;
+ xup = (struct xunpcb *)xug;
+ if (!check_ksize(xup->xu_len, struct xunpcb))
+ goto out;
+ if ((xup->unp_conn == 0 && !opt_l) ||
+ (xup->unp_conn != 0 && !opt_c))
+ continue;
+ if ((sock = calloc(1, sizeof(*sock))) == NULL)
+ xo_err(1, "malloc()");
+ if ((laddr = calloc(1, sizeof *laddr)) == NULL)
+ xo_err(1, "malloc()");
+ if ((faddr = calloc(1, sizeof *faddr)) == NULL)
+ xo_err(1, "malloc()");
+ sock->socket = xup->xu_socket.xso_so;
+ sock->pcb = xup->xu_unpp;
+ sock->proto = proto;
+ sock->family = AF_UNIX;
+ sock->protoname = protoname;
+ if (xup->xu_addr.sun_family == AF_UNIX)
+ laddr->address =
+ *(struct sockaddr_storage *)(void *)&xup->xu_addr;
+ faddr->conn = xup->unp_conn;
+ faddr->firstref = xup->xu_firstref;
+ faddr->nextref = xup->xu_nextref;
+ laddr->next = NULL;
+ faddr->next = NULL;
+ sock->laddr = laddr;
+ sock->faddr = faddr;
+ RB_INSERT(socks_t, &socks, sock);
+ RB_INSERT(pcbs_t, &pcbs, sock);
+ }
+out:
+ free(buf);
+}
+
+static void
+getfiles(void)
+{
+ struct xfile *xfiles;
+ size_t len, olen;
+
+ olen = len = sizeof(*xfiles);
+ if ((xfiles = malloc(len)) == NULL)
+ xo_err(1, "malloc()");
+ while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
+ == -1) {
+ if (errno != ENOMEM || len != olen)
+ xo_err(1, "cap_sysctlbyname()");
+ olen = len *= 2;
+ if ((xfiles = realloc(xfiles, len)) == NULL)
+ xo_err(1, "realloc()");
+ }
+ if (len > 0)
+ enforce_ksize(xfiles->xf_size, struct xfile);
+ nfiles = len / sizeof(*xfiles);
+
+ if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
+ xo_err(1, "malloc()");
+
+ for (int i = 0; i < nfiles; i++) {
+ files[i].xf_data = xfiles[i].xf_data;
+ files[i].xf_pid = xfiles[i].xf_pid;
+ files[i].xf_uid = xfiles[i].xf_uid;
+ files[i].xf_fd = xfiles[i].xf_fd;
+ RB_INSERT(files_t, &ftree, &files[i]);
+ }
+
+ free(xfiles);
+}
+
+static int
+formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
+{
+ struct sockaddr_un *sun;
+ char addrstr[NI_MAXHOST] = { '\0', '\0' };
+ int error, off, port = 0;
+
+ switch (ss->ss_family) {
+ case AF_INET:
+ if (sstosin(ss)->sin_addr.s_addr == INADDR_ANY)
+ addrstr[0] = '*';
+ port = ntohs(sstosin(ss)->sin_port);
+ break;
+ case AF_INET6:
+ if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
+ addrstr[0] = '*';
+ port = ntohs(sstosin6(ss)->sin6_port);
+ break;
+ case AF_UNIX:
+ sun = sstosun(ss);
+ off = (int)((char *)&sun->sun_path - (char *)sun);
+ if (is_xo_style_encoding) {
+ xo_emit("{:path/%.*s}", sun->sun_len - off,
+ sun->sun_path);
+ return 0;
+ }
+ return snprintf(buf, bufsize, "%.*s",
+ sun->sun_len - off, sun->sun_path);
+ }
+ if (addrstr[0] == '\0') {
+ error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
+ addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
+ if (error)
+ xo_errx(1, "cap_getnameinfo()");
+ }
+ if (is_xo_style_encoding) {
+ xo_emit("{:address/%s}", addrstr);
+ xo_emit("{:port/%d}", port);
+ return 0;
+ }
+ if (port == 0)
+ return snprintf(buf, bufsize, "%s:*", addrstr);
+ return snprintf(buf, bufsize, "%s:%d", addrstr, port);
+}
+
+static const char *
+getprocname(pid_t pid)
+{
+ static struct kinfo_proc proc;
+ size_t len;
+ int mib[4];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = (int)pid;
+ len = sizeof(proc);
+ if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
+ == -1) {
+ /* Do not warn if the process exits before we get its name. */
+ if (errno != ESRCH)
+ xo_warn("cap_sysctl()");
+ return ("??");
+ }
+ return (proc.ki_comm);
+}
+
+static int
+getprocjid(pid_t pid)
+{
+ static struct kinfo_proc proc;
+ size_t len;
+ int mib[4];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = (int)pid;
+ len = sizeof(proc);
+ if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
+ == -1) {
+ /* Do not warn if the process exits before we get its jid. */
+ if (errno != ESRCH)
+ xo_warn("cap_sysctl()");
+ return (-1);
+ }
+ return (proc.ki_jid);
+}
+
+static int
+check_ports(struct sock *s)
+{
+ int port;
+ struct addr *addr;
+
+ if (ports == NULL)
+ return (1);
+ if ((s->family != AF_INET) && (s->family != AF_INET6))
+ return (1);
+ for (addr = s->laddr; addr != NULL; addr = addr->next) {
+ if (s->family == AF_INET)
+ port = ntohs(sstosin(&addr->address)->sin_port);
+ else
+ port = ntohs(sstosin6(&addr->address)->sin6_port);
+ if (CHK_PORT(port))
+ return (1);
+ }
+ for (addr = s->faddr; addr != NULL; addr = addr->next) {
+ if (s->family == AF_INET)
+ port = ntohs(sstosin(&addr->address)->sin_port);
+ else
+ port = ntohs(sstosin6(&addr->address)->sin6_port);
+ if (CHK_PORT(port))
+ return (1);
+ }
+ return (0);
+}
+
+static const char *
+sctp_conn_state(int state)
+{
+ switch (state) {
+ case SCTP_CLOSED:
+ return "CLOSED";
+ break;
+ case SCTP_BOUND:
+ return "BOUND";
+ break;
+ case SCTP_LISTEN:
+ return "LISTEN";
+ break;
+ case SCTP_COOKIE_WAIT:
+ return "COOKIE_WAIT";
+ break;
+ case SCTP_COOKIE_ECHOED:
+ return "COOKIE_ECHOED";
+ break;
+ case SCTP_ESTABLISHED:
+ return "ESTABLISHED";
+ break;
+ case SCTP_SHUTDOWN_SENT:
+ return "SHUTDOWN_SENT";
+ break;
+ case SCTP_SHUTDOWN_RECEIVED:
+ return "SHUTDOWN_RECEIVED";
+ break;
+ case SCTP_SHUTDOWN_ACK_SENT:
+ return "SHUTDOWN_ACK_SENT";
+ break;
+ case SCTP_SHUTDOWN_PENDING:
+ return "SHUTDOWN_PENDING";
+ break;
+ default:
+ return "UNKNOWN";
+ break;
+ }
+}
+
+static const char *
+sctp_path_state(int state)
+{
+ switch (state) {
+ case SCTP_UNCONFIRMED:
+ return "UNCONFIRMED";
+ break;
+ case SCTP_ACTIVE:
+ return "ACTIVE";
+ break;
+ case SCTP_INACTIVE:
+ return "INACTIVE";
+ break;
+ default:
+ return "UNKNOWN";
+ break;
+ }
+}
+
+static int
+format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
+ #define SAFEBUF (buf == NULL ? NULL : buf + pos)
+ #define SAFESIZE (buf == NULL ? 0 : bufsize - pos)
+
+ size_t pos = 0;
+ if (faddr->conn != 0) {
+ /* Remote peer we connect(2) to, if any. */
+ struct sock *p;
+ if (!is_xo_style_encoding)
+ pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
+ p = RB_FIND(pcbs_t, &pcbs,
+ &(struct sock){ .pcb = faddr->conn });
+ if (__predict_false(p == NULL) && !is_xo_style_encoding) {
+ /* XXGL: can this happen at all? */
+ pos += snprintf(SAFEBUF, SAFESIZE, "??");
+ } else if (p->laddr->address.ss_len == 0) {
+ struct file *f;
+ f = RB_FIND(files_t, &ftree,
+ &(struct file){ .xf_data =
+ p->socket });
+ if (f != NULL) {
+ if (!is_xo_style_encoding) {
+ pos += snprintf(SAFEBUF, SAFESIZE,
+ "[%lu %d]", (u_long)f->xf_pid,
+ f->xf_fd);
+ } else {
+ xo_open_list("connections");
+ xo_open_instance("connections");
+ xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
+ xo_emit("{:fd/%d}", f->xf_fd);
+ xo_close_instance("connections");
+ xo_close_list("connections");
+ }
+ }
+ } else
+ pos += formataddr(&p->laddr->address,
+ SAFEBUF, SAFESIZE);
+ } else if (faddr->firstref != 0) {
+ /* Remote peer(s) connect(2)ed to us, if any. */
+ struct sock *p;
+ struct file *f;
+ kvaddr_t ref = faddr->firstref;
+ bool fref = true;
+
+ if (!is_xo_style_encoding)
+ pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
+ xo_open_list("connections");
+ while ((p = RB_FIND(pcbs_t, &pcbs,
+ &(struct sock){ .pcb = ref })) != 0) {
+ f = RB_FIND(files_t, &ftree,
+ &(struct file){ .xf_data = p->socket });
+ if (f != NULL) {
+ if (!is_xo_style_encoding) {
+ pos += snprintf(SAFEBUF, SAFESIZE,
+ "%s[%lu %d]", fref ? "" : ",",
+ (u_long)f->xf_pid, f->xf_fd);
+ } else {
+ xo_open_instance("connections");
+ xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
+ xo_emit("{:fd/%d}", f->xf_fd);
+ xo_close_instance("connections");
+ }
+ }
+ ref = p->faddr->nextref;
+ fref = false;
+ }
+ xo_close_list("connections");
+ }
+ return pos;
+}
+
+struct col_widths {
+ int user;
+ int command;
+ int pid;
+ int fd;
+ int proto;
+ int local_addr;
+ int foreign_addr;
+ int pcb_kva;
+ int fib;
+ int splice_address;
+ int inp_gencnt;
+ int encaps;
+ int path_state;
+ int conn_state;
+ int stack;
+ int cc;
+};
+
+static void
+calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
+{
+ struct addr *laddr, *faddr;
+ bool first = true;
+ int len = 0;
+ laddr = s->laddr;
+ faddr = s->faddr;
+ first = true;
+
+ len = strlen(s->protoname);
+ if (s->vflag & (INP_IPV4 | INP_IPV6))
+ len += 1;
+ cw->proto = MAX(cw->proto, len);
+
+ while (laddr != NULL || faddr != NULL) {
+ if (opt_w && s->family == AF_UNIX) {
+ if ((laddr == NULL) || (faddr == NULL))
+ xo_errx(1, "laddr = %p or faddr = %p is NULL",
+ (void *)laddr, (void *)faddr);
+ if (laddr->address.ss_len > 0)
+ len = formataddr(&laddr->address, NULL, 0);
+ cw->local_addr = MAX(cw->local_addr, len);
+ len = format_unix_faddr(faddr, NULL, 0);
+ cw->foreign_addr = MAX(cw->foreign_addr, len);
+ } else if (opt_w) {
+ if (laddr != NULL) {
+ len = formataddr(&laddr->address, NULL, 0);
+ cw->local_addr = MAX(cw->local_addr, len);
+ }
+ if (faddr != NULL) {
+ len = formataddr(&faddr->address, NULL, 0);
+ cw->foreign_addr = MAX(cw->foreign_addr, len);
+ }
+ }
+ if (opt_f) {
+ len = snprintf(NULL, 0, "%d", s->fibnum);
+ cw->fib = MAX(cw->fib, len);
+ }
+ if (opt_I) {
+ if (s->splice_socket != 0) {
+ struct sock *sp;
+
+ sp = RB_FIND(socks_t, &socks, &(struct sock)
+ { .socket = s->splice_socket });
+ if (sp != NULL) {
+ len = formataddr(&sp->laddr->address,
+ NULL, 0);
+ cw->splice_address = MAX(
+ cw->splice_address, len);
+ }
+ }
+ }
+ if (opt_i) {
+ if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
+ {
+ len = snprintf(NULL, 0,
+ "%" PRIu64, s->inp_gencnt);
+ cw->inp_gencnt = MAX(cw->inp_gencnt, len);
+ }
+ }
+ if (opt_U) {
+ if (faddr != NULL &&
+ ((s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) ||
+ (s->proto == IPPROTO_TCP &&
+ s->state != TCPS_CLOSED &&
+ s->state != TCPS_LISTEN))) {
+ len = snprintf(NULL, 0, "%u",
+ ntohs(faddr->encaps_port));
+ cw->encaps = MAX(cw->encaps, len);
+ }
+ }
+ if (opt_s) {
+ if (faddr != NULL &&
+ s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) {
+ len = strlen(sctp_path_state(faddr->state));
+ cw->path_state = MAX(cw->path_state, len);
+ }
+ }
+ if (first) {
+ if (opt_s) {
+ if (s->proto == IPPROTO_SCTP ||
+ s->proto == IPPROTO_TCP) {
+ switch (s->proto) {
+ case IPPROTO_SCTP:
+ len = strlen(
+ sctp_conn_state(s->state));
+ cw->conn_state = MAX(
+ cw->conn_state, len);
+ break;
+ case IPPROTO_TCP:
+ if (s->state >= 0 &&
+ s->state < TCP_NSTATES) {
+ len = strlen(
+ tcpstates[s->state]);
+ cw->conn_state = MAX(
+ cw->conn_state, len);
+ }
+ break;
+ }
+ }
+ }
+ if (opt_S && s->proto == IPPROTO_TCP) {
+ len = strlen(s->stack);
+ cw->stack = MAX(cw->stack, len);
+ }
+ if (opt_C && s->proto == IPPROTO_TCP) {
+ len = strlen(s->cc);
+ cw->cc = MAX(cw->cc, len);
+ }
+ }
+ if (laddr != NULL)
+ laddr = laddr->next;
+ if (faddr != NULL)
+ faddr = faddr->next;
+ first = false;
+ }
+}
+
+static void
+calculate_column_widths(struct col_widths *cw)
+{
+ int n, len;
+ struct file *xf;
+ struct sock *s;
+ struct passwd *pwd;
+
+ cap_setpassent(cappwd, 1);
+ for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
+ if (xf->xf_data == 0)
+ continue;
+ if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
+ continue;
+ s = RB_FIND(socks_t, &socks,
+ &(struct sock){ .socket = xf->xf_data});
+ if (s == NULL || (!check_ports(s)))
+ continue;
+ s->shown = 1;
+ if (opt_n ||
+ (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
+ len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_uid);
+ else
+ len = snprintf(NULL, 0, "%s", pwd->pw_name);
+ cw->user = MAX(cw->user, len);
+ len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_pid);
+ cw->pid = MAX(cw->pid, len);
+ len = snprintf(NULL, 0, "%d", xf->xf_fd);
+ cw->fd = MAX(cw->fd, len);
+
+ calculate_sock_column_widths(cw, s);
+ }
+ if (opt_j >= 0)
+ return;
+ SLIST_FOREACH(s, &nosocks, socket_list) {
+ if (!check_ports(s))
+ continue;
+ calculate_sock_column_widths(cw, s);
+ }
+ RB_FOREACH(s, socks_t, &socks) {
+ if (s->shown)
+ continue;
+ if (!check_ports(s))
+ continue;
+ calculate_sock_column_widths(cw, s);
+ }
+}
+
+static void
+display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
+{
+ struct addr *laddr, *faddr;
+ bool first;
+ laddr = s->laddr;
+ faddr = s->faddr;
+ first = true;
+
+ snprintf(buf, bufsize, "%s%s%s",
+ s->protoname,
+ s->vflag & INP_IPV4 ? "4" : "",
+ s->vflag & INP_IPV6 ? "6" : "");
+ xo_emit(" {:proto/%-*s}", cw->proto, buf);
+ while (laddr != NULL || faddr != NULL) {
+ if (s->family == AF_UNIX) {
+ if ((laddr == NULL) || (faddr == NULL))
+ xo_errx(1, "laddr = %p or faddr = %p is NULL",
+ (void *)laddr, (void *)faddr);
+ if (laddr->address.ss_len > 0) {
+ xo_open_container("local");
+ formataddr(&laddr->address, buf, bufsize);
+ if (!is_xo_style_encoding) {
+ xo_emit(" {:local-address/%-*.*s}",
+ cw->local_addr, cw->local_addr,
+ buf);
+ }
+ xo_close_container("local");
+ } else if (laddr->address.ss_len == 0 &&
+ faddr->conn == 0 && !is_xo_style_encoding) {
+ xo_emit(" {:local-address/%-*.*s}",
+ cw->local_addr, cw->local_addr,
+ "(not connected)");
+ } else if (!is_xo_style_encoding) {
+ xo_emit(" {:local-address/%-*.*s}",
+ cw->local_addr, cw->local_addr, "??");
+ }
+ if (faddr->conn != 0 || faddr->firstref != 0) {
+ xo_open_container("foreign");
+ int len = format_unix_faddr(faddr, buf,
+ bufsize);
+ if (len == 0 && !is_xo_style_encoding)
+ xo_emit(" {:foreign-address/%-*s}",
+ cw->foreign_addr, "??");
+ else if (!is_xo_style_encoding)
+ xo_emit(" {:foreign-address/%-*.*s}",
+ cw->foreign_addr,
+ cw->foreign_addr, buf);
+ xo_close_container("foreign");
+ } else if (!is_xo_style_encoding)
+ xo_emit(" {:foreign-address/%-*s}",
+ cw->foreign_addr, "??");
+ } else {
+ if (laddr != NULL) {
+ xo_open_container("local");
+ formataddr(&laddr->address, buf, bufsize);
+ if (!is_xo_style_encoding) {
+ xo_emit(" {:local-address/%-*.*s}",
+ cw->local_addr, cw->local_addr,
+ buf);
+ }
+ xo_close_container("local");
+ } else if (!is_xo_style_encoding)
+ xo_emit(" {:local-address/%-*.*s}",
+ cw->local_addr, cw->local_addr, "??");
+ if (faddr != NULL) {
+ xo_open_container("foreign");
+ formataddr(&faddr->address, buf, bufsize);
+ if (!is_xo_style_encoding) {
+ xo_emit(" {:foreign-address/%-*.*s}",
+ cw->foreign_addr,
+ cw->foreign_addr, buf);
+ }
+ xo_close_container("foreign");
+ } else if (!is_xo_style_encoding) {
+ xo_emit(" {:foreign-address/%-*.*s}",
+ cw->foreign_addr, cw->foreign_addr,
+ "??");
+ }
+ }
+ if (opt_A) {
+ snprintf(buf, bufsize, "%#*" PRIx64,
+ cw->pcb_kva, s->pcb);
+ xo_emit(" {:pcb-kva/%s}", buf);
+ }
+ if (opt_f)
+ xo_emit(" {:fib/%*d}", cw->fib, s->fibnum);
+ if (opt_I) {
+ if (s->splice_socket != 0) {
+ struct sock *sp;
+ sp = RB_FIND(socks_t, &socks, &(struct sock)
+ { .socket = s->splice_socket });
+ if (sp != NULL) {
+ xo_open_container("splice");
+ formataddr(&sp->laddr->address,
+ buf, bufsize);
+ xo_close_container("splice");
+ } else if (!is_xo_style_encoding)
+ strlcpy(buf, "??", bufsize);
+ } else if (!is_xo_style_encoding)
+ strlcpy(buf, "??", bufsize);
+ if (!is_xo_style_encoding)
+ xo_emit(" {:splice-address/%-*s}",
+ cw->splice_address, buf);
+ }
+ if (opt_i) {
+ if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
+ {
+ snprintf(buf, bufsize, "%" PRIu64,
+ s->inp_gencnt);
+ xo_emit(" {:id/%*s}", cw->inp_gencnt, buf);
+ } else if (!is_xo_style_encoding)
+ xo_emit(" {:id/%*s}", cw->inp_gencnt, "??");
+ }
+ if (opt_U) {
+ if (faddr != NULL &&
+ ((s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) ||
+ (s->proto == IPPROTO_TCP &&
+ s->state != TCPS_CLOSED &&
+ s->state != TCPS_LISTEN))) {
+ xo_emit(" {:encaps/%*u}", cw->encaps,
+ ntohs(faddr->encaps_port));
+ } else if (!is_xo_style_encoding)
+ xo_emit(" {:encaps/%*s}", cw->encaps, "??");
+ }
+ if (opt_s) {
+ if (faddr != NULL &&
+ s->proto == IPPROTO_SCTP &&
+ s->state != SCTP_CLOSED &&
+ s->state != SCTP_BOUND &&
+ s->state != SCTP_LISTEN) {
+ xo_emit(" {:path-state/%-*s}", cw->path_state,
+ sctp_path_state(faddr->state));
+ } else if (!is_xo_style_encoding)
+ xo_emit(" {:path-state/%-*s}", cw->path_state,
+ "??");
+ }
+ if (first) {
+ if (opt_s) {
+ if (s->proto == IPPROTO_SCTP ||
+ s->proto == IPPROTO_TCP) {
+ switch (s->proto) {
+ case IPPROTO_SCTP:
+ xo_emit(" {:conn-state/%-*s}",
+ cw->conn_state,
+ sctp_conn_state(s->state));
+ break;
+ case IPPROTO_TCP:
+ if (s->state >= 0 &&
+ s->state < TCP_NSTATES)
+ xo_emit(" {:conn-state/%-*s}",
+ cw->conn_state,
+ tcpstates[s->state]);
+ else if (!is_xo_style_encoding)
+ xo_emit(" {:conn-state/%-*s}",
+ cw->conn_state, "??");
+ break;
+ }
+ } else if (!is_xo_style_encoding)
+ xo_emit(" {:conn-state/%-*s}",
+ cw->conn_state, "??");
+ }
+ if (opt_S) {
+ if (s->proto == IPPROTO_TCP)
+ xo_emit(" {:stack/%-*s}",
+ cw->stack, s->stack);
+ else if (!is_xo_style_encoding)
+ xo_emit(" {:stack/%-*s}",
+ cw->stack, "??");
+ }
+ if (opt_C) {
+ if (s->proto == IPPROTO_TCP)
+ xo_emit(" {:cc/%-*s}", cw->cc, s->cc);
+ else if (!is_xo_style_encoding)
+ xo_emit(" {:cc/%-*s}", cw->cc, "??");
+ }
+ }
+ if (laddr != NULL)
+ laddr = laddr->next;
+ if (faddr != NULL)
+ faddr = faddr->next;
+ if (!is_xo_style_encoding && (laddr != NULL || faddr != NULL))
+ xo_emit("{:user/%-*s} {:command/%-*s} {:pid/%*s}"
+ " {:fd/%*s}", cw->user, "??", cw->command, "??",
+ cw->pid, "??", cw->fd, "??");
+ first = false;
+ }
+ xo_emit("\n");
+}
+
+static void
+display(void)
+{
+ struct passwd *pwd;
+ struct file *xf;
+ struct sock *s;
+ int n;
+ struct col_widths cw;
+ const size_t bufsize = 512;
+ void *buf;
+ if ((buf = (char *)malloc(bufsize)) == NULL) {
+ xo_err(1, "malloc()");
+ return;
+ }
+
+ if (!is_xo_style_encoding) {
+ cw = (struct col_widths) {
+ .user = strlen("USER"),
+ .command = 10,
+ .pid = strlen("PID"),
+ .fd = strlen("FD"),
+ .proto = strlen("PROTO"),
+ .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
+ .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
+ .pcb_kva = 18,
+ .fib = strlen("FIB"),
+ .splice_address = strlen("SPLICE ADDRESS"),
+ .inp_gencnt = strlen("ID"),
+ .encaps = strlen("ENCAPS"),
+ .path_state = strlen("PATH STATE"),
+ .conn_state = strlen("CONN STATE"),
+ .stack = strlen("STACK"),
+ .cc = strlen("CC"),
+ };
+ calculate_column_widths(&cw);
+ } else
+ memset(&cw, 0, sizeof(cw));
+
+ xo_set_version(SOCKSTAT_XO_VERSION);
+ xo_open_container("sockstat");
+ xo_open_list("socket");
+ if (!opt_q) {
+ xo_emit("{T:/%-*s} {T:/%-*s} {T:/%*s} {T:/%*s} {T:/%-*s} "
+ "{T:/%-*s} {T:/%-*s}", cw.user, "USER", cw.command,
+ "COMMAND", cw.pid, "PID", cw.fd, "FD", cw.proto,
+ "PROTO", cw.local_addr, "LOCAL ADDRESS",
+ cw.foreign_addr, "FOREIGN ADDRESS");
+ if (opt_A)
+ xo_emit(" {T:/%-*s}", cw.pcb_kva, "PCB KVA");
+ if (opt_f)
+ /* RT_MAXFIBS is 65535. */
+ xo_emit(" {T:/%*s}", cw.fib, "FIB");
+ if (opt_I)
+ xo_emit(" {T:/%-*s}", cw.splice_address,
+ "SPLICE ADDRESS");
+ if (opt_i)
+ xo_emit(" {T:/%*s}", cw.inp_gencnt, "ID");
+ if (opt_U)
+ xo_emit(" {T:/%*s}", cw.encaps, "ENCAPS");
+ if (opt_s) {
+ xo_emit(" {T:/%-*s}", cw.path_state, "PATH STATE");
+ xo_emit(" {T:/%-*s}", cw.conn_state, "CONN STATE");
+ }
+ if (opt_S)
+ xo_emit(" {T:/%-*s}", cw.stack, "STACK");
+ if (opt_C)
+ xo_emit(" {T:/%-*s}", cw.cc, "CC");
+ xo_emit("\n");
+ }
+ cap_setpassent(cappwd, 1);
+ for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
+ if (xf->xf_data == 0)
+ continue;
+ if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
+ continue;
+ s = RB_FIND(socks_t, &socks,
+ &(struct sock){ .socket = xf->xf_data});
+ if (s != NULL && check_ports(s)) {
+ xo_open_instance("socket");
+ s->shown = 1;
+ if (opt_n ||
+ (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
+ xo_emit("{:user/%-*lu}", cw.user,
+ (u_long)xf->xf_uid);
+ else
+ xo_emit("{:user/%-*s}", cw.user, pwd->pw_name);
+ if (!is_xo_style_encoding)
+ xo_emit(" {:command/%-*.10s}", cw.command,
+ getprocname(xf->xf_pid));
+ else
+ xo_emit(" {:command/%-*s}", cw.command,
+ getprocname(xf->xf_pid));
+ xo_emit(" {:pid/%*lu}", cw.pid, (u_long)xf->xf_pid);
+ xo_emit(" {:fd/%*d}", cw.fd, xf->xf_fd);
+ display_sock(s, &cw, buf, bufsize);
+ xo_close_instance("socket");
+ }
+ }
+ if (opt_j >= 0)
+ return;
+ SLIST_FOREACH(s, &nosocks, socket_list) {
+ if (!check_ports(s))
+ continue;
+ xo_open_instance("socket");
+ if (!is_xo_style_encoding)
+ xo_emit("{:user/%-*s} {:command/%-*s} {:pid/%*s}"
+ " {:fd/%*s}", cw.user, "??", cw.command, "??",
+ cw.pid, "??", cw.fd, "??");
+ display_sock(s, &cw, buf, bufsize);
+ xo_close_instance("socket");
+ }
+ RB_FOREACH(s, socks_t, &socks) {
+ if (s->shown)
+ continue;
+ if (!check_ports(s))
+ continue;
+ xo_open_instance("socket");
+ if (!is_xo_style_encoding)
+ xo_emit("{:user/%-*s} {:command/%-*s} {:pid/%*s}"
+ " {:fd/%*s}", cw.user, "??", cw.command, "??",
+ cw.pid, "??", cw.fd, "??");
+ display_sock(s, &cw, buf, bufsize);
+ xo_close_instance("socket");
+ }
+ xo_close_list("socket");
+ xo_close_container("sockstat");
+ if (xo_finish() < 0)
+ xo_err(1, "stdout");
+ free(buf);
+ cap_endpwent(cappwd);
+}
+
+static int
+set_default_protos(void)
+{
+ struct protoent *prot;
+ const char *pname;
+ size_t pindex;
+
+ init_protos(default_numprotos);
+
+ for (pindex = 0; pindex < default_numprotos; pindex++) {
+ pname = default_protos[pindex];
+ prot = cap_getprotobyname(capnetdb, pname);
+ if (prot == NULL)
+ xo_err(1, "cap_getprotobyname: %s", pname);
+ protos[pindex] = prot->p_proto;
+ }
+ numprotos = pindex;
+ return (pindex);
+}
+
+/*
+ * Return the vnet property of the jail, or -1 on error.
+ */
+static int
+jail_getvnet(int jid)
+{
+ struct iovec jiov[6];
+ int vnet;
+ size_t len = sizeof(vnet);
+
+ if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
+ return (0);
+
+ vnet = -1;
+ jiov[0].iov_base = __DECONST(char *, "jid");
+ jiov[0].iov_len = sizeof("jid");
+ jiov[1].iov_base = &jid;
+ jiov[1].iov_len = sizeof(jid);
+ jiov[2].iov_base = __DECONST(char *, "vnet");
+ jiov[2].iov_len = sizeof("vnet");
+ jiov[3].iov_base = &vnet;
+ jiov[3].iov_len = sizeof(vnet);
+ jiov[4].iov_base = __DECONST(char *, "errmsg");
+ jiov[4].iov_len = sizeof("errmsg");
+ jiov[5].iov_base = jail_errmsg;
+ jiov[5].iov_len = JAIL_ERRMSGLEN;
+ jail_errmsg[0] = '\0';
+ if (jail_get(jiov, nitems(jiov), 0) < 0) {
+ if (!jail_errmsg[0])
+ snprintf(jail_errmsg, JAIL_ERRMSGLEN,
+ "jail_get: %s", strerror(errno));
+ return (-1);
+ }
+ return (vnet);
+}
+
+static void
+usage(void)
+{
+ xo_error(
+"usage: sockstat [--libxo ...] [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports]\n"
+" [-P protocols]\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ cap_channel_t *capcas;
+ cap_net_limit_t *limit;
+ const char *pwdcmds[] = { "setpassent", "getpwuid" };
+ const char *pwdfields[] = { "pw_name" };
+ int protos_defined = -1;
+ int o, i, err;
+
+ argc = xo_parse_args(argc, argv);
+ if (argc < 0)
+ exit(1);
+ if (xo_get_style(NULL) != XO_STYLE_TEXT &&
+ xo_get_style(NULL) != XO_STYLE_HTML)
+ is_xo_style_encoding = true;
+ opt_j = -1;
+ while ((o = getopt(argc, argv, "46ACcfIij:Llnp:P:qSsUuvw")) != -1)
+ switch (o) {
+ case '4':
+ opt_4 = true;
+ break;
+ case '6':
+ opt_6 = true;
+ break;
+ case 'A':
+ opt_A = true;
+ break;
+ case 'C':
+ opt_C = true;
+ break;
+ case 'c':
+ opt_c = true;
+ break;
+ case 'f':
+ opt_f = true;
+ break;
+ case 'I':
+ opt_I = true;
+ break;
+ case 'i':
+ opt_i = true;
+ break;
+ case 'j':
+ opt_j = jail_getid(optarg);
+ if (opt_j < 0)
+ xo_errx(1, "jail_getid: %s", jail_errmsg);
+ break;
+ case 'L':
+ opt_L = true;
+ break;
+ case 'l':
+ opt_l = true;
+ break;
+ case 'n':
+ opt_n = true;
+ break;
+ case 'p':
+ err = parse_ports(optarg);
+ switch (err) {
+ case EINVAL:
+ xo_errx(1, "syntax error in port range");
+ break;
+ case ERANGE:
+ xo_errx(1, "invalid port number");
+ break;
+ }
+ break;
+ case 'P':
+ protos_defined = parse_protos(optarg);
+ break;
+ case 'q':
+ opt_q = true;
+ break;
+ case 'S':
+ opt_S = true;
+ break;
+ case 's':
+ opt_s = true;
+ break;
+ case 'U':
+ opt_U = true;
+ break;
+ case 'u':
+ opt_u = true;
+ break;
+ case 'v':
+ ++opt_v;
+ break;
+ case 'w':
+ opt_w = true;
+ break;
+ default:
+ usage();
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0)
+ usage();
+
+ if (opt_j > 0) {
+ switch (jail_getvnet(opt_j)) {
+ case -1:
+ xo_errx(2, "jail_getvnet: %s", jail_errmsg);
+ case JAIL_SYS_NEW:
+ if (jail_attach(opt_j) < 0)
+ xo_err(3, "jail_attach()");
+ /* Set back to -1 for normal output in vnet jail. */
+ opt_j = -1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ capcas = cap_init();
+ if (capcas == NULL)
+ xo_err(1, "Unable to contact Casper");
+ if (caph_enter_casper() < 0)
+ xo_err(1, "Unable to enter capability mode");
+ capnet = cap_service_open(capcas, "system.net");
+ if (capnet == NULL)
+ xo_err(1, "Unable to open system.net service");
+ capnetdb = cap_service_open(capcas, "system.netdb");
+ if (capnetdb == NULL)
+ xo_err(1, "Unable to open system.netdb service");
+ capsysctl = cap_service_open(capcas, "system.sysctl");
+ if (capsysctl == NULL)
+ xo_err(1, "Unable to open system.sysctl service");
+ cappwd = cap_service_open(capcas, "system.pwd");
+ if (cappwd == NULL)
+ xo_err(1, "Unable to open system.pwd service");
+ cap_close(capcas);
+ limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
+ if (limit == NULL)
+ xo_err(1, "Unable to init cap_net limits");
+ if (cap_net_limit(limit) < 0)
+ xo_err(1, "Unable to apply limits");
+ if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
+ xo_err(1, "Unable to apply pwd commands limits");
+ if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
+ xo_err(1, "Unable to apply pwd commands limits");
+
+ if ((!opt_4 && !opt_6) && protos_defined != -1)
+ opt_4 = opt_6 = true;
+ if (!opt_4 && !opt_6 && !opt_u)
+ opt_4 = opt_6 = opt_u = true;
+ if ((opt_4 || opt_6) && protos_defined == -1)
+ protos_defined = set_default_protos();
+ if (!opt_c && !opt_l)
+ opt_c = opt_l = true;
+
+ if (opt_4 || opt_6) {
+ for (i = 0; i < protos_defined; i++)
+ if (protos[i] == IPPROTO_SCTP)
+ gather_sctp();
+ else
+ gather_inet(protos[i]);
+ }
+
+ if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
+ gather_unix(SOCK_STREAM);
+ gather_unix(SOCK_DGRAM);
+ gather_unix(SOCK_SEQPACKET);
+ }
+ getfiles();
+ display();
+ exit(0);
+}
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 6761faae5210..7bb7f6a66e3f 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2002 Dag-Erling Smørgrav
+ * Copyright (c) 2025 ConnectWise
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -13,8 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -28,1889 +26,52 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/jail.h>
-#include <sys/user.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-
-#include <sys/un.h>
-#include <sys/unpcb.h>
-
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/in_pcb.h>
-#include <netinet/sctp.h>
-#include <netinet/tcp.h>
-#define TCPSTATES /* load state names */
-#include <netinet/tcp_fsm.h>
-#include <netinet/tcp_seq.h>
-#include <netinet/tcp_var.h>
-#include <arpa/inet.h>
-
-#include <capsicum_helpers.h>
#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <jail.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <libxo/xo.h>
-#include <libcasper.h>
-#include <casper/cap_net.h>
-#include <casper/cap_netdb.h>
-#include <casper/cap_pwd.h>
-#include <casper/cap_sysctl.h>
-
-#define SOCKSTAT_XO_VERSION "1"
-#define sstosin(ss) ((struct sockaddr_in *)(ss))
-#define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
-#define sstosun(ss) ((struct sockaddr_un *)(ss))
-#define sstosa(ss) ((struct sockaddr *)(ss))
-
-static bool opt_4; /* Show IPv4 sockets */
-static bool opt_6; /* Show IPv6 sockets */
-static bool opt_A; /* Show kernel address of pcb */
-static bool opt_C; /* Show congestion control */
-static bool opt_c; /* Show connected sockets */
-static bool opt_f; /* Show FIB numbers */
-static bool opt_I; /* Show spliced socket addresses */
-static bool opt_i; /* Show inp_gencnt */
-static int opt_j; /* Show specified jail */
-static bool opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
-static bool opt_l; /* Show listening sockets */
-static bool opt_n; /* Don't resolve UIDs to user names */
-static bool opt_q; /* Don't show header */
-static bool opt_S; /* Show protocol stack if applicable */
-static bool opt_s; /* Show protocol state if applicable */
-static bool opt_U; /* Show remote UDP encapsulation port number */
-static bool opt_u; /* Show Unix domain sockets */
-static u_int opt_v; /* Verbose mode */
-static bool opt_w; /* Automatically size the columns */
-
-/*
- * Default protocols to use if no -P was defined.
- */
-static const char *default_protos[] = {"sctp", "tcp", "udp", "divert" };
-static size_t default_numprotos = nitems(default_protos);
-
-static int *protos; /* protocols to use */
-static size_t numprotos; /* allocated size of protos[] */
+#include "sockstat.h"
-static int *ports;
-
-#define INT_BIT (sizeof(int)*CHAR_BIT)
-#define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
-#define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
-
-struct addr {
- union {
- struct sockaddr_storage address;
- struct { /* unix(4) faddr */
- kvaddr_t conn;
- kvaddr_t firstref;
- kvaddr_t nextref;
- };
- };
- unsigned int encaps_port;
- int state;
- struct addr *next;
-};
-
-struct sock {
- union {
- RB_ENTRY(sock) socket_tree; /* tree of pcbs with socket */
- SLIST_ENTRY(sock) socket_list; /* list of pcbs w/o socket */
- };
- RB_ENTRY(sock) pcb_tree;
- kvaddr_t socket;
- kvaddr_t pcb;
- kvaddr_t splice_socket;
- uint64_t inp_gencnt;
- int shown;
- int vflag;
- int family;
- int proto;
- int state;
- int fibnum;
- const char *protoname;
- char stack[TCP_FUNCTION_NAME_LEN_MAX];
- char cc[TCP_CA_NAME_MAX];
- struct addr *laddr;
- struct addr *faddr;
-};
-
-static RB_HEAD(socks_t, sock) socks = RB_INITIALIZER(&socks);
-static int64_t
-socket_compare(const struct sock *a, const struct sock *b)
-{
- return ((int64_t)(a->socket/2 - b->socket/2));
-}
-RB_GENERATE_STATIC(socks_t, sock, socket_tree, socket_compare);
-
-static RB_HEAD(pcbs_t, sock) pcbs = RB_INITIALIZER(&pcbs);
-static int64_t
-pcb_compare(const struct sock *a, const struct sock *b)
-{
- return ((int64_t)(a->pcb/2 - b->pcb/2));
-}
-RB_GENERATE_STATIC(pcbs_t, sock, pcb_tree, pcb_compare);
-
-static SLIST_HEAD(, sock) nosocks = SLIST_HEAD_INITIALIZER(&nosocks);
-
-struct file {
- RB_ENTRY(file) file_tree;
- kvaddr_t xf_data;
- pid_t xf_pid;
- uid_t xf_uid;
- int xf_fd;
-};
-
-static RB_HEAD(files_t, file) ftree = RB_INITIALIZER(&ftree);
-static int64_t
-file_compare(const struct file *a, const struct file *b)
-{
- return ((int64_t)(a->xf_data/2 - b->xf_data/2));
-}
-RB_GENERATE_STATIC(files_t, file, file_tree, file_compare);
-
-static struct file *files;
-static int nfiles;
-
-static cap_channel_t *capnet;
-static cap_channel_t *capnetdb;
-static cap_channel_t *capsysctl;
-static cap_channel_t *cappwd;
-
-static bool
-_check_ksize(size_t received_size, size_t expected_size, const char *struct_name)
-{
- if (received_size != expected_size) {
- xo_warnx("%s size mismatch: expected %zd, received %zd",
- struct_name, expected_size, received_size);
- return false;
- }
- return true;
-}
-#define check_ksize(_sz, _struct) (_check_ksize(_sz, sizeof(_struct), #_struct))
-
-static void
-_enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name)
-{
- if (received_size != expected_size) {
- xo_errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd",
- struct_name, expected_size, received_size);
- }
-}
-#define enforce_ksize(_sz, _struct) (_enforce_ksize(_sz, sizeof(_struct), #_struct))
-
-static int
-get_proto_type(const char *proto)
-{
- struct protoent *pent;
+int *ports;
- if (strlen(proto) == 0)
- return (0);
- if (capnetdb != NULL)
- pent = cap_getprotobyname(capnetdb, proto);
- else
- pent = getprotobyname(proto);
- if (pent == NULL) {
- xo_warn("cap_getprotobyname");
- return (-1);
- }
- return (pent->p_proto);
-}
-
-static void
-init_protos(int num)
-{
- int proto_count = 0;
-
- if (num > 0) {
- proto_count = num;
- } else {
- /* Find the maximum number of possible protocols. */
- while (getprotoent() != NULL)
- proto_count++;
- endprotoent();
- }
-
- if ((protos = malloc(sizeof(int) * proto_count)) == NULL)
- xo_err(1, "malloc");
- numprotos = proto_count;
-}
-
-static int
-parse_protos(char *protospec)
-{
- char *prot;
- int proto_type, proto_index;
-
- if (protospec == NULL)
- return (-1);
-
- init_protos(0);
- proto_index = 0;
- while ((prot = strsep(&protospec, ",")) != NULL) {
- if (strlen(prot) == 0)
- continue;
- proto_type = get_proto_type(prot);
- if (proto_type != -1)
- protos[proto_index++] = proto_type;
- }
- numprotos = proto_index;
- return (proto_index);
-}
-
-static void
+int
parse_ports(const char *portspec)
{
- const char *p, *q;
- int port, end;
+ const char *p;
if (ports == NULL)
if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL)
xo_err(1, "calloc()");
p = portspec;
while (*p != '\0') {
- if (!isdigit(*p))
- xo_errx(1, "syntax error in port range");
- for (q = p; *q != '\0' && isdigit(*q); ++q)
- /* nothing */ ;
- for (port = 0; p < q; ++p)
- port = port * 10 + digittoint(*p);
+ long port, end;
+ char *endptr = NULL;
+
+ errno = 0;
+ port = strtol(p, &endptr, 10);
+ if (errno)
+ return (errno);
if (port < 0 || port > 65535)
- xo_errx(1, "invalid port number");
+ return (ERANGE);
SET_PORT(port);
- switch (*p) {
+ switch (*endptr) {
case '-':
- ++p;
+ p = endptr + 1;
+ end = strtol(p, &endptr, 10);
break;
case ',':
- ++p;
- /* fall through */
- case '\0':
+ p = endptr + 1;
+ continue;
default:
+ p = endptr;
continue;
}
- for (q = p; *q != '\0' && isdigit(*q); ++q)
- /* nothing */ ;
- for (end = 0; p < q; ++p)
- end = end * 10 + digittoint(*p);
+ if (errno)
+ return (errno);
if (end < port || end > 65535)
- xo_errx(1, "invalid port number");
+ return (ERANGE);
while (port++ < end)
SET_PORT(port);
- if (*p == ',')
- ++p;
- }
-}
-
-static void
-sockaddr(struct sockaddr_storage *ss, int af, void *addr, int port)
-{
- struct sockaddr_in *sin4;
- struct sockaddr_in6 *sin6;
-
- bzero(ss, sizeof(*ss));
- switch (af) {
- case AF_INET:
- sin4 = sstosin(ss);
- sin4->sin_len = sizeof(*sin4);
- sin4->sin_family = af;
- sin4->sin_port = port;
- sin4->sin_addr = *(struct in_addr *)addr;
- break;
- case AF_INET6:
- sin6 = sstosin6(ss);
- sin6->sin6_len = sizeof(*sin6);
- sin6->sin6_family = af;
- sin6->sin6_port = port;
- sin6->sin6_addr = *(struct in6_addr *)addr;
-#define s6_addr16 __u6_addr.__u6_addr16
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- sin6->sin6_scope_id =
- ntohs(sin6->sin6_addr.s6_addr16[1]);
- sin6->sin6_addr.s6_addr16[1] = 0;
- }
- break;
- default:
- abort();
- }
-}
-
-static void
-free_socket(struct sock *sock)
-{
- struct addr *cur, *next;
-
- cur = sock->laddr;
- while (cur != NULL) {
- next = cur->next;
- free(cur);
- cur = next;
- }
- cur = sock->faddr;
- while (cur != NULL) {
- next = cur->next;
- free(cur);
- cur = next;
- }
- free(sock);
-}
-
-static void
-gather_sctp(void)
-{
- struct sock *sock;
- struct addr *laddr, *prev_laddr, *faddr, *prev_faddr;
- struct xsctp_inpcb *xinpcb;
- struct xsctp_tcb *xstcb;
- struct xsctp_raddr *xraddr;
- struct xsctp_laddr *xladdr;
- const char *varname;
- size_t len, offset;
- char *buf;
- int vflag;
- int no_stcb, local_all_loopback, foreign_all_loopback;
-
- vflag = 0;
- if (opt_4)
- vflag |= INP_IPV4;
- if (opt_6)
- vflag |= INP_IPV6;
-
- varname = "net.inet.sctp.assoclist";
- if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) {
- if (errno != ENOENT)
- xo_err(1, "cap_sysctlbyname()");
- return;
- }
- if ((buf = (char *)malloc(len)) == NULL) {
- xo_err(1, "malloc()");
- return;
- }
- if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
- xo_err(1, "cap_sysctlbyname()");
- free(buf);
- return;
- }
- xinpcb = (struct xsctp_inpcb *)(void *)buf;
- offset = sizeof(struct xsctp_inpcb);
- while ((offset < len) && (xinpcb->last == 0)) {
- if ((sock = calloc(1, sizeof *sock)) == NULL)
- xo_err(1, "malloc()");
- sock->socket = xinpcb->socket;
- sock->proto = IPPROTO_SCTP;
- sock->protoname = "sctp";
- if (xinpcb->maxqlen == 0)
- sock->state = SCTP_CLOSED;
- else
- sock->state = SCTP_LISTEN;
- if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
- sock->family = AF_INET6;
- /*
- * Currently there is no way to distinguish between
- * IPv6 only sockets or dual family sockets.
- * So mark it as dual socket.
- */
- sock->vflag = INP_IPV6 | INP_IPV4;
- } else {
- sock->family = AF_INET;
- sock->vflag = INP_IPV4;
- }
- prev_laddr = NULL;
- local_all_loopback = 1;
- while (offset < len) {
- xladdr = (struct xsctp_laddr *)(void *)(buf + offset);
- offset += sizeof(struct xsctp_laddr);
- if (xladdr->last == 1)
- break;
- if ((laddr = calloc(1, sizeof(struct addr))) == NULL)
- xo_err(1, "malloc()");
- switch (xladdr->address.sa.sa_family) {
- case AF_INET:
-#define __IN_IS_ADDR_LOOPBACK(pina) \
- ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
- if (!__IN_IS_ADDR_LOOPBACK(
- &xladdr->address.sin.sin_addr))
- local_all_loopback = 0;
-#undef __IN_IS_ADDR_LOOPBACK
- sockaddr(&laddr->address, AF_INET,
- &xladdr->address.sin.sin_addr,
- htons(xinpcb->local_port));
- break;
- case AF_INET6:
- if (!IN6_IS_ADDR_LOOPBACK(
- &xladdr->address.sin6.sin6_addr))
- local_all_loopback = 0;
- sockaddr(&laddr->address, AF_INET6,
- &xladdr->address.sin6.sin6_addr,
- htons(xinpcb->local_port));
- break;
- default:
- xo_errx(1, "address family %d not supported",
- xladdr->address.sa.sa_family);
- }
- laddr->next = NULL;
- if (prev_laddr == NULL)
- sock->laddr = laddr;
- else
- prev_laddr->next = laddr;
- prev_laddr = laddr;
- }
- if (sock->laddr == NULL) {
- if ((sock->laddr =
- calloc(1, sizeof(struct addr))) == NULL)
- xo_err(1, "malloc()");
- sock->laddr->address.ss_family = sock->family;
- if (sock->family == AF_INET)
- sock->laddr->address.ss_len =
- sizeof(struct sockaddr_in);
- else
- sock->laddr->address.ss_len =
- sizeof(struct sockaddr_in6);
- local_all_loopback = 0;
- }
- if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL)
- xo_err(1, "malloc()");
- sock->faddr->address.ss_family = sock->family;
- if (sock->family == AF_INET)
- sock->faddr->address.ss_len =
- sizeof(struct sockaddr_in);
- else
- sock->faddr->address.ss_len =
- sizeof(struct sockaddr_in6);
- no_stcb = 1;
- while (offset < len) {
- xstcb = (struct xsctp_tcb *)(void *)(buf + offset);
- offset += sizeof(struct xsctp_tcb);
- if (no_stcb) {
- if (opt_l && (sock->vflag & vflag) &&
- (!opt_L || !local_all_loopback) &&
- ((xinpcb->flags & SCTP_PCB_FLAGS_UDPTYPE) ||
- (xstcb->last == 1))) {
- RB_INSERT(socks_t, &socks, sock);
- } else {
- free_socket(sock);
- }
- }
- if (xstcb->last == 1)
- break;
- no_stcb = 0;
- if (opt_c) {
- if ((sock = calloc(1, sizeof *sock)) == NULL)
- xo_err(1, "malloc()");
- sock->socket = xinpcb->socket;
- sock->proto = IPPROTO_SCTP;
- sock->protoname = "sctp";
- sock->state = (int)xstcb->state;
- if (xinpcb->flags & SCTP_PCB_FLAGS_BOUND_V6) {
- sock->family = AF_INET6;
- /*
- * Currently there is no way to distinguish
- * between IPv6 only sockets or dual family
- * sockets. So mark it as dual socket.
- */
- sock->vflag = INP_IPV6 | INP_IPV4;
- } else {
- sock->family = AF_INET;
- sock->vflag = INP_IPV4;
- }
- }
- prev_laddr = NULL;
- local_all_loopback = 1;
- while (offset < len) {
- xladdr = (struct xsctp_laddr *)(void *)(buf +
- offset);
- offset += sizeof(struct xsctp_laddr);
- if (xladdr->last == 1)
- break;
- if (!opt_c)
- continue;
- laddr = calloc(1, sizeof(struct addr));
- if (laddr == NULL)
- xo_err(1, "malloc()");
- switch (xladdr->address.sa.sa_family) {
- case AF_INET:
-#define __IN_IS_ADDR_LOOPBACK(pina) \
- ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
- if (!__IN_IS_ADDR_LOOPBACK(
- &xladdr->address.sin.sin_addr))
- local_all_loopback = 0;
-#undef __IN_IS_ADDR_LOOPBACK
- sockaddr(&laddr->address, AF_INET,
- &xladdr->address.sin.sin_addr,
- htons(xstcb->local_port));
- break;
- case AF_INET6:
- if (!IN6_IS_ADDR_LOOPBACK(
- &xladdr->address.sin6.sin6_addr))
- local_all_loopback = 0;
- sockaddr(&laddr->address, AF_INET6,
- &xladdr->address.sin6.sin6_addr,
- htons(xstcb->local_port));
- break;
- default:
- xo_errx(1,
- "address family %d not supported",
- xladdr->address.sa.sa_family);
- }
- laddr->next = NULL;
- if (prev_laddr == NULL)
- sock->laddr = laddr;
- else
- prev_laddr->next = laddr;
- prev_laddr = laddr;
- }
- prev_faddr = NULL;
- foreign_all_loopback = 1;
- while (offset < len) {
- xraddr = (struct xsctp_raddr *)(void *)(buf +
- offset);
- offset += sizeof(struct xsctp_raddr);
- if (xraddr->last == 1)
- break;
- if (!opt_c)
- continue;
- faddr = calloc(1, sizeof(struct addr));
- if (faddr == NULL)
- xo_err(1, "malloc()");
- switch (xraddr->address.sa.sa_family) {
- case AF_INET:
-#define __IN_IS_ADDR_LOOPBACK(pina) \
- ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
- if (!__IN_IS_ADDR_LOOPBACK(
- &xraddr->address.sin.sin_addr))
- foreign_all_loopback = 0;
-#undef __IN_IS_ADDR_LOOPBACK
- sockaddr(&faddr->address, AF_INET,
- &xraddr->address.sin.sin_addr,
- htons(xstcb->remote_port));
- break;
- case AF_INET6:
- if (!IN6_IS_ADDR_LOOPBACK(
- &xraddr->address.sin6.sin6_addr))
- foreign_all_loopback = 0;
- sockaddr(&faddr->address, AF_INET6,
- &xraddr->address.sin6.sin6_addr,
- htons(xstcb->remote_port));
- break;
- default:
- xo_errx(1,
- "address family %d not supported",
- xraddr->address.sa.sa_family);
- }
- faddr->encaps_port = xraddr->encaps_port;
- faddr->state = xraddr->state;
- faddr->next = NULL;
- if (prev_faddr == NULL)
- sock->faddr = faddr;
- else
- prev_faddr->next = faddr;
- prev_faddr = faddr;
- }
- if (opt_c) {
- if ((sock->vflag & vflag) &&
- (!opt_L ||
- !(local_all_loopback ||
- foreign_all_loopback))) {
- RB_INSERT(socks_t, &socks, sock);
- } else {
- free_socket(sock);
- }
- }
- }
- xinpcb = (struct xsctp_inpcb *)(void *)(buf + offset);
- offset += sizeof(struct xsctp_inpcb);
- }
- free(buf);
-}
-
-static void
-gather_inet(int proto)
-{
- struct xinpgen *xig, *exig;
- struct xinpcb *xip;
- struct xtcpcb *xtp = NULL;
- struct xsocket *so;
- struct sock *sock;
- struct addr *laddr, *faddr;
- const char *varname, *protoname;
- size_t len, bufsize;
- void *buf;
- int retry, vflag;
-
- vflag = 0;
- if (opt_4)
- vflag |= INP_IPV4;
- if (opt_6)
- vflag |= INP_IPV6;
-
- switch (proto) {
- case IPPROTO_TCP:
- varname = "net.inet.tcp.pcblist";
- protoname = "tcp";
- break;
- case IPPROTO_UDP:
- varname = "net.inet.udp.pcblist";
- protoname = "udp";
- break;
- case IPPROTO_DIVERT:
- varname = "net.inet.divert.pcblist";
- protoname = "div";
- break;
- default:
- xo_errx(1, "protocol %d not supported", proto);
- }
-
- buf = NULL;
- bufsize = 8192;
- retry = 5;
- do {
- for (;;) {
- if ((buf = realloc(buf, bufsize)) == NULL)
- xo_err(1, "realloc()");
- len = bufsize;
- if (cap_sysctlbyname(capsysctl, varname, buf, &len,
- NULL, 0) == 0)
- break;
- if (errno == ENOENT)
- goto out;
- if (errno != ENOMEM || len != bufsize)
- xo_err(1, "cap_sysctlbyname()");
- bufsize *= 2;
- }
- xig = (struct xinpgen *)buf;
- exig = (struct xinpgen *)(void *)
- ((char *)buf + len - sizeof *exig);
- enforce_ksize(xig->xig_len, struct xinpgen);
- enforce_ksize(exig->xig_len, struct xinpgen);
- } while (xig->xig_gen != exig->xig_gen && retry--);
-
- if (xig->xig_gen != exig->xig_gen && opt_v)
- xo_warnx("warning: data may be inconsistent");
-
- for (;;) {
- xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
- if (xig >= exig)
- break;
- switch (proto) {
- case IPPROTO_TCP:
- xtp = (struct xtcpcb *)xig;
- xip = &xtp->xt_inp;
- if (!check_ksize(xtp->xt_len, struct xtcpcb))
- goto out;
- protoname = xtp->t_flags & TF_TOE ? "toe" : "tcp";
- break;
- case IPPROTO_UDP:
- case IPPROTO_DIVERT:
- xip = (struct xinpcb *)xig;
- if (!check_ksize(xip->xi_len, struct xinpcb))
- goto out;
- break;
- default:
- xo_errx(1, "protocol %d not supported", proto);
- }
- so = &xip->xi_socket;
- if ((xip->inp_vflag & vflag) == 0)
- continue;
- if (xip->inp_vflag & INP_IPV4) {
- if ((xip->inp_fport == 0 && !opt_l) ||
- (xip->inp_fport != 0 && !opt_c))
- continue;
-#define __IN_IS_ADDR_LOOPBACK(pina) \
- ((ntohl((pina)->s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
- if (opt_L &&
- (__IN_IS_ADDR_LOOPBACK(&xip->inp_faddr) ||
- __IN_IS_ADDR_LOOPBACK(&xip->inp_laddr)))
- continue;
-#undef __IN_IS_ADDR_LOOPBACK
- } else if (xip->inp_vflag & INP_IPV6) {
- if ((xip->inp_fport == 0 && !opt_l) ||
- (xip->inp_fport != 0 && !opt_c))
- continue;
- if (opt_L &&
- (IN6_IS_ADDR_LOOPBACK(&xip->in6p_faddr) ||
- IN6_IS_ADDR_LOOPBACK(&xip->in6p_laddr)))
- continue;
- } else {
- if (opt_v)
- xo_warnx("invalid vflag 0x%x", xip->inp_vflag);
- continue;
- }
- if ((sock = calloc(1, sizeof(*sock))) == NULL)
- xo_err(1, "malloc()");
- if ((laddr = calloc(1, sizeof *laddr)) == NULL)
- xo_err(1, "malloc()");
- if ((faddr = calloc(1, sizeof *faddr)) == NULL)
- xo_err(1, "malloc()");
- sock->socket = so->xso_so;
- sock->pcb = so->so_pcb;
- sock->splice_socket = so->so_splice_so;
- sock->proto = proto;
- sock->inp_gencnt = xip->inp_gencnt;
- sock->fibnum = so->so_fibnum;
- if (xip->inp_vflag & INP_IPV4) {
- sock->family = AF_INET;
- sockaddr(&laddr->address, sock->family,
- &xip->inp_laddr, xip->inp_lport);
- sockaddr(&faddr->address, sock->family,
- &xip->inp_faddr, xip->inp_fport);
- } else if (xip->inp_vflag & INP_IPV6) {
- sock->family = AF_INET6;
- sockaddr(&laddr->address, sock->family,
- &xip->in6p_laddr, xip->inp_lport);
- sockaddr(&faddr->address, sock->family,
- &xip->in6p_faddr, xip->inp_fport);
- }
- if (proto == IPPROTO_TCP)
- faddr->encaps_port = xtp->xt_encaps_port;
- laddr->next = NULL;
- faddr->next = NULL;
- sock->laddr = laddr;
- sock->faddr = faddr;
- sock->vflag = xip->inp_vflag;
- if (proto == IPPROTO_TCP) {
- sock->state = xtp->t_state;
- memcpy(sock->stack, xtp->xt_stack,
- TCP_FUNCTION_NAME_LEN_MAX);
- memcpy(sock->cc, xtp->xt_cc, TCP_CA_NAME_MAX);
- }
- sock->protoname = protoname;
- if (sock->socket != 0)
- RB_INSERT(socks_t, &socks, sock);
- else
- SLIST_INSERT_HEAD(&nosocks, sock, socket_list);
- }
-out:
- free(buf);
-}
-
-static void
-gather_unix(int proto)
-{
- struct xunpgen *xug, *exug;
- struct xunpcb *xup;
- struct sock *sock;
- struct addr *laddr, *faddr;
- const char *varname, *protoname;
- size_t len, bufsize;
- void *buf;
- int retry;
-
- switch (proto) {
- case SOCK_STREAM:
- varname = "net.local.stream.pcblist";
- protoname = "stream";
- break;
- case SOCK_DGRAM:
- varname = "net.local.dgram.pcblist";
- protoname = "dgram";
- break;
- case SOCK_SEQPACKET:
- varname = "net.local.seqpacket.pcblist";
- protoname = (xo_get_style(NULL) == XO_STYLE_TEXT)
- ? "seqpac"
- : "seqpacket";
- break;
- default:
- abort();
- }
- buf = NULL;
- bufsize = 8192;
- retry = 5;
- do {
- for (;;) {
- if ((buf = realloc(buf, bufsize)) == NULL)
- xo_err(1, "realloc()");
- len = bufsize;
- if (cap_sysctlbyname(capsysctl, varname, buf, &len,
- NULL, 0) == 0)
- break;
- if (errno != ENOMEM || len != bufsize)
- xo_err(1, "cap_sysctlbyname()");
- bufsize *= 2;
- }
- xug = (struct xunpgen *)buf;
- exug = (struct xunpgen *)(void *)
- ((char *)buf + len - sizeof(*exug));
- if (!check_ksize(xug->xug_len, struct xunpgen) ||
- !check_ksize(exug->xug_len, struct xunpgen))
- goto out;
- } while (xug->xug_gen != exug->xug_gen && retry--);
-
- if (xug->xug_gen != exug->xug_gen && opt_v)
- xo_warnx("warning: data may be inconsistent");
-
- for (;;) {
- xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
- if (xug >= exug)
- break;
- xup = (struct xunpcb *)xug;
- if (!check_ksize(xup->xu_len, struct xunpcb))
- goto out;
- if ((xup->unp_conn == 0 && !opt_l) ||
- (xup->unp_conn != 0 && !opt_c))
- continue;
- if ((sock = calloc(1, sizeof(*sock))) == NULL)
- xo_err(1, "malloc()");
- if ((laddr = calloc(1, sizeof *laddr)) == NULL)
- xo_err(1, "malloc()");
- if ((faddr = calloc(1, sizeof *faddr)) == NULL)
- xo_err(1, "malloc()");
- sock->socket = xup->xu_socket.xso_so;
- sock->pcb = xup->xu_unpp;
- sock->proto = proto;
- sock->family = AF_UNIX;
- sock->protoname = protoname;
- if (xup->xu_addr.sun_family == AF_UNIX)
- laddr->address =
- *(struct sockaddr_storage *)(void *)&xup->xu_addr;
- faddr->conn = xup->unp_conn;
- faddr->firstref = xup->xu_firstref;
- faddr->nextref = xup->xu_nextref;
- laddr->next = NULL;
- faddr->next = NULL;
- sock->laddr = laddr;
- sock->faddr = faddr;
- RB_INSERT(socks_t, &socks, sock);
- RB_INSERT(pcbs_t, &pcbs, sock);
- }
-out:
- free(buf);
-}
-
-static void
-getfiles(void)
-{
- struct xfile *xfiles;
- size_t len, olen;
-
- olen = len = sizeof(*xfiles);
- if ((xfiles = malloc(len)) == NULL)
- xo_err(1, "malloc()");
- while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0)
- == -1) {
- if (errno != ENOMEM || len != olen)
- xo_err(1, "cap_sysctlbyname()");
- olen = len *= 2;
- if ((xfiles = realloc(xfiles, len)) == NULL)
- xo_err(1, "realloc()");
- }
- if (len > 0)
- enforce_ksize(xfiles->xf_size, struct xfile);
- nfiles = len / sizeof(*xfiles);
-
- if ((files = malloc(nfiles * sizeof(struct file))) == NULL)
- xo_err(1, "malloc()");
-
- for (int i = 0; i < nfiles; i++) {
- files[i].xf_data = xfiles[i].xf_data;
- files[i].xf_pid = xfiles[i].xf_pid;
- files[i].xf_uid = xfiles[i].xf_uid;
- files[i].xf_fd = xfiles[i].xf_fd;
- RB_INSERT(files_t, &ftree, &files[i]);
- }
-
- free(xfiles);
-}
-
-static int
-formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
-{
- struct sockaddr_un *sun;
- char addrstr[NI_MAXHOST] = { '\0', '\0' };
- int error, off, port = 0;
- const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT);
-
- switch (ss->ss_family) {
- case AF_INET:
- if (sstosin(ss)->sin_addr.s_addr == INADDR_ANY)
- addrstr[0] = '*';
- port = ntohs(sstosin(ss)->sin_port);
- break;
- case AF_INET6:
- if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
- addrstr[0] = '*';
- port = ntohs(sstosin6(ss)->sin6_port);
- break;
- case AF_UNIX:
- sun = sstosun(ss);
- off = (int)((char *)&sun->sun_path - (char *)sun);
- if (!is_text_style) {
- xo_emit("{:path/%.*s}", sun->sun_len - off,
- sun->sun_path);
- return 0;
- }
- return snprintf(buf, bufsize, "%.*s",
- sun->sun_len - off, sun->sun_path);
- }
- if (addrstr[0] == '\0') {
- error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
- addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
- if (error)
- xo_errx(1, "cap_getnameinfo()");
- }
- if (!is_text_style) {
- xo_emit("{:address/%s}", addrstr);
- xo_emit("{:port/%d}", port);
- return 0;
- }
- if (port == 0)
- return snprintf(buf, bufsize, "%s:*", addrstr);
- return snprintf(buf, bufsize, "%s:%d", addrstr, port);
-}
-
-static const char *
-getprocname(pid_t pid)
-{
- static struct kinfo_proc proc;
- size_t len;
- int mib[4];
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = (int)pid;
- len = sizeof(proc);
- if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
- == -1) {
- /* Do not warn if the process exits before we get its name. */
- if (errno != ESRCH)
- xo_warn("cap_sysctl()");
- return ("??");
- }
- return (proc.ki_comm);
-}
-
-static int
-getprocjid(pid_t pid)
-{
- static struct kinfo_proc proc;
- size_t len;
- int mib[4];
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = (int)pid;
- len = sizeof(proc);
- if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0)
- == -1) {
- /* Do not warn if the process exits before we get its jid. */
- if (errno != ESRCH)
- xo_warn("cap_sysctl()");
- return (-1);
- }
- return (proc.ki_jid);
-}
-
-static int
-check_ports(struct sock *s)
-{
- int port;
- struct addr *addr;
-
- if (ports == NULL)
- return (1);
- if ((s->family != AF_INET) && (s->family != AF_INET6))
- return (1);
- for (addr = s->laddr; addr != NULL; addr = addr->next) {
- if (s->family == AF_INET)
- port = ntohs(sstosin(&addr->address)->sin_port);
- else
- port = ntohs(sstosin6(&addr->address)->sin6_port);
- if (CHK_PORT(port))
- return (1);
- }
- for (addr = s->faddr; addr != NULL; addr = addr->next) {
- if (s->family == AF_INET)
- port = ntohs(sstosin(&addr->address)->sin_port);
- else
- port = ntohs(sstosin6(&addr->address)->sin6_port);
- if (CHK_PORT(port))
- return (1);
}
return (0);
}
-
-static const char *
-sctp_conn_state(int state)
-{
- switch (state) {
- case SCTP_CLOSED:
- return "CLOSED";
- break;
- case SCTP_BOUND:
- return "BOUND";
- break;
- case SCTP_LISTEN:
- return "LISTEN";
- break;
- case SCTP_COOKIE_WAIT:
- return "COOKIE_WAIT";
- break;
- case SCTP_COOKIE_ECHOED:
- return "COOKIE_ECHOED";
- break;
- case SCTP_ESTABLISHED:
- return "ESTABLISHED";
- break;
- case SCTP_SHUTDOWN_SENT:
- return "SHUTDOWN_SENT";
- break;
- case SCTP_SHUTDOWN_RECEIVED:
- return "SHUTDOWN_RECEIVED";
- break;
- case SCTP_SHUTDOWN_ACK_SENT:
- return "SHUTDOWN_ACK_SENT";
- break;
- case SCTP_SHUTDOWN_PENDING:
- return "SHUTDOWN_PENDING";
- break;
- default:
- return "UNKNOWN";
- break;
- }
-}
-
-static const char *
-sctp_path_state(int state)
-{
- switch (state) {
- case SCTP_UNCONFIRMED:
- return "UNCONFIRMED";
- break;
- case SCTP_ACTIVE:
- return "ACTIVE";
- break;
- case SCTP_INACTIVE:
- return "INACTIVE";
- break;
- default:
- return "UNKNOWN";
- break;
- }
-}
-
-static int
-format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) {
- #define SAFEBUF (buf == NULL ? NULL : buf + pos)
- #define SAFESIZE (buf == NULL ? 0 : bufsize - pos)
-
- size_t pos = 0;
- const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT);
- if (faddr->conn != 0) {
- /* Remote peer we connect(2) to, if any. */
- struct sock *p;
- if (is_text_style)
- pos += strlcpy(SAFEBUF, "-> ", SAFESIZE);
- p = RB_FIND(pcbs_t, &pcbs,
- &(struct sock){ .pcb = faddr->conn });
- if (__predict_false(p == NULL) && is_text_style) {
- /* XXGL: can this happen at all? */
- pos += snprintf(SAFEBUF, SAFESIZE, "??");
- } else if (p->laddr->address.ss_len == 0) {
- struct file *f;
- f = RB_FIND(files_t, &ftree,
- &(struct file){ .xf_data =
- p->socket });
- if (f != NULL) {
- if (is_text_style) {
- pos += snprintf(SAFEBUF, SAFESIZE,
- "[%lu %d]", (u_long)f->xf_pid,
- f->xf_fd);
- } else {
- xo_open_list("connections");
- xo_open_instance("connections");
- xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
- xo_emit("{:fd/%d}", f->xf_fd);
- xo_close_instance("connections");
- xo_close_list("connections");
- }
- }
- } else
- pos += formataddr(&p->laddr->address,
- SAFEBUF, SAFESIZE);
- } else if (faddr->firstref != 0) {
- /* Remote peer(s) connect(2)ed to us, if any. */
- struct sock *p;
- struct file *f;
- kvaddr_t ref = faddr->firstref;
- bool fref = true;
-
- if (is_text_style)
- pos += snprintf(SAFEBUF, SAFESIZE, " <- ");
- xo_open_list("connections");
- while ((p = RB_FIND(pcbs_t, &pcbs,
- &(struct sock){ .pcb = ref })) != 0) {
- f = RB_FIND(files_t, &ftree,
- &(struct file){ .xf_data = p->socket });
- if (f != NULL) {
- if (is_text_style) {
- pos += snprintf(SAFEBUF, SAFESIZE,
- "%s[%lu %d]", fref ? "" : ",",
- (u_long)f->xf_pid, f->xf_fd);
- } else {
- xo_open_instance("connections");
- xo_emit("{:pid/%lu}", (u_long)f->xf_pid);
- xo_emit("{:fd/%d}", f->xf_fd);
- xo_close_instance("connections");
- }
- }
- ref = p->faddr->nextref;
- fref = false;
- }
- xo_close_list("connections");
- }
- return pos;
-}
-
-struct col_widths {
- int user;
- int command;
- int pid;
- int fd;
- int proto;
- int local_addr;
- int foreign_addr;
- int pcb_kva;
- int fib;
- int splice_address;
- int inp_gencnt;
- int encaps;
- int path_state;
- int conn_state;
- int stack;
- int cc;
-};
-
-static void
-calculate_sock_column_widths(struct col_widths *cw, struct sock *s)
-{
- struct addr *laddr, *faddr;
- bool first = true;
- int len = 0;
- laddr = s->laddr;
- faddr = s->faddr;
- first = true;
-
- len = strlen(s->protoname);
- if (s->vflag & (INP_IPV4 | INP_IPV6))
- len += 1;
- cw->proto = MAX(cw->proto, len);
-
- while (laddr != NULL || faddr != NULL) {
- if (opt_w && s->family == AF_UNIX) {
- if ((laddr == NULL) || (faddr == NULL))
- xo_errx(1, "laddr = %p or faddr = %p is NULL",
- (void *)laddr, (void *)faddr);
- if (laddr->address.ss_len > 0)
- len = formataddr(&laddr->address, NULL, 0);
- cw->local_addr = MAX(cw->local_addr, len);
- len = format_unix_faddr(faddr, NULL, 0);
- cw->foreign_addr = MAX(cw->foreign_addr, len);
- } else if (opt_w) {
- if (laddr != NULL) {
- len = formataddr(&laddr->address, NULL, 0);
- cw->local_addr = MAX(cw->local_addr, len);
- }
- if (faddr != NULL) {
- len = formataddr(&faddr->address, NULL, 0);
- cw->foreign_addr = MAX(cw->foreign_addr, len);
- }
- }
- if (opt_f) {
- len = snprintf(NULL, 0, "%d", s->fibnum);
- cw->fib = MAX(cw->fib, len);
- }
- if (opt_I) {
- if (s->splice_socket != 0) {
- struct sock *sp;
-
- sp = RB_FIND(socks_t, &socks, &(struct sock)
- { .socket = s->splice_socket });
- if (sp != NULL) {
- len = formataddr(&sp->laddr->address,
- NULL, 0);
- cw->splice_address = MAX(
- cw->splice_address, len);
- }
- }
- }
- if (opt_i) {
- if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
- {
- len = snprintf(NULL, 0,
- "%" PRIu64, s->inp_gencnt);
- cw->inp_gencnt = MAX(cw->inp_gencnt, len);
- }
- }
- if (opt_U) {
- if (faddr != NULL &&
- ((s->proto == IPPROTO_SCTP &&
- s->state != SCTP_CLOSED &&
- s->state != SCTP_BOUND &&
- s->state != SCTP_LISTEN) ||
- (s->proto == IPPROTO_TCP &&
- s->state != TCPS_CLOSED &&
- s->state != TCPS_LISTEN))) {
- len = snprintf(NULL, 0, "%u",
- ntohs(faddr->encaps_port));
- cw->encaps = MAX(cw->encaps, len);
- }
- }
- if (opt_s) {
- if (faddr != NULL &&
- s->proto == IPPROTO_SCTP &&
- s->state != SCTP_CLOSED &&
- s->state != SCTP_BOUND &&
- s->state != SCTP_LISTEN) {
- len = strlen(sctp_path_state(faddr->state));
- cw->path_state = MAX(cw->path_state, len);
- }
- }
- if (first) {
- if (opt_s) {
- if (s->proto == IPPROTO_SCTP ||
- s->proto == IPPROTO_TCP) {
- switch (s->proto) {
- case IPPROTO_SCTP:
- len = strlen(
- sctp_conn_state(s->state));
- cw->conn_state = MAX(
- cw->conn_state, len);
- break;
- case IPPROTO_TCP:
- if (s->state >= 0 &&
- s->state < TCP_NSTATES) {
- len = strlen(
- tcpstates[s->state]);
- cw->conn_state = MAX(
- cw->conn_state, len);
- }
- break;
- }
- }
- }
- if (opt_S && s->proto == IPPROTO_TCP) {
- len = strlen(s->stack);
- cw->stack = MAX(cw->stack, len);
- }
- if (opt_C && s->proto == IPPROTO_TCP) {
- len = strlen(s->cc);
- cw->cc = MAX(cw->cc, len);
- }
- }
- if (laddr != NULL)
- laddr = laddr->next;
- if (faddr != NULL)
- faddr = faddr->next;
- first = false;
- }
-}
-
-static void
-calculate_column_widths(struct col_widths *cw)
-{
- int n, len;
- struct file *xf;
- struct sock *s;
- struct passwd *pwd;
-
- cap_setpassent(cappwd, 1);
- for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
- if (xf->xf_data == 0)
- continue;
- if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
- continue;
- s = RB_FIND(socks_t, &socks,
- &(struct sock){ .socket = xf->xf_data});
- if (s == NULL || (!check_ports(s)))
- continue;
- s->shown = 1;
- if (opt_n ||
- (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
- len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_uid);
- else
- len = snprintf(NULL, 0, "%s", pwd->pw_name);
- cw->user = MAX(cw->user, len);
- len = snprintf(NULL, 0, "%lu", (u_long)xf->xf_pid);
- cw->pid = MAX(cw->pid, len);
- len = snprintf(NULL, 0, "%d", xf->xf_fd);
- cw->fd = MAX(cw->fd, len);
-
- calculate_sock_column_widths(cw, s);
- }
- if (opt_j >= 0)
- return;
- SLIST_FOREACH(s, &nosocks, socket_list) {
- if (!check_ports(s))
- continue;
- calculate_sock_column_widths(cw, s);
- }
- RB_FOREACH(s, socks_t, &socks) {
- if (s->shown)
- continue;
- if (!check_ports(s))
- continue;
- calculate_sock_column_widths(cw, s);
- }
-}
-
-static void
-display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize)
-{
- struct addr *laddr, *faddr;
- bool first;
- laddr = s->laddr;
- faddr = s->faddr;
- first = true;
- const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT);
-
- snprintf(buf, bufsize, "%s%s%s",
- s->protoname,
- s->vflag & INP_IPV4 ? "4" : "",
- s->vflag & INP_IPV6 ? "6" : "");
- xo_emit(" {:proto/%-*s}", cw->proto, buf);
- while (laddr != NULL || faddr != NULL) {
- if (s->family == AF_UNIX) {
- if ((laddr == NULL) || (faddr == NULL))
- xo_errx(1, "laddr = %p or faddr = %p is NULL",
- (void *)laddr, (void *)faddr);
- if (laddr->address.ss_len > 0) {
- xo_open_container("local");
- formataddr(&laddr->address, buf, bufsize);
- if (is_text_style) {
- xo_emit(" {:/%-*.*s}", cw->local_addr,
- cw->local_addr, buf);
- }
- xo_close_container("local");
- } else if (laddr->address.ss_len == 0 &&
- faddr->conn == 0 && is_text_style) {
- xo_emit(" {:/%-*.*s}", cw->local_addr,
- cw->local_addr, "(not connected)");
- } else if (is_text_style) {
- xo_emit(" {:/%-*.*s}", cw->local_addr,
- cw->local_addr, "??");
- }
- if (faddr->conn != 0 || faddr->firstref != 0) {
- xo_open_container("foreign");
- int len = format_unix_faddr(faddr, buf,
- bufsize);
- if (len == 0 && is_text_style)
- xo_emit(" {:/%-*s}",
- cw->foreign_addr, "??");
- else if (is_text_style)
- xo_emit(" {:/%-*.*s}", cw->foreign_addr,
- cw->foreign_addr, buf);
- xo_close_container("foreign");
- } else if (is_text_style)
- xo_emit(" {:/%-*s}", cw->foreign_addr, "??");
- } else {
- if (laddr != NULL) {
- xo_open_container("local");
- formataddr(&laddr->address, buf, bufsize);
- if (is_text_style) {
- xo_emit(" {:/%-*.*s}", cw->local_addr,
- cw->local_addr, buf);
- }
- xo_close_container("local");
- } else if (is_text_style)
- xo_emit(" {:/%-*.*s}", cw->local_addr,
- cw->local_addr, "??");
- if (faddr != NULL) {
- xo_open_container("foreign");
- formataddr(&faddr->address, buf, bufsize);
- if (is_text_style) {
- xo_emit(" {:/%-*.*s}", cw->foreign_addr,
- cw->foreign_addr, buf);
- }
- xo_close_container("foreign");
- } else if (is_text_style) {
- xo_emit(" {:/%-*.*s}", cw->foreign_addr,
- cw->foreign_addr, "??");
- }
- }
- if (opt_A) {
- snprintf(buf, bufsize, "%#*" PRIx64,
- cw->pcb_kva, s->pcb);
- xo_emit(" {:pcb-kva/%s}", buf);
- }
- if (opt_f)
- xo_emit(" {:fib/%*d}", cw->fib, s->fibnum);
- if (opt_I) {
- if (s->splice_socket != 0) {
- struct sock *sp;
- sp = RB_FIND(socks_t, &socks, &(struct sock)
- { .socket = s->splice_socket });
- if (sp != NULL) {
- xo_open_container("splice");
- formataddr(&sp->laddr->address,
- buf, bufsize);
- xo_close_container("splice");
- } else if (is_text_style)
- strlcpy(buf, "??", bufsize);
- } else if (is_text_style)
- strlcpy(buf, "??", bufsize);
- if (is_text_style)
- xo_emit(" {:/%-*s}", cw->splice_address, buf);
- }
- if (opt_i) {
- if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP)
- {
- snprintf(buf, bufsize, "%" PRIu64,
- s->inp_gencnt);
- xo_emit(" {:id/%*s}", cw->inp_gencnt, buf);
- } else if (is_text_style)
- xo_emit(" {:/%*s}", cw->inp_gencnt, "??");
- }
- if (opt_U) {
- if (faddr != NULL &&
- ((s->proto == IPPROTO_SCTP &&
- s->state != SCTP_CLOSED &&
- s->state != SCTP_BOUND &&
- s->state != SCTP_LISTEN) ||
- (s->proto == IPPROTO_TCP &&
- s->state != TCPS_CLOSED &&
- s->state != TCPS_LISTEN))) {
- xo_emit(" {:encaps/%*u}", cw->encaps,
- ntohs(faddr->encaps_port));
- } else if (is_text_style)
- xo_emit(" {:/%*s}", cw->encaps, "??");
- }
- if (opt_s) {
- if (faddr != NULL &&
- s->proto == IPPROTO_SCTP &&
- s->state != SCTP_CLOSED &&
- s->state != SCTP_BOUND &&
- s->state != SCTP_LISTEN) {
- xo_emit(" {:path-state/%-*s}", cw->path_state,
- sctp_path_state(faddr->state));
- } else if (is_text_style)
- xo_emit(" {:/%-*s}", cw->path_state, "??");
- }
- if (first) {
- if (opt_s) {
- if (s->proto == IPPROTO_SCTP ||
- s->proto == IPPROTO_TCP) {
- switch (s->proto) {
- case IPPROTO_SCTP:
- xo_emit(" {:conn-state/%-*s}",
- cw->conn_state,
- sctp_conn_state(s->state));
- break;
- case IPPROTO_TCP:
- if (s->state >= 0 &&
- s->state < TCP_NSTATES)
- xo_emit(" {:conn-state/%-*s}",
- cw->conn_state,
- tcpstates[s->state]);
- else if (is_text_style)
- xo_emit(" {:/%-*s}",
- cw->conn_state, "??");
- break;
- }
- } else if (is_text_style)
- xo_emit(" {:/%-*s}",
- cw->conn_state, "??");
- }
- if (opt_S) {
- if (s->proto == IPPROTO_TCP)
- xo_emit(" {:stack/%-*s}",
- cw->stack, s->stack);
- else if (is_text_style)
- xo_emit(" {:/%-*s}",
- cw->stack, "??");
- }
- if (opt_C) {
- if (s->proto == IPPROTO_TCP)
- xo_emit(" {:cc/%-*s}", cw->cc, s->cc);
- else if (is_text_style)
- xo_emit(" {:/%-*s}", cw->cc, "??");
- }
- }
- if (laddr != NULL)
- laddr = laddr->next;
- if (faddr != NULL)
- faddr = faddr->next;
- if (is_text_style && (laddr != NULL || faddr != NULL))
- xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}",
- cw->user, "??", cw->command, "??",
- cw->pid, "??", cw->fd, "??");
- first = false;
- }
- xo_emit("\n");
-}
-
-static void
-display(void)
-{
- struct passwd *pwd;
- struct file *xf;
- struct sock *s;
- int n;
- struct col_widths cw;
- const size_t bufsize = 512;
- void *buf;
- if ((buf = (char *)malloc(bufsize)) == NULL) {
- xo_err(1, "malloc()");
- return;
- }
-
- if (xo_get_style(NULL) == XO_STYLE_TEXT) {
- cw = (struct col_widths) {
- .user = strlen("USER"),
- .command = 10,
- .pid = strlen("PID"),
- .fd = strlen("FD"),
- .proto = strlen("PROTO"),
- .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21,
- .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21,
- .pcb_kva = 18,
- .fib = strlen("FIB"),
- .splice_address = strlen("SPLICE ADDRESS"),
- .inp_gencnt = strlen("ID"),
- .encaps = strlen("ENCAPS"),
- .path_state = strlen("PATH STATE"),
- .conn_state = strlen("CONN STATE"),
- .stack = strlen("STACK"),
- .cc = strlen("CC"),
- };
- calculate_column_widths(&cw);
- } else
- memset(&cw, 0, sizeof(cw));
-
- xo_set_version(SOCKSTAT_XO_VERSION);
- xo_open_container("sockstat");
- xo_open_list("socket");
- if (!opt_q) {
- xo_emit("{T:/%-*s} {T:/%-*s} {T:/%*s} {T:/%*s} {T:/%-*s} "
- "{T:/%-*s} {T:/%-*s}", cw.user, "USER", cw.command,
- "COMMAND", cw.pid, "PID", cw.fd, "FD", cw.proto,
- "PROTO", cw.local_addr, "LOCAL ADDRESS",
- cw.foreign_addr, "FOREIGN ADDRESS");
- if (opt_A)
- xo_emit(" {T:/%-*s}", cw.pcb_kva, "PCB KVA");
- if (opt_f)
- /* RT_MAXFIBS is 65535. */
- xo_emit(" {T:/%*s}", cw.fib, "FIB");
- if (opt_I)
- xo_emit(" {T:/%-*s}", cw.splice_address,
- "SPLICE ADDRESS");
- if (opt_i)
- xo_emit(" {T:/%*s}", cw.inp_gencnt, "ID");
- if (opt_U)
- xo_emit(" {T:/%*s}", cw.encaps, "ENCAPS");
- if (opt_s) {
- xo_emit(" {T:/%-*s}", cw.path_state, "PATH STATE");
- xo_emit(" {T:/%-*s}", cw.conn_state, "CONN STATE");
- }
- if (opt_S)
- xo_emit(" {T:/%-*s}", cw.stack, "STACK");
- if (opt_C)
- xo_emit(" {T:/%-*s}", cw.cc, "CC");
- xo_emit("\n");
- }
- cap_setpassent(cappwd, 1);
- for (xf = files, n = 0; n < nfiles; ++n, ++xf) {
- if (xf->xf_data == 0)
- continue;
- if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
- continue;
- s = RB_FIND(socks_t, &socks,
- &(struct sock){ .socket = xf->xf_data});
- if (s != NULL && check_ports(s)) {
- xo_open_instance("socket");
- s->shown = 1;
- if (opt_n ||
- (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL)
- xo_emit("{:user/%-*lu}", cw.user,
- (u_long)xf->xf_uid);
- else
- xo_emit("{:user/%-*s}", cw.user, pwd->pw_name);
- if (xo_get_style(NULL) == XO_STYLE_TEXT)
- xo_emit(" {:/%-*.10s}", cw.command,
- getprocname(xf->xf_pid));
- else
- xo_emit(" {:command/%-*s}", cw.command,
- getprocname(xf->xf_pid));
- xo_emit(" {:pid/%*lu}", cw.pid, (u_long)xf->xf_pid);
- xo_emit(" {:fd/%*d}", cw.fd, xf->xf_fd);
- display_sock(s, &cw, buf, bufsize);
- xo_close_instance("socket");
- }
- }
- if (opt_j >= 0)
- return;
- SLIST_FOREACH(s, &nosocks, socket_list) {
- if (!check_ports(s))
- continue;
- xo_open_instance("socket");
- if (xo_get_style(NULL) == XO_STYLE_TEXT)
- xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}",
- cw.user, "??", cw.command, "??",
- cw.pid, "??", cw.fd, "??");
- display_sock(s, &cw, buf, bufsize);
- xo_close_instance("socket");
- }
- RB_FOREACH(s, socks_t, &socks) {
- if (s->shown)
- continue;
- if (!check_ports(s))
- continue;
- xo_open_instance("socket");
- if (xo_get_style(NULL) == XO_STYLE_TEXT)
- xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}",
- cw.user, "??", cw.command, "??",
- cw.pid, "??", cw.fd, "??");
- display_sock(s, &cw, buf, bufsize);
- xo_close_instance("socket");
- }
- xo_close_list("socket");
- xo_close_container("sockstat");
- if (xo_finish() < 0)
- xo_err(1, "stdout");
- free(buf);
- cap_endpwent(cappwd);
-}
-
-static int
-set_default_protos(void)
-{
- struct protoent *prot;
- const char *pname;
- size_t pindex;
-
- init_protos(default_numprotos);
-
- for (pindex = 0; pindex < default_numprotos; pindex++) {
- pname = default_protos[pindex];
- prot = cap_getprotobyname(capnetdb, pname);
- if (prot == NULL)
- xo_err(1, "cap_getprotobyname: %s", pname);
- protos[pindex] = prot->p_proto;
- }
- numprotos = pindex;
- return (pindex);
-}
-
-/*
- * Return the vnet property of the jail, or -1 on error.
- */
-static int
-jail_getvnet(int jid)
-{
- struct iovec jiov[6];
- int vnet;
- size_t len = sizeof(vnet);
-
- if (sysctlbyname("kern.features.vimage", &vnet, &len, NULL, 0) != 0)
- return (0);
-
- vnet = -1;
- jiov[0].iov_base = __DECONST(char *, "jid");
- jiov[0].iov_len = sizeof("jid");
- jiov[1].iov_base = &jid;
- jiov[1].iov_len = sizeof(jid);
- jiov[2].iov_base = __DECONST(char *, "vnet");
- jiov[2].iov_len = sizeof("vnet");
- jiov[3].iov_base = &vnet;
- jiov[3].iov_len = sizeof(vnet);
- jiov[4].iov_base = __DECONST(char *, "errmsg");
- jiov[4].iov_len = sizeof("errmsg");
- jiov[5].iov_base = jail_errmsg;
- jiov[5].iov_len = JAIL_ERRMSGLEN;
- jail_errmsg[0] = '\0';
- if (jail_get(jiov, nitems(jiov), 0) < 0) {
- if (!jail_errmsg[0])
- snprintf(jail_errmsg, JAIL_ERRMSGLEN,
- "jail_get: %s", strerror(errno));
- return (-1);
- }
- return (vnet);
-}
-
-static void
-usage(void)
-{
- xo_error(
-"usage: sockstat [--libxo] [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports]\n"
-" [-P protocols]\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- cap_channel_t *capcas;
- cap_net_limit_t *limit;
- const char *pwdcmds[] = { "setpassent", "getpwuid" };
- const char *pwdfields[] = { "pw_name" };
- int protos_defined = -1;
- int o, i;
-
- argc = xo_parse_args(argc, argv);
- if (argc < 0)
- exit(1);
- opt_j = -1;
- while ((o = getopt(argc, argv, "46ACcfIij:Llnp:P:qSsUuvw")) != -1)
- switch (o) {
- case '4':
- opt_4 = true;
- break;
- case '6':
- opt_6 = true;
- break;
- case 'A':
- opt_A = true;
- break;
- case 'C':
- opt_C = true;
- break;
- case 'c':
- opt_c = true;
- break;
- case 'f':
- opt_f = true;
- break;
- case 'I':
- opt_I = true;
- break;
- case 'i':
- opt_i = true;
- break;
- case 'j':
- opt_j = jail_getid(optarg);
- if (opt_j < 0)
- xo_errx(1, "jail_getid: %s", jail_errmsg);
- break;
- case 'L':
- opt_L = true;
- break;
- case 'l':
- opt_l = true;
- break;
- case 'n':
- opt_n = true;
- break;
- case 'p':
- parse_ports(optarg);
- break;
- case 'P':
- protos_defined = parse_protos(optarg);
- break;
- case 'q':
- opt_q = true;
- break;
- case 'S':
- opt_S = true;
- break;
- case 's':
- opt_s = true;
- break;
- case 'U':
- opt_U = true;
- break;
- case 'u':
- opt_u = true;
- break;
- case 'v':
- ++opt_v;
- break;
- case 'w':
- opt_w = true;
- break;
- default:
- usage();
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc > 0)
- usage();
-
- if (opt_j > 0) {
- switch (jail_getvnet(opt_j)) {
- case -1:
- xo_errx(2, "jail_getvnet: %s", jail_errmsg);
- case JAIL_SYS_NEW:
- if (jail_attach(opt_j) < 0)
- xo_err(3, "jail_attach()");
- /* Set back to -1 for normal output in vnet jail. */
- opt_j = -1;
- break;
- default:
- break;
- }
- }
-
- capcas = cap_init();
- if (capcas == NULL)
- xo_err(1, "Unable to contact Casper");
- if (caph_enter_casper() < 0)
- xo_err(1, "Unable to enter capability mode");
- capnet = cap_service_open(capcas, "system.net");
- if (capnet == NULL)
- xo_err(1, "Unable to open system.net service");
- capnetdb = cap_service_open(capcas, "system.netdb");
- if (capnetdb == NULL)
- xo_err(1, "Unable to open system.netdb service");
- capsysctl = cap_service_open(capcas, "system.sysctl");
- if (capsysctl == NULL)
- xo_err(1, "Unable to open system.sysctl service");
- cappwd = cap_service_open(capcas, "system.pwd");
- if (cappwd == NULL)
- xo_err(1, "Unable to open system.pwd service");
- cap_close(capcas);
- limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME);
- if (limit == NULL)
- xo_err(1, "Unable to init cap_net limits");
- if (cap_net_limit(limit) < 0)
- xo_err(1, "Unable to apply limits");
- if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0)
- xo_err(1, "Unable to apply pwd commands limits");
- if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0)
- xo_err(1, "Unable to apply pwd commands limits");
-
- if ((!opt_4 && !opt_6) && protos_defined != -1)
- opt_4 = opt_6 = true;
- if (!opt_4 && !opt_6 && !opt_u)
- opt_4 = opt_6 = opt_u = true;
- if ((opt_4 || opt_6) && protos_defined == -1)
- protos_defined = set_default_protos();
- if (!opt_c && !opt_l)
- opt_c = opt_l = true;
-
- if (opt_4 || opt_6) {
- for (i = 0; i < protos_defined; i++)
- if (protos[i] == IPPROTO_SCTP)
- gather_sctp();
- else
- gather_inet(protos[i]);
- }
-
- if (opt_u || (protos_defined == -1 && !opt_4 && !opt_6)) {
- gather_unix(SOCK_STREAM);
- gather_unix(SOCK_DGRAM);
- gather_unix(SOCK_SEQPACKET);
- }
- getfiles();
- display();
- exit(0);
-}
diff --git a/usr.bin/sockstat/sockstat.h b/usr.bin/sockstat/sockstat.h
new file mode 100644
index 000000000000..80d91ebbaddc
--- /dev/null
+++ b/usr.bin/sockstat/sockstat.h
@@ -0,0 +1,35 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 ConnectWise
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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.
+ */
+
+#define INT_BIT (sizeof(int)*CHAR_BIT)
+#define SET_PORT(p) do { ports[p / INT_BIT] |= 1 << (p % INT_BIT); } while (0)
+#define CHK_PORT(p) (ports[p / INT_BIT] & (1 << (p % INT_BIT)))
+
+extern int *ports;
+
+int parse_ports(const char *portspec);
diff --git a/usr.bin/sockstat/tests/Makefile b/usr.bin/sockstat/tests/Makefile
new file mode 100644
index 000000000000..9971bca2d474
--- /dev/null
+++ b/usr.bin/sockstat/tests/Makefile
@@ -0,0 +1,8 @@
+ATF_TESTS_C+= sockstat_test
+SRCS.sockstat_test= sockstat_test.c ../sockstat.c
+
+LIBADD= xo
+
+PACKAGE= tests
+
+.include <bsd.test.mk>
diff --git a/usr.bin/sockstat/tests/sockstat_test.c b/usr.bin/sockstat/tests/sockstat_test.c
new file mode 100644
index 000000000000..2d2a23c7a166
--- /dev/null
+++ b/usr.bin/sockstat/tests/sockstat_test.c
@@ -0,0 +1,190 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 ConnectWise
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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.
+ */
+
+#include <sys/param.h>
+#include <sys/errno.h>
+
+#include <atf-c.h>
+
+#include "../sockstat.h"
+
+ATF_TC_WITHOUT_HEAD(backwards_range);
+ATF_TC_BODY(backwards_range, tc)
+{
+ const char portspec[] = "22-21";
+
+ ATF_CHECK_EQ(ERANGE, parse_ports(portspec));
+}
+
+ATF_TC_WITHOUT_HEAD(erange_low);
+ATF_TC_BODY(erange_low, tc)
+{
+ const char portspec[] = "-1";
+
+ ATF_CHECK_EQ(ERANGE, parse_ports(portspec));
+}
+
+ATF_TC_WITHOUT_HEAD(erange_high);
+ATF_TC_BODY(erange_high, tc)
+{
+ const char portspec[] = "65536";
+
+ ATF_CHECK_EQ(ERANGE, parse_ports(portspec));
+}
+
+ATF_TC_WITHOUT_HEAD(erange_on_range_end);
+ATF_TC_BODY(erange_on_range_end, tc)
+{
+ const char portspec[] = "22-65536";
+
+ ATF_CHECK_EQ(ERANGE, parse_ports(portspec));
+}
+
+ATF_TC_WITHOUT_HEAD(multiple);
+ATF_TC_BODY(multiple, tc)
+{
+ const char portspec[] = "80,443";
+
+ ATF_REQUIRE_EQ(0, parse_ports(portspec));
+
+ ATF_CHECK(!CHK_PORT(0));
+
+ ATF_CHECK(!CHK_PORT(79));
+ ATF_CHECK(CHK_PORT(80));
+ ATF_CHECK(!CHK_PORT(81));
+
+ ATF_CHECK(!CHK_PORT(442));
+ ATF_CHECK(CHK_PORT(443));
+ ATF_CHECK(!CHK_PORT(444));
+}
+
+ATF_TC_WITHOUT_HEAD(multiple_plus_ranges);
+ATF_TC_BODY(multiple_plus_ranges, tc)
+{
+ const char portspec[] = "80,443,500-501,510,520,40000-40002";
+
+ ATF_REQUIRE_EQ(0, parse_ports(portspec));
+
+ ATF_CHECK(!CHK_PORT(0));
+
+ ATF_CHECK(!CHK_PORT(79));
+ ATF_CHECK(CHK_PORT(80));
+ ATF_CHECK(!CHK_PORT(81));
+
+ ATF_CHECK(!CHK_PORT(442));
+ ATF_CHECK(CHK_PORT(443));
+ ATF_CHECK(!CHK_PORT(444));
+
+ ATF_CHECK(!CHK_PORT(499));
+ ATF_CHECK(CHK_PORT(500));
+ ATF_CHECK(CHK_PORT(501));
+ ATF_CHECK(!CHK_PORT(502));
+
+ ATF_CHECK(!CHK_PORT(519));
+ ATF_CHECK(CHK_PORT(520));
+ ATF_CHECK(!CHK_PORT(521));
+
+ ATF_CHECK(!CHK_PORT(39999));
+ ATF_CHECK(CHK_PORT(40000));
+ ATF_CHECK(CHK_PORT(40001));
+ ATF_CHECK(CHK_PORT(40002));
+ ATF_CHECK(!CHK_PORT(40003));
+}
+
+ATF_TC_WITHOUT_HEAD(nonnumeric);
+ATF_TC_BODY(nonnumeric, tc)
+{
+ const char portspec[] = "foo";
+
+ ATF_CHECK_EQ(EINVAL, parse_ports(portspec));
+}
+
+ATF_TC_WITHOUT_HEAD(null_range);
+ATF_TC_BODY(null_range, tc)
+{
+ const char portspec[] = "22-22";
+
+ ATF_REQUIRE_EQ(0, parse_ports(portspec));
+
+ ATF_CHECK(!CHK_PORT(0));
+ ATF_CHECK(CHK_PORT(22));
+ ATF_CHECK(!CHK_PORT(23));
+}
+
+ATF_TC_WITHOUT_HEAD(range);
+ATF_TC_BODY(range, tc)
+{
+ const char portspec[] = "22-25";
+
+ ATF_REQUIRE_EQ(0, parse_ports(portspec));
+
+ ATF_CHECK(!CHK_PORT(0));
+ ATF_CHECK(CHK_PORT(22));
+ ATF_CHECK(CHK_PORT(23));
+ ATF_CHECK(CHK_PORT(24));
+ ATF_CHECK(CHK_PORT(25));
+ ATF_CHECK(!CHK_PORT(26));
+}
+
+ATF_TC_WITHOUT_HEAD(single);
+ATF_TC_BODY(single, tc)
+{
+ const char portspec[] = "22";
+
+ ATF_REQUIRE_EQ(0, parse_ports(portspec));
+
+ ATF_CHECK(!CHK_PORT(0));
+ ATF_CHECK(CHK_PORT(22));
+}
+
+ATF_TC_WITHOUT_HEAD(zero);
+ATF_TC_BODY(zero, tc)
+{
+ const char portspec[] = "0";
+
+ ATF_REQUIRE_EQ(0, parse_ports(portspec));
+
+ ATF_CHECK(CHK_PORT(0));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, backwards_range);
+ ATF_TP_ADD_TC(tp, erange_low);
+ ATF_TP_ADD_TC(tp, erange_high);
+ ATF_TP_ADD_TC(tp, erange_on_range_end);
+ ATF_TP_ADD_TC(tp, multiple);
+ ATF_TP_ADD_TC(tp, multiple_plus_ranges);
+ ATF_TP_ADD_TC(tp, nonnumeric);
+ ATF_TP_ADD_TC(tp, null_range);
+ ATF_TP_ADD_TC(tp, range);
+ ATF_TP_ADD_TC(tp, single);
+ ATF_TP_ADD_TC(tp, zero);
+
+ return (atf_no_error());
+}
diff --git a/usr.bin/systat/ip.c b/usr.bin/systat/ip.c
index 6cb3787b3f91..344b74011e99 100644
--- a/usr.bin/systat/ip.c
+++ b/usr.bin/systat/ip.c
@@ -82,9 +82,10 @@ static struct stat curstat, initstat, oldstat;
13999999999 packets forwarded 999999999 - no checksum
14999999999 - unreachable dests 999999999 - invalid length
15999999999 - redirects generated 999999999 - no socket for dest port
-16999999999 option errors 999999999 - no socket for broadcast
-17999999999 unwanted multicasts 999999999 - socket buffer full
-18999999999 delivered to upper layer 999999999 total output packets
+16999999999 option errors 999999999 - no socket for broadcast
+17999999999 unwanted multicasts 999999999 - no socket for multicast
+18999999999 delivered to upper layer 999999999 - socket buffer full
+19999999999 999999999 total output packets
--0123456789012345678901234567890123456789012345678901234567890123456789012345
--0 1 2 3 4 5 6 7
*/
@@ -127,9 +128,10 @@ labelip(void)
L(13, "packets forwarded"); R(13, "- no checksum");
L(14, "- unreachable dests"); R(14, "- invalid length");
L(15, "- redirects generated"); R(15, "- no socket for dest port");
- L(16, "option errors"); R(16, "- no socket for broadcast");
- L(17, "unwanted multicasts"); R(17, "- socket buffer full");
- L(18, "delivered to upper layer"); R(18, "total output packets");
+ L(16, "option errors"); R(16, " - no socket for broadcast");
+ L(17, "unwanted multicasts"); R(17, " - no socket for multicast");
+ L(18, "delivered to upper layer"); R(18, "- socket buffer full");
+ R(19, "total output packets");
#undef L
#undef R
}
@@ -189,6 +191,7 @@ domode(struct stat *ret)
DO(u.udps_badlen);
DO(u.udps_noport);
DO(u.udps_noportbcast);
+ DO(u.udps_noportmcast);
DO(u.udps_fullsock);
DO(u.udps_opackets);
#undef DO
@@ -237,9 +240,10 @@ showip(void)
DO(i.ips_badoptions, 16, 0);
DO(u.udps_noportbcast, 16, 35);
DO(i.ips_notmember, 17, 0);
- DO(u.udps_fullsock, 17, 35);
+ DO(u.udps_noportmcast, 17, 35);
DO(i.ips_delivered, 18, 0);
- DO(u.udps_opackets, 18, 35);
+ DO(u.udps_fullsock, 18, 35);
+ DO(u.udps_opackets, 19, 35);
#undef DO
}
diff --git a/usr.bin/tcopy/Makefile b/usr.bin/tcopy/Makefile
index 73dcd45b2e0f..831de7625db8 100644
--- a/usr.bin/tcopy/Makefile
+++ b/usr.bin/tcopy/Makefile
@@ -1,4 +1,4 @@
-PROG= tcopy
-LIBADD= util
+PROG_CXX= tcopy
+LIBADD= util
.include <bsd.prog.mk>
diff --git a/usr.bin/tcopy/tcopy.1 b/usr.bin/tcopy/tcopy.1
index 3f12a807e41e..f74a29ba1173 100644
--- a/usr.bin/tcopy/tcopy.1
+++ b/usr.bin/tcopy/tcopy.1
@@ -30,65 +30,189 @@
.Os
.Sh NAME
.Nm tcopy
-.Nd copy and/or verify mag tapes
+.Nd read, write, copy and verify tapes
.Sh SYNOPSIS
.Nm
-.Op Fl cvx
+.Op Fl crvx
+.Op Fl l Ar logfile
.Op Fl s Ar maxblk
.Oo Ar src Op Ar dest
.Oc
.Sh DESCRIPTION
The
.Nm
-utility is designed to copy magnetic tapes.
+utility is designed to read, write and copy tapes.
+.Pp
The only assumption made
about the tape layout is that there are two sequential EOF marks
at the end.
-By default, the
-.Nm
-utility will print
-information about the sizes of records and files found
-on the
+.Pp
+The
+.Ar src
+argument can be a tape device and defaults to
.Pa /dev/sa0
-tape, or on the tape specified by the
+or it can be data in SIMH-TAP format.
+If
+.Ar src
+is
+.Dq Cm -
+the standard input is read.
+.Pp
+If the
+.Ar dest
+argument is also specified, a copy of the
.Ar src
-argument.
-If a destination tape is also specified by the
+will be made onto the
+.Ar dest .
+If
+.Ar dest
+is
+.Dq Cm -
+standard output will be written to.
+.Pp
+If
.Ar dest
-argument, a copy of the source tape will be made.
-The blocking on the
-destination tape will be identical to that used on the source tape.
-Copying
-a tape will yield the same program output as if just printing the sizes.
+is a tape device, the file and record structure will be the same.
+.Pp
+If
+.Ar dest
+is a filename ending in
+.Dq Cm .000
+the contents each file on
+.Ar src
+will be written to sequentially numbered files
+.Dq Cm .000 ,
+.Dq Cm .001 ,
+.Dq Cm .002
+etc.
+Information about record sizes will be lost.
+.Pp
+If the
+.Fl r
+flag is specified, only the data will be written, information about
+file and record layout is lost.
+.Pp
+Otherwise the data, file and record structure of
+.Ar src
+will be written in SIMH-TAP format.
+.Pp
+The
+.Nm
+utility will report information about the layout of
+.Ar src
+like this on standard output:
+.Bd -literal -offset indent
+file 0: block size 80: 6 records
+file 0: eof after 6 records: 480 bytes
+file 1: block size 3072: records 0 to 262
+file 1: block size 612: record 262
+file 1: eof after 263 records: 805476 bytes
+[…]
+eot
+total length: 972851280 bytes time: 41 s rate: 22934.8 kB/s
+.Ed
+.Pp
+If
+.Ar dest
+is
+.Dq Cm -
+or if
+.Fl x
+is specified this goes to standard error instead,
+and can also be redirected with
+.Fl l Ar logfile ,
+in which case the final total line will also be reported on standard error.
+.Pp
+If
+.Nm
+receives a
+.Dv SIGINFO
+signal, current counts are reported on standard error.
.Pp
The following options are available:
.Bl -tag -width ".Fl s Ar maxblk"
.It Fl c
-Copy
+Rewind both tapes, copy
.Ar src
to
-.Ar dest
-and then verify that the two tapes are identical.
+.Ar dest ,
+rewind again and verify that the two tapes are now identical.
+.It Fl l Ar logfile
+Output all informational messages to
+.Ar logfile .
+.It Fl r
+Write only the contents of all data blocks to the output.
+The file and record structure of the input will be lost.
.It Fl s Ar maxblk
Specify a maximum block size,
.Ar maxblk .
+The default is
+.Va kern.maxphys .
.It Fl v
-Given the two tapes
+Verify that
.Ar src
and
-.Ar dest ,
-verify that they are identical.
+.Ar dest
+are identical.
+Note that the tapes are not rewound prior to the comparison.
.It Fl x
Output all informational messages to the standard error
instead of the standard output.
-This option is useful when
+This option is automatic if
.Ar dest
is given as
-.Pa /dev/stdout .
+.Dq Cm - .
.El
+.Sh EXIT STATUS
+Unfortunately all over the place, but zero always means succeess.
+.Sh EXAMPLES
+Verify that the tape in /dev/sa0 can be read and see the layout
+of its content:
+.Bd -literal -offset indent
+tcopy
+.Ed
+.Pp
+Copy a tape using two tape drives:
+.Bd -literal -offset indent
+tcopy /dev/sa0 /dev/sa1
+.Ed
+.Pp
+Copy a tape using only a single tape drive, and verify the result:
+.Bd -literal -offset indent
+tcopy /dev/sa0 /tmp/temp.tapfile
+# change tape
+tcopy -c /tmp/temp.tapfile /dev/sa0
+.Ed
+.Pp
+Make a cryptographic hash of both the contents and the layout of the tape in
+/dev/sa1:
+.Pp
+.Bd -literal -offset indent
+tcopy /dev/sa1 - | sha256
+.Ed
+.Pp
+Copy a tape to a tape drive on another machine:
+.Bd -literal -offset indent
+tcopy /dev/sa0 - | ssh otherhost tcopy - /dev/sa0
+.Ed
+.Pp
+Extract the tape files into individual files:
+.Bd -literal -offset indent
+tcopy /dev/sa0 /tmp/_.tape.000
+.Ed
+.Pp
+Ignore all structure on the tape and feed all data to
+.Xr tar 1 :
+.Bd -literal -offset indent
+tcopy -l /dev/null -r /dev/sa0 - | tar tvf -
+.Ed
.Sh SEE ALSO
.Xr mt 1 ,
+.Xr sa 4 ,
.Xr mtio 4
+.Sh STANDARDS
+The SIMH-TAP format is documented in the open-simh github repos:
+.Pa https://github.com/open-simh/simh/blob/master/doc/simh_magtape.doc
.Sh HISTORY
The
.Nm
@@ -99,19 +223,16 @@ command appeared in
.It
Modern tape drives may return a SCSI "Incorrect Length Indicator (ILI)"
for each read with a different block size that what is on the
-tape, and that slows things down a lot.
+tape, and that slows
+.Nm
+down a lot.
This can be disabled with the
.Xr mt 1
command:
.Bd -literal -offset indent
-$ mt param sili -s 1
+mt param sili -s 1
.Ed
.It
-Writing an image of a tape to a file does not preserve much more than
-the raw data.
-Block size(s) and tape EOF marks are lost which would
-otherwise be preserved in a tape-to-tape copy.
-.It
End of data (EOD) is determined by two sequential EOF marks
with no data between them.
There used to be old systems which typically wrote three EOF's between tape
@@ -120,13 +241,7 @@ The
.Nm
utility will erroneously stop copying early in this case.
.It
-When using the copy/verify option
-.Fl c ,
-.Nm
-does not rewind the tapes prior to start.
-A rewind is performed
-after writing, prior to the verification stage.
-If one does not start
-at the beginning-of-tape (BOT) then the comparison
-may not be of the intended data.
+With
+.Fl c
+the tape drives are not rewound at the same time, but one after the other.
.El
diff --git a/usr.bin/tcopy/tcopy.c b/usr.bin/tcopy/tcopy.c
deleted file mode 100644
index 39eae4126324..000000000000
--- a/usr.bin/tcopy/tcopy.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1985, 1987, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * 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.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/mtio.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libutil.h>
-#include <paths.h>
-#include <sys/sysctl.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define MAXREC (64 * 1024)
-#define NOCOUNT (-2)
-
-static int filen, guesslen, maxblk = MAXREC;
-static uint64_t lastrec, record, size, tsize;
-static FILE *msg;
-
-static void *getspace(int);
-static void intr(int);
-static void usage(void) __dead2;
-static void verify(int, int, char *);
-static void writeop(int, int);
-static void rewind_tape(int);
-
-int
-main(int argc, char *argv[])
-{
- int lastnread, nread, nw, inp, outp;
- enum {READ, VERIFY, COPY, COPYVERIFY} op = READ;
- sig_t oldsig;
- int ch, needeof;
- char *buff;
- const char *inf;
- unsigned long maxphys = 0;
- size_t l_maxphys = sizeof maxphys;
- uint64_t tmp;
-
- if (!sysctlbyname("kern.maxphys", &maxphys, &l_maxphys, NULL, 0))
- maxblk = maxphys;
-
- msg = stdout;
- guesslen = 1;
- outp = -1;
- while ((ch = getopt(argc, argv, "cs:vx")) != -1)
- switch((char)ch) {
- case 'c':
- op = COPYVERIFY;
- break;
- case 's':
- if (expand_number(optarg, &tmp)) {
- warnx("illegal block size");
- usage();
- }
- maxblk = tmp;
- if (maxblk == 0) {
- warnx("illegal block size");
- usage();
- }
- guesslen = 0;
- break;
- case 'v':
- op = VERIFY;
- break;
- case 'x':
- msg = stderr;
- break;
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-
- switch(argc) {
- case 0:
- if (op != READ)
- usage();
- inf = _PATH_DEFTAPE;
- break;
- case 1:
- if (op != READ)
- usage();
- inf = argv[0];
- break;
- case 2:
- if (op == READ)
- op = COPY;
- inf = argv[0];
- if ((outp = open(argv[1], op == VERIFY ? O_RDONLY :
- op == COPY ? O_WRONLY : O_RDWR, DEFFILEMODE)) < 0)
- err(3, "%s", argv[1]);
- break;
- default:
- usage();
- }
-
- if ((inp = open(inf, O_RDONLY, 0)) < 0)
- err(1, "%s", inf);
-
- buff = getspace(maxblk);
-
- if (op == VERIFY) {
- verify(inp, outp, buff);
- exit(0);
- }
-
- if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
- (void) signal(SIGINT, intr);
-
- needeof = 0;
- for (lastnread = NOCOUNT;;) {
- if ((nread = read(inp, buff, maxblk)) == -1) {
- while (errno == EINVAL && (maxblk -= 1024)) {
- nread = read(inp, buff, maxblk);
- if (nread >= 0)
- goto r1;
- }
- err(1, "read error, file %d, record %ju", filen, (intmax_t)record);
- } else if (nread != lastnread) {
- if (lastnread != 0 && lastnread != NOCOUNT) {
- if (lastrec == 0 && nread == 0)
- fprintf(msg, "%ju records\n", (intmax_t)record);
- else if (record - lastrec > 1)
- fprintf(msg, "records %ju to %ju\n",
- (intmax_t)lastrec, (intmax_t)record);
- else
- fprintf(msg, "record %ju\n", (intmax_t)lastrec);
- }
- if (nread != 0)
- fprintf(msg, "file %d: block size %d: ",
- filen, nread);
- (void) fflush(stdout);
- lastrec = record;
- }
-r1: guesslen = 0;
- if (nread > 0) {
- if (op == COPY || op == COPYVERIFY) {
- if (needeof) {
- writeop(outp, MTWEOF);
- needeof = 0;
- }
- nw = write(outp, buff, nread);
- if (nw != nread) {
- if (nw == -1) {
- warn("write error, file %d, record %ju", filen,
- (intmax_t)record);
- } else {
- warnx("write error, file %d, record %ju", filen,
- (intmax_t)record);
- warnx("write (%d) != read (%d)", nw, nread);
- }
- errx(5, "copy aborted");
- }
- }
- size += nread;
- record++;
- } else {
- if (lastnread <= 0 && lastnread != NOCOUNT) {
- fprintf(msg, "eot\n");
- break;
- }
- fprintf(msg,
- "file %d: eof after %ju records: %ju bytes\n",
- filen, (intmax_t)record, (intmax_t)size);
- needeof = 1;
- filen++;
- tsize += size;
- size = record = lastrec = 0;
- lastnread = 0;
- }
- lastnread = nread;
- }
- fprintf(msg, "total length: %ju bytes\n", (intmax_t)tsize);
- (void)signal(SIGINT, oldsig);
- if (op == COPY || op == COPYVERIFY) {
- writeop(outp, MTWEOF);
- writeop(outp, MTWEOF);
- if (op == COPYVERIFY) {
- rewind_tape(outp);
- rewind_tape(inp);
- verify(inp, outp, buff);
- }
- }
- exit(0);
-}
-
-static void
-verify(int inp, int outp, char *outb)
-{
- int eot, inmaxblk, inn, outmaxblk, outn;
- char *inb;
-
- inb = getspace(maxblk);
- inmaxblk = outmaxblk = maxblk;
- for (eot = 0;; guesslen = 0) {
- if ((inn = read(inp, inb, inmaxblk)) == -1) {
- if (guesslen)
- while (errno == EINVAL && (inmaxblk -= 1024)) {
- inn = read(inp, inb, inmaxblk);
- if (inn >= 0)
- goto r1;
- }
- warn("read error");
- break;
- }
-r1: if ((outn = read(outp, outb, outmaxblk)) == -1) {
- if (guesslen)
- while (errno == EINVAL && (outmaxblk -= 1024)) {
- outn = read(outp, outb, outmaxblk);
- if (outn >= 0)
- goto r2;
- }
- warn("read error");
- break;
- }
-r2: if (inn != outn) {
- fprintf(msg,
- "%s: tapes have different block sizes; %d != %d.\n",
- "tcopy", inn, outn);
- break;
- }
- if (!inn) {
- if (eot++) {
- fprintf(msg, "tcopy: tapes are identical.\n");
- free(inb);
- return;
- }
- } else {
- if (bcmp(inb, outb, inn)) {
- fprintf(msg,
- "tcopy: tapes have different data.\n");
- break;
- }
- eot = 0;
- }
- }
- exit(1);
-}
-
-static void
-intr(int signo __unused)
-{
- if (record) {
- if (record - lastrec > 1)
- fprintf(msg, "records %ju to %ju\n", (intmax_t)lastrec, (intmax_t)record);
- else
- fprintf(msg, "record %ju\n", (intmax_t)lastrec);
- }
- fprintf(msg, "interrupt at file %d: record %ju\n", filen, (intmax_t)record);
- fprintf(msg, "total length: %ju bytes\n", (uintmax_t)(tsize + size));
- exit(1);
-}
-
-static void *
-getspace(int blk)
-{
- void *bp;
-
- if ((bp = malloc((size_t)blk)) == NULL)
- errx(11, "no memory");
- return (bp);
-}
-
-static void
-writeop(int fd, int type)
-{
- struct mtop op;
-
- op.mt_op = type;
- op.mt_count = (daddr_t)1;
- if (ioctl(fd, MTIOCTOP, (char *)&op) < 0)
- err(6, "tape op");
-}
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: tcopy [-cvx] [-s maxblk] [src [dest]]\n");
- exit(1);
-}
-
-static void
-rewind_tape(int fd)
-{
- struct stat sp;
-
- if(fstat(fd, &sp))
- errx(12, "fstat in rewind");
-
- /*
- * don't want to do tape ioctl on regular files:
- */
- if( S_ISREG(sp.st_mode) ) {
- if( lseek(fd, 0, SEEK_SET) == -1 )
- errx(13, "lseek");
- } else
- /* assume its a tape */
- writeop(fd, MTREW);
-}
diff --git a/usr.bin/tcopy/tcopy.cc b/usr.bin/tcopy/tcopy.cc
new file mode 100644
index 000000000000..891c37f871e5
--- /dev/null
+++ b/usr.bin/tcopy/tcopy.cc
@@ -0,0 +1,837 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Poul-Henning Kamp, <phk@FreeBSD.org>
+ * Copyright (c) 1985, 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include <sys/endian.h>
+#include <sys/mtio.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/uio.h>
+
+#include <libutil.h>
+
+#define MAXREC (1024 * 1024)
+#define NOCOUNT (-2)
+
+enum operation {READ, VERIFY, COPY, COPYVERIFY};
+
+// Stuff the tape_devs need to know about
+static int filen;
+static uint64_t record;
+
+//---------------------------------------------------------------------
+
+class tape_dev {
+ size_t max_read_size;
+public:
+ int fd;
+ char *name;
+ enum direction {SRC, DST} direction;
+
+ tape_dev(int file_handle, const char *spec, bool destination);
+
+ virtual ssize_t read_blk(void *dst, size_t len);
+ virtual ssize_t verify_blk(void *dst, size_t len, size_t expected);
+ virtual void write_blk(const void *src, size_t len);
+ virtual void file_mark(void);
+ virtual void rewind(void);
+};
+
+tape_dev::tape_dev(int file_handle, const char *spec, bool destination)
+{
+ assert(file_handle >= 0);
+ fd = file_handle;
+ name = strdup(spec);
+ assert(name != NULL);
+ direction = destination ? DST : SRC;
+ max_read_size = 0;
+}
+
+ssize_t
+tape_dev::read_blk(void *dst, size_t len)
+{
+ ssize_t retval = -1;
+
+ if (max_read_size == 0) {
+ max_read_size = len;
+ while (max_read_size > 0) {
+ retval = read(fd, dst, max_read_size);
+ if (retval >= 0 || (errno != EINVAL && errno != EFBIG))
+ break;
+ if (max_read_size < 512)
+ errx(1, "Cannot find a sane max blocksize");
+
+ // Reduce to next lower power of two
+ int i = flsl((long)max_read_size - 1L);
+ max_read_size = 1UL << (i - 1);
+ }
+ } else {
+ retval = read(fd, dst, (size_t)max_read_size);
+ }
+ if (retval < 0) {
+ err(1, "read error, %s, file %d, record %ju",
+ name, filen, (uintmax_t)record);
+ }
+ return (retval);
+}
+
+ssize_t
+tape_dev::verify_blk(void *dst, size_t len, size_t expected)
+{
+ (void)expected;
+ return read_blk(dst, len);
+}
+
+void
+tape_dev::write_blk(const void *src, size_t len)
+{
+ assert(len > 0);
+ ssize_t nwrite = write(fd, src, len);
+ if (nwrite < 0 || (size_t) nwrite != len) {
+ if (nwrite == -1) {
+ warn("write error, file %d, record %ju",
+ filen, (intmax_t)record);
+ } else {
+ warnx("write error, file %d, record %ju",
+ filen, (intmax_t)record);
+ warnx("write (%zd) != read (%zd)", nwrite, len);
+ }
+ errx(5, "copy aborted");
+ }
+ return;
+}
+
+void
+tape_dev::file_mark(void)
+{
+ struct mtop op;
+
+ op.mt_op = MTWEOF;
+ op.mt_count = (daddr_t)1;
+ if (ioctl(fd, MTIOCTOP, (char *)&op) < 0)
+ err(6, "tape op (write file mark)");
+}
+
+void
+tape_dev::rewind(void)
+{
+ struct mtop op;
+
+ op.mt_op = MTREW;
+ op.mt_count = (daddr_t)1;
+ if (ioctl(fd, MTIOCTOP, (char *)&op) < 0)
+ err(6, "tape op (rewind)");
+}
+
+//---------------------------------------------------------------------
+
+class tap_file: public tape_dev {
+public:
+ tap_file(int file_handle, const char *spec, bool dst) :
+ tape_dev(file_handle, spec, dst) {};
+ ssize_t read_blk(void *dst, size_t len);
+ void write_blk(const void *src, size_t len);
+ void file_mark(void);
+ virtual void rewind(void);
+};
+
+static
+ssize_t full_read(int fd, void *dst, size_t len)
+{
+ // Input may be a socket which returns partial reads
+
+ ssize_t retval = read(fd, dst, len);
+ if (retval <= 0 || (size_t)retval == len)
+ return (retval);
+
+ char *ptr = (char *)dst + retval;
+ size_t left = len - (size_t)retval;
+ while (left > 0) {
+ retval = read(fd, ptr, left);
+ if (retval <= 0)
+ return (retval);
+ left -= (size_t)retval;
+ ptr += retval;
+ }
+ return ((ssize_t)len);
+}
+
+ssize_t
+tap_file::read_blk(void *dst, size_t len)
+{
+ char lbuf[4];
+
+ ssize_t nread = full_read(fd, lbuf, sizeof lbuf);
+ if (nread == 0)
+ return (0);
+
+ if ((size_t)nread != sizeof lbuf)
+ err(EX_DATAERR, "Corrupt tap-file, read hdr1=%zd", nread);
+
+ uint32_t u = le32dec(lbuf);
+ if (u == 0 || (u >> 24) == 0xff)
+ return(0);
+
+ if (u > len)
+ err(17, "tapfile blocksize too big, 0x%08x", u);
+
+ size_t alen = (u + 1) & ~1;
+ assert (alen <= len);
+
+ ssize_t retval = full_read(fd, dst, alen);
+ if (retval < 0 || (size_t)retval != alen)
+ err(EX_DATAERR, "Corrupt tap-file, read data=%zd", retval);
+
+ nread = full_read(fd, lbuf, sizeof lbuf);
+ if ((size_t)nread != sizeof lbuf)
+ err(EX_DATAERR, "Corrupt tap-file, read hdr2=%zd", nread);
+
+ uint32_t v = le32dec(lbuf);
+ if (u == v)
+ return (u);
+ err(EX_DATAERR,
+ "Corrupt tap-file, headers differ (0x%08x != 0x%08x)", u, v);
+}
+
+void
+tap_file::write_blk(const void *src, size_t len)
+{
+ struct iovec iov[4];
+ uint8_t zero = 0;
+ int niov = 0;
+ size_t expect = 0;
+ char tbuf[4];
+
+ assert((len & ~0xffffffffULL) == 0);
+ le32enc(tbuf, (uint32_t)len);
+
+ iov[niov].iov_base = tbuf;
+ iov[niov].iov_len = sizeof tbuf;
+ expect += iov[niov].iov_len;
+ niov += 1;
+
+ iov[niov].iov_base = (void*)(uintptr_t)src;
+ iov[niov].iov_len = len;
+ expect += iov[niov].iov_len;
+ niov += 1;
+
+ if (len & 1) {
+ iov[niov].iov_base = &zero;
+ iov[niov].iov_len = 1;
+ expect += iov[niov].iov_len;
+ niov += 1;
+ }
+
+ iov[niov].iov_base = tbuf;
+ iov[niov].iov_len = sizeof tbuf;
+ expect += iov[niov].iov_len;
+ niov += 1;
+
+ ssize_t nwrite = writev(fd, iov, niov);
+ if (nwrite < 0 || (size_t)nwrite != expect)
+ errx(17, "write error (%zd != %zd)", nwrite, expect);
+}
+
+void
+tap_file::file_mark(void)
+{
+ char tbuf[4];
+ le32enc(tbuf, 0);
+ ssize_t nwrite = write(fd, tbuf, sizeof tbuf);
+ if ((size_t)nwrite != sizeof tbuf)
+ errx(17, "write error (%zd != %zd)", nwrite, sizeof tbuf);
+}
+
+void
+tap_file::rewind(void)
+{
+ off_t where;
+ if (direction == DST) {
+ char tbuf[4];
+ le32enc(tbuf, 0xffffffff);
+ ssize_t nwrite = write(fd, tbuf, sizeof tbuf);
+ if ((size_t)nwrite != sizeof tbuf)
+ errx(17,
+ "write error (%zd != %zd)", nwrite, sizeof tbuf);
+ }
+ where = lseek(fd, 0L, SEEK_SET);
+ if (where != 0 && errno == ESPIPE)
+ err(EX_USAGE, "Cannot rewind sockets and pipes");
+ if (where != 0)
+ err(17, "lseek(0) failed");
+}
+
+//---------------------------------------------------------------------
+
+class file_set: public tape_dev {
+public:
+ file_set(int file_handle, const char *spec, bool dst) :
+ tape_dev(file_handle, spec, dst) {};
+ ssize_t read_blk(void *dst, size_t len);
+ ssize_t verify_blk(void *dst, size_t len, size_t expected);
+ void write_blk(const void *src, size_t len);
+ void file_mark(void);
+ void rewind(void);
+ void open_next(bool increment);
+};
+
+void
+file_set::open_next(bool increment)
+{
+ if (fd >= 0) {
+ assert(close(fd) >= 0);
+ fd = -1;
+ }
+ if (increment) {
+ char *p = strchr(name, '\0') - 3;
+ if (++p[2] == '9') {
+ p[2] = '0';
+ if (++p[1] == '9') {
+ p[1] = '0';
+ if (++p[0] == '9') {
+ errx(EX_USAGE,
+ "file-set sequence overflow");
+ }
+ }
+ }
+ }
+ if (direction == DST) {
+ fd = open(name, O_RDWR|O_CREAT, DEFFILEMODE);
+ if (fd < 0)
+ err(1, "Could not open %s", name);
+ } else {
+ fd = open(name, O_RDONLY, 0);
+ }
+}
+
+ssize_t
+file_set::read_blk(void *dst, size_t len)
+{
+ (void)dst;
+ (void)len;
+ errx(EX_SOFTWARE, "That was not supposed to happen");
+}
+
+ssize_t
+file_set::verify_blk(void *dst, size_t len, size_t expected)
+{
+ (void)len;
+ if (fd < 0)
+ open_next(true);
+ if (fd < 0)
+ return (0);
+ ssize_t retval = read(fd, dst, expected);
+ if (retval == 0) {
+ assert(close(fd) >= 0);
+ fd = -1;
+ }
+ return (retval);
+}
+
+void
+file_set::write_blk(const void *src, size_t len)
+{
+ if (fd < 0)
+ open_next(true);
+ ssize_t nwrite = write(fd, src, len);
+ if (nwrite < 0 || (size_t)nwrite != len)
+ errx(17, "write error (%zd != %zd)", nwrite, len);
+}
+
+void
+file_set::file_mark(void)
+{
+ if (fd < 0)
+ return;
+
+ off_t where = lseek(fd, 0UL, SEEK_CUR);
+
+ int i = ftruncate(fd, where);
+ if (i < 0)
+ errx(17, "truncate error, %s to %jd", name, (intmax_t)where);
+ assert(close(fd) >= 0);
+ fd = -1;
+}
+
+void
+file_set::rewind(void)
+{
+ char *p = strchr(name, '\0') - 3;
+ p[0] = '0';
+ p[1] = '0';
+ p[2] = '0';
+ open_next(false);
+}
+
+//---------------------------------------------------------------------
+
+class flat_file: public tape_dev {
+public:
+ flat_file(int file_handle, const char *spec, bool dst) :
+ tape_dev(file_handle, spec, dst) {};
+ ssize_t read_blk(void *dst, size_t len);
+ ssize_t verify_blk(void *dst, size_t len, size_t expected);
+ void write_blk(const void *src, size_t len);
+ void file_mark(void);
+ virtual void rewind(void);
+};
+
+ssize_t
+flat_file::read_blk(void *dst, size_t len)
+{
+ (void)dst;
+ (void)len;
+ errx(EX_SOFTWARE, "That was not supposed to happen");
+}
+
+ssize_t
+flat_file::verify_blk(void *dst, size_t len, size_t expected)
+{
+ (void)len;
+ return (read(fd, dst, expected));
+}
+
+void
+flat_file::write_blk(const void *src, size_t len)
+{
+ ssize_t nwrite = write(fd, src, len);
+ if (nwrite < 0 || (size_t)nwrite != len)
+ errx(17, "write error (%zd != %zd)", nwrite, len);
+}
+
+void
+flat_file::file_mark(void)
+{
+ return;
+}
+
+void
+flat_file::rewind(void)
+{
+ errx(EX_SOFTWARE, "That was not supposed to happen");
+}
+
+//---------------------------------------------------------------------
+
+enum e_how {H_INPUT, H_OUTPUT, H_VERIFY};
+
+static tape_dev *
+open_arg(const char *arg, enum e_how how, int rawfile)
+{
+ int fd;
+
+ if (!strcmp(arg, "-") && how == H_OUTPUT)
+ fd = STDOUT_FILENO;
+ else if (!strcmp(arg, "-"))
+ fd = STDIN_FILENO;
+ else if (how == H_OUTPUT)
+ fd = open(arg, O_RDWR|O_CREAT, DEFFILEMODE);
+ else
+ fd = open(arg, O_RDONLY);
+
+ if (fd < 0)
+ err(EX_NOINPUT, "Cannot open %s:", arg);
+
+ struct mtop mt;
+ mt.mt_op = MTNOP;
+ mt.mt_count = 1;
+ int i = ioctl(fd, MTIOCTOP, &mt);
+
+ if (i >= 0)
+ return (new tape_dev(fd, arg, how == H_OUTPUT));
+
+ size_t alen = strlen(arg);
+ if (alen >= 5 && !strcmp(arg + (alen - 4), ".000")) {
+ if (how == H_INPUT)
+ errx(EX_USAGE,
+ "File-sets files cannot be used as source");
+ return (new file_set(fd, arg, how == H_OUTPUT));
+ }
+
+ if (how != H_INPUT && rawfile)
+ return (new flat_file(fd, arg, how == H_OUTPUT));
+
+ return (new tap_file(fd, arg, how == H_OUTPUT));
+}
+
+//---------------------------------------------------------------------
+
+static tape_dev *input;
+static tape_dev *output;
+
+static size_t maxblk = MAXREC;
+static uint64_t lastrec, fsize, tsize;
+static FILE *msg;
+static ssize_t lastnread;
+static struct timespec t_start, t_end;
+
+static void
+report_total(FILE *file)
+{
+ double dur = (t_end.tv_nsec - t_start.tv_nsec) * 1e-9;
+ dur += t_end.tv_sec - t_start.tv_sec;
+ uintmax_t tot = tsize + fsize;
+ fprintf(file, "total length: %ju bytes", tot);
+ fprintf(file, " time: %.0f s", dur);
+ tot /= 1024;
+ fprintf(file, " rate: %.1f kB/s", (double)tot/dur);
+ fprintf(file, "\n");
+}
+
+static void
+sigintr(int signo __unused)
+{
+ (void)signo;
+ (void)clock_gettime(CLOCK_MONOTONIC, &t_end);
+ if (record) {
+ if (record - lastrec > 1)
+ fprintf(msg, "records %ju to %ju\n",
+ (intmax_t)lastrec, (intmax_t)record);
+ else
+ fprintf(msg, "record %ju\n", (intmax_t)lastrec);
+ }
+ fprintf(msg, "interrupt at file %d: record %ju\n",
+ filen, (uintmax_t)record);
+ report_total(msg);
+ exit(1);
+}
+
+#ifdef SIGINFO
+static volatile sig_atomic_t want_info;
+
+static void
+siginfo(int signo)
+{
+ (void)signo;
+ want_info = 1;
+}
+
+static void
+check_want_info(void)
+{
+ if (want_info) {
+ (void)clock_gettime(CLOCK_MONOTONIC, &t_end);
+ fprintf(stderr, "tcopy: file %d record %ju ",
+ filen, (uintmax_t)record);
+ report_total(stderr);
+ want_info = 0;
+ }
+}
+
+#else /* !SIGINFO */
+
+static void
+check_want_info(void)
+{
+}
+
+#endif
+
+static char *
+getspace(size_t blk)
+{
+ void *bp;
+
+ assert(blk > 0);
+ if ((bp = malloc(blk)) == NULL)
+ errx(11, "no memory");
+ return ((char *)bp);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: tcopy [-cvx] [-s maxblk] [src [dest]]\n");
+ exit(1);
+}
+
+static void
+progress(ssize_t nread)
+{
+ if (nread != lastnread) {
+ if (lastnread != 0 && lastnread != NOCOUNT) {
+ if (lastrec == 0 && nread == 0)
+ fprintf(msg, "%ju records\n",
+ (uintmax_t)record);
+ else if (record - lastrec > 1)
+ fprintf(msg, "records %ju to %ju\n",
+ (uintmax_t)lastrec,
+ (uintmax_t)record);
+ else
+ fprintf(msg, "record %ju\n",
+ (uintmax_t)lastrec);
+ }
+ if (nread != 0)
+ fprintf(msg,
+ "file %d: block size %zd: ", filen, nread);
+ (void) fflush(msg);
+ lastrec = record;
+ }
+ if (nread > 0) {
+ fsize += (size_t)nread;
+ record++;
+ } else {
+ if (lastnread <= 0 && lastnread != NOCOUNT) {
+ fprintf(msg, "eot\n");
+ return;
+ }
+ fprintf(msg,
+ "file %d: eof after %ju records: %ju bytes\n",
+ filen, (uintmax_t)record, (uintmax_t)fsize);
+ filen++;
+ tsize += fsize;
+ fsize = record = lastrec = 0;
+ lastnread = 0;
+ }
+ lastnread = nread;
+}
+
+static void
+read_or_copy(void)
+{
+ int needeof;
+ ssize_t nread, prev_read;
+ char *buff = getspace(maxblk);
+
+ (void)clock_gettime(CLOCK_MONOTONIC, &t_start);
+ needeof = 0;
+ for (prev_read = NOCOUNT;;) {
+ check_want_info();
+ nread = input->read_blk(buff, maxblk);
+ progress(nread);
+ if (nread > 0) {
+ if (output != NULL) {
+ if (needeof) {
+ output->file_mark();
+ needeof = 0;
+ }
+ output->write_blk(buff, (size_t)nread);
+ }
+ } else {
+ if (prev_read <= 0 && prev_read != NOCOUNT) {
+ break;
+ }
+ needeof = 1;
+ }
+ prev_read = nread;
+ }
+ (void)clock_gettime(CLOCK_MONOTONIC, &t_end);
+ report_total(msg);
+ free(buff);
+}
+
+static void
+verify(void)
+{
+ char *buf1 = getspace(maxblk);
+ char *buf2 = getspace(maxblk);
+ int eot = 0;
+ ssize_t nread1, nread2;
+ filen = 0;
+ tsize = 0;
+
+ assert(output != NULL);
+ (void)clock_gettime(CLOCK_MONOTONIC, &t_start);
+
+ while (1) {
+ check_want_info();
+ nread1 = input->read_blk(buf1, (size_t)maxblk);
+ nread2 = output->verify_blk(buf2, maxblk, (size_t)nread1);
+ progress(nread1);
+ if (nread1 != nread2) {
+ fprintf(msg,
+ "tcopy: tapes have different block sizes; "
+ "%zd != %zd.\n", nread1, nread2);
+ exit(1);
+ }
+ if (nread1 > 0 && memcmp(buf1, buf2, (size_t)nread1)) {
+ fprintf(msg, "tcopy: tapes have different data.\n");
+ exit(1);
+ } else if (nread1 > 0) {
+ eot = 0;
+ } else if (eot++) {
+ break;
+ }
+ }
+ (void)clock_gettime(CLOCK_MONOTONIC, &t_end);
+ report_total(msg);
+ fprintf(msg, "tcopy: tapes are identical.\n");
+ fprintf(msg, "rewinding\n");
+ input->rewind();
+ output->rewind();
+
+ free(buf1);
+ free(buf2);
+}
+
+int
+main(int argc, char *argv[])
+{
+ enum operation op = READ;
+ int ch;
+ unsigned long maxphys = 0;
+ size_t l_maxphys = sizeof maxphys;
+ int64_t tmp;
+ int rawfile = 0;
+
+ setbuf(stderr, NULL);
+
+ if (!sysctlbyname("kern.maxphys", &maxphys, &l_maxphys, NULL, 0UL))
+ maxblk = maxphys;
+
+ msg = stdout;
+ while ((ch = getopt(argc, argv, "cl:rs:vx")) != -1)
+ switch((char)ch) {
+ case 'c':
+ op = COPYVERIFY;
+ break;
+ case 'l':
+ msg = fopen(optarg, "w");
+ if (msg == NULL)
+ errx(EX_CANTCREAT, "Cannot open %s", optarg);
+ setbuf(msg, NULL);
+ break;
+ case 'r':
+ rawfile = 1;
+ break;
+ case 's':
+ if (expand_number(optarg, &tmp)) {
+ warnx("illegal block size");
+ usage();
+ }
+ if (maxblk <= 0) {
+ warnx("illegal block size");
+ usage();
+ }
+ maxblk = tmp;
+ break;
+ case 'v':
+ op = VERIFY;
+ break;
+ case 'x':
+ if (msg == stdout)
+ msg = stderr;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ switch(argc) {
+ case 0:
+ if (op != READ)
+ usage();
+ break;
+ case 1:
+ if (op != READ)
+ usage();
+ break;
+ case 2:
+ if (op == READ)
+ op = COPY;
+ if (!strcmp(argv[1], "-")) {
+ if (op == COPYVERIFY)
+ errx(EX_USAGE,
+ "Cannot copy+verify with '-' destination");
+ if (msg == stdout)
+ msg = stderr;
+ }
+ if (op == VERIFY)
+ output = open_arg(argv[1], H_VERIFY, 0);
+ else
+ output = open_arg(argv[1], H_OUTPUT, rawfile);
+ break;
+ default:
+ usage();
+ }
+
+ if (argc == 0) {
+ input = open_arg(_PATH_DEFTAPE, H_INPUT, 0);
+ } else {
+ input = open_arg(argv[0], H_INPUT, 0);
+ }
+
+ if ((signal(SIGINT, SIG_IGN)) != SIG_IGN)
+ (void) signal(SIGINT, sigintr);
+
+#ifdef SIGINFO
+ (void)signal(SIGINFO, siginfo);
+#endif
+
+ if (op != VERIFY) {
+ if (op == COPYVERIFY) {
+ assert(output != NULL);
+ fprintf(msg, "rewinding\n");
+ input->rewind();
+ output->rewind();
+ }
+
+ read_or_copy();
+
+ if (op == COPY || op == COPYVERIFY) {
+ assert(output != NULL);
+ output->file_mark();
+ output->file_mark();
+ }
+ }
+
+ if (op == VERIFY || op == COPYVERIFY) {
+
+ if (op == COPYVERIFY) {
+ assert(output != NULL);
+ fprintf(msg, "rewinding\n");
+ input->rewind();
+ output->rewind();
+ input->direction = tape_dev::SRC;
+ output->direction = tape_dev::SRC;
+ }
+
+ verify();
+ }
+
+ if (msg != stderr && msg != stdout)
+ report_total(stderr);
+
+ return(0);
+}
diff --git a/usr.sbin/autofs/common.c b/usr.sbin/autofs/common.c
index 6b98214162ae..2dd7c290cebc 100644
--- a/usr.sbin/autofs/common.c
+++ b/usr.sbin/autofs/common.c
@@ -153,6 +153,7 @@ create_directory(const char *path)
}
}
+ free(partial);
free(tofree);
}
diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c
index d9fb29474d87..7ec5a00b50f0 100644
--- a/usr.sbin/chroot/chroot.c
+++ b/usr.sbin/chroot/chroot.c
@@ -103,7 +103,9 @@ main(int argc, char *argv[])
gid = 0;
uid = 0;
+ gids = 0;
user = group = grouplist = NULL;
+ gidlist = NULL;
nonprivileged = false;
while ((ch = getopt(argc, argv, "G:g:u:n")) != -1) {
switch(ch) {
@@ -119,6 +121,11 @@ main(int argc, char *argv[])
break;
case 'G':
grouplist = optarg;
+
+ /*
+ * XXX Why not allow us to drop all of our supplementary
+ * groups?
+ */
if (*grouplist == '\0')
usage();
break;
@@ -139,23 +146,25 @@ main(int argc, char *argv[])
if (group != NULL)
gid = resolve_group(group);
- ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
- if ((gidlist = malloc(sizeof(gid_t) * ngroups_max)) == NULL)
- err(1, "malloc");
- /* Populate the egid slot in our groups to avoid accidents. */
- if (gid == 0)
- gidlist[0] = getegid();
- else
- gidlist[0] = gid;
- for (gids = 1;
- (p = strsep(&grouplist, ",")) != NULL && gids < ngroups_max; ) {
- if (*p == '\0')
- continue;
-
- gidlist[gids++] = resolve_group(p);
+ if (grouplist != NULL) {
+ ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
+ if ((gidlist = malloc(sizeof(gid_t) * ngroups_max)) == NULL)
+ err(1, "malloc");
+ /* Populate the egid slot in our groups to avoid accidents. */
+ if (gid == 0)
+ gidlist[0] = getegid();
+ else
+ gidlist[0] = gid;
+ for (gids = 1; (p = strsep(&grouplist, ",")) != NULL &&
+ gids < ngroups_max; ) {
+ if (*p == '\0')
+ continue;
+
+ gidlist[gids++] = resolve_group(p);
+ }
+ if (p != NULL && gids == ngroups_max)
+ errx(1, "too many supplementary groups provided");
}
- if (p != NULL && gids == ngroups_max)
- errx(1, "too many supplementary groups provided");
if (user != NULL)
uid = resolve_user(user);
@@ -175,7 +184,7 @@ main(int argc, char *argv[])
err(1, "%s", argv[0]);
}
- if (gids && setgroups(gids, gidlist) == -1)
+ if (gidlist != NULL && setgroups(gids, gidlist) == -1)
err(1, "setgroups");
if (group && setgid(gid) == -1)
err(1, "setgid");