aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2022-11-16 20:25:24 +0000
committerMartin Matuska <mm@FreeBSD.org>2022-11-16 20:27:42 +0000
commitdbd5678dca91abcefe8d046aa2f9b66497a95ffb (patch)
tree23c7cf5ccced42596b6f6da3c8450e86124f5248 /sys/contrib/openzfs
parent61b146ba43cd3886c81e79b37fdc665d6e1d74b8 (diff)
parent2163cde450d0898b5f7bac16afb4e238485411ff (diff)
downloadsrc-dbd5678dca91abcefe8d046aa2f9b66497a95ffb.tar.gz
src-dbd5678dca91abcefe8d046aa2f9b66497a95ffb.zip
zfs: merge openzfs/zfs@2163cde45
Notable upstream pull request merges: #13680 Add options to zfs redundant_metadata property #13758 Allow mounting snapshots in .zfs/snapshot as a regular user #13838 quota: disable quota check for ZVOL #13839 quota: extend quota for dataset #13973 Fix memory leaks in dmu_send()/dmu_send_obj() #13977 Avoid unnecessary metaslab_check_free calling #13978 PAM: Fix unchecked return value from zfs_key_config_load() #13979 Handle possible null pointers from malloc/strdup/strndup() #13997 zstream: allow decompress to fix metadata for uncompressed records #13998 zvol_wait logic may terminate prematurely #14001 FreeBSD: Fix a pair of bugs in zfs_fhtovp() #14003 Stop ganging due to past vdev write errors #14039 Optimize microzaps #14050 Fix draid2+2s metadata error on simultaneous 2 drive failures #14062 zed: Avoid core dump if wholedisk property does not exist #14077 Propagate extent_bytes change to autotrim thread #14079 FreeBSD: vn_flush_cached_data: observe vnode locking contract #14093 Fix ARC target collapse when zfs_arc_meta_limit_percent=100 #14106 Add ability to recompress send streams with new compression algorithm #14119 Deny receiving into encrypted datasets if the keys are not loaded #14120 Fix arc_p aggressive increase #14129 zed: Prevent special vdev to be replaced by hot spare #14133 Expose zfs_vdev_open_timeout_ms as a tunable #14135 FreeBSD: Fix out of bounds read in zfs_ioctl_ozfs_to_legacy() #14152 Adds the `-p` option to `zfs holds` #14161 Handle and detect #13709's unlock regression Obtained from: OpenZFS OpenZFS commit: 2163cde450d0898b5f7bac16afb4e238485411ff
Diffstat (limited to 'sys/contrib/openzfs')
-rw-r--r--sys/contrib/openzfs/.github/workflows/checkstyle.yaml4
-rw-r--r--sys/contrib/openzfs/.github/workflows/codeql.yml36
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml4
-rw-r--r--sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml4
-rw-r--r--sys/contrib/openzfs/.github/workflows/zloop.yml6
-rw-r--r--sys/contrib/openzfs/AUTHORS2
-rw-r--r--sys/contrib/openzfs/META2
-rw-r--r--sys/contrib/openzfs/Makefile.am2
-rwxr-xr-xsys/contrib/openzfs/cmd/arc_summary8
-rw-r--r--sys/contrib/openzfs/cmd/raidz_test/raidz_test.c4
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb.c23
-rw-r--r--sys/contrib/openzfs/cmd/zdb/zdb_il.c11
-rw-r--r--sys/contrib/openzfs/cmd/zed/agents/fmd_api.c1
-rw-r--r--sys/contrib/openzfs/cmd/zed/agents/fmd_serd.c19
-rw-r--r--sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c22
-rw-r--r--sys/contrib/openzfs/cmd/zed/zed_event.c6
-rw-r--r--sys/contrib/openzfs/cmd/zed/zed_exec.c4
-rw-r--r--sys/contrib/openzfs/cmd/zfs/zfs_main.c85
-rw-r--r--sys/contrib/openzfs/cmd/zhack.c8
-rw-r--r--sys/contrib/openzfs/cmd/zpool/zpool_main.c9
-rw-r--r--sys/contrib/openzfs/cmd/zstream/Makefile.am1
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream.c4
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream.h1
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream_decompress.c40
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream_dump.c8
-rw-r--r--sys/contrib/openzfs/cmd/zstream/zstream_recompress.c356
-rw-r--r--sys/contrib/openzfs/cmd/ztest.c42
-rwxr-xr-xsys/contrib/openzfs/cmd/zvol_wait7
-rw-r--r--sys/contrib/openzfs/config/kernel-dentry-alias.m430
-rw-r--r--sys/contrib/openzfs/config/kernel-iattr-vfsid.m424
-rw-r--r--sys/contrib/openzfs/config/kernel-idmap_mnt_api.m425
-rw-r--r--sys/contrib/openzfs/config/kernel-mod-param.m433
-rw-r--r--sys/contrib/openzfs/config/kernel-rename.m471
-rw-r--r--sys/contrib/openzfs/config/kernel.m423
-rw-r--r--sys/contrib/openzfs/contrib/coverity/model.c389
-rw-r--r--sys/contrib/openzfs/contrib/debian/changelog7
-rw-r--r--sys/contrib/openzfs/contrib/debian/clean11
-rw-r--r--sys/contrib/openzfs/contrib/debian/control328
-rw-r--r--sys/contrib/openzfs/contrib/debian/control.modules.in33
-rw-r--r--sys/contrib/openzfs/contrib/debian/copyright19
-rw-r--r--sys/contrib/openzfs/contrib/debian/not-installed13
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.install.in1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.install2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.postinst6
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.prerm8
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.install.in1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.install.in3
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.install.in2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.install.in1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.install.in1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-python3-pyzfs.install1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.config31
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.dkms1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.install1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.postinst51
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.prerm8
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.templates40
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.triggers1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-dracut.install2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-initramfs.install2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_-di.install.in2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.install.in2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postinst.in16
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postrm.in7
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-test.install15
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.install5
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postinst20
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postrm17
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.prerm16
l---------sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.zfs-zed.init1
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.docs2
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.examples5
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.install135
-rw-r--r--sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.postinst28
l---------sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-import.init1
l---------sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-load-key.init1
l---------sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-mount.init1
l---------sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-share.init1
-rwxr-xr-xsys/contrib/openzfs/contrib/debian/rules223
-rw-r--r--sys/contrib/openzfs/contrib/debian/source/format1
-rw-r--r--sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/conf.d/zfs8
-rwxr-xr-xsys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/hooks/zdev67
-rwxr-xr-xsys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in28
-rw-r--r--sys/contrib/openzfs/contrib/pam_zfs_key/pam_zfs_key.c5
-rw-r--r--sys/contrib/openzfs/etc/Makefile.am1
-rw-r--r--sys/contrib/openzfs/include/libuutil_impl.h31
-rw-r--r--sys/contrib/openzfs/include/libzfs.h10
-rw-r--r--sys/contrib/openzfs/include/libzutil.h27
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/acl/acl_common.h2
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h5
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/dkio.h460
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/isa_defs.h415
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/kmem.h3
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/mod_os.h18
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/sysmacros.h40
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/types.h2
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h12
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h13
-rw-r--r--sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vnops_os.h13
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h10
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h21
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h69
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/vfs_compat.h13
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/xattr_compat.h10
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/cred.h80
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/debug.h37
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/isa_defs.h38
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/kmem.h2
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h10
-rw-r--r--sys/contrib/openzfs/include/os/linux/spl/sys/types.h3
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/policy.h5
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/trace_acl.h9
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/trace_common.h6
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_dir.h1
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vnops_os.h16
-rw-r--r--sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h9
-rw-r--r--sys/contrib/openzfs/include/sys/arc_impl.h6
-rw-r--r--sys/contrib/openzfs/include/sys/btree.h15
-rw-r--r--sys/contrib/openzfs/include/sys/dbuf.h4
-rw-r--r--sys/contrib/openzfs/include/sys/dmu.h7
-rw-r--r--sys/contrib/openzfs/include/sys/dmu_zfetch.h2
-rw-r--r--sys/contrib/openzfs/include/sys/dsl_deadlist.h2
-rw-r--r--sys/contrib/openzfs/include/sys/dsl_pool.h8
-rw-r--r--sys/contrib/openzfs/include/sys/fs/zfs.h6
-rw-r--r--sys/contrib/openzfs/include/sys/mmp.h2
-rw-r--r--sys/contrib/openzfs/include/sys/spa.h8
-rw-r--r--sys/contrib/openzfs/include/sys/vdev_impl.h5
-rw-r--r--sys/contrib/openzfs/include/sys/zap_impl.h11
-rw-r--r--sys/contrib/openzfs/include/sys/zcp.h4
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_acl.h11
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_context.h5
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h2
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_onexit.h2
-rw-r--r--sys/contrib/openzfs/include/sys/zfs_znode.h7
-rw-r--r--sys/contrib/openzfs/include/sys/zil.h21
-rw-r--r--sys/contrib/openzfs/include/sys/zio.h102
-rw-r--r--sys/contrib/openzfs/lib/libefi/rdwr_efi.c6
-rw-r--r--sys/contrib/openzfs/lib/libshare/os/linux/smb.c17
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h6
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/sys/types.h25
-rw-r--r--sys/contrib/openzfs/lib/libspl/include/umem.h20
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c6
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/zone.c2
-rw-r--r--sys/contrib/openzfs/lib/libuutil/uu_avl.c30
-rw-r--r--sys/contrib/openzfs/lib/libuutil/uu_list.c30
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs.abi36
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c12
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_diff.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_pool.c9
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c9
-rw-r--r--sys/contrib/openzfs/lib/libzfs/libzfs_util.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c2
-rw-r--r--sys/contrib/openzfs/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c13
-rw-r--r--sys/contrib/openzfs/lib/libzpool/kernel.c31
-rw-r--r--sys/contrib/openzfs/lib/libzpool/util.c7
-rw-r--r--sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c8
-rw-r--r--sys/contrib/openzfs/lib/libzutil/zutil_import.c118
-rw-r--r--sys/contrib/openzfs/lib/libzutil/zutil_import.h15
-rw-r--r--sys/contrib/openzfs/man/man4/zfs.4145
-rw-r--r--sys/contrib/openzfs/man/man7/vdevprops.75
-rw-r--r--sys/contrib/openzfs/man/man7/zfsprops.718
-rw-r--r--sys/contrib/openzfs/man/man8/zfs-hold.86
-rw-r--r--sys/contrib/openzfs/man/man8/zstream.833
-rw-r--r--sys/contrib/openzfs/module/Kbuild.in6
-rw-r--r--sys/contrib/openzfs/module/icp/algs/blake3/blake3.c4
-rw-r--r--sys/contrib/openzfs/module/icp/algs/modes/ccm.c1
-rw-r--r--sys/contrib/openzfs/module/icp/algs/modes/ctr.c1
-rw-r--r--sys/contrib/openzfs/module/icp/algs/modes/gcm.c1
-rw-r--r--sys/contrib/openzfs/module/icp/algs/modes/modes.c4
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/aes/aes_amd64.S2
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx2.S12
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx512.S16
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse2.S16
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse41.S16
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S20
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/modes/ghash-x86_64.S16
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S1
-rw-r--r--sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S1
-rw-r--r--sys/contrib/openzfs/module/icp/include/sys/ia32/asm_linkage.h27
-rw-r--r--sys/contrib/openzfs/module/icp/io/sha2_mod.c13
-rw-r--r--sys/contrib/openzfs/module/lua/lapi.c4
-rw-r--r--sys/contrib/openzfs/module/lua/ldo.c2
-rw-r--r--sys/contrib/openzfs/module/lua/setjmp/setjmp_x86_64.S15
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c30
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c12
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c16
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c30
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c8
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c37
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c4
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c278
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c68
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c5
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c1
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c8
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-err.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-generic.c112
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-kmem-cache.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-procfs-list.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c1
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-zone.c3
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/abd_os.c10
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/arc_os.c8
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/mmp_os.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/policy.c16
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/spa_misc_os.c4
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c35
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/vdev_file.c8
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c93
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c1
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_debug.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c104
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c2
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c5
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c354
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c9
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c3
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c6
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c159
-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.c34
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c10
-rw-r--r--sys/contrib/openzfs/module/zcommon/zfs_prop.c31
-rw-r--r--sys/contrib/openzfs/module/zcommon/zpool_prop.c3
-rw-r--r--sys/contrib/openzfs/module/zfs/abd.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/arc.c88
-rw-r--r--sys/contrib/openzfs/module/zfs/btree.c50
-rw-r--r--sys/contrib/openzfs/module/zfs/dataset_kstats.c7
-rw-r--r--sys/contrib/openzfs/module/zfs/dbuf.c11
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu.c27
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_objset.c7
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_recv.c6
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_send.c15
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_traverse.c3
-rw-r--r--sys/contrib/openzfs/module/zfs/dmu_zfetch.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_bookmark.c1
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_crypt.c18
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_dataset.c3
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_deadlist.c5
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_dir.c59
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_pool.c17
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_prop.c93
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_scan.c17
-rw-r--r--sys/contrib/openzfs/module/zfs/fm.c1
-rw-r--r--sys/contrib/openzfs/module/zfs/metaslab.c20
-rw-r--r--sys/contrib/openzfs/module/zfs/mmp.c18
-rw-r--r--sys/contrib/openzfs/module/zfs/range_tree.c1
-rw-r--r--sys/contrib/openzfs/module/zfs/spa.c74
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_checkpoint.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_log_spacemap.c40
-rw-r--r--sys/contrib/openzfs/module/zfs/spa_misc.c14
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev.c57
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_indirect.c9
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_initialize.c18
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_queue.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_raidz_math.c23
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_rebuild.c22
-rw-r--r--sys/contrib/openzfs/module/zfs/vdev_trim.c5
-rw-r--r--sys/contrib/openzfs/module/zfs/zap_leaf.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zap_micro.c247
-rw-r--r--sys/contrib/openzfs/module/zfs/zcp.c14
-rw-r--r--sys/contrib/openzfs/module/zfs/zcp_get.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_chksum.c38
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_fm.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_ioctl.c8
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_log.c88
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_onexit.c4
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_replay.c153
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_vnops.c20
-rw-r--r--sys/contrib/openzfs/module/zfs/zil.c46
-rw-r--r--sys/contrib/openzfs/module/zfs/zio.c43
-rw-r--r--sys/contrib/openzfs/module/zfs/zio_compress.c2
-rw-r--r--sys/contrib/openzfs/module/zfs/zvol.c5
-rw-r--r--sys/contrib/openzfs/scripts/Makefile.am20
-rwxr-xr-xsys/contrib/openzfs/scripts/cstyle.pl13
-rwxr-xr-xsys/contrib/openzfs/scripts/debian-packaging.sh36
-rwxr-xr-xsys/contrib/openzfs/scripts/enum-extract.pl2
-rw-r--r--sys/contrib/openzfs/tests/runfiles/common.run14
-rw-r--r--sys/contrib/openzfs/tests/runfiles/linux.run8
-rwxr-xr-xsys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in15
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am5
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/badsend.c4
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c48
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/edonr_test.c18
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/sha2_test.c20
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/skein_test.c16
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/ctime.c1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/draid.c5
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/file/largest_file.c2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/idmap_util.c808
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/mkbusy.c8
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_libaio.c2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/mmapwrite.c14
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/nvlist_to_lua.c5
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/renameat2.c128
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/stride_dd.c4
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/cmd/user_ns_exec.c1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg7
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/include/properties.shlib3
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am15
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh31
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh6
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh4
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_004_pos.ksh4
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh4
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh4
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh4
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh4
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh5
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh25
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg25
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh76
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh97
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh121
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh106
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_005.ksh138
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib23
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh30
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh10
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/Makefile.am7
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/cleanup.ksh34
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_exchange.ksh61
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_noreplace.ksh51
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_whiteout.ksh50
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/setup.ksh37
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/rsend_009_pos.ksh43
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send-c_zstream_recompress.ksh58
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/slog_replay_fs_001.ksh23
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_002_pos.c7
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c30
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/13709_reproducer.bz2bin0 -> 135829 bytes
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_encrypted_13709.ksh45
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/perf/regression/random_readwrite.ksh2
347 files changed, 7590 insertions, 2691 deletions
diff --git a/sys/contrib/openzfs/.github/workflows/checkstyle.yaml b/sys/contrib/openzfs/.github/workflows/checkstyle.yaml
index 8dafdcf07fed..2e593e0a5669 100644
--- a/sys/contrib/openzfs/.github/workflows/checkstyle.yaml
+++ b/sys/contrib/openzfs/.github/workflows/checkstyle.yaml
@@ -8,7 +8,7 @@ jobs:
checkstyle:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install dependencies
@@ -49,7 +49,7 @@ jobs:
if: failure() && steps.CheckABI.outcome == 'failure'
run: |
find -name *.abi | tar -cf abi_files.tar -T -
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v3
if: failure() && steps.CheckABI.outcome == 'failure'
with:
name: New ABI files (use only if you're sure about interface changes)
diff --git a/sys/contrib/openzfs/.github/workflows/codeql.yml b/sys/contrib/openzfs/.github/workflows/codeql.yml
new file mode 100644
index 000000000000..c8a49a7f00bc
--- /dev/null
+++ b/sys/contrib/openzfs/.github/workflows/codeql.yml
@@ -0,0 +1,36 @@
+name: "CodeQL"
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'cpp', 'python' ]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml b/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml
index 0273610af045..1c2b2b804064 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-tests-functional.yml
@@ -12,7 +12,7 @@ jobs:
os: [18.04, 20.04]
runs-on: ubuntu-${{ matrix.os }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Reclaim disk space
@@ -72,7 +72,7 @@ jobs:
sudo chmod +r $RESULTS_PATH/*
# Replace ':' in dir names, actions/upload-artifact doesn't support it
for f in $(find /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v3
if: failure()
with:
name: Test logs Ubuntu-${{ matrix.os }}
diff --git a/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml b/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml
index 73606f909e10..ace046ad1c12 100644
--- a/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml
+++ b/sys/contrib/openzfs/.github/workflows/zfs-tests-sanity.yml
@@ -8,7 +8,7 @@ jobs:
tests:
runs-on: ubuntu-20.04
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Reclaim disk space
@@ -68,7 +68,7 @@ jobs:
sudo chmod +r $RESULTS_PATH/*
# Replace ':' in dir names, actions/upload-artifact doesn't support it
for f in $(find /var/tmp/test_results -name '*:*'); do mv "$f" "${f//:/__}"; done
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v3
if: failure()
with:
name: Test logs Ubuntu-${{ matrix.os }}
diff --git a/sys/contrib/openzfs/.github/workflows/zloop.yml b/sys/contrib/openzfs/.github/workflows/zloop.yml
index d49eeae1653c..807a1bc46123 100644
--- a/sys/contrib/openzfs/.github/workflows/zloop.yml
+++ b/sys/contrib/openzfs/.github/workflows/zloop.yml
@@ -10,7 +10,7 @@ jobs:
env:
TEST_DIR: /var/tmp/zloop
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install dependencies
@@ -45,7 +45,7 @@ jobs:
if: failure()
run: |
sudo chmod +r -R $TEST_DIR/
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v3
if: failure()
with:
name: Logs
@@ -53,7 +53,7 @@ jobs:
/var/tmp/zloop/*/
!/var/tmp/zloop/*/vdev/
if-no-files-found: ignore
- - uses: actions/upload-artifact@v2
+ - uses: actions/upload-artifact@v3
if: failure()
with:
name: Pool files
diff --git a/sys/contrib/openzfs/AUTHORS b/sys/contrib/openzfs/AUTHORS
index 86083ba87715..c2af58d75085 100644
--- a/sys/contrib/openzfs/AUTHORS
+++ b/sys/contrib/openzfs/AUTHORS
@@ -20,6 +20,7 @@ CONTRIBUTORS:
Alec Salazar <alec.j.salazar@gmail.com>
Alejandro R. Sedeño <asedeno@mit.edu>
Alek Pinchuk <alek@nexenta.com>
+ Aleksa Sarai <cyphar@cyphar.com>
Alex Braunegg <alex.braunegg@gmail.com>
Alex McWhirter <alexmcwhirter@triadic.us>
Alex Reece <alex@delphix.com>
@@ -236,6 +237,7 @@ CONTRIBUTORS:
Paul Dagnelie <pcd@delphix.com>
Paul Zuchowski <pzuchowski@datto.com>
Pavel Boldin <boldin.pavel@gmail.com>
+ Pavel Snajdr <snajpa@snajpa.net>
Pavel Zakharov <pavel.zakharov@delphix.com>
Pawel Jakub Dawidek <pjd@FreeBSD.org>
Pedro Giffuni <pfg@freebsd.org>
diff --git a/sys/contrib/openzfs/META b/sys/contrib/openzfs/META
index 692497fcf1fc..0b4d784bb77c 100644
--- a/sys/contrib/openzfs/META
+++ b/sys/contrib/openzfs/META
@@ -6,5 +6,5 @@ Release: 1
Release-Tags: relext
License: CDDL
Author: OpenZFS
-Linux-Maximum: 5.19
+Linux-Maximum: 6.0
Linux-Minimum: 3.10
diff --git a/sys/contrib/openzfs/Makefile.am b/sys/contrib/openzfs/Makefile.am
index 54d300e7d40b..11e45dae8255 100644
--- a/sys/contrib/openzfs/Makefile.am
+++ b/sys/contrib/openzfs/Makefile.am
@@ -9,6 +9,7 @@ include $(top_srcdir)/config/Rules.am
include $(top_srcdir)/config/CppCheck.am
include $(top_srcdir)/config/Shellcheck.am
include $(top_srcdir)/config/Substfiles.am
+include $(top_srcdir)/scripts/Makefile.am
ACLOCAL_AMFLAGS = -I config
@@ -23,7 +24,6 @@ include $(srcdir)/%D%/contrib/Makefile.am
include $(srcdir)/%D%/etc/Makefile.am
include $(srcdir)/%D%/lib/Makefile.am
include $(srcdir)/%D%/man/Makefile.am
-include $(srcdir)/%D%/scripts/Makefile.am
include $(srcdir)/%D%/tests/Makefile.am
if BUILD_LINUX
include $(srcdir)/%D%/udev/Makefile.am
diff --git a/sys/contrib/openzfs/cmd/arc_summary b/sys/contrib/openzfs/cmd/arc_summary
index 4f275813d973..9d0c2d30ddd6 100755
--- a/sys/contrib/openzfs/cmd/arc_summary
+++ b/sys/contrib/openzfs/cmd/arc_summary
@@ -678,9 +678,9 @@ def section_archits(kstats_dict):
print()
print('Cache hits by data type:')
dt_todo = (('Demand data:', arc_stats['demand_data_hits']),
- ('Demand prefetch data:', arc_stats['prefetch_data_hits']),
+ ('Prefetch data:', arc_stats['prefetch_data_hits']),
('Demand metadata:', arc_stats['demand_metadata_hits']),
- ('Demand prefetch metadata:',
+ ('Prefetch metadata:',
arc_stats['prefetch_metadata_hits']))
for title, value in dt_todo:
@@ -689,10 +689,10 @@ def section_archits(kstats_dict):
print()
print('Cache misses by data type:')
dm_todo = (('Demand data:', arc_stats['demand_data_misses']),
- ('Demand prefetch data:',
+ ('Prefetch data:',
arc_stats['prefetch_data_misses']),
('Demand metadata:', arc_stats['demand_metadata_misses']),
- ('Demand prefetch metadata:',
+ ('Prefetch metadata:',
arc_stats['prefetch_metadata_misses']))
for title, value in dm_todo:
diff --git a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c
index 1ece55960d33..195026d3a7ab 100644
--- a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c
+++ b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c
@@ -146,8 +146,6 @@ static void process_options(int argc, char **argv)
memcpy(o, &rto_opts_defaults, sizeof (*o));
while ((opt = getopt(argc, argv, "TDBSvha:er:o:d:s:t:")) != -1) {
- value = 0;
-
switch (opt) {
case 'a':
value = strtoull(optarg, NULL, 0);
@@ -939,7 +937,7 @@ run_sweep(void)
opts = umem_zalloc(sizeof (raidz_test_opts_t), UMEM_NOFAIL);
opts->rto_ashift = ashift_v[a];
opts->rto_dcols = dcols_v[d];
- opts->rto_offset = (1 << ashift_v[a]) * rand();
+ opts->rto_offset = (1ULL << ashift_v[a]) * rand();
opts->rto_dsize = size_v[s];
opts->rto_expand = rto_opts.rto_expand;
opts->rto_expand_offset = rto_opts.rto_expand_offset;
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c
index 96db9c4b9a76..d19eb71f0f69 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb.c
@@ -128,7 +128,7 @@ uint8_t dump_opt[256];
typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
-uint64_t *zopt_metaslab = NULL;
+static uint64_t *zopt_metaslab = NULL;
static unsigned zopt_metaslab_args = 0;
typedef struct zopt_object_range {
@@ -136,7 +136,8 @@ typedef struct zopt_object_range {
uint64_t zor_obj_end;
uint64_t zor_flags;
} zopt_object_range_t;
-zopt_object_range_t *zopt_object_ranges = NULL;
+
+static zopt_object_range_t *zopt_object_ranges = NULL;
static unsigned zopt_object_args = 0;
static int flagbits[256];
@@ -160,7 +161,7 @@ static int flagbits[256];
#define ZDB_FLAG_PRINT_BLKPTR 0x0040
#define ZDB_FLAG_VERBOSE 0x0080
-uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
+static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */
static int leaked_objects = 0;
static range_tree_t *mos_refd_objs;
@@ -2857,9 +2858,11 @@ dump_bookmarks(objset_t *os, int verbosity)
zap_cursor_advance(&zc)) {
char osname[ZFS_MAX_DATASET_NAME_LEN];
char buf[ZFS_MAX_DATASET_NAME_LEN];
+ int len;
dmu_objset_name(os, osname);
- VERIFY3S(0, <=, snprintf(buf, sizeof (buf), "%s#%s", osname,
- attr.za_name));
+ len = snprintf(buf, sizeof (buf), "%s#%s", osname,
+ attr.za_name);
+ VERIFY3S(len, <, ZFS_MAX_DATASET_NAME_LEN);
(void) dump_bookmark(dp, buf, verbosity >= 5, verbosity >= 6);
}
zap_cursor_fini(&zc);
@@ -3066,7 +3069,7 @@ open_objset(const char *path, const void *tag, objset_t **osp)
}
sa_os = *osp;
- return (0);
+ return (err);
}
static void
@@ -8778,8 +8781,12 @@ main(int argc, char **argv)
args.path = searchdirs;
args.can_be_active = B_TRUE;
- error = zpool_find_config(NULL, target_pool, &cfg, &args,
- &libzpool_config_ops);
+ libpc_handle_t lpch = {
+ .lpc_lib_handle = NULL,
+ .lpc_ops = &libzpool_config_ops,
+ .lpc_printerr = B_TRUE
+ };
+ error = zpool_find_config(&lpch, target_pool, &cfg, &args);
if (error == 0) {
diff --git a/sys/contrib/openzfs/cmd/zdb/zdb_il.c b/sys/contrib/openzfs/cmd/zdb/zdb_il.c
index 4de7619e4bde..55df1f559f6e 100644
--- a/sys/contrib/openzfs/cmd/zdb/zdb_il.c
+++ b/sys/contrib/openzfs/cmd/zdb/zdb_il.c
@@ -128,6 +128,14 @@ zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg)
(void) printf("%ssdoid %llu, tdoid %llu\n", tab_prefix,
(u_longlong_t)lr->lr_sdoid, (u_longlong_t)lr->lr_tdoid);
(void) printf("%ssrc %s tgt %s\n", tab_prefix, snm, tnm);
+ switch (txtype) {
+ case TX_RENAME_EXCHANGE:
+ (void) printf("%sflags RENAME_EXCHANGE\n", tab_prefix);
+ break;
+ case TX_RENAME_WHITEOUT:
+ (void) printf("%sflags RENAME_WHITEOUT\n", tab_prefix);
+ break;
+ }
}
static int
@@ -182,6 +190,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, const void *arg)
return;
}
+ ASSERT3U(BP_GET_LSIZE(bp), !=, 0);
SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os),
lr->lr_foid, ZB_ZIL_LEVEL,
lr->lr_offset / BP_GET_LSIZE(bp));
@@ -329,6 +338,8 @@ static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
{.zri_print = zil_prt_rec_write, .zri_name = "TX_WRITE2 "},
{.zri_print = zil_prt_rec_setsaxattr,
.zri_name = "TX_SETSAXATTR "},
+ {.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME_EXCHANGE "},
+ {.zri_print = zil_prt_rec_rename, .zri_name = "TX_RENAME_WHITEOUT "},
};
static int
diff --git a/sys/contrib/openzfs/cmd/zed/agents/fmd_api.c b/sys/contrib/openzfs/cmd/zed/agents/fmd_api.c
index 56c134b731b8..6858da5e7cf1 100644
--- a/sys/contrib/openzfs/cmd/zed/agents/fmd_api.c
+++ b/sys/contrib/openzfs/cmd/zed/agents/fmd_api.c
@@ -616,6 +616,7 @@ fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta)
sev.sigev_notify_function = _timer_notify;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = ftp;
+ sev.sigev_signo = 0;
timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid);
timer_settime(ftp->ft_tid, 0, &its, NULL);
diff --git a/sys/contrib/openzfs/cmd/zed/agents/fmd_serd.c b/sys/contrib/openzfs/cmd/zed/agents/fmd_serd.c
index 763ecb9589e7..0bb2c535f094 100644
--- a/sys/contrib/openzfs/cmd/zed/agents/fmd_serd.c
+++ b/sys/contrib/openzfs/cmd/zed/agents/fmd_serd.c
@@ -74,9 +74,18 @@ fmd_serd_eng_alloc(const char *name, uint64_t n, hrtime_t t)
fmd_serd_eng_t *sgp;
sgp = malloc(sizeof (fmd_serd_eng_t));
+ if (sgp == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
memset(sgp, 0, sizeof (fmd_serd_eng_t));
sgp->sg_name = strdup(name);
+ if (sgp->sg_name == NULL) {
+ perror("strdup");
+ exit(EXIT_FAILURE);
+ }
+
sgp->sg_flags = FMD_SERD_DIRTY;
sgp->sg_n = n;
sgp->sg_t = t;
@@ -123,6 +132,12 @@ fmd_serd_hash_create(fmd_serd_hash_t *shp)
shp->sh_hashlen = FMD_STR_BUCKETS;
shp->sh_hash = calloc(shp->sh_hashlen, sizeof (void *));
shp->sh_count = 0;
+
+ if (shp->sh_hash == NULL) {
+ perror("calloc");
+ exit(EXIT_FAILURE);
+ }
+
}
void
@@ -241,6 +256,10 @@ fmd_serd_eng_record(fmd_serd_eng_t *sgp, hrtime_t hrt)
fmd_serd_eng_discard(sgp, list_tail(&sgp->sg_list));
sep = malloc(sizeof (fmd_serd_elem_t));
+ if (sep == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
sep->se_hrt = hrt;
list_insert_head(&sgp->sg_list, sep);
diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
index 53d9ababded9..0271fffe42ef 100644
--- a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
+++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
@@ -133,6 +133,11 @@ zfs_unavail_pool(zpool_handle_t *zhp, void *data)
if (zfs_toplevel_state(zhp) < VDEV_STATE_DEGRADED) {
unavailpool_t *uap;
uap = malloc(sizeof (unavailpool_t));
+ if (uap == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
uap->uap_zhp = zhp;
list_insert_tail((list_t *)data, uap);
} else {
@@ -411,6 +416,11 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
* completed.
*/
device = malloc(sizeof (pendingdev_t));
+ if (device == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
(void) strlcpy(device->pd_physpath, physpath,
sizeof (device->pd_physpath));
list_insert_tail(&g_device_list, device);
@@ -938,14 +948,13 @@ vdev_whole_disk_from_config(zpool_handle_t *zhp, const char *vdev_path)
{
nvlist_t *nvl = NULL;
boolean_t avail_spare, l2cache, log;
- uint64_t wholedisk;
+ uint64_t wholedisk = 0;
nvl = zpool_find_vdev(zhp, vdev_path, &avail_spare, &l2cache, &log);
if (!nvl)
return (0);
- verify(nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_WHOLE_DISK,
- &wholedisk) == 0);
+ (void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk);
return (wholedisk);
}
@@ -984,7 +993,7 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
if ((tgt = zpool_find_vdev_by_physpath(zhp, devname,
&avail_spare, &l2cache, NULL)) != NULL) {
char *path, fullpath[MAXPATHLEN];
- uint64_t wholedisk;
+ uint64_t wholedisk = 0;
error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path);
if (error) {
@@ -992,10 +1001,8 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data)
return (0);
}
- error = nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
+ (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
&wholedisk);
- if (error)
- wholedisk = 0;
if (wholedisk) {
path = strrchr(path, '/');
@@ -1125,6 +1132,7 @@ zfs_deliver_dle(nvlist_t *nvl)
strlcpy(name, devname, MAXPATHLEN);
zfs_append_partition(name, MAXPATHLEN);
} else {
+ sprintf(name, "unknown");
zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath");
}
diff --git a/sys/contrib/openzfs/cmd/zed/zed_event.c b/sys/contrib/openzfs/cmd/zed/zed_event.c
index 079c6a043e5d..ebd6851a2a86 100644
--- a/sys/contrib/openzfs/cmd/zed/zed_event.c
+++ b/sys/contrib/openzfs/cmd/zed/zed_event.c
@@ -139,8 +139,12 @@ _bump_event_queue_length(void)
if (qlen == orig_qlen)
goto done;
wr = snprintf(qlen_buf, sizeof (qlen_buf), "%ld", qlen);
+ if (wr >= sizeof (qlen_buf)) {
+ wr = sizeof (qlen_buf) - 1;
+ zed_log_msg(LOG_WARNING, "Truncation in %s()", __func__);
+ }
- if (pwrite(zzlm, qlen_buf, wr, 0) < 0)
+ if (pwrite(zzlm, qlen_buf, wr + 1, 0) < 0)
goto done;
zed_log_msg(LOG_WARNING, "Bumping queue length to %ld", qlen);
diff --git a/sys/contrib/openzfs/cmd/zed/zed_exec.c b/sys/contrib/openzfs/cmd/zed/zed_exec.c
index 51c292d41ccc..e45acfb2c69f 100644
--- a/sys/contrib/openzfs/cmd/zed/zed_exec.c
+++ b/sys/contrib/openzfs/cmd/zed/zed_exec.c
@@ -175,6 +175,10 @@ _zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog,
node->pid = pid;
node->eid = eid;
node->name = strdup(prog);
+ if (node->name == NULL) {
+ perror("strdup");
+ exit(EXIT_FAILURE);
+ }
avl_add(&_launched_processes, node);
}
diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_main.c b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
index 7bda3f5292b3..6e79a73b95fb 100644
--- a/sys/contrib/openzfs/cmd/zfs/zfs_main.c
+++ b/sys/contrib/openzfs/cmd/zfs/zfs_main.c
@@ -392,7 +392,7 @@ get_usage(zfs_help_t idx)
case HELP_HOLD:
return (gettext("\thold [-r] <tag> <snapshot> ...\n"));
case HELP_HOLDS:
- return (gettext("\tholds [-rH] <snapshot> ...\n"));
+ return (gettext("\tholds [-rHp] <snapshot> ...\n"));
case HELP_RELEASE:
return (gettext("\trelease [-r] <tag> <snapshot> ...\n"));
case HELP_DIFF:
@@ -1453,8 +1453,13 @@ destroy_callback(zfs_handle_t *zhp, void *data)
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
cb->cb_snap_count++;
fnvlist_add_boolean(cb->cb_batchedsnaps, name);
- if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy)
+ if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy) {
error = destroy_batched(cb);
+ if (error != 0) {
+ zfs_close(zhp);
+ return (-1);
+ }
+ }
} else {
error = destroy_batched(cb);
if (error != 0 ||
@@ -2576,7 +2581,7 @@ zfs_do_upgrade(int argc, char **argv)
cb.cb_foundone = B_FALSE;
cb.cb_newer = B_TRUE;
- ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
+ ret |= zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM,
NULL, NULL, 0, upgrade_list_callback, &cb);
if (!cb.cb_foundone && !found) {
@@ -4499,6 +4504,7 @@ zfs_do_send(int argc, char **argv)
gettext("missing argument for '%s' "
"option\n"), argv[optind - 1]);
}
+ free(excludes.list);
usage(B_FALSE);
break;
case '?':
@@ -4517,6 +4523,7 @@ zfs_do_send(int argc, char **argv)
argv[optind - 1]);
}
+ free(excludes.list);
usage(B_FALSE);
}
}
@@ -4525,6 +4532,7 @@ zfs_do_send(int argc, char **argv)
flags.verbosity = 1;
if (excludes.count > 0 && !flags.replicate) {
+ free(excludes.list);
(void) fprintf(stderr, gettext("Cannot specify "
"dataset exclusion (-X) on a non-recursive "
"send.\n"));
@@ -4538,21 +4546,25 @@ zfs_do_send(int argc, char **argv)
if (fromname != NULL || flags.replicate || flags.props ||
flags.backup || flags.holds ||
flags.saved || redactbook != NULL) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("invalid flags combined with -t\n"));
usage(B_FALSE);
}
if (argc > 0) {
+ free(excludes.list);
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
} else {
if (argc < 1) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("missing snapshot argument\n"));
usage(B_FALSE);
}
if (argc > 1) {
+ free(excludes.list);
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
@@ -4563,11 +4575,15 @@ zfs_do_send(int argc, char **argv)
flags.doall || flags.backup ||
flags.holds || flags.largeblock || flags.embed_data ||
flags.compress || flags.raw || redactbook != NULL) {
+ free(excludes.list);
+
(void) fprintf(stderr, gettext("incompatible flags "
"combined with saved send flag\n"));
usage(B_FALSE);
}
if (strchr(argv[0], '@') != NULL) {
+ free(excludes.list);
+
(void) fprintf(stderr, gettext("saved send must "
"specify the dataset with partially-received "
"state\n"));
@@ -4576,12 +4592,14 @@ zfs_do_send(int argc, char **argv)
}
if (flags.raw && redactbook != NULL) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("Error: raw sends may not be redacted.\n"));
return (1);
}
if (!flags.dryrun && isatty(STDOUT_FILENO)) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("Error: Stream can not be written to a terminal.\n"
"You must redirect standard output.\n"));
@@ -4590,19 +4608,24 @@ zfs_do_send(int argc, char **argv)
if (flags.saved) {
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
- if (zhp == NULL)
+ if (zhp == NULL) {
+ free(excludes.list);
return (1);
+ }
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
resume_token);
+ free(excludes.list);
zfs_close(zhp);
return (err != 0);
} else if (resume_token != NULL) {
+ free(excludes.list);
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
resume_token));
}
if (flags.skipmissing && !flags.replicate) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("skip-missing flag can only be used in "
"conjunction with replicate\n"));
@@ -4645,10 +4668,14 @@ zfs_do_send(int argc, char **argv)
}
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
- if (zhp == NULL)
+ if (zhp == NULL) {
+ free(excludes.list);
return (1);
+ }
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
redactbook);
+
+ free(excludes.list);
zfs_close(zhp);
return (err != 0);
}
@@ -4657,25 +4684,30 @@ zfs_do_send(int argc, char **argv)
(void) fprintf(stderr,
gettext("Error: multiple snapshots cannot be "
"sent from a bookmark.\n"));
+ free(excludes.list);
return (1);
}
if (redactbook != NULL) {
(void) fprintf(stderr, gettext("Error: multiple snapshots "
"cannot be sent redacted.\n"));
+ free(excludes.list);
return (1);
}
if ((cp = strchr(argv[0], '@')) == NULL) {
(void) fprintf(stderr, gettext("Error: "
"Unsupported flag with filesystem or bookmark.\n"));
+ free(excludes.list);
return (1);
}
*cp = '\0';
toname = cp + 1;
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (zhp == NULL)
+ if (zhp == NULL) {
+ free(excludes.list);
return (1);
+ }
/*
* If they specified the full path to the snapshot, chop off
@@ -4695,6 +4727,8 @@ zfs_do_send(int argc, char **argv)
} else {
*cp = '\0';
if (cp != fromname && strcmp(argv[0], fromname)) {
+ zfs_close(zhp);
+ free(excludes.list);
(void) fprintf(stderr,
gettext("incremental source must be "
"in same filesystem\n"));
@@ -4702,6 +4736,8 @@ zfs_do_send(int argc, char **argv)
}
fromname = cp + 1;
if (strchr(fromname, '@') || strchr(fromname, '/')) {
+ zfs_close(zhp);
+ free(excludes.list);
(void) fprintf(stderr,
gettext("invalid incremental source\n"));
usage(B_FALSE);
@@ -6420,7 +6456,8 @@ typedef struct holds_cbdata {
*
*/
static void
-print_holds(boolean_t scripted, int nwidth, int tagwidth, nvlist_t *nvl)
+print_holds(boolean_t scripted, int nwidth, int tagwidth, nvlist_t *nvl,
+ boolean_t parsable)
{
int i;
nvpair_t *nvp = NULL;
@@ -6457,11 +6494,23 @@ print_holds(boolean_t scripted, int nwidth, int tagwidth, nvlist_t *nvl)
gettext(STRFTIME_FMT_STR), &t);
if (scripted) {
- (void) printf("%s\t%s\t%s\n", zname,
- tagname, tsbuf);
+ if (parsable) {
+ (void) printf("%s\t%s\t%ld\n", zname,
+ tagname, time);
+ } else {
+ (void) printf("%s\t%s\t%s\n", zname,
+ tagname, tsbuf);
+ }
} else {
- (void) printf("%-*s %-*s %s\n", nwidth,
- zname, tagwidth, tagname, tsbuf);
+ if (parsable) {
+ (void) printf("%-*s %-*s %ld\n",
+ nwidth, zname, tagwidth,
+ tagname, time);
+ } else {
+ (void) printf("%-*s %-*s %s\n",
+ nwidth, zname, tagwidth,
+ tagname, tsbuf);
+ }
}
}
}
@@ -6508,10 +6557,11 @@ holds_callback(zfs_handle_t *zhp, void *data)
}
/*
- * zfs holds [-rH] <snap> ...
+ * zfs holds [-rHp] <snap> ...
*
* -r Lists holds that are set on the named snapshots recursively.
* -H Scripted mode; elide headers and separate columns by tabs.
+ * -p Display values in parsable (literal) format.
*/
static int
zfs_do_holds(int argc, char **argv)
@@ -6520,6 +6570,7 @@ zfs_do_holds(int argc, char **argv)
boolean_t errors = B_FALSE;
boolean_t scripted = B_FALSE;
boolean_t recursive = B_FALSE;
+ boolean_t parsable = B_FALSE;
int types = ZFS_TYPE_SNAPSHOT;
holds_cbdata_t cb = { 0 };
@@ -6529,7 +6580,7 @@ zfs_do_holds(int argc, char **argv)
int flags = 0;
/* check options */
- while ((c = getopt(argc, argv, "rH")) != -1) {
+ while ((c = getopt(argc, argv, "rHp")) != -1) {
switch (c) {
case 'r':
recursive = B_TRUE;
@@ -6537,6 +6588,9 @@ zfs_do_holds(int argc, char **argv)
case 'H':
scripted = B_TRUE;
break;
+ case 'p':
+ parsable = B_TRUE;
+ break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
@@ -6590,7 +6644,8 @@ zfs_do_holds(int argc, char **argv)
/*
* 2. print holds data
*/
- print_holds(scripted, cb.cb_max_namelen, cb.cb_max_taglen, nvl);
+ print_holds(scripted, cb.cb_max_namelen, cb.cb_max_taglen, nvl,
+ parsable);
if (nvlist_empty(nvl))
(void) fprintf(stderr, gettext("no datasets available\n"));
@@ -8518,7 +8573,7 @@ static int
zfs_do_wait(int argc, char **argv)
{
boolean_t enabled[ZFS_WAIT_NUM_ACTIVITIES];
- int error, i;
+ int error = 0, i;
int c;
/* By default, wait for all types of activity. */
diff --git a/sys/contrib/openzfs/cmd/zhack.c b/sys/contrib/openzfs/cmd/zhack.c
index 8797a53e4763..a1063ab147e2 100644
--- a/sys/contrib/openzfs/cmd/zhack.c
+++ b/sys/contrib/openzfs/cmd/zhack.c
@@ -140,8 +140,12 @@ zhack_import(char *target, boolean_t readonly)
g_importargs.can_be_active = readonly;
g_pool = strdup(target);
- error = zpool_find_config(NULL, target, &config, &g_importargs,
- &libzpool_config_ops);
+ libpc_handle_t lpch = {
+ .lpc_lib_handle = NULL,
+ .lpc_ops = &libzpool_config_ops,
+ .lpc_printerr = B_TRUE
+ };
+ error = zpool_find_config(&lpch, target, &config, &g_importargs);
if (error)
fatal(NULL, FTAG, "cannot import '%s'", target);
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index 39ea615f6319..8a4f3dd16271 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -3773,7 +3773,12 @@ zpool_do_import(int argc, char **argv)
idata.scan = do_scan;
idata.policy = policy;
- pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
+ libpc_handle_t lpch = {
+ .lpc_lib_handle = g_zfs,
+ .lpc_ops = &libzfs_config_ops,
+ .lpc_printerr = B_TRUE
+ };
+ pools = zpool_search_import(&lpch, &idata);
if (pools != NULL && pool_exists &&
(argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
@@ -3829,7 +3834,7 @@ zpool_do_import(int argc, char **argv)
*/
idata.scan = B_TRUE;
nvlist_free(pools);
- pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
+ pools = zpool_search_import(&lpch, &idata);
err = import_pools(pools, props, mntopts, flags,
argc >= 1 ? argv[0] : NULL,
diff --git a/sys/contrib/openzfs/cmd/zstream/Makefile.am b/sys/contrib/openzfs/cmd/zstream/Makefile.am
index 9ae33179e5d6..8506b351165e 100644
--- a/sys/contrib/openzfs/cmd/zstream/Makefile.am
+++ b/sys/contrib/openzfs/cmd/zstream/Makefile.am
@@ -6,6 +6,7 @@ zstream_SOURCES = \
%D%/zstream.h \
%D%/zstream_decompress.c \
%D%/zstream_dump.c \
+ %D%/zstream_recompress.c \
%D%/zstream_redup.c \
%D%/zstream_token.c
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream.c b/sys/contrib/openzfs/cmd/zstream/zstream.c
index eeceba2475ca..b1509c1f29ea 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream.c
+++ b/sys/contrib/openzfs/cmd/zstream/zstream.c
@@ -42,6 +42,8 @@ zstream_usage(void)
"\n"
"\tzstream decompress [-v] [OBJECT,OFFSET[,TYPE]] ...\n"
"\n"
+ "\tzstream recompress [ -l level] TYPE\n"
+ "\n"
"\tzstream token resume_token\n"
"\n"
"\tzstream redup [-v] FILE | ...\n");
@@ -65,6 +67,8 @@ main(int argc, char *argv[])
return (zstream_do_dump(argc - 1, argv + 1));
} else if (strcmp(subcommand, "decompress") == 0) {
return (zstream_do_decompress(argc - 1, argv + 1));
+ } else if (strcmp(subcommand, "recompress") == 0) {
+ return (zstream_do_recompress(argc - 1, argv + 1));
} else if (strcmp(subcommand, "token") == 0) {
return (zstream_do_token(argc - 1, argv + 1));
} else if (strcmp(subcommand, "redup") == 0) {
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream.h b/sys/contrib/openzfs/cmd/zstream/zstream.h
index 931d4e13fec0..f629a6cdfbab 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream.h
+++ b/sys/contrib/openzfs/cmd/zstream/zstream.h
@@ -30,6 +30,7 @@ extern void *safe_malloc(size_t size);
extern int zstream_do_redup(int, char *[]);
extern int zstream_do_dump(int, char *[]);
extern int zstream_do_decompress(int argc, char *argv[]);
+extern int zstream_do_recompress(int argc, char *argv[]);
extern int zstream_do_token(int, char *[]);
extern void zstream_usage(void);
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_decompress.c b/sys/contrib/openzfs/cmd/zstream/zstream_decompress.c
index 31d4b2d36982..6e0da0852b72 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream_decompress.c
+++ b/sys/contrib/openzfs/cmd/zstream/zstream_decompress.c
@@ -115,7 +115,9 @@ zstream_do_decompress(int argc, char *argv[])
if (errno || *end != '\0')
errx(1, "invalid value for offset");
if (argv[i]) {
- if (0 == strcmp("lz4", argv[i]))
+ if (0 == strcmp("off", argv[i]))
+ type = ZIO_COMPRESS_OFF;
+ else if (0 == strcmp("lz4", argv[i]))
type = ZIO_COMPRESS_LZ4;
else if (0 == strcmp("lzjb", argv[i]))
type = ZIO_COMPRESS_LZJB;
@@ -127,8 +129,8 @@ zstream_do_decompress(int argc, char *argv[])
type = ZIO_COMPRESS_ZSTD;
else {
fprintf(stderr, "Invalid compression type %s.\n"
- "Supported types are lz4, lzjb, gzip, zle, "
- "and zstd\n",
+ "Supported types are off, lz4, lzjb, gzip, "
+ "zle, and zstd\n",
argv[i]);
exit(2);
}
@@ -144,7 +146,7 @@ zstream_do_decompress(int argc, char *argv[])
p = hsearch(e, ENTER);
if (p == NULL)
errx(1, "hsearch");
- p->data = (void*)type;
+ p->data = (void*)(intptr_t)type;
}
if (isatty(STDIN_FILENO)) {
@@ -240,6 +242,9 @@ zstream_do_decompress(int argc, char *argv[])
if (p != NULL) {
zio_decompress_func_t *xfunc = NULL;
switch ((enum zio_compress)(intptr_t)p->data) {
+ case ZIO_COMPRESS_OFF:
+ xfunc = NULL;
+ break;
case ZIO_COMPRESS_LZJB:
xfunc = lzjb_decompress;
break;
@@ -258,7 +263,6 @@ zstream_do_decompress(int argc, char *argv[])
default:
assert(B_FALSE);
}
- assert(xfunc != NULL);
/*
@@ -266,12 +270,27 @@ zstream_do_decompress(int argc, char *argv[])
*/
char *lzbuf = safe_calloc(payload_size);
(void) sfread(lzbuf, payload_size, stdin);
- if (0 != xfunc(lzbuf, buf,
+ if (xfunc == NULL) {
+ memcpy(buf, lzbuf, payload_size);
+ drrw->drr_compressiontype =
+ ZIO_COMPRESS_OFF;
+ if (verbose)
+ fprintf(stderr, "Resetting "
+ "compression type to off "
+ "for ino %llu offset "
+ "%llu\n",
+ (u_longlong_t)
+ drrw->drr_object,
+ (u_longlong_t)
+ drrw->drr_offset);
+ } else if (0 != xfunc(lzbuf, buf,
payload_size, payload_size, 0)) {
/*
* The block must not be compressed,
- * possibly because it gets written
- * multiple times in this stream.
+ * at least not with this compression
+ * type, possibly because it gets
+ * written multiple times in this
+ * stream.
*/
warnx("decompression failed for "
"ino %llu offset %llu",
@@ -279,11 +298,16 @@ zstream_do_decompress(int argc, char *argv[])
(u_longlong_t)drrw->drr_offset);
memcpy(buf, lzbuf, payload_size);
} else if (verbose) {
+ drrw->drr_compressiontype =
+ ZIO_COMPRESS_OFF;
fprintf(stderr, "successfully "
"decompressed ino %llu "
"offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
+ } else {
+ drrw->drr_compressiontype =
+ ZIO_COMPRESS_OFF;
}
free(lzbuf);
} else {
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_dump.c b/sys/contrib/openzfs/cmd/zstream/zstream_dump.c
index 4b562c237373..9955a1361e8d 100644
--- a/sys/contrib/openzfs/cmd/zstream/zstream_dump.c
+++ b/sys/contrib/openzfs/cmd/zstream/zstream_dump.c
@@ -54,10 +54,10 @@
*/
#define DUMP_GROUPING 4
-uint64_t total_stream_len = 0;
-FILE *send_stream = 0;
-boolean_t do_byteswap = B_FALSE;
-boolean_t do_cksum = B_TRUE;
+static uint64_t total_stream_len = 0;
+static FILE *send_stream = 0;
+static boolean_t do_byteswap = B_FALSE;
+static boolean_t do_cksum = B_TRUE;
void *
safe_malloc(size_t size)
diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c b/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c
new file mode 100644
index 000000000000..b7370587fc6a
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zstream/zstream_recompress.c
@@ -0,0 +1,356 @@
+/*
+ * 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 2022 Axcient. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2022 by Delphix. All rights reserved.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/zio_checksum.h>
+#include <sys/zstd/zstd.h>
+#include "zfs_fletcher.h"
+#include "zstream.h"
+
+static int
+dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
+ zio_cksum_t *zc, int outfd)
+{
+ assert(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum)
+ == sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
+ fletcher_4_incremental_native(drr,
+ offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
+ if (drr->drr_type != DRR_BEGIN) {
+ assert(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
+ drr_checksum.drr_checksum));
+ drr->drr_u.drr_checksum.drr_checksum = *zc;
+ }
+ fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
+ sizeof (zio_cksum_t), zc);
+ if (write(outfd, drr, sizeof (*drr)) == -1)
+ return (errno);
+ if (payload_len != 0) {
+ fletcher_4_incremental_native(payload, payload_len, zc);
+ if (write(outfd, payload, payload_len) == -1)
+ return (errno);
+ }
+ return (0);
+}
+
+int
+zstream_do_recompress(int argc, char *argv[])
+{
+ int bufsz = SPA_MAXBLOCKSIZE;
+ char *buf = safe_malloc(bufsz);
+ dmu_replay_record_t thedrr;
+ dmu_replay_record_t *drr = &thedrr;
+ zio_cksum_t stream_cksum;
+ int c;
+ int level = -1;
+
+ while ((c = getopt(argc, argv, "l:")) != -1) {
+ switch (c) {
+ case 'l':
+ if (sscanf(optarg, "%d", &level) != 0) {
+ fprintf(stderr,
+ "failed to parse level '%s'\n",
+ optarg);
+ zstream_usage();
+ }
+ break;
+ case '?':
+ (void) fprintf(stderr, "invalid option '%c'\n",
+ optopt);
+ zstream_usage();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ zstream_usage();
+ int type = 0;
+ zio_compress_info_t *cinfo = NULL;
+ if (0 == strcmp(argv[0], "off")) {
+ type = ZIO_COMPRESS_OFF;
+ cinfo = &zio_compress_table[type];
+ } else if (0 == strcmp(argv[0], "inherit") ||
+ 0 == strcmp(argv[0], "empty") ||
+ 0 == strcmp(argv[0], "on")) {
+ // Fall through to invalid compression type case
+ } else {
+ for (int i = 0; i < ZIO_COMPRESS_FUNCTIONS; i++) {
+ if (0 == strcmp(zio_compress_table[i].ci_name,
+ argv[0])) {
+ cinfo = &zio_compress_table[i];
+ type = i;
+ break;
+ }
+ }
+ }
+ if (cinfo == NULL) {
+ fprintf(stderr, "Invalid compression type %s.\n",
+ argv[0]);
+ exit(2);
+ }
+
+ if (cinfo->ci_compress == NULL) {
+ type = 0;
+ cinfo = &zio_compress_table[0];
+ }
+
+ if (isatty(STDIN_FILENO)) {
+ (void) fprintf(stderr,
+ "Error: The send stream is a binary format "
+ "and can not be read from a\n"
+ "terminal. Standard input must be redirected.\n");
+ exit(1);
+ }
+
+ fletcher_4_init();
+ zio_init();
+ zstd_init();
+ while (sfread(drr, sizeof (*drr), stdin) != 0) {
+ struct drr_write *drrw;
+ uint64_t payload_size = 0;
+
+ /*
+ * We need to regenerate the checksum.
+ */
+ if (drr->drr_type != DRR_BEGIN) {
+ memset(&drr->drr_u.drr_checksum.drr_checksum, 0,
+ sizeof (drr->drr_u.drr_checksum.drr_checksum));
+ }
+
+
+ switch (drr->drr_type) {
+ case DRR_BEGIN:
+ {
+ ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
+
+ int sz = drr->drr_payloadlen;
+ if (sz != 0) {
+ if (sz > bufsz) {
+ buf = realloc(buf, sz);
+ if (buf == NULL)
+ err(1, "realloc");
+ bufsz = sz;
+ }
+ (void) sfread(buf, sz, stdin);
+ }
+ payload_size = sz;
+ break;
+ }
+ case DRR_END:
+ {
+ struct drr_end *drre = &drr->drr_u.drr_end;
+ /*
+ * Use the recalculated checksum, unless this is
+ * the END record of a stream package, which has
+ * no checksum.
+ */
+ if (!ZIO_CHECKSUM_IS_ZERO(&drre->drr_checksum))
+ drre->drr_checksum = stream_cksum;
+ break;
+ }
+
+ case DRR_OBJECT:
+ {
+ struct drr_object *drro = &drr->drr_u.drr_object;
+
+ if (drro->drr_bonuslen > 0) {
+ payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
+ (void) sfread(buf, payload_size, stdin);
+ }
+ break;
+ }
+
+ case DRR_SPILL:
+ {
+ struct drr_spill *drrs = &drr->drr_u.drr_spill;
+ payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
+ (void) sfread(buf, payload_size, stdin);
+ break;
+ }
+
+ case DRR_WRITE_BYREF:
+ fprintf(stderr,
+ "Deduplicated streams are not supported\n");
+ exit(1);
+ break;
+
+ case DRR_WRITE:
+ {
+ drrw = &thedrr.drr_u.drr_write;
+ payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
+ /*
+ * In order to recompress an encrypted block, you have
+ * to decrypt, decompress, recompress, and
+ * re-encrypt. That can be a future enhancement (along
+ * with decryption or re-encryption), but for now we
+ * skip encrypted blocks.
+ */
+ boolean_t encrypted = B_FALSE;
+ for (int i = 0; i < ZIO_DATA_SALT_LEN; i++) {
+ if (drrw->drr_salt[i] != 0) {
+ encrypted = B_TRUE;
+ break;
+ }
+ }
+ if (encrypted) {
+ (void) sfread(buf, payload_size, stdin);
+ break;
+ }
+ if (drrw->drr_compressiontype >=
+ ZIO_COMPRESS_FUNCTIONS) {
+ fprintf(stderr, "Invalid compression type in "
+ "stream: %d\n", drrw->drr_compressiontype);
+ exit(3);
+ }
+ zio_compress_info_t *dinfo =
+ &zio_compress_table[drrw->drr_compressiontype];
+
+ /* Set up buffers to minimize memcpys */
+ char *cbuf, *dbuf;
+ if (cinfo->ci_compress == NULL)
+ dbuf = buf;
+ else
+ dbuf = safe_calloc(bufsz);
+
+ if (dinfo->ci_decompress == NULL)
+ cbuf = dbuf;
+ else
+ cbuf = safe_calloc(payload_size);
+
+ /* Read and decompress the payload */
+ (void) sfread(cbuf, payload_size, stdin);
+ if (dinfo->ci_decompress != NULL) {
+ if (0 != dinfo->ci_decompress(cbuf, dbuf,
+ payload_size, MIN(bufsz,
+ drrw->drr_logical_size), dinfo->ci_level)) {
+ warnx("decompression type %d failed "
+ "for ino %llu offset %llu",
+ type,
+ (u_longlong_t)drrw->drr_object,
+ (u_longlong_t)drrw->drr_offset);
+ exit(4);
+ }
+ payload_size = drrw->drr_logical_size;
+ free(cbuf);
+ }
+
+ /* Recompress the payload */
+ if (cinfo->ci_compress != NULL) {
+ payload_size = P2ROUNDUP(cinfo->ci_compress(
+ dbuf, buf, drrw->drr_logical_size,
+ MIN(payload_size, bufsz), (level == -1 ?
+ cinfo->ci_level : level)),
+ SPA_MINBLOCKSIZE);
+ if (payload_size != drrw->drr_logical_size) {
+ drrw->drr_compressiontype = type;
+ drrw->drr_compressed_size =
+ payload_size;
+ } else {
+ memcpy(buf, dbuf, payload_size);
+ drrw->drr_compressiontype = 0;
+ drrw->drr_compressed_size = 0;
+ }
+ free(dbuf);
+ } else {
+ drrw->drr_compressiontype = type;
+ drrw->drr_compressed_size = 0;
+ }
+ break;
+ }
+
+ case DRR_WRITE_EMBEDDED:
+ {
+ struct drr_write_embedded *drrwe =
+ &drr->drr_u.drr_write_embedded;
+ payload_size =
+ P2ROUNDUP((uint64_t)drrwe->drr_psize, 8);
+ (void) sfread(buf, payload_size, stdin);
+ break;
+ }
+
+ case DRR_FREEOBJECTS:
+ case DRR_FREE:
+ case DRR_OBJECT_RANGE:
+ break;
+
+ default:
+ (void) fprintf(stderr, "INVALID record type 0x%x\n",
+ drr->drr_type);
+ /* should never happen, so assert */
+ assert(B_FALSE);
+ }
+
+ if (feof(stdout)) {
+ fprintf(stderr, "Error: unexpected end-of-file\n");
+ exit(1);
+ }
+ if (ferror(stdout)) {
+ fprintf(stderr, "Error while reading file: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * We need to recalculate the checksum, and it needs to be
+ * initially zero to do that. BEGIN records don't have
+ * a checksum.
+ */
+ if (drr->drr_type != DRR_BEGIN) {
+ memset(&drr->drr_u.drr_checksum.drr_checksum, 0,
+ sizeof (drr->drr_u.drr_checksum.drr_checksum));
+ }
+ if (dump_record(drr, buf, payload_size,
+ &stream_cksum, STDOUT_FILENO) != 0)
+ break;
+ if (drr->drr_type == DRR_END) {
+ /*
+ * Typically the END record is either the last
+ * thing in the stream, or it is followed
+ * by a BEGIN record (which also zeros the checksum).
+ * However, a stream package ends with two END
+ * records. The last END record's checksum starts
+ * from zero.
+ */
+ ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
+ }
+ }
+ free(buf);
+ fletcher_4_fini();
+ zio_fini();
+ zstd_fini();
+
+ return (0);
+}
diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c
index e630d3353187..1c7c74c5d80f 100644
--- a/sys/contrib/openzfs/cmd/ztest.c
+++ b/sys/contrib/openzfs/cmd/ztest.c
@@ -252,7 +252,7 @@ static const ztest_shared_opts_t ztest_opts_defaults = {
extern uint64_t metaslab_force_ganging;
extern uint64_t metaslab_df_alloc_threshold;
-extern unsigned long zfs_deadman_synctime_ms;
+extern uint64_t zfs_deadman_synctime_ms;
extern uint_t metaslab_preload_limit;
extern int zfs_compressed_arc_enabled;
extern int zfs_abd_scatter_enabled;
@@ -423,11 +423,11 @@ ztest_func_t ztest_fletcher;
ztest_func_t ztest_fletcher_incr;
ztest_func_t ztest_verify_dnode_bt;
-uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
-uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
-uint64_t zopt_often = 1ULL * NANOSEC; /* every second */
-uint64_t zopt_sometimes = 10ULL * NANOSEC; /* every 10 seconds */
-uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */
+static uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
+static uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
+static uint64_t zopt_often = 1ULL * NANOSEC; /* every second */
+static uint64_t zopt_sometimes = 10ULL * NANOSEC; /* every 10 seconds */
+static uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */
#define ZTI_INIT(func, iters, interval) \
{ .zi_func = (func), \
@@ -435,7 +435,7 @@ uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */
.zi_interval = (interval), \
.zi_funcname = # func }
-ztest_info_t ztest_info[] = {
+static ztest_info_t ztest_info[] = {
ZTI_INIT(ztest_dmu_read_write, 1, &zopt_always),
ZTI_INIT(ztest_dmu_write_parallel, 10, &zopt_always),
ZTI_INIT(ztest_dmu_object_alloc_free, 1, &zopt_always),
@@ -515,7 +515,7 @@ typedef struct ztest_shared {
static char ztest_dev_template[] = "%s/%s.%llua";
static char ztest_aux_template[] = "%s/%s.%s.%llu";
-ztest_shared_t *ztest_shared;
+static ztest_shared_t *ztest_shared;
static spa_t *ztest_spa = NULL;
static ztest_ds_t *ztest_ds;
@@ -2177,6 +2177,7 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
* but not always, because we also want to verify correct
* behavior when the data was not recently read into cache.
*/
+ ASSERT(doi.doi_data_block_size);
ASSERT0(offset % doi.doi_data_block_size);
if (ztest_random(4) != 0) {
int prefetch = ztest_random(2) ?
@@ -2346,7 +2347,7 @@ ztest_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
return (0);
}
-zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = {
+static zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = {
NULL, /* 0 no such transaction type */
ztest_replay_create, /* TX_CREATE */
NULL, /* TX_MKDIR */
@@ -2368,6 +2369,8 @@ zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = {
NULL, /* TX_MKDIR_ACL_ATTR */
NULL, /* TX_WRITE2 */
NULL, /* TX_SETSAXATTR */
+ NULL, /* TX_RENAME_EXCHANGE */
+ NULL, /* TX_RENAME_WHITEOUT */
};
/*
@@ -3512,7 +3515,8 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
VERIFY0(nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN,
&child, &children));
- schild = malloc(rvd->vdev_children * sizeof (nvlist_t *));
+ schild = umem_alloc(rvd->vdev_children * sizeof (nvlist_t *),
+ UMEM_NOFAIL);
for (c = 0; c < children; c++) {
vdev_t *tvd = rvd->vdev_child[c];
nvlist_t **mchild;
@@ -3546,7 +3550,7 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
for (c = 0; c < schildren; c++)
fnvlist_free(schild[c]);
- free(schild);
+ umem_free(schild, rvd->vdev_children * sizeof (nvlist_t *));
fnvlist_free(split);
spa_config_exit(spa, SCL_VDEV, FTAG);
@@ -6663,7 +6667,7 @@ join_strings(char **strings, const char *sep)
}
size_t buflen = totallen + 1;
- char *o = malloc(buflen); /* trailing 0 byte */
+ char *o = umem_alloc(buflen, UMEM_NOFAIL); /* trailing 0 byte */
o[0] = '\0';
for (char **sp = strings; *sp != NULL; sp++) {
size_t would;
@@ -6925,7 +6929,7 @@ ztest_run_zdb(const char *pool)
pool);
ASSERT3U(would, <, len);
- free(set_gvars_args_joined);
+ umem_free(set_gvars_args_joined, strlen(set_gvars_args_joined) + 1);
if (ztest_opts.zo_verbose >= 5)
(void) printf("Executing %s\n", zdb);
@@ -7118,9 +7122,9 @@ ztest_deadman_thread(void *arg)
*/
if (spa_suspended(spa) || spa->spa_root_vdev == NULL) {
fatal(B_FALSE,
- "aborting test after %lu seconds because "
+ "aborting test after %llu seconds because "
"pool has transitioned to a suspended state.",
- zfs_deadman_synctime_ms / 1000);
+ (u_longlong_t)zfs_deadman_synctime_ms / 1000);
}
vdev_deadman(spa->spa_root_vdev, FTAG);
@@ -7471,8 +7475,12 @@ ztest_import_impl(void)
args.path = searchdirs;
args.can_be_active = B_FALSE;
- VERIFY0(zpool_find_config(NULL, ztest_opts.zo_pool, &cfg, &args,
- &libzpool_config_ops));
+ libpc_handle_t lpch = {
+ .lpc_lib_handle = NULL,
+ .lpc_ops = &libzpool_config_ops,
+ .lpc_printerr = B_TRUE
+ };
+ VERIFY0(zpool_find_config(&lpch, ztest_opts.zo_pool, &cfg, &args));
VERIFY0(spa_import(ztest_opts.zo_pool, cfg, NULL, flags));
fnvlist_free(cfg);
}
diff --git a/sys/contrib/openzfs/cmd/zvol_wait b/sys/contrib/openzfs/cmd/zvol_wait
index f1fa42e27dc9..0b2a8a3e60c3 100755
--- a/sys/contrib/openzfs/cmd/zvol_wait
+++ b/sys/contrib/openzfs/cmd/zvol_wait
@@ -109,6 +109,13 @@ while [ "$outer_loop" -lt 20 ]; do
exit 0
fi
fi
+
+ #
+ # zvol_count made some progress - let's stay in this loop.
+ #
+ if [ "$old_zvols_count" -gt "$zvols_count" ]; then
+ outer_loop=$((outer_loop - 1))
+ fi
done
echo "Timed out waiting on zvol links"
diff --git a/sys/contrib/openzfs/config/kernel-dentry-alias.m4 b/sys/contrib/openzfs/config/kernel-dentry-alias.m4
new file mode 100644
index 000000000000..f0ddb8d010b0
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-dentry-alias.m4
@@ -0,0 +1,30 @@
+dnl #
+dnl # 3.18 API change
+dnl # Dentry aliases are in d_u struct dentry member
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U], [
+ ZFS_LINUX_TEST_SRC([dentry_alias_d_u], [
+ #include <linux/fs.h>
+ #include <linux/dcache.h>
+ #include <linux/list.h>
+ ], [
+ struct inode *inode __attribute__ ((unused)) = NULL;
+ struct dentry *dentry __attribute__ ((unused)) = NULL;
+ hlist_for_each_entry(dentry, &inode->i_dentry,
+ d_u.d_alias) {
+ d_drop(dentry);
+ }
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_DENTRY_ALIAS_D_U], [
+ AC_MSG_CHECKING([whether dentry aliases are in d_u member])
+ ZFS_LINUX_TEST_RESULT([dentry_alias_d_u], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_DENTRY_D_U_ALIASES, 1,
+ [dentry aliases are in d_u member])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
diff --git a/sys/contrib/openzfs/config/kernel-iattr-vfsid.m4 b/sys/contrib/openzfs/config/kernel-iattr-vfsid.m4
new file mode 100644
index 000000000000..75bc4613b838
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-iattr-vfsid.m4
@@ -0,0 +1,24 @@
+dnl #
+dnl # 6.0 API change
+dnl # struct iattr has two unions for the uid and gid
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_IATTR_VFSID], [
+ ZFS_LINUX_TEST_SRC([iattr_vfsid], [
+ #include <linux/fs.h>
+ ], [
+ struct iattr ia;
+ ia.ia_vfsuid = (vfsuid_t){0};
+ ia.ia_vfsgid = (vfsgid_t){0};
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_IATTR_VFSID], [
+ AC_MSG_CHECKING([whether iattr->ia_vfsuid and iattr->ia_vfsgid exist])
+ ZFS_LINUX_TEST_RESULT([iattr_vfsid], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_IATTR_VFSID, 1,
+ [iattr->ia_vfsuid and iattr->ia_vfsgid exist])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
diff --git a/sys/contrib/openzfs/config/kernel-idmap_mnt_api.m4 b/sys/contrib/openzfs/config/kernel-idmap_mnt_api.m4
new file mode 100644
index 000000000000..47ddc5702fb7
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-idmap_mnt_api.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 5.12 API
+dnl #
+dnl # Check if APIs for idmapped mount are available
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_IDMAP_MNT_API], [
+ ZFS_LINUX_TEST_SRC([idmap_mnt_api], [
+ #include <linux/fs.h>
+ ],[
+ int fs_flags = 0;
+ fs_flags |= FS_ALLOW_IDMAP;
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_IDMAP_MNT_API], [
+ AC_MSG_CHECKING([whether APIs for idmapped mount are present])
+ ZFS_LINUX_TEST_RESULT([idmap_mnt_api], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_IDMAP_MNT_API, 1,
+ [APIs for idmapped mount are present])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+])
+
diff --git a/sys/contrib/openzfs/config/kernel-mod-param.m4 b/sys/contrib/openzfs/config/kernel-mod-param.m4
deleted file mode 100644
index e00f19d61e7d..000000000000
--- a/sys/contrib/openzfs/config/kernel-mod-param.m4
+++ /dev/null
@@ -1,33 +0,0 @@
-dnl #
-dnl # Grsecurity kernel API change
-dnl # constified parameters of module_param_call() methods
-dnl #
-AC_DEFUN([ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST], [
- ZFS_LINUX_TEST_SRC([module_param_call], [
- #include <linux/module.h>
- #include <linux/moduleparam.h>
-
- int param_get(char *b, const struct kernel_param *kp)
- {
- return (0);
- }
-
- int param_set(const char *b, const struct kernel_param *kp)
- {
- return (0);
- }
-
- module_param_call(p, param_set, param_get, NULL, 0644);
- ],[])
-])
-
-AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [
- AC_MSG_CHECKING([whether module_param_call() is hardened])
- ZFS_LINUX_TEST_RESULT([module_param_call], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(MODULE_PARAM_CALL_CONST, 1,
- [hardened module_param_call])
- ],[
- AC_MSG_RESULT(no)
- ])
-])
diff --git a/sys/contrib/openzfs/config/kernel-rename.m4 b/sys/contrib/openzfs/config/kernel-rename.m4
index 302db43f5748..a2b0800ab4d2 100644
--- a/sys/contrib/openzfs/config/kernel-rename.m4
+++ b/sys/contrib/openzfs/config/kernel-rename.m4
@@ -1,8 +1,28 @@
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
dnl #
+ dnl # 3.9 (to 4.9) API change,
+ dnl #
+ dnl # A new version of iops->rename() was added (rename2) that takes a flag
+ dnl # argument (to support renameat2). However this separate function was
+ dnl # merged back into iops->rename() in Linux 4.9.
+ dnl #
+ ZFS_LINUX_TEST_SRC([inode_operations_rename2], [
+ #include <linux/fs.h>
+ int rename2_fn(struct inode *sip, struct dentry *sdp,
+ struct inode *tip, struct dentry *tdp,
+ unsigned int flags) { return 0; }
+
+ static const struct inode_operations
+ iops __attribute__ ((unused)) = {
+ .rename2 = rename2_fn,
+ };
+ ],[])
+
+ dnl #
dnl # 4.9 API change,
- dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
- dnl # flags.
+ dnl #
+ dnl # iops->rename2() merged into iops->rename(), and iops->rename() now
+ dnl # wants flags.
dnl #
ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
#include <linux/fs.h>
@@ -17,10 +37,28 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
],[])
dnl #
+ dnl # EL7 compatibility
+ dnl #
+ dnl # EL7 has backported renameat2 support, but it's done by defining a
+ dnl # separate iops wrapper structure that takes the .renameat2 function.
+ dnl #
+ ZFS_LINUX_TEST_SRC([dir_inode_operations_wrapper_rename2], [
+ #include <linux/fs.h>
+ int rename2_fn(struct inode *sip, struct dentry *sdp,
+ struct inode *tip, struct dentry *tdp,
+ unsigned int flags) { return 0; }
+
+ static const struct inode_operations_wrapper
+ iops __attribute__ ((unused)) = {
+ .rename2 = rename2_fn,
+ };
+ ],[])
+
+ dnl #
dnl # 5.12 API change,
dnl #
- dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
- dnl # of the rename() and other inode_operations members.
+ dnl # Linux 5.12 introduced passing struct user_namespace* as the first
+ dnl # argument of the rename() and other inode_operations members.
dnl #
ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
#include <linux/fs.h>
@@ -44,13 +82,30 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
],[
AC_MSG_RESULT(no)
- AC_MSG_CHECKING([whether iop->rename() wants flags])
- ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
+ AC_MSG_CHECKING([whether iops->rename2() exists])
+ ZFS_LINUX_TEST_RESULT([inode_operations_rename2], [
AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
- [iops->rename() wants flags])
+ AC_DEFINE(HAVE_RENAME2, 1, [iops->rename2() exists])
],[
AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([whether iops->rename() wants flags])
+ ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
+ [iops->rename() wants flags])
+ ],[
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([whether struct inode_operations_wrapper takes .rename2()])
+ ZFS_LINUX_TEST_RESULT([dir_inode_operations_wrapper_rename2], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_RENAME2_OPERATIONS_WRAPPER, 1,
+ [struct inode_operations_wrapper takes .rename2()])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ ])
])
])
])
diff --git a/sys/contrib/openzfs/config/kernel.m4 b/sys/contrib/openzfs/config/kernel.m4
index 6aad2cf88e02..c71d576f492e 100644
--- a/sys/contrib/openzfs/config/kernel.m4
+++ b/sys/contrib/openzfs/config/kernel.m4
@@ -96,6 +96,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_SETATTR_PREPARE
ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED
ZFS_AC_KERNEL_SRC_DENTRY
+ ZFS_AC_KERNEL_SRC_DENTRY_ALIAS_D_U
ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE
ZFS_AC_KERNEL_SRC_SECURITY_INODE
ZFS_AC_KERNEL_SRC_FST_MOUNT
@@ -122,7 +123,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_FMODE_T
ZFS_AC_KERNEL_SRC_KUIDGID_T
ZFS_AC_KERNEL_SRC_KUID_HELPERS
- ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
ZFS_AC_KERNEL_SRC_RENAME
ZFS_AC_KERNEL_SRC_CURRENT_TIME
ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
@@ -148,6 +148,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_ZERO_PAGE
ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC
ZFS_AC_KERNEL_SRC_USER_NS_COMMON_INUM
+ ZFS_AC_KERNEL_SRC_IDMAP_MNT_API
+ ZFS_AC_KERNEL_SRC_IATTR_VFSID
AC_MSG_CHECKING([for available kernel interfaces])
ZFS_LINUX_TEST_COMPILE_ALL([kabi])
@@ -217,6 +219,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_SETATTR_PREPARE
ZFS_AC_KERNEL_INSERT_INODE_LOCKED
ZFS_AC_KERNEL_DENTRY
+ ZFS_AC_KERNEL_DENTRY_ALIAS_D_U
ZFS_AC_KERNEL_TRUNCATE_SETSIZE
ZFS_AC_KERNEL_SECURITY_INODE
ZFS_AC_KERNEL_FST_MOUNT
@@ -243,7 +246,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_FMODE_T
ZFS_AC_KERNEL_KUIDGID_T
ZFS_AC_KERNEL_KUID_HELPERS
- ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
ZFS_AC_KERNEL_RENAME
ZFS_AC_KERNEL_CURRENT_TIME
ZFS_AC_KERNEL_USERNS_CAPABILITIES
@@ -269,6 +271,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_ZERO_PAGE
ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC
ZFS_AC_KERNEL_USER_NS_COMMON_INUM
+ ZFS_AC_KERNEL_IDMAP_MNT_API
+ ZFS_AC_KERNEL_IATTR_VFSID
])
dnl #
@@ -942,8 +946,15 @@ dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are
dnl # provided via the fifth parameter
dnl #
AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
- ZFS_LINUX_COMPILE_IFELSE(
- [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]], [[ZFS_META_LICENSE]])],
- [test -f build/conftest/conftest.ko],
- [$3], [$4], [$5])
+ AS_IF([test "x$enable_linux_builtin" = "xyes"], [
+ ZFS_LINUX_COMPILE_IFELSE(
+ [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
+ [[ZFS_META_LICENSE]])],
+ [test -f build/conftest/conftest.o], [$3], [$4], [$5])
+ ], [
+ ZFS_LINUX_COMPILE_IFELSE(
+ [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
+ [[ZFS_META_LICENSE]])],
+ [test -f build/conftest/conftest.ko], [$3], [$4], [$5])
+ ])
])
diff --git a/sys/contrib/openzfs/contrib/coverity/model.c b/sys/contrib/openzfs/contrib/coverity/model.c
index 8baa3a7e2d31..8e3e83cada19 100644
--- a/sys/contrib/openzfs/contrib/coverity/model.c
+++ b/sys/contrib/openzfs/contrib/coverity/model.c
@@ -29,11 +29,20 @@
#define NULL (0)
+typedef enum {
+ B_FALSE = 0,
+ B_TRUE = 1
+} boolean_t;
+
+typedef unsigned int uint_t;
+
int condition0, condition1;
int
ddi_copyin(const void *from, void *to, size_t len, int flags)
{
+ (void) flags;
+ __coverity_negative_sink__(len);
__coverity_tainted_data_argument__(from);
__coverity_tainted_data_argument__(to);
__coverity_writeall__(to);
@@ -42,13 +51,21 @@ ddi_copyin(const void *from, void *to, size_t len, int flags)
void *
memset(void *dst, int c, size_t len)
{
- __coverity_writeall__(dst);
+ __coverity_negative_sink__(len);
+ if (c == 0)
+ __coverity_writeall0__(dst);
+ else
+ __coverity_writeall__(dst);
return (dst);
}
void *
memmove(void *dst, void *src, size_t len)
{
+ int first = ((char *)src)[0];
+ int last = ((char *)src)[len-1];
+
+ __coverity_negative_sink__(len);
__coverity_writeall__(dst);
return (dst);
}
@@ -56,6 +73,10 @@ memmove(void *dst, void *src, size_t len)
void *
memcpy(void *dst, void *src, size_t len)
{
+ int first = ((char *)src)[0];
+ int last = ((char *)src)[len-1];
+
+ __coverity_negative_sink__(len);
__coverity_writeall__(dst);
return (dst);
}
@@ -63,43 +84,53 @@ memcpy(void *dst, void *src, size_t len)
void *
umem_alloc_aligned(size_t size, size_t align, int kmflags)
{
- (void) align;
+ __coverity_negative_sink__(size);
+ __coverity_negative_sink__(align);
- if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL)
- return (__coverity_alloc__(size));
- else if (condition0)
- return (__coverity_alloc__(size));
- else
- return (NULL);
+ if (((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) || condition0) {
+ void *buf = __coverity_alloc__(size);
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "umem_free");
+ return (buf);
+ }
+
+ return (NULL);
}
void *
umem_alloc(size_t size, int kmflags)
{
- if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL)
- return (__coverity_alloc__(size));
- else if (condition0)
- return (__coverity_alloc__(size));
- else
- return (NULL);
+ __coverity_negative_sink__(size);
+
+ if (((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) || condition0) {
+ void *buf = __coverity_alloc__(size);
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "umem_free");
+ return (buf);
+ }
+
+ return (NULL);
}
void *
umem_zalloc(size_t size, int kmflags)
{
- if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL)
- return (__coverity_alloc__(size));
- else if (condition0)
- return (__coverity_alloc__(size));
- else
- return (NULL);
+ __coverity_negative_sink__(size);
+
+ if (((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) || condition0) {
+ void *buf = __coverity_alloc__(size);
+ __coverity_writeall0__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "umem_free");
+ return (buf);
+ }
+
+ return (NULL);
}
void
umem_free(void *buf, size_t size)
{
- (void) size;
-
+ __coverity_negative_sink__(size);
__coverity_free__(buf);
}
@@ -113,12 +144,14 @@ umem_cache_alloc(umem_cache_t *skc, int flags)
if (condition1)
__coverity_sleep__();
- if ((UMEM_NOFAIL & flags) == UMEM_NOFAIL)
- return (__coverity_alloc_nosize__());
- else if (condition0)
- return (__coverity_alloc_nosize__());
- else
- return (NULL);
+ if (((UMEM_NOFAIL & flags) == UMEM_NOFAIL) || condition0) {
+ void *buf = __coverity_alloc_nosize__();
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "umem_cache_free");
+ return (buf);
+ }
+
+ return (NULL);
}
void
@@ -135,15 +168,19 @@ spl_kmem_alloc(size_t sz, int fl, const char *func, int line)
(void) func;
(void) line;
+ __coverity_negative_sink__(sz);
+
if (condition1)
__coverity_sleep__();
- if (fl == 0) {
- return (__coverity_alloc__(sz));
- } else if (condition0)
- return (__coverity_alloc__(sz));
- else
- return (NULL);
+ if ((fl == 0) || condition0) {
+ void *buf = __coverity_alloc__(sz);
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "spl_kmem_free");
+ return (buf);
+ }
+
+ return (NULL);
}
void *
@@ -152,22 +189,126 @@ spl_kmem_zalloc(size_t sz, int fl, const char *func, int line)
(void) func;
(void) line;
+ __coverity_negative_sink__(sz);
+
if (condition1)
__coverity_sleep__();
- if (fl == 0) {
- return (__coverity_alloc__(sz));
- } else if (condition0)
- return (__coverity_alloc__(sz));
- else
- return (NULL);
+ if ((fl == 0) || condition0) {
+ void *buf = __coverity_alloc__(sz);
+ __coverity_writeall0__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "spl_kmem_free");
+ return (buf);
+ }
+
+ return (NULL);
}
void
spl_kmem_free(const void *ptr, size_t sz)
{
- (void) sz;
+ __coverity_negative_sink__(sz);
+ __coverity_free__(ptr);
+}
+
+char *
+kmem_vasprintf(const char *fmt, va_list ap)
+{
+ char *buf = __coverity_alloc_nosize__();
+ (void) ap;
+
+ __coverity_string_null_sink__(fmt);
+ __coverity_string_size_sink__(fmt);
+
+ __coverity_writeall__(buf);
+
+ __coverity_mark_as_afm_allocated__(buf, "kmem_strfree");
+
+ return (buf);
+}
+
+char *
+kmem_asprintf(const char *fmt, ...)
+{
+ char *buf = __coverity_alloc_nosize__();
+ __coverity_string_null_sink__(fmt);
+ __coverity_string_size_sink__(fmt);
+
+ __coverity_writeall__(buf);
+
+ __coverity_mark_as_afm_allocated__(buf, "kmem_strfree");
+
+ return (buf);
+}
+
+char *
+kmem_strdup(const char *str)
+{
+ char *buf = __coverity_alloc_nosize__();
+
+ __coverity_string_null_sink__(str);
+ __coverity_string_size_sink__(str);
+
+ __coverity_writeall__(buf);
+
+ __coverity_mark_as_afm_allocated__(buf, "kmem_strfree");
+
+ return (buf);
+
+
+}
+
+void
+kmem_strfree(char *str)
+{
+ __coverity_free__(str);
+}
+
+void *
+spl_vmem_alloc(size_t sz, int fl, const char *func, int line)
+{
+ (void) func;
+ (void) line;
+
+ __coverity_negative_sink__(sz);
+
+ if (condition1)
+ __coverity_sleep__();
+
+ if ((fl == 0) || condition0) {
+ void *buf = __coverity_alloc__(sz);
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "spl_vmem_free");
+ return (buf);
+ }
+
+ return (NULL);
+}
+
+void *
+spl_vmem_zalloc(size_t sz, int fl, const char *func, int line)
+{
+ (void) func;
+ (void) line;
+
+ if (condition1)
+ __coverity_sleep__();
+
+ if ((fl == 0) || condition0) {
+ void *buf = __coverity_alloc__(sz);
+ __coverity_writeall0__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "spl_vmem_free");
+ return (buf);
+ }
+
+ return (NULL);
+}
+
+void
+spl_vmem_free(const void *ptr, size_t sz)
+{
+ __coverity_negative_sink__(sz);
__coverity_free__(ptr);
}
@@ -181,12 +322,12 @@ spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags)
if (condition1)
__coverity_sleep__();
- if (flags == 0) {
- return (__coverity_alloc_nosize__());
- } else if (condition0)
- return (__coverity_alloc_nosize__());
- else
- return (NULL);
+ if ((flags == 0) || condition0) {
+ void *buf = __coverity_alloc_nosize__();
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "spl_kmem_cache_free");
+ return (buf);
+ }
}
void
@@ -197,12 +338,164 @@ spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj)
__coverity_free__(obj);
}
+typedef struct {} zfsvfs_t;
+
+int
+zfsvfs_create(const char *osname, boolean_t readonly, zfsvfs_t **zfvp)
+{
+ (void) osname;
+ (void) readonly;
+
+ if (condition1)
+ __coverity_sleep__();
+
+ if (condition0) {
+ *zfvp = __coverity_alloc_nosize__();
+ __coverity_writeall__(*zfvp);
+ return (0);
+ }
+
+ return (1);
+}
+
void
+zfsvfs_free(zfsvfs_t *zfsvfs)
+{
+ __coverity_free__(zfsvfs);
+}
+
+typedef struct {} nvlist_t;
+
+int
+nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag)
+{
+ (void) nvflag;
+
+ if (condition1)
+ __coverity_sleep__();
+
+ if ((kmflag == 0) || condition0) {
+ *nvlp = __coverity_alloc_nosize__();
+ __coverity_mark_as_afm_allocated__(*nvlp, "nvlist_free");
+ __coverity_writeall__(*nvlp);
+ return (0);
+ }
+
+ return (-1);
+
+}
+
+int
+nvlist_dup(const nvlist_t *nvl, nvlist_t **nvlp, int kmflag)
+{
+ nvlist_t read = *nvl;
+
+ if (condition1)
+ __coverity_sleep__();
+
+ if ((kmflag == 0) || condition0) {
+ nvlist_t *nvl = __coverity_alloc_nosize__();
+ __coverity_mark_as_afm_allocated__(nvl, "nvlist_free");
+ __coverity_writeall__(nvl);
+ *nvlp = nvl;
+ return (0);
+ }
+
+ return (-1);
+}
+
+void
+nvlist_free(nvlist_t *nvl)
+{
+ __coverity_free__(nvl);
+}
+
+int
+nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
+ int kmflag)
+{
+ (void) nvl;
+ (void) encoding;
+
+ if (*bufp == NULL) {
+ if (condition1)
+ __coverity_sleep__();
+
+ if ((kmflag == 0) || condition0) {
+ char *buf = __coverity_alloc_nosize__();
+ __coverity_writeall__(buf);
+ /*
+ * We cannot use __coverity_mark_as_afm_allocated__()
+ * because the free function varies between the kernel
+ * and userspace.
+ */
+ *bufp = buf;
+ return (0);
+ }
+
+ return (-1);
+ }
+
+ /*
+ * Unfortunately, errors from the buffer being too small are not
+ * possible to model, so we assume success.
+ */
+ __coverity_negative_sink__(*buflen);
+ __coverity_writeall__(*bufp);
+ return (0);
+}
+
+
+int
+nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag)
+{
+ __coverity_negative_sink__(buflen);
+
+ if (condition1)
+ __coverity_sleep__();
+
+ if ((kmflag == 0) || condition0) {
+ nvlist_t *nvl = __coverity_alloc_nosize__();
+ __coverity_mark_as_afm_allocated__(nvl, "nvlist_free");
+ __coverity_writeall__(nvl);
+ *nvlp = nvl;
+ int first = buf[0];
+ int last = buf[buflen-1];
+ return (0);
+ }
+
+ return (-1);
+
+}
+
+void *
malloc(size_t size)
{
- __coverity_alloc__(size);
+ void *buf = __coverity_alloc__(size);
+
+ if (condition1)
+ __coverity_sleep__();
+
+ __coverity_negative_sink__(size);
+ __coverity_mark_as_uninitialized_buffer__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "free");
+
+ return (buf);
}
+void *
+calloc(size_t nmemb, size_t size)
+{
+ void *buf = __coverity_alloc__(size * nmemb);
+
+ if (condition1)
+ __coverity_sleep__();
+
+ __coverity_negative_sink__(size);
+ __coverity_writeall0__(buf);
+ __coverity_mark_as_afm_allocated__(buf, "free");
+ return (buf);
+}
void
free(void *buf)
{
diff --git a/sys/contrib/openzfs/contrib/debian/changelog b/sys/contrib/openzfs/contrib/debian/changelog
new file mode 100644
index 000000000000..6273d603834a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/changelog
@@ -0,0 +1,7 @@
+openzfs-linux (2.1.99-1) unstable; urgency=low
+
+ * Integrate minimally modified Debian packaging from ZFS on Linux
+ (source: https://salsa.debian.org/zfsonlinux-team/zfs)
+ * This packaging is a fork of Debian zfs-linux 2.1.6-2 release.
+
+ -- Umer Saleem <usaleem@ixsystems.com> Fri, 11 Oct 2022 15:00:00 -0400
diff --git a/sys/contrib/openzfs/contrib/debian/clean b/sys/contrib/openzfs/contrib/debian/clean
new file mode 100644
index 000000000000..3100d693aeba
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/clean
@@ -0,0 +1,11 @@
+bin/
+cmd/zed/zed.d/history_event-zfs-list-cacher.sh
+contrib/pyzfs/build/
+contrib/pyzfs/libzfs_core/__pycache__/
+contrib/pyzfs/libzfs_core/bindings/__pycache__/
+contrib/pyzfs/pyzfs.egg-info/
+debian/openzfs-libnvpair3.install
+debian/openzfs-libuutil3.install
+debian/openzfs-libzfs4.install
+debian/openzfs-libzfs-dev.install
+debian/openzfs-libzpool5.install
diff --git a/sys/contrib/openzfs/contrib/debian/control b/sys/contrib/openzfs/contrib/debian/control
new file mode 100644
index 000000000000..a0db4985ed1a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/control
@@ -0,0 +1,328 @@
+Source: openzfs-linux
+Section: contrib/kernel
+Priority: optional
+Maintainer: ZFS on Linux specific mailing list <zfs-discuss@list.zfsonlinux.org>
+Build-Depends: abigail-tools,
+ debhelper-compat (= 12),
+ dh-python,
+ dkms (>> 2.1.1.2-5),
+ libaio-dev,
+ libblkid-dev,
+ libcurl4-openssl-dev,
+ libelf-dev,
+ libpam0g-dev,
+ libssl-dev | libssl1.0-dev,
+ libtool,
+ libudev-dev,
+ lsb-release,
+ po-debconf,
+ python3-all-dev,
+ python3-cffi,
+ python3-setuptools,
+ python3-sphinx,
+ uuid-dev,
+ zlib1g-dev
+Standards-Version: 4.5.1
+Homepage: https://openzfs.org/
+Vcs-Git: https://github.com/openzfs/zfs.git
+Vcs-Browser: https://github.com/openzfs/zfs
+Rules-Requires-Root: no
+XS-Autobuild: yes
+
+Package: openzfs-libnvpair3
+Section: contrib/libs
+Architecture: linux-any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Breaks: libnvpair1, libnvpair3
+Replaces: libnvpair1, libnvpair3, libnvpair3linux
+Conflicts: libnvpair3linux
+Description: Solaris name-value library for Linux
+ This library provides routines for packing and unpacking nv pairs for
+ transporting data across process boundaries, transporting between
+ kernel and userland, and possibly saving onto disk files.
+
+Package: openzfs-libpam-zfs
+Section: contrib/admin
+Architecture: linux-any
+Depends: libpam-runtime, ${misc:Depends}, ${shlibs:Depends}
+Replaces: libpam-zfs
+Conflicts: libpam-zfs
+Description: PAM module for managing encryption keys for ZFS
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This provides a Pluggable Authentication Module (PAM) that automatically
+ unlocks encrypted ZFS datasets upon login.
+
+Package: openzfs-libuutil3
+Section: contrib/libs
+Architecture: linux-any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Breaks: libuutil1, libuutil3
+Replaces: libuutil1, libuutil3, libuutil3linux
+Conflicts: libuutil3linux
+Description: Solaris userland utility library for Linux
+ This library provides a variety of glue functions for ZFS on Linux:
+ * libspl: The Solaris Porting Layer userland library, which provides APIs
+ that make it possible to run Solaris user code in a Linux environment
+ with relatively minimal modification.
+ * libavl: The Adelson-Velskii Landis balanced binary tree manipulation
+ library.
+ * libefi: The Extensible Firmware Interface library for GUID disk
+ partitioning.
+ * libshare: NFS, SMB, and iSCSI service integration for ZFS.
+
+Package: openzfs-libzfs-dev
+Section: contrib/libdevel
+Architecture: linux-any
+Depends: libssl-dev | libssl1.0-dev,
+ openzfs-libnvpair3 (= ${binary:Version}),
+ openzfs-libuutil3 (= ${binary:Version}),
+ openzfs-libzfs4 (= ${binary:Version}),
+ openzfs-libzfsbootenv1 (= ${binary:Version}),
+ openzfs-libzpool5 (= ${binary:Version}),
+ ${misc:Depends}
+Replaces: libzfslinux-dev
+Conflicts: libzfslinux-dev
+Provides: libnvpair-dev, libuutil-dev
+Description: OpenZFS filesystem development files for Linux
+ Header files and static libraries for compiling software against
+ libraries of OpenZFS filesystem.
+ .
+ This package includes the development files of libnvpair3, libuutil3,
+ libzpool5 and libzfs4.
+
+Package: openzfs-libzfs4
+Section: contrib/libs
+Architecture: linux-any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+# The libcurl4 is loaded through dlopen("libcurl.so.4").
+# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988521
+Recommends: libcurl4
+Breaks: libzfs2, libzfs4
+Replaces: libzfs2, libzfs4, libzfs4linux
+Conflicts: libzfs4linux
+Description: OpenZFS filesystem library for Linux - general support
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ The OpenZFS library provides support for managing OpenZFS filesystems.
+
+Package: openzfs-libzfsbootenv1
+Section: contrib/libs
+Architecture: linux-any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Breaks: libzfs2, libzfs4
+Replaces: libzfs2, libzfs4, libzfsbootenv1linux
+Conflicts: libzfsbootenv1linux
+Description: OpenZFS filesystem library for Linux - label info support
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ The zfsbootenv library provides support for modifying ZFS label information.
+
+Package: openzfs-libzpool5
+Section: contrib/libs
+Architecture: linux-any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Breaks: libzpool2, libzpool5
+Replaces: libzpool2, libzpool5, libzpool5linux
+Conflicts: libzpool5linux
+Description: OpenZFS pool library for Linux
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This zpool library provides support for managing zpools.
+
+Package: openzfs-python3-pyzfs
+Section: contrib/python
+Architecture: linux-any
+Depends: python3-cffi,
+ openzfs-zfsutils (= ${binary:Version}),
+ ${misc:Depends},
+ ${python3:Depends}
+Replaces: python3-pyzfs
+Conflicts: python3-pyzfs
+Description: wrapper for libzfs_core C library
+ libzfs_core is intended to be a stable interface for programmatic
+ administration of ZFS. This wrapper provides one-to-one wrappers for
+ libzfs_core API functions, but the signatures and types are more natural to
+ Python.
+ .
+ nvlists are wrapped as dictionaries or lists depending on their usage.
+ Some parameters have default values depending on typical use for
+ increased convenience. Enumerations and bit flags become strings and lists
+ of strings in Python. Errors are reported as exceptions rather than integer
+ errno-style error codes. The wrapper takes care to provide one-to-many
+ mapping of the error codes to the exceptions by interpreting a context
+ in which the error code is produced.
+
+Package: openzfs-pyzfs-doc
+Section: contrib/doc
+Architecture: all
+Depends: ${misc:Depends}, ${sphinxdoc:Depends}
+Recommends: openzfs-python3-pyzfs
+Replaces: pyzfs-doc
+Conflicts: pyzfs-doc
+Description: wrapper for libzfs_core C library (documentation)
+ libzfs_core is intended to be a stable interface for programmatic
+ administration of ZFS. This wrapper provides one-to-one wrappers for
+ libzfs_core API functions, but the signatures and types are more natural to
+ Python.
+ .
+ nvlists are wrapped as dictionaries or lists depending on their usage.
+ Some parameters have default values depending on typical use for
+ increased convenience. Enumerations and bit flags become strings and lists
+ of strings in Python. Errors are reported as exceptions rather than integer
+ errno-style error codes. The wrapper takes care to provide one-to-many
+ mapping of the error codes to the exceptions by interpreting a context
+ in which the error code is produced.
+ .
+ This package contains the documentation.
+
+Package: openzfs-zfs-dkms
+Architecture: all
+Depends: dkms (>> 2.1.1.2-5),
+ file,
+ libc6-dev | libc-dev,
+ lsb-release,
+ python3-distutils | libpython3-stdlib (<< 3.6.4),
+ ${misc:Depends},
+ ${perl:Depends}
+Recommends: openzfs-zfs-zed, openzfs-zfsutils (>= ${source:Version}), ${linux:Recommends}
+# suggests debhelper because e.g. `dkms mkdeb -m zfs -v 0.8.2` needs dh_testdir (#909183)
+Suggests: debhelper
+Breaks: spl-dkms (<< 0.8.0~rc1)
+Replaces: spl-dkms, zfs-dkms
+Conflicts: zfs-dkms
+Provides: openzfs-zfs-modules
+Description: OpenZFS filesystem kernel modules for Linux
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This DKMS package includes the SPA, DMU, ZVOL, and ZPL components of
+ OpenZFS.
+
+Package: openzfs-zfs-initramfs
+Architecture: all
+Depends: busybox-initramfs | busybox-static | busybox,
+ initramfs-tools,
+ openzfs-zfs-modules | openzfs-zfs-dkms,
+ openzfs-zfsutils (>= ${source:Version}),
+ ${misc:Depends}
+Breaks: zfsutils-linux (<= 0.7.11-2)
+Replaces: zfsutils-linux (<= 0.7.11-2), zfs-initramfs
+Conflicts: zfs-initramfs
+Description: OpenZFS root filesystem capabilities for Linux - initramfs
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This package adds OpenZFS to the system initramfs with a hook
+ for the initramfs-tools infrastructure.
+
+Package: openzfs-zfs-dracut
+Architecture: all
+Depends: dracut,
+ openzfs-zfs-modules | openzfs-zfs-dkms,
+ openzfs-zfsutils (>= ${source:Version}),
+ ${misc:Depends}
+Conflicts: zfs-dracut
+Replaces: zfs-dracut
+Description: OpenZFS root filesystem capabilities for Linux - dracut
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This package adds OpenZFS to the system initramfs with a hook
+ for the dracut infrastructure.
+
+Package: openzfs-zfsutils
+Section: contrib/admin
+Architecture: linux-any
+Pre-Depends: ${misc:Pre-Depends}
+Depends: openzfs-libnvpair3 (= ${binary:Version}),
+ openzfs-libuutil3 (= ${binary:Version}),
+ openzfs-libzfs4 (= ${binary:Version}),
+ openzfs-libzpool5 (= ${binary:Version}),
+ python3,
+ ${misc:Depends},
+ ${shlibs:Depends}
+Recommends: lsb-base, openzfs-zfs-modules | openzfs-zfs-dkms, openzfs-zfs-zed
+Breaks: openrc,
+ spl (<< 0.7.9-2),
+ spl-dkms (<< 0.8.0~rc1),
+ openzfs-zfs-dkms (<< ${source:Version}),
+ openzfs-zfs-dkms (>> ${source:Version}...)
+Replaces: spl (<< 0.7.9-2), spl-dkms, zfsutils-linux
+Conflicts: zfs, zfs-fuse, zfsutils-linux
+Suggests: nfs-kernel-server,
+ samba-common-bin (>= 3.0.23),
+ openzfs-zfs-initramfs | openzfs-zfs-dracut
+Provides: openzfsutils
+Description: command-line tools to manage OpenZFS filesystems
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This package provides the zfs and zpool commands to create and administer
+ OpenZFS filesystems.
+
+Package: openzfs-zfs-zed
+Section: contrib/admin
+Architecture: linux-any
+Pre-Depends: ${misc:Pre-Depends}
+Depends: openzfs-zfs-modules | openzfs-zfs-dkms,
+ openzfs-zfsutils (>= ${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
+Conflicts: zfs, zfs-zed
+Replaces: zfs-zed
+Description: OpenZFS Event Daemon
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ ZED (ZFS Event Daemon) monitors events generated by the ZFS kernel
+ module. When a zevent (ZFS Event) is posted, ZED will run any ZEDLETs
+ (ZFS Event Daemon Linkage for Executable Tasks) that have been enabled
+ for the corresponding zevent class.
+ .
+ This package provides the OpenZFS Event Daemon (zed).
+
+Package: openzfs-zfs-test
+Section: contrib/admin
+Architecture: linux-any
+Depends: acl,
+ attr,
+ bc,
+ fio,
+ ksh,
+ lsscsi,
+ mdadm,
+ parted,
+ python3,
+ openzfs-python3-pyzfs,
+ sudo,
+ sysstat,
+ openzfs-zfs-modules | openzfs-zfs-dkms,
+ openzfs-zfsutils (>=${binary:Version}),
+ ${misc:Depends},
+ ${shlibs:Depends}
+Recommends: nfs-kernel-server
+Breaks: zfsutils-linux (<= 0.7.9-2)
+Replaces: zfsutils-linux (<= 0.7.9-2), zfs-test
+Conflicts: zutils, zfs-test
+Description: OpenZFS test infrastructure and support scripts
+ OpenZFS is a storage platform that encompasses the functionality of
+ traditional filesystems and volume managers. It supports data checksums,
+ compression, encryption, snapshots, and more.
+ .
+ This package provides the OpenZFS test infrastructure for destructively
+ testing and validating a system using OpenZFS. It is entirely optional
+ and should only be installed and used in test environments.
diff --git a/sys/contrib/openzfs/contrib/debian/control.modules.in b/sys/contrib/openzfs/contrib/debian/control.modules.in
new file mode 100644
index 000000000000..70a165266d16
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/control.modules.in
@@ -0,0 +1,33 @@
+Source: openzfs-linux
+Section: contrib/kernel
+Priority: optional
+Maintainer: ZFS on Linux specific mailing list <zfs-discuss@list.zfsonlinux.org>
+Build-Depends: debhelper-compat (= 10),
+ dkms (>> 2.1.1.2-5),
+ libtool,
+ linux-headers-_KVERS_
+Standards-Version: 4.3.0
+Homepage: http://www.openzfs.org/
+Vcs-Git: https://github.com/openzfs/zfs.git
+Vcs-Browser: https://github.com/openzfs/zfs
+
+Package: openzfs-zfs-modules-_KVERS_
+Architecture: _ARCH_
+Provides: openzfs-zfs-modules
+Depends: linux-image-_KVERS_
+Recommends: openzfsutils
+Replaces: zfs-modules-_KVERS_
+Conflicts: zfs-modules-_KVERS_
+Description: OpenZFS filesystem kernel modules for Linux (kernel _KVERS_)
+ An advanced integrated volume manager and filesystem that is designed for
+ performance and data integrity. Snapshots, clones, checksums, deduplication,
+ compression, and RAID redundancy are built-in features.
+ .
+ This package contains the compiled kernel module for _KVERS_
+ .
+ Includes the SPA, DMU, ZVOL, and ZPL components of OpenZFS.
+ .
+ If you have compiled your own kernel, you will most likely need to build
+ your own zfs-modules. The zfs-source package has been
+ provided for use with the Debian kernel-package utility to produce a
+ version of zfs-module for your kernel.
diff --git a/sys/contrib/openzfs/contrib/debian/copyright b/sys/contrib/openzfs/contrib/debian/copyright
new file mode 100644
index 000000000000..65c7d209d8eb
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/copyright
@@ -0,0 +1,19 @@
+This Debian packaging is a derived work of Debian's zfs-linux package [1].
+The original copy of the Debian-styled copyright file can be found at [2].
+The detailed contributor information can be found in [2][3].
+
+Files: contrib/debian/*
+Copyright:
+ 2013-2016, Aron Xu <aron@debian.org>
+ 2016, Petter Reinholdtsen <pere@hungry.com>
+ 2013, Carlos Alberto Lopez Perez <clopez@igalia.com>
+ 2013, Turbo Fredriksson <turbo@bayour.com>
+ 2012-2013, Richard Laager <rlaager@wiktel.com>
+ 2011-2013, Darik Horn <dajhorn@vanadac.com>
+ 2018-2019, Mo Zhou <cdluminate@gmail.com>
+ 2018-2020, Mo Zhou <lumin@debian.org>
+License: GPL-2+
+
+[1] https://tracker.debian.org/pkg/zfs-linux
+[2] https://salsa.debian.org/zfsonlinux-team/zfs/-/blob/master/debian/copyright
+[3] https://salsa.debian.org/zfsonlinux-team/zfs/-/blob/master/debian/changelog
diff --git a/sys/contrib/openzfs/contrib/debian/not-installed b/sys/contrib/openzfs/contrib/debian/not-installed
new file mode 100644
index 000000000000..ad14776f3b7e
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/not-installed
@@ -0,0 +1,13 @@
+usr/bin/arc_summary.py
+usr/share/zfs/enum-extract.pl
+usr/share/zfs/zfs-helpers.sh
+etc/default/zfs
+etc/init.d
+etc/sudoers.d
+etc/zfs/vdev_id.conf.alias.example
+etc/zfs/vdev_id.conf.multipath.example
+etc/zfs/vdev_id.conf.sas_direct.example
+etc/zfs/vdev_id.conf.sas_switch.example
+etc/zfs/vdev_id.conf.scsi.example
+etc/zfs/zfs-functions
+lib/systemd/system/zfs-import.service
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.install.in
new file mode 100644
index 000000000000..ed7b541e3607
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libnvpair3.install.in
@@ -0,0 +1 @@
+lib/@DEB_HOST_MULTIARCH@/libnvpair.so.*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.install b/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.install
new file mode 100644
index 000000000000..c33123f69a8d
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.install
@@ -0,0 +1,2 @@
+lib/*/security/pam_zfs_key.so
+usr/share/pam-configs/zfs_key
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.postinst b/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.postinst
new file mode 100644
index 000000000000..2db86744e4e6
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.postinst
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+pam-auth-update --package
+
+#DEBHELPER#
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.prerm b/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.prerm
new file mode 100644
index 000000000000..21e827001c23
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libpam-zfs.prerm
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -e
+
+if [ "$1" = remove ] ; then
+ pam-auth-update --package --remove zfs_key
+fi
+
+#DEBHELPER#
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.install.in
new file mode 100644
index 000000000000..a197d030d743
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libuutil3.install.in
@@ -0,0 +1 @@
+lib/@DEB_HOST_MULTIARCH@/libuutil.so.*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.install.in
new file mode 100644
index 000000000000..eaa8c3925e24
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs-dev.install.in
@@ -0,0 +1,3 @@
+lib/@DEB_HOST_MULTIARCH@/*.a usr/lib/@DEB_HOST_MULTIARCH@
+usr/include
+usr/lib/@DEB_HOST_MULTIARCH@
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.install.in
new file mode 100644
index 000000000000..6765aaee59cc
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs4.install.in
@@ -0,0 +1,2 @@
+lib/@DEB_HOST_MULTIARCH@/libzfs.so.*
+lib/@DEB_HOST_MULTIARCH@/libzfs_core.so.*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.install.in
new file mode 100644
index 000000000000..49216742433f
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfsbootenv1.install.in
@@ -0,0 +1 @@
+lib/@DEB_HOST_MULTIARCH@/libzfsbootenv.so.*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.install.in
new file mode 100644
index 000000000000..b9e872df9ba8
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool5.install.in
@@ -0,0 +1 @@
+lib/@DEB_HOST_MULTIARCH@/libzpool.so.*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-python3-pyzfs.install b/sys/contrib/openzfs/contrib/debian/openzfs-python3-pyzfs.install
new file mode 100644
index 000000000000..4606faae20a7
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-python3-pyzfs.install
@@ -0,0 +1 @@
+usr/lib/python3*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.config b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.config
new file mode 100644
index 000000000000..ad7e160a2b11
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.config
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+set -e
+
+# Source debconf library
+. /usr/share/debconf/confmodule
+
+db_input critical zfs-dkms/note-incompatible-licenses || true
+db_go
+
+kernelbits=unknown
+if [ -r /proc/kallsyms ]; then
+ addrlen=$(head -1 /proc/kallsyms|awk '{print $1}'|wc -c)
+ if [ $addrlen = 17 ]; then
+ kernelbits=64
+ elif [ $addrlen = 9 ]; then
+ kernelbits=32
+ fi
+fi
+
+if [ $kernelbits != 64 ]; then
+ if [ $kernelbits = 32 ]; then
+ db_input critical zfs-dkms/stop-build-for-32bit-kernel || true
+ db_go || true
+ else
+ db_input critical zfs-dkms/stop-build-for-unknown-kernel || true
+ db_go || true
+ fi
+fi
+
+#DEBHELPER#
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.dkms b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.dkms
new file mode 100644
index 000000000000..3ac8677b7cde
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.dkms
@@ -0,0 +1 @@
+scripts/zfs-dkms.dkms
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.docs b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.install b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.install
new file mode 100644
index 000000000000..b601f22c481a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.install
@@ -0,0 +1 @@
+usr/src
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.postinst b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.postinst
new file mode 100644
index 000000000000..0ecb9674d559
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.postinst
@@ -0,0 +1,51 @@
+#!/bin/sh
+set -e
+
+# Source debconf library (see dh_installdebconf(1) and #106070 #626312)
+. /usr/share/debconf/confmodule
+
+kernelbits=unknown
+if [ -r /proc/kallsyms ]; then
+ addrlen=$(head -1 /proc/kallsyms| grep -o '^ *[^ ]*' |wc -c)
+ if [ $addrlen = 17 ]; then
+ kernelbits=64
+ elif [ $addrlen = 9 ]; then
+ kernelbits=32
+ fi
+fi
+
+if [ $kernelbits != 64 ]; then
+ if [ $kernelbits = 32 ]; then
+ db_get zfs-dkms/stop-build-for-32bit-kernel
+ if [ "$RET" = "true" ]; then
+ echo "Ok, aborting, since ZFS is not designed for 32-bit kernels." 1>&2
+ # Exit 0: Tell dpkg that we finished OK but stop here.
+ # (don't build the module)
+ exit 0
+ else
+ echo "WARNING: Building ZFS module on a 32-bit kernel." 1>&2
+ fi
+ else
+ db_get zfs-dkms/stop-build-for-unknown-kernel
+ if [ "$RET" = "true" ]; then
+ echo "Ok, aborting, since ZFS is not designed for 32-bit kernels." 1>&2
+ # Exit 0: (same that above)
+ exit 0
+ else
+ echo "WARNING: Building ZFS module on an unknown kernel." 1>&2
+ fi
+ fi
+fi
+
+# Here the module gets built (automatically handled by dh_dkms)
+
+#DEBHELPER#
+
+
+case $1 in
+ (configure)
+ if [ -x /usr/share/update-notifier/notify-reboot-required ]; then
+ /usr/share/update-notifier/notify-reboot-required
+ fi
+ ;;
+esac
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.prerm b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.prerm
new file mode 100644
index 000000000000..fea2aee8b902
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.prerm
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -e
+
+#DEBHELPER#
+
+if [ "$1" = "remove" ]; then
+ rm -f /etc/zfs/zpool.cache
+fi
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.templates b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.templates
new file mode 100644
index 000000000000..3db643464e7f
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.templates
@@ -0,0 +1,40 @@
+Template: zfs-dkms/stop-build-for-32bit-kernel
+Type: boolean
+Default: true
+_Description: Abort building OpenZFS on a 32-bit kernel?
+ You are attempting to build OpenZFS against a 32-bit running kernel.
+ .
+ Although possible, building in a 32-bit environment is unsupported and
+ likely to cause instability leading to possible data corruption. You
+ are strongly advised to use a 64-bit kernel; if you do decide to
+ proceed with using OpenZFS on this kernel then keep in mind that it is at
+ your own risk.
+
+Template: zfs-dkms/stop-build-for-unknown-kernel
+Type: boolean
+Default: true
+_Description: Abort building OpenZFS on an unknown kernel?
+ You are attempting to build OpenZFS against a running kernel that could not
+ be identified as 32-bit or 64-bit. If you are not completely sure that
+ the running kernel is a 64-bit one, you should probably stop the build.
+ .
+ Although possible, building in a 32-bit environment is unsupported and
+ likely to cause instability leading to possible data corruption. You
+ are strongly advised to use a 64-bit kernel; if you do decide to
+ proceed with using OpenZFS on this kernel then keep in mind that it is at
+ your own risk.
+
+Template: zfs-dkms/note-incompatible-licenses
+Type: note
+_Description: Licenses of OpenZFS and Linux are incompatible
+ OpenZFS is licensed under the Common Development and Distribution License (CDDL),
+ and the Linux kernel is licensed under the GNU General Public License Version 2
+ (GPL-2). While both are free open source licenses they are restrictive
+ licenses. The combination of them causes problems because it prevents using
+ pieces of code exclusively available under one license with pieces of code
+ exclusively available under the other in the same binary.
+ .
+ You are going to build OpenZFS using DKMS in such a way that they are not going to
+ be built into one monolithic binary. Please be aware that distributing both of
+ the binaries in the same media (disk images, virtual appliances, etc) may
+ lead to infringing.
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.triggers b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.triggers
new file mode 100644
index 000000000000..865f50a5d99d
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dkms.triggers
@@ -0,0 +1 @@
+activate-await update-initramfs
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dracut.install b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dracut.install
new file mode 100644
index 000000000000..8c2bf1b5c58b
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-dracut.install
@@ -0,0 +1,2 @@
+usr/lib/dracut
+usr/share/man/man7/dracut.zfs.7
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-initramfs.install b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-initramfs.install
new file mode 100644
index 000000000000..222620947f10
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-initramfs.install
@@ -0,0 +1,2 @@
+../tree/zfs-initramfs/* /
+usr/share/initramfs-tools/*
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_-di.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_-di.install.in
new file mode 100644
index 000000000000..fc1828ee9639
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_-di.install.in
@@ -0,0 +1,2 @@
+module/spl.ko lib/modules/_KVERS_/extra/zcommon/
+module/zfs.ko lib/modules/_KVERS_/extra/zcommon/
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.install.in
new file mode 100644
index 000000000000..fc1828ee9639
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.install.in
@@ -0,0 +1,2 @@
+module/spl.ko lib/modules/_KVERS_/extra/zcommon/
+module/zfs.ko lib/modules/_KVERS_/extra/zcommon/
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postinst.in b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postinst.in
new file mode 100644
index 000000000000..4eb2314508a6
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postinst.in
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -e
+
+# Run depmod first
+depmod -a _KVERS_
+
+#DEBHELPER#
+
+
+case $1 in
+ (configure)
+ if [ -x /usr/share/update-notifier/notify-reboot-required ]; then
+ /usr/share/update-notifier/notify-reboot-required
+ fi
+ ;;
+esac
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postrm.in b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postrm.in
new file mode 100644
index 000000000000..2a2fc4b5cb95
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-modules-_KVERS_.postrm.in
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -e
+
+# Run depmod after module uninstallation.
+depmod
+
+#DEBHELPER#
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-test.install b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-test.install
new file mode 100644
index 000000000000..cafcfdc0e15b
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-test.install
@@ -0,0 +1,15 @@
+sbin/zinject
+sbin/ztest
+usr/bin/raidz_test
+usr/share/man/man1/raidz_test.1
+usr/share/man/man1/test-runner.1
+usr/share/man/man1/ztest.1
+usr/share/man/man8/zinject.8
+usr/share/zfs/common.sh
+usr/share/zfs/runfiles/
+usr/share/zfs/test-runner
+usr/share/zfs/zfs-tests.sh
+usr/share/zfs/zfs-tests/
+usr/share/zfs/zfs.sh
+usr/share/zfs/zimport.sh
+usr/share/zfs/zloop.sh
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.install b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.install
new file mode 100644
index 000000000000..a348ba828ee5
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.install
@@ -0,0 +1,5 @@
+etc/zfs/zed.d/*
+lib/systemd/system/zfs-zed.service
+usr/lib/zfs-linux/zed.d/*
+usr/sbin/zed
+usr/share/man/man8/zed.8
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postinst b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postinst
new file mode 100644
index 000000000000..a615eec95760
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postinst
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -e
+
+zedd="/usr/lib/zfs-linux/zed.d"
+etcd="/etc/zfs/zed.d"
+
+# enable all default zedlets that are not overridden
+while read -r file ; do
+ etcfile="${etcd}/${file}"
+ [ -e "${etcfile}" ] && continue
+ ln -sfT "${zedd}/${file}" "${etcfile}"
+done < "${zedd}/DEFAULT-ENABLED"
+
+# remove the overrides created in prerm
+find "${etcd}" -maxdepth 1 -lname '/dev/null' -delete
+# remove any dangling symlinks to old zedlets
+find "${etcd}" -maxdepth 1 -lname "${zedd}/*" -xtype l -delete
+
+#DEBHELPER#
+
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postrm b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postrm
new file mode 100644
index 000000000000..e9aed3f4ce2b
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.postrm
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -e
+
+zedd="/usr/lib/zfs-linux/zed.d"
+etcd="/etc/zfs/zed.d"
+
+if [ "$1" = "purge" ] && [ -d "$etcd" ] ; then
+ # remove the overrides created in prerm
+ find "${etcd}" -maxdepth 1 -lname '/dev/null' -delete
+ # remove any dangling symlinks to old zedlets
+ find "${etcd}" -maxdepth 1 -lname "${zedd}/*" -xtype l -delete
+ # clean up any empty directories
+ ( rmdir "$etcd" && rmdir "/etc/zfs" ) || true
+fi
+
+#DEBHELPER#
+
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.prerm b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.prerm
new file mode 100644
index 000000000000..b8340df53438
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.prerm
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -e
+
+zedd="/usr/lib/zfs-linux/zed.d"
+etcd="/etc/zfs/zed.d"
+
+if [ "$1" != "failed-upgrade" ] && [ -d "${etcd}" ] && [ -d "${zedd}" ] ; then
+ while read -r file ; do
+ etcfile="${etcd}/${file}"
+ ( [ -L "${etcfile}" ] || [ -e "${etcfile}" ] ) && continue
+ ln -sT /dev/null "${etcfile}"
+ done < "${zedd}/DEFAULT-ENABLED"
+fi
+
+#DEBHELPER#
+
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.zfs-zed.init b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.zfs-zed.init
new file mode 120000
index 000000000000..3f41f6813577
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfs-zed.zfs-zed.init
@@ -0,0 +1 @@
+../etc/init.d/zfs-zed \ No newline at end of file
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.docs b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.docs
new file mode 100644
index 000000000000..4302f1b2ab6a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.docs
@@ -0,0 +1,2 @@
+COPYRIGHT
+LICENSE
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.examples b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.examples
new file mode 100644
index 000000000000..9f10d3fc0a7a
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.examples
@@ -0,0 +1,5 @@
+etc/zfs/vdev_id.conf.alias.example
+etc/zfs/vdev_id.conf.multipath.example
+etc/zfs/vdev_id.conf.sas_direct.example
+etc/zfs/vdev_id.conf.sas_switch.example
+etc/zfs/vdev_id.conf.scsi.example
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.install b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.install
new file mode 100644
index 000000000000..e10a50e012c1
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.install
@@ -0,0 +1,135 @@
+etc/default/zfs
+etc/zfs/zfs-functions
+etc/zfs/zpool.d/
+etc/bash_completion.d/zfs
+lib/systemd/system-generators/
+lib/systemd/system-preset/
+lib/systemd/system/zfs-import-cache.service
+lib/systemd/system/zfs-import-scan.service
+lib/systemd/system/zfs-import.target
+lib/systemd/system/zfs-load-key.service
+lib/systemd/system/zfs-mount.service
+lib/systemd/system/zfs-scrub-monthly@.timer
+lib/systemd/system/zfs-scrub-weekly@.timer
+lib/systemd/system/zfs-scrub@.service
+lib/systemd/system/zfs-trim-monthly@.timer
+lib/systemd/system/zfs-trim-weekly@.timer
+lib/systemd/system/zfs-trim@.service
+lib/systemd/system/zfs-share.service
+lib/systemd/system/zfs-volume-wait.service
+lib/systemd/system/zfs-volumes.target
+lib/systemd/system/zfs.target
+lib/udev/
+sbin/fsck.zfs
+sbin/mount.zfs
+sbin/zdb
+sbin/zfs
+sbin/zfs_ids_to_path
+sbin/zgenhostid
+sbin/zhack
+sbin/zpool
+sbin/zstream
+sbin/zstreamdump
+usr/bin/zvol_wait
+usr/lib/modules-load.d/ lib/
+usr/lib/zfs-linux/zpool.d/
+usr/lib/zfs-linux/zpool_influxdb
+usr/sbin/arc_summary
+usr/sbin/arcstat
+usr/sbin/dbufstat
+usr/sbin/zilstat
+usr/share/zfs/compatibility.d/
+usr/share/bash-completion/completions
+usr/share/man/man1/arcstat.1
+usr/share/man/man1/zhack.1
+usr/share/man/man1/zvol_wait.1
+usr/share/man/man5/
+usr/share/man/man8/fsck.zfs.8
+usr/share/man/man8/mount.zfs.8
+usr/share/man/man8/vdev_id.8
+usr/share/man/man8/zdb.8
+usr/share/man/man8/zfs-allow.8
+usr/share/man/man8/zfs-bookmark.8
+usr/share/man/man8/zfs-change-key.8
+usr/share/man/man8/zfs-clone.8
+usr/share/man/man8/zfs-create.8
+usr/share/man/man8/zfs-destroy.8
+usr/share/man/man8/zfs-diff.8
+usr/share/man/man8/zfs-get.8
+usr/share/man/man8/zfs-groupspace.8
+usr/share/man/man8/zfs-hold.8
+usr/share/man/man8/zfs-inherit.8
+usr/share/man/man8/zfs-jail.8
+usr/share/man/man8/zfs-list.8
+usr/share/man/man8/zfs-load-key.8
+usr/share/man/man8/zfs-mount-generator.8
+usr/share/man/man8/zfs-mount.8
+usr/share/man/man8/zfs-program.8
+usr/share/man/man8/zfs-project.8
+usr/share/man/man8/zfs-projectspace.8
+usr/share/man/man8/zfs-promote.8
+usr/share/man/man8/zfs-receive.8
+usr/share/man/man8/zfs-recv.8
+usr/share/man/man8/zfs-redact.8
+usr/share/man/man8/zfs-release.8
+usr/share/man/man8/zfs-rename.8
+usr/share/man/man8/zfs-rollback.8
+usr/share/man/man8/zfs-send.8
+usr/share/man/man8/zfs-set.8
+usr/share/man/man8/zfs-share.8
+usr/share/man/man8/zfs-snapshot.8
+usr/share/man/man8/zfs-unallow.8
+usr/share/man/man8/zfs-unjail.8
+usr/share/man/man8/zfs-unload-key.8
+usr/share/man/man8/zfs-unmount.8
+usr/share/man/man8/zfs-unzone.8
+usr/share/man/man8/zfs-upgrade.8
+usr/share/man/man8/zfs-userspace.8
+usr/share/man/man8/zfs-wait.8
+usr/share/man/man8/zfs-zone.8
+usr/share/man/man8/zfs.8
+usr/share/man/man8/zfs_ids_to_path.8
+usr/share/man/man7/zfsconcepts.7
+usr/share/man/man7/zfsprops.7
+usr/share/man/man8/zgenhostid.8
+usr/share/man/man8/zpool-add.8
+usr/share/man/man8/zpool-attach.8
+usr/share/man/man8/zpool-checkpoint.8
+usr/share/man/man8/zpool-clear.8
+usr/share/man/man8/zpool-create.8
+usr/share/man/man8/zpool-destroy.8
+usr/share/man/man8/zpool-detach.8
+usr/share/man/man8/zpool-events.8
+usr/share/man/man8/zpool-export.8
+usr/share/man/man8/zpool-get.8
+usr/share/man/man8/zpool-history.8
+usr/share/man/man8/zpool-import.8
+usr/share/man/man8/zpool-initialize.8
+usr/share/man/man8/zpool-iostat.8
+usr/share/man/man8/zpool-labelclear.8
+usr/share/man/man8/zpool-list.8
+usr/share/man/man8/zpool-offline.8
+usr/share/man/man8/zpool-online.8
+usr/share/man/man8/zpool-reguid.8
+usr/share/man/man8/zpool-remove.8
+usr/share/man/man8/zpool-reopen.8
+usr/share/man/man8/zpool-replace.8
+usr/share/man/man8/zpool-resilver.8
+usr/share/man/man8/zpool-scrub.8
+usr/share/man/man8/zpool-set.8
+usr/share/man/man8/zpool-split.8
+usr/share/man/man8/zpool-status.8
+usr/share/man/man8/zpool-sync.8
+usr/share/man/man8/zpool-trim.8
+usr/share/man/man8/zpool-upgrade.8
+usr/share/man/man8/zpool-wait.8
+usr/share/man/man8/zpool.8
+usr/share/man/man7/zpoolconcepts.7
+usr/share/man/man7/zpoolprops.7
+usr/share/man/man8/zstream.8
+usr/share/man/man8/zstreamdump.8
+usr/share/man/man4/spl.4
+usr/share/man/man4/zfs.4
+usr/share/man/man7/zpool-features.7
+usr/share/man/man7/dracut.zfs.7
+usr/share/man/man8/zpool_influxdb.8
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.postinst b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.postinst
new file mode 100644
index 000000000000..b13a78654c37
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.postinst
@@ -0,0 +1,28 @@
+#!/bin/sh
+set -e
+
+# The hostname and hostid of the last system to access a ZFS pool are stored in
+# the ZFS pool itself. A pool is foreign if, during `zpool import`, the
+# current hostname and hostid are different than the stored values thereof.
+#
+# The only way of having a stable hostid is to define it in /etc/hostid.
+# This postinst helper will check if we already have the hostid stabilized by
+# checking the existence of the file /etc/hostid to be 4 bytes at least.
+# If this file don't already exists on our system or has less than 4 bytes, then
+# a new (random) value is generated with zgenhostid (8) and stored in
+# /etc/hostid
+
+if [ ! -f /etc/hostid ] || [ "$(stat -c %s /etc/hostid)" -lt 4 ] ; then
+ zgenhostid
+fi
+
+# When processed to here but zfs kernel module is not loaded, the subsequent
+# services would fail to start. In this case the installation process just
+# fails at the postinst stage. The user could do
+# $ sudo modprobe zfs; sudo dpkg --configure -a
+# to complete the installation.
+#
+modprobe -v zfs || true # modprobe zfs does nothing if zfs.ko was already loaded.
+
+#DEBHELPER#
+
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-import.init b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-import.init
new file mode 120000
index 000000000000..bfc368fd3426
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-import.init
@@ -0,0 +1 @@
+../etc/init.d/zfs-import \ No newline at end of file
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-load-key.init b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-load-key.init
new file mode 120000
index 000000000000..3f3e97f811bb
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-load-key.init
@@ -0,0 +1 @@
+../etc/init.d/zfs-load-key \ No newline at end of file
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-mount.init b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-mount.init
new file mode 120000
index 000000000000..62a544332422
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-mount.init
@@ -0,0 +1 @@
+../etc/init.d/zfs-mount \ No newline at end of file
diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-share.init b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-share.init
new file mode 120000
index 000000000000..3f069f9baaaf
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/openzfs-zfsutils.zfs-share.init
@@ -0,0 +1 @@
+../etc/init.d/zfs-share \ No newline at end of file
diff --git a/sys/contrib/openzfs/contrib/debian/rules b/sys/contrib/openzfs/contrib/debian/rules
new file mode 100755
index 000000000000..5f4889445bea
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/rules
@@ -0,0 +1,223 @@
+#!/usr/bin/make -f
+
+include /usr/share/dpkg/default.mk
+
+LSB_DISTRIBUTOR := $(shell lsb_release -is)
+NAME := $(shell awk '$$1 == "Name:" { print $$2; }' META)
+LINUX_MIN := $(shell awk '/Linux-Minimum:/{print $$2}' META)
+LINUX_NEXT := $(shell awk -F'[ .]' '/Linux-Maximum:/{print $$2 "." $$3+1}' META)
+
+DKMSFILES := module include config zfs.release.in autogen.sh META AUTHORS \
+ COPYRIGHT LICENSE README.md
+
+ifndef KVERS
+KVERS=$(shell uname -r)
+endif
+
+non_epoch_version=$(shell echo $(KVERS) | perl -pe 's/^\d+://')
+PACKAGE=openzfs-zfs
+pmodules = $(PACKAGE)-modules-$(non_epoch_version)
+
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+NUM_CPUS = $(shell nproc 2>/dev/null)
+PARALLEL = $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+NJOBS = -j$(or $(PARALLEL),$(NUM_CPUS),1)
+
+%:
+ dh $@ --with autoreconf,dkms,python3,sphinxdoc
+
+override_dh_autoreconf:
+ @# Embed the downstream version in the module.
+ @sed -e 's/^Version:.*/Version: $(DEB_VERSION_UPSTREAM)/' -i.orig META
+
+ dh_autoreconf
+
+override_dh_auto_configure:
+ @# Build the userland, but don't build the kernel modules.
+ dh_auto_configure -- \
+ --bindir=/usr/bin \
+ --sbindir=/sbin \
+ --libdir=/lib/"$(DEB_HOST_MULTIARCH)" \
+ --with-udevdir=/lib/udev \
+ --with-zfsexecdir=/usr/lib/zfs-linux \
+ --enable-systemd \
+ --enable-pyzfs \
+ --with-python=python3 \
+ --with-pammoduledir='/lib/$(DEB_HOST_MULTIARCH)/security' \
+ --with-pkgconfigdir='/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig' \
+ --with-systemdunitdir=/lib/systemd/system \
+ --with-systemdpresetdir=/lib/systemd/system-preset \
+ --with-systemdgeneratordir=/lib/systemd/system-generators \
+ --with-config=user
+
+ for i in $(wildcard $(CURDIR)/debian/*.install.in) ; do \
+ basename "$$i" | grep _KVERS_ && continue ; \
+ sed 's/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/g' "$$i" > "$${i%%.in}" ; \
+ done
+
+override_dh_gencontrol:
+ dh_gencontrol -- -Vlinux:Recommends="linux-libc-dev (<< $(LINUX_NEXT)~), linux-libc-dev (>= $(LINUX_MIN)~),"
+
+override_dh_auto_build:
+ @# Get a bare copy of the source code for DKMS.
+ @# This creates the $(CURDIR)/$(NAME)-$(DEB_VERSION_UPSTREAM)/ tree, which does not
+ @# contain the userland sources. NB: Remove-userland-dist-rules.patch
+ $(MAKE) distdir
+
+ dh_auto_build
+
+override_dh_auto_install:
+ @# Install the utilities.
+ $(MAKE) install DESTDIR='$(CURDIR)/debian/tmp'
+
+ # Use upstream's bash completion
+ install -D -t '$(CURDIR)/debian/tmp/usr/share/bash-completion/completions/' \
+ '$(CURDIR)/contrib/bash_completion.d/zfs'
+
+ # Move from bin_dir to /usr/sbin
+ # Remove suffix (.py) as per policy 10.4 - Scripts
+ # https://www.debian.org/doc/debian-policy/ch-files.html#s-scripts
+ mkdir -p '$(CURDIR)/debian/tmp/usr/sbin/'
+ mv '$(CURDIR)/debian/tmp/usr/bin/arc_summary' '$(CURDIR)/debian/tmp/usr/sbin/arc_summary'
+ mv '$(CURDIR)/debian/tmp/usr/bin/arcstat' '$(CURDIR)/debian/tmp/usr/sbin/arcstat'
+ mv '$(CURDIR)/debian/tmp/usr/bin/dbufstat' '$(CURDIR)/debian/tmp/usr/sbin/dbufstat'
+ mv '$(CURDIR)/debian/tmp/usr/bin/zilstat' '$(CURDIR)/debian/tmp/usr/sbin/zilstat'
+
+ @# Zed has dependencies outside of the system root.
+ mv '$(CURDIR)/debian/tmp/sbin/zed' '$(CURDIR)/debian/tmp/usr/sbin/zed'
+
+ @# Install the DKMS source.
+ @# We only want the files needed to build the modules
+ install -D -t '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/scripts' \
+ '$(CURDIR)/scripts/enum-extract.pl' \
+ '$(CURDIR)/scripts/dkms.postbuild'
+ $(foreach file,$(DKMSFILES),mv '$(CURDIR)/$(NAME)-$(DEB_VERSION_UPSTREAM)/$(file)' '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)' || exit 1;)
+
+ @# Only ever build Linux modules
+ echo 'SUBDIRS = linux' > '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/include/os/Makefile.am'
+
+ @# Hellish awk line:
+ @# * Deletes from configure.ac the parts not needed for building the kernel module
+ @# * It deletes from inside AC_CONFIG_FILES([]) everything except:
+ @# - Makefile$
+ @# - include/(Makefile|sys|os/(Makefile|linux))
+ @# - module/
+ @# - zfs.release$
+ @# * Takes care of spaces and tabs
+ @# * Remove reference to ZFS_AC_PACKAGE
+ awk '/^AC_CONFIG_FILES\(\[/,/^\]\)/ {\
+ if ($$0 !~ /^(AC_CONFIG_FILES\(\[([ \t]+)?$$|\]\)([ \t]+)?$$|([ \t]+)?(include\/(Makefile|sys|os\/(Makefile|linux))|module\/|Makefile([ \t]+)?$$|zfs\.release([ \t]+)?$$))/) \
+ {next} } {print}' \
+ '$(CURDIR)/$(NAME)-$(DEB_VERSION_UPSTREAM)/configure.ac' | sed '/ZFS_AC_PACKAGE/d' > '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/configure.ac'
+ @# Set "SUBDIRS = module include" for CONFIG_KERNEL and remove SUBDIRS for all other configs.
+ @# Do not regenerate zfs_gitrev.h during dkms build
+ sed '1,/CONFIG_KERNEL/s/SUBDIRS.*=.*//g;s/SUBDIRS.*=.*/SUBDIRS = module include/g;/make_gitrev.sh/d' \
+ '$(CURDIR)/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am' > '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am'
+ @# Sanity test
+ grep -q 'SUBDIRS = module include' '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am'
+ sed -i '/rpm.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/cmd.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/contrib.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/etc.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/lib.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/man.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/scripts.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/tests.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ sed -i '/udev.Makefile/d' $(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/Makefile.am
+ @# Run autogen on the stripped source tree
+ cd '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)'; ./autogen.sh
+ rm -fr '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/autom4te.cache'
+
+ for i in `ls $(CURDIR)/debian/tmp/lib/$(DEB_HOST_MULTIARCH)/*.so`; do \
+ ln -s '/lib/$(DEB_HOST_MULTIARCH)/'`readlink $${i}` '$(CURDIR)/debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/'`basename $${i}`; \
+ rm $${i}; \
+ done
+
+ chmod a-x '$(CURDIR)/debian/tmp/etc/zfs/zfs-functions'
+ chmod a-x '$(CURDIR)/debian/tmp/etc/default/zfs'
+ chmod a-x '$(CURDIR)/debian/tmp/usr/share/bash-completion/completions/zfs'
+
+override_dh_python3:
+ dh_python3 -p openzfs-python3-pyzfs
+
+override_dh_dkms:
+ '$(CURDIR)/scripts/dkms.mkconf' -n $(NAME) -v $(DEB_VERSION_UPSTREAM) -f '$(CURDIR)/scripts/zfs-dkms.dkms'
+ dh_dkms
+ rm -f '$(CURDIR)/scripts/zfs-dkms.dkms'
+
+override_dh_makeshlibs:
+ dh_makeshlibs -a -V
+
+override_dh_strip:
+ dh_strip
+
+override_dh_auto_clean:
+ rm -rf zfs-$(DEB_VERSION_UPSTREAM)
+ dh_auto_clean
+ @if test -e META.orig; then mv META.orig META; fi
+
+override_dh_install:
+ find debian/tmp/lib -name '*.la' -delete
+ dh_install
+
+override_dh_missing:
+ dh_missing --fail-missing
+
+override_dh_installinit:
+ dh_installinit -r --no-restart-after-upgrade --name zfs-import
+ dh_installinit -r --no-restart-after-upgrade --name zfs-mount
+ dh_installinit -r --no-restart-after-upgrade --name zfs-load-key
+ dh_installinit -R --name zfs-share
+ dh_installinit -R --name zfs-zed
+
+override_dh_installsystemd:
+ mkdir -p debian/openzfs-zfsutils/lib/systemd/system
+ ln -sr /dev/null debian/openzfs-zfsutils/lib/systemd/system/zfs-import.service
+ dh_installsystemd --no-stop-on-upgrade -X zfs-zed.service
+ dh_installsystemd --name zfs-zed
+
+override_dh_installdocs:
+ dh_installdocs -A
+ifeq (,$(findstring nodoc, $(DEB_BUILD_OPTIONS)))
+ http_proxy='127.0.0.1:9' sphinx-build -N -bhtml "$(CURDIR)/contrib/pyzfs/docs/source/" debian/openzfs-pyzfs-doc/usr/share/doc/openzfs-pyzfs-doc/html/
+endif
+
+# ------------
+
+override_dh_prep-deb-files:
+ for templ in $(wildcard $(CURDIR)/debian/*_KVERS_*.in); do \
+ sed -e 's/##KVERS##/$(KVERS)/g ; s/#KVERS#/$(KVERS)/g ; s/_KVERS_/$(KVERS)/g ; s/##KDREV##/$(KDREV)/g ; s/#KDREV#/$(KDREV)/g ; s/_KDREV_/$(KDREV)/g ; s/_ARCH_/$(DEB_HOST_ARCH)/' \
+ < $$templ > `echo $$templ | sed -e 's/_KVERS_/$(KVERS)/g ; s/_ARCH_/$(DEB_HOST_ARCH)/g ; s/\.in$$//'` ; \
+ done
+ sed -e 's/##KVERS##/$(KVERS)/g ; s/#KVERS#/$(KVERS)/g ; s/_KVERS_/$(KVERS)/g ; s/##KDREV##/$(KDREV)/g ; s/#KDREV#/$(KDREV)/g ; s/_KDREV_/$(KDREV)/g ; s/_ARCH_/$(DEB_HOST_ARCH)/g' \
+ < debian/control.modules.in > debian/control
+
+override_dh_configure_modules: override_dh_configure_modules_stamp
+override_dh_configure_modules_stamp:
+ ./configure \
+ --with-config=kernel \
+ --with-linux=$(KSRC) \
+ --with-linux-obj=$(KOBJ)
+ touch override_dh_configure_modules_stamp
+
+override_dh_binary-modules: override_dh_prep-deb-files override_dh_configure_modules
+ dh_testdir
+ dh_testroot
+ dh_prep
+
+ $(MAKE) $(NJOBS) -C $(CURDIR)/module modules
+
+ dh_install -p${pmodules}
+ dh_installdocs -p${pmodules}
+ dh_installchangelogs -p${pmodules}
+ dh_compress -p${pmodules}
+ dh_strip -p${pmodules}
+ dh_fixperms -p${pmodules}
+ dh_installdeb -p${pmodules}
+ dh_gencontrol -p${pmodules}
+ dh_md5sums -p${pmodules}
+ dh_builddeb -p${pmodules}
+
+debian-copyright:
+ cme update dpkg-copyright -file debian/copyright.cme
diff --git a/sys/contrib/openzfs/contrib/debian/source/format b/sys/contrib/openzfs/contrib/debian/source/format
new file mode 100644
index 000000000000..163aaf8d82b6
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/conf.d/zfs b/sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/conf.d/zfs
new file mode 100644
index 000000000000..5103cc450858
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/conf.d/zfs
@@ -0,0 +1,8 @@
+for x in $(cat /proc/cmdline)
+do
+ case $x in
+ root=ZFS=*)
+ BOOT=zfs
+ ;;
+ esac
+done
diff --git a/sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/hooks/zdev b/sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/hooks/zdev
new file mode 100755
index 000000000000..0cf21a4211a8
--- /dev/null
+++ b/sys/contrib/openzfs/contrib/debian/tree/zfs-initramfs/usr/share/initramfs-tools/hooks/zdev
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# Add udev rules for ZoL to the initrd.
+#
+
+PREREQ="udev"
+PREREQ_UDEV_RULES="60-zvol.rules 69-vdev.rules"
+COPY_EXEC_LIST="/lib/udev/zvol_id /lib/udev/vdev_id"
+
+# Generic result code.
+RC=0
+
+case $1 in
+prereqs)
+ echo "$PREREQ"
+ exit 0
+ ;;
+esac
+
+for ii in $COPY_EXEC_LIST
+do
+ if [ ! -x "$ii" ]
+ then
+ echo "Error: $ii is not executable."
+ RC=2
+ fi
+done
+
+if [ "$RC" -ne 0 ]
+then
+ exit "$RC"
+fi
+
+. /usr/share/initramfs-tools/hook-functions
+
+mkdir -p "$DESTDIR/lib/udev/rules.d/"
+for ii in $PREREQ_UDEV_RULES
+do
+ if [ -e "/etc/udev/rules.d/$ii" ]
+ then
+ cp -p "/etc/udev/rules.d/$ii" "$DESTDIR/lib/udev/rules.d/"
+ elif [ -e "/lib/udev/rules.d/$ii" ]
+ then
+ cp -p "/lib/udev/rules.d/$ii" "$DESTDIR/lib/udev/rules.d/"
+ else
+ echo "Error: Missing udev rule: $ii"
+ echo " This file must be in the /etc/udev/rules.d or /lib/udev/rules.d directory."
+ exit 1
+ fi
+done
+
+for ii in $COPY_EXEC_LIST
+do
+ copy_exec "$ii"
+done
+
+if [ -f '/etc/default/zfs' -a -r '/etc/default/zfs' ]
+then
+ mkdir -p "$DESTDIR/etc/default"
+ cp -a '/etc/default/zfs' "$DESTDIR/etc/default/"
+fi
+
+if [ -d '/etc/zfs' -a -r '/etc/zfs' ]
+then
+ mkdir -p "$DESTDIR/etc"
+ cp -a '/etc/zfs' "$DESTDIR/etc/"
+fi
diff --git a/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in b/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in
index 81d7d2abe496..528abe42957b 100755
--- a/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in
+++ b/sys/contrib/openzfs/contrib/dracut/90zfs/module-setup.sh.in
@@ -81,11 +81,30 @@ install() {
inst_simple "${moddir}/zfs-env-bootfs.service" "${systemdsystemunitdir}/zfs-env-bootfs.service"
systemctl -q --root "${initdir}" add-wants zfs-import.target zfs-env-bootfs.service
+ # Add user-provided unit overrides:
+ # - /etc/systemd/system/${_service}
+ # - /etc/systemd/system/${_service}.d/overrides.conf
+ # -H ensures they are marked host-only
+ # -o ensures there is no error upon absence of these files
+ inst_multiple -o -H \
+ "${systemdsystemconfdir}/zfs-import.target" \
+ "${systemdsystemconfdir}/zfs-import.target.d/"*.conf
+
for _service in \
"zfs-import-scan.service" \
"zfs-import-cache.service"; do
inst_simple "${systemdsystemunitdir}/${_service}"
systemctl -q --root "${initdir}" add-wants zfs-import.target "${_service}"
+
+ # Add user-provided unit overrides:
+ # - /etc/systemd/system/${_service}
+ # - /etc/systemd/system/${_service}.d/overrides.conf
+ # -H ensures they are marked host-only
+ # -o ensures there is no error upon absence of these files
+ inst_multiple -o -H \
+ "${systemdsystemconfdir}/${_service}" \
+ "${systemdsystemconfdir}/${_service}.d/"*.conf
+
done
for _service in \
@@ -93,6 +112,15 @@ install() {
"zfs-rollback-bootfs.service"; do
inst_simple "${moddir}/${_service}" "${systemdsystemunitdir}/${_service}"
systemctl -q --root "${initdir}" add-wants initrd.target "${_service}"
+
+ # Add user-provided unit overrides:
+ # - /etc/systemd/system/${_service}
+ # - /etc/systemd/system/${_service}.d/overrides.conf
+ # -H ensures they are marked host-only
+ # -o ensures there is no error upon absence of these files
+ inst_multiple -o -H \
+ "${systemdsystemconfdir}/${_service}" \
+ "${systemdsystemconfdir}/${_service}.d/"*.conf
done
inst_simple "${moddir}/import-opts-generator.sh" "${systemdutildir}/system-environment-generators/zfs-import-opts.sh"
diff --git a/sys/contrib/openzfs/contrib/pam_zfs_key/pam_zfs_key.c b/sys/contrib/openzfs/contrib/pam_zfs_key/pam_zfs_key.c
index 8c59fc7eb716..e3fa9e9b2553 100644
--- a/sys/contrib/openzfs/contrib/pam_zfs_key/pam_zfs_key.c
+++ b/sys/contrib/openzfs/contrib/pam_zfs_key/pam_zfs_key.c
@@ -754,7 +754,10 @@ pam_sm_open_session(pam_handle_t *pamh, int flags,
return (PAM_SUCCESS);
}
zfs_key_config_t config;
- zfs_key_config_load(pamh, &config, argc, argv);
+ if (zfs_key_config_load(pamh, &config, argc, argv) != 0) {
+ return (PAM_SESSION_ERR);
+ }
+
if (config.uid < 1000) {
zfs_key_config_free(&config);
return (PAM_SUCCESS);
diff --git a/sys/contrib/openzfs/etc/Makefile.am b/sys/contrib/openzfs/etc/Makefile.am
index b4b3ae1f5798..7187762d3802 100644
--- a/sys/contrib/openzfs/etc/Makefile.am
+++ b/sys/contrib/openzfs/etc/Makefile.am
@@ -74,6 +74,7 @@ INSTALL_DATA_HOOKS += systemd-install-data-hook
systemd-install-data-hook:
$(MKDIR_P) "$(DESTDIR)$(systemdunitdir)"
ln -sf /dev/null "$(DESTDIR)$(systemdunitdir)/zfs-import.service"
+ ln -sf /dev/null "$(DESTDIR)$(systemdunitdir)/zfs-load-key.service"
systemdgenerator_PROGRAMS = \
diff --git a/sys/contrib/openzfs/include/libuutil_impl.h b/sys/contrib/openzfs/include/libuutil_impl.h
index 7aa8f0cedf15..58b6df579d72 100644
--- a/sys/contrib/openzfs/include/libuutil_impl.h
+++ b/sys/contrib/openzfs/include/libuutil_impl.h
@@ -47,21 +47,6 @@ void uu_panic(const char *format, ...);
/*
- * For debugging purposes, libuutil keeps around linked lists of all uu_lists
- * and uu_avls, along with pointers to their parents. These can cause false
- * negatives when looking for memory leaks, so we encode the pointers by
- * storing them with swapped endianness; this is not perfect, but it's about
- * the best we can do without wasting a lot of space.
- */
-#ifdef _LP64
-#define UU_PTR_ENCODE(ptr) BSWAP_64((uintptr_t)(void *)(ptr))
-#else
-#define UU_PTR_ENCODE(ptr) BSWAP_32((uintptr_t)(void *)(ptr))
-#endif
-
-#define UU_PTR_DECODE(ptr) ((void *)UU_PTR_ENCODE(ptr))
-
-/*
* uu_list structures
*/
typedef struct uu_list_node_impl {
@@ -80,11 +65,11 @@ struct uu_list_walk {
};
struct uu_list {
- uintptr_t ul_next_enc;
- uintptr_t ul_prev_enc;
+ uu_list_t *ul_next;
+ uu_list_t *ul_prev;
uu_list_pool_t *ul_pool;
- uintptr_t ul_parent_enc; /* encoded parent pointer */
+ void *ul_parent;
size_t ul_offset;
size_t ul_numnodes;
uint8_t ul_debug;
@@ -95,8 +80,6 @@ struct uu_list {
uu_list_walk_t ul_null_walk; /* for robust walkers */
};
-#define UU_LIST_PTR(ptr) ((uu_list_t *)UU_PTR_DECODE(ptr))
-
#define UU_LIST_POOL_MAXNAME 64
struct uu_list_pool {
@@ -129,11 +112,11 @@ struct uu_avl_walk {
};
struct uu_avl {
- uintptr_t ua_next_enc;
- uintptr_t ua_prev_enc;
+ uu_avl_t *ua_next;
+ uu_avl_t *ua_prev;
uu_avl_pool_t *ua_pool;
- uintptr_t ua_parent_enc;
+ void *ua_parent;
uint8_t ua_debug;
uint8_t ua_index; /* mark for uu_avl_index_ts */
@@ -141,8 +124,6 @@ struct uu_avl {
uu_avl_walk_t ua_null_walk;
};
-#define UU_AVL_PTR(x) ((uu_avl_t *)UU_PTR_DECODE(x))
-
#define UU_AVL_POOL_MAXNAME 64
struct uu_avl_pool {
diff --git a/sys/contrib/openzfs/include/libzfs.h b/sys/contrib/openzfs/include/libzfs.h
index df17873369ad..2806d1f7cff5 100644
--- a/sys/contrib/openzfs/include/libzfs.h
+++ b/sys/contrib/openzfs/include/libzfs.h
@@ -260,10 +260,10 @@ _LIBZFS_H int zpool_add(zpool_handle_t *, nvlist_t *);
typedef struct splitflags {
/* do not split, but return the config that would be split off */
- int dryrun : 1;
+ unsigned int dryrun : 1;
/* after splitting, import the pool */
- int import : 1;
+ unsigned int import : 1;
int name_flags;
} splitflags_t;
@@ -690,13 +690,13 @@ _LIBZFS_H int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
typedef struct renameflags {
/* recursive rename */
- int recursive : 1;
+ unsigned int recursive : 1;
/* don't unmount file systems */
- int nounmount : 1;
+ unsigned int nounmount : 1;
/* force unmount file systems */
- int forceunmount : 1;
+ unsigned int forceunmount : 1;
} renameflags_t;
_LIBZFS_H int zfs_rename(zfs_handle_t *, const char *, renameflags_t);
diff --git a/sys/contrib/openzfs/include/libzutil.h b/sys/contrib/openzfs/include/libzutil.h
index 0b4075c16016..617dd0cd1715 100644
--- a/sys/contrib/openzfs/include/libzutil.h
+++ b/sys/contrib/openzfs/include/libzutil.h
@@ -59,6 +59,15 @@ typedef const struct pool_config_ops {
_LIBZUTIL_H pool_config_ops_t libzfs_config_ops;
_LIBZUTIL_H pool_config_ops_t libzpool_config_ops;
+typedef enum lpc_error {
+ LPC_SUCCESS = 0, /* no error -- success */
+ LPC_BADCACHE = 2000, /* out of memory */
+ LPC_BADPATH, /* must be an absolute path */
+ LPC_NOMEM, /* out of memory */
+ LPC_EACCESS, /* some devices require root privileges */
+ LPC_UNKNOWN
+} lpc_error_t;
+
typedef struct importargs {
char **path; /* a list of paths to search */
int paths; /* number of paths to search */
@@ -70,10 +79,20 @@ typedef struct importargs {
nvlist_t *policy; /* load policy (max txg, rewind, etc.) */
} importargs_t;
-_LIBZUTIL_H nvlist_t *zpool_search_import(void *, importargs_t *,
- pool_config_ops_t *);
-_LIBZUTIL_H int zpool_find_config(void *, const char *, nvlist_t **,
- importargs_t *, pool_config_ops_t *);
+typedef struct libpc_handle {
+ int lpc_error;
+ boolean_t lpc_printerr;
+ boolean_t lpc_open_access_error;
+ boolean_t lpc_desc_active;
+ char lpc_desc[1024];
+ pool_config_ops_t *lpc_ops;
+ void *lpc_lib_handle;
+} libpc_handle_t;
+
+_LIBZUTIL_H const char *libpc_error_description(libpc_handle_t *);
+_LIBZUTIL_H nvlist_t *zpool_search_import(libpc_handle_t *, importargs_t *);
+_LIBZUTIL_H int zpool_find_config(libpc_handle_t *, const char *, nvlist_t **,
+ importargs_t *);
_LIBZUTIL_H const char * const * zpool_default_search_paths(size_t *count);
_LIBZUTIL_H int zpool_read_label(int, nvlist_t **, int *);
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/acl/acl_common.h b/sys/contrib/openzfs/include/os/freebsd/spl/acl/acl_common.h
index 2b77bdb6ea3d..53b69154d671 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/acl/acl_common.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/acl/acl_common.h
@@ -47,7 +47,7 @@ extern int acltrivial(const char *);
extern void adjust_ace_pair(ace_t *pair, mode_t mode);
extern void adjust_ace_pair_common(void *, size_t, size_t, mode_t);
extern int ace_trivial_common(void *, int,
- uint64_t (*walk)(void *, uint64_t, int aclcnt, uint16_t *, uint16_t *,
+ uintptr_t (*walk)(void *, uintptr_t, int aclcnt, uint16_t *, uint16_t *,
uint32_t *mask));
#if !defined(_KERNEL)
extern acl_t *acl_alloc(acl_type_t);
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 a5bd677b16d4..3e67cf0e9a7d 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/debug.h
@@ -54,6 +54,9 @@
/*
* Common DEBUG functionality.
*/
+#if defined(__COVERITY__) || defined(__clang_analyzer__)
+__attribute__((__noreturn__))
+#endif
extern void spl_panic(const char *file, const char *func, int line,
const char *fmt, ...) __attribute__((__noreturn__));
extern void spl_dumpstack(void);
@@ -128,7 +131,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
const int64_t _verify3_right = (int64_t)(RIGHT); \
if (unlikely(!(_verify3_left == _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
- "VERIFY3(0 == " #RIGHT ") " \
+ "VERIFY0(0 == " #RIGHT ") " \
"failed (0 == %lld)\n", \
(long long) (_verify3_right)); \
} while (0)
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/dkio.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/dkio.h
index 009886cb0763..cd747089d422 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/dkio.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/dkio.h
@@ -28,467 +28,7 @@
#ifndef _OPENSOLARIS_SYS_DKIO_H_
#define _OPENSOLARIS_SYS_DKIO_H_
-#include <sys/types.h> /* Needed for NDKMAP define */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_SUNOS_VTOC_16)
-#define NDKMAP 16 /* # of logical partitions */
-#define DK_LABEL_LOC 1 /* location of disk label */
-#elif defined(_SUNOS_VTOC_8)
-#define NDKMAP 8 /* # of logical partitions */
-#define DK_LABEL_LOC 0 /* location of disk label */
-#else
-#error "No VTOC format defined."
-#endif
-
-/*
- * Structures and definitions for disk io control commands
- */
-
-/*
- * Structures used as data by ioctl calls.
- */
-
-#define DK_DEVLEN 16 /* device name max length, including */
- /* unit # & NULL (ie - "xyc1") */
-
-/*
- * Used for controller info
- */
-struct dk_cinfo {
- char dki_cname[DK_DEVLEN]; /* controller name (no unit #) */
- ushort_t dki_ctype; /* controller type */
- ushort_t dki_flags; /* flags */
- ushort_t dki_cnum; /* controller number */
- uint_t dki_addr; /* controller address */
- uint_t dki_space; /* controller bus type */
- uint_t dki_prio; /* interrupt priority */
- uint_t dki_vec; /* interrupt vector */
- char dki_dname[DK_DEVLEN]; /* drive name (no unit #) */
- uint_t dki_unit; /* unit number */
- ushort_t dki_partition; /* partition number */
- ushort_t dki_maxtransfer; /* max. transfer size in DEV_BSIZE */
-};
-
-/*
- * Controller types
- */
-#define DKC_UNKNOWN 0
-#define DKC_CDROM 1 /* CD-ROM, SCSI or otherwise */
-#define DKC_WDC2880 2
-#define DKC_XXX_0 3 /* unassigned */
-#define DKC_XXX_1 4 /* unassigned */
-#define DKC_DSD5215 5
-#define DKC_ACB4000 7
-#define DKC_MD21 8
-#define DKC_XXX_2 9 /* unassigned */
-#define DKC_NCRFLOPPY 10
-#define DKC_SMSFLOPPY 12
-#define DKC_SCSI_CCS 13 /* SCSI CCS compatible */
-#define DKC_INTEL82072 14 /* native floppy chip */
-#define DKC_MD 16 /* meta-disk (virtual-disk) driver */
-#define DKC_INTEL82077 19 /* 82077 floppy disk controller */
-#define DKC_DIRECT 20 /* Intel direct attached device i.e. IDE */
-#define DKC_PCMCIA_MEM 21 /* PCMCIA memory disk-like type */
-#define DKC_PCMCIA_ATA 22 /* PCMCIA AT Attached type */
-#define DKC_VBD 23 /* virtual block device */
-
-/*
- * Sun reserves up through 1023
- */
-
-#define DKC_CUSTOMER_BASE 1024
-
-/*
- * Flags
- */
-#define DKI_BAD144 0x01 /* use DEC std 144 bad sector fwding */
-#define DKI_MAPTRK 0x02 /* controller does track mapping */
-#define DKI_FMTTRK 0x04 /* formats only full track at a time */
-#define DKI_FMTVOL 0x08 /* formats only full volume at a time */
-#define DKI_FMTCYL 0x10 /* formats only full cylinders at a time */
-#define DKI_HEXUNIT 0x20 /* unit number is printed as 3 hex digits */
-#define DKI_PCMCIA_PFD 0x40 /* PCMCIA pseudo-floppy memory card */
-
-/*
- * partition headers: section 1
- * Returned in struct dk_allmap by ioctl DKIOC[SG]APART (dkio(7I))
- */
-struct dk_map {
- uint64_t dkl_cylno; /* starting cylinder */
- uint64_t dkl_nblk; /* number of blocks; if == 0, */
- /* partition is undefined */
-};
-
-/*
- * Used for all partitions
- */
-struct dk_allmap {
- struct dk_map dka_map[NDKMAP];
-};
-
-#if defined(_SYSCALL32)
-struct dk_allmap32 {
- struct dk_map32 dka_map[NDKMAP];
-};
-#endif /* _SYSCALL32 */
-
-/*
- * Definition of a disk's geometry
- */
-struct dk_geom {
- unsigned short dkg_ncyl; /* # of data cylinders */
- unsigned short dkg_acyl; /* # of alternate cylinders */
- unsigned short dkg_bcyl; /* cyl offset (for fixed head area) */
- unsigned short dkg_nhead; /* # of heads */
- unsigned short dkg_obs1; /* obsolete */
- unsigned short dkg_nsect; /* # of data sectors per track */
- unsigned short dkg_intrlv; /* interleave factor */
- unsigned short dkg_obs2; /* obsolete */
- unsigned short dkg_obs3; /* obsolete */
- unsigned short dkg_apc; /* alternates per cyl (SCSI only) */
- unsigned short dkg_rpm; /* revolutions per minute */
- unsigned short dkg_pcyl; /* # of physical cylinders */
- unsigned short dkg_write_reinstruct; /* # sectors to skip, writes */
- unsigned short dkg_read_reinstruct; /* # sectors to skip, reads */
- unsigned short dkg_extra[7]; /* for compatible expansion */
-};
-
-/*
- * These defines are for historic compatibility with old drivers.
- */
-#define dkg_bhead dkg_obs1 /* used to be head offset */
-#define dkg_gap1 dkg_obs2 /* used to be gap1 */
-#define dkg_gap2 dkg_obs3 /* used to be gap2 */
-
-/*
- * Disk io control commands
- * Warning: some other ioctls with the DIOC prefix exist elsewhere.
- * The Generic DKIOC numbers are from 0 - 50.
- * The Floppy Driver uses 51 - 100.
- * The Hard Disk (except SCSI) 101 - 106. (these are obsolete)
- * The CDROM Driver 151 - 200.
- * The USCSI ioctl 201 - 250.
- */
#define DKIOC (0x04 << 8)
-
-/*
- * The following ioctls are generic in nature and need to be
- * supported as appropriate by all disk drivers
- */
-#define DKIOCGGEOM (DKIOC|1) /* Get geometry */
-#define DKIOCINFO (DKIOC|3) /* Get info */
-#define DKIOCEJECT (DKIOC|6) /* Generic 'eject' */
-#define DKIOCGVTOC (DKIOC|11) /* Get VTOC */
-#define DKIOCSVTOC (DKIOC|12) /* Set VTOC & Write to Disk */
-
-/*
- * Disk Cache Controls. These ioctls should be supported by
- * all disk drivers.
- *
- * DKIOCFLUSHWRITECACHE when used from user-mode ignores the ioctl
- * argument, but it should be passed as NULL to allow for future
- * reinterpretation. From user-mode, this ioctl request is synchronous.
- *
- * When invoked from within the kernel, the arg can be NULL to indicate
- * a synchronous request or can be the address of a struct dk_callback
- * to request an asynchronous callback when the flush request is complete.
- * In this case, the flag to the ioctl must include FKIOCTL and the
- * dkc_callback field of the pointed to struct must be non-null or the
- * request is made synchronously.
- *
- * In the callback case: if the ioctl returns 0, a callback WILL be performed.
- * If the ioctl returns non-zero, a callback will NOT be performed.
- * NOTE: In some cases, the callback may be done BEFORE the ioctl call
- * returns. The caller's locking strategy should be prepared for this case.
- */
#define DKIOCFLUSHWRITECACHE (DKIOC|34) /* flush cache to phys medium */
-struct dk_callback {
- void (*dkc_callback)(void *dkc_cookie, int error);
- void *dkc_cookie;
- int dkc_flag;
-};
-
-/* bit flag definitions for dkc_flag */
-#define FLUSH_VOLATILE 0x1 /* Bit 0: if set, only flush */
- /* volatile cache; otherwise, flush */
- /* volatile and non-volatile cache */
-
-#define DKIOCGETWCE (DKIOC|36) /* Get current write cache */
- /* enablement status */
-#define DKIOCSETWCE (DKIOC|37) /* Enable/Disable write cache */
-
-/*
- * The following ioctls are used by Sun drivers to communicate
- * with their associated format routines. Support of these ioctls
- * is not required of foreign drivers
- */
-#define DKIOCSGEOM (DKIOC|2) /* Set geometry */
-#define DKIOCSAPART (DKIOC|4) /* Set all partitions */
-#define DKIOCGAPART (DKIOC|5) /* Get all partitions */
-#define DKIOCG_PHYGEOM (DKIOC|32) /* get physical geometry */
-#define DKIOCG_VIRTGEOM (DKIOC|33) /* get virtual geometry */
-
-/*
- * The following ioctl's are removable media support
- */
-#define DKIOCLOCK (DKIOC|7) /* Generic 'lock' */
-#define DKIOCUNLOCK (DKIOC|8) /* Generic 'unlock' */
-#define DKIOCSTATE (DKIOC|13) /* Inquire insert/eject state */
-#define DKIOCREMOVABLE (DKIOC|16) /* is media removable */
-
-
-/*
- * ioctl for hotpluggable devices
- */
-#define DKIOCHOTPLUGGABLE (DKIOC|35) /* is hotpluggable */
-
-/*
- * Ioctl to force driver to re-read the alternate partition and rebuild
- * the internal defect map.
- */
-#define DKIOCADDBAD (DKIOC|20) /* Re-read the alternate map (IDE) */
-#define DKIOCGETDEF (DKIOC|21) /* read defect list (IDE) */
-
-/*
- * Used by applications to get disk defect information from IDE
- * drives.
- */
-#ifdef _SYSCALL32
-struct defect_header32 {
- int head;
- caddr32_t buffer;
-};
-#endif /* _SYSCALL32 */
-
-struct defect_header {
- int head;
- caddr_t buffer;
-};
-
-#define DKIOCPARTINFO (DKIOC|22) /* Get partition or slice parameters */
-
-/*
- * Used by applications to get partition or slice information
- */
-#ifdef _SYSCALL32
-struct part_info32 {
- uint32_t p_start;
- int p_length;
-};
-#endif /* _SYSCALL32 */
-
-struct part_info {
- uint64_t p_start;
- int p_length;
-};
-
-/* The following ioctls are for Optical Memory Device */
-#define DKIOC_EBP_ENABLE (DKIOC|40) /* enable by pass erase on write */
-#define DKIOC_EBP_DISABLE (DKIOC|41) /* disable by pass erase on write */
-
-/*
- * This state enum is the argument passed to the DKIOCSTATE ioctl.
- */
-enum dkio_state { DKIO_NONE, DKIO_EJECTED, DKIO_INSERTED, DKIO_DEV_GONE };
-
-#define DKIOCGMEDIAINFO (DKIOC|42) /* get information about the media */
-
-/*
- * ioctls to read/write mboot info.
- */
-#define DKIOCGMBOOT (DKIOC|43) /* get mboot info */
-#define DKIOCSMBOOT (DKIOC|44) /* set mboot info */
-
-/*
- * ioctl to get the device temperature.
- */
-#define DKIOCGTEMPERATURE (DKIOC|45) /* get temperature */
-
-/*
- * Used for providing the temperature.
- */
-
-struct dk_temperature {
- uint_t dkt_flags; /* Flags */
- short dkt_cur_temp; /* Current disk temperature */
- short dkt_ref_temp; /* reference disk temperature */
-};
-
-#define DKT_BYPASS_PM 0x1
-#define DKT_INVALID_TEMP 0xFFFF
-
-
-/*
- * Media types or profiles known
- */
-#define DK_UNKNOWN 0x00 /* Media inserted - type unknown */
-
-
-/*
- * SFF 8090 Specification Version 3, media types 0x01 - 0xfffe are retained to
- * maintain compatibility with SFF8090. The following define the
- * optical media type.
- */
-#define DK_REMOVABLE_DISK 0x02 /* Removable Disk */
-#define DK_MO_ERASABLE 0x03 /* MO Erasable */
-#define DK_MO_WRITEONCE 0x04 /* MO Write once */
-#define DK_AS_MO 0x05 /* AS MO */
-#define DK_CDROM 0x08 /* CDROM */
-#define DK_CDR 0x09 /* CD-R */
-#define DK_CDRW 0x0A /* CD-RW */
-#define DK_DVDROM 0x10 /* DVD-ROM */
-#define DK_DVDR 0x11 /* DVD-R */
-#define DK_DVDRAM 0x12 /* DVD_RAM or DVD-RW */
-
-/*
- * Media types for other rewritable magnetic media
- */
-#define DK_FIXED_DISK 0x10001 /* Fixed disk SCSI or otherwise */
-#define DK_FLOPPY 0x10002 /* Floppy media */
-#define DK_ZIP 0x10003 /* IOMEGA ZIP media */
-#define DK_JAZ 0x10004 /* IOMEGA JAZ media */
-
-#define DKIOCSETEFI (DKIOC|17) /* Set EFI info */
-#define DKIOCGETEFI (DKIOC|18) /* Get EFI info */
-
-#define DKIOCPARTITION (DKIOC|9) /* Get partition info */
-
-/*
- * Ioctls to get/set volume capabilities related to Logical Volume Managers.
- * They include the ability to get/set capabilities and to issue a read to a
- * specific underlying device of a replicated device.
- */
-
-#define DKIOCGETVOLCAP (DKIOC | 25) /* Get volume capabilities */
-#define DKIOCSETVOLCAP (DKIOC | 26) /* Set volume capabilities */
-#define DKIOCDMR (DKIOC | 27) /* Issue a directed read */
-
-typedef uint_t volcapinfo_t;
-
-typedef uint_t volcapset_t;
-
-#define DKV_ABR_CAP 0x00000001 /* Support Appl.Based Recovery */
-#define DKV_DMR_CAP 0x00000002 /* Support Directed Mirror Read */
-
-typedef struct volcap {
- volcapinfo_t vc_info; /* Capabilities available */
- volcapset_t vc_set; /* Capabilities set */
-} volcap_t;
-
-#define VOL_SIDENAME 256
-
-typedef struct vol_directed_rd {
- int vdr_flags;
- offset_t vdr_offset;
- size_t vdr_nbytes;
- size_t vdr_bytesread;
- void *vdr_data;
- int vdr_side;
- char vdr_side_name[VOL_SIDENAME];
-} vol_directed_rd_t;
-
-#define DKV_SIDE_INIT (-1)
-#define DKV_DMR_NEXT_SIDE 0x00000001
-#define DKV_DMR_DONE 0x00000002
-#define DKV_DMR_ERROR 0x00000004
-#define DKV_DMR_SUCCESS 0x00000008
-#define DKV_DMR_SHORT 0x00000010
-
-#ifdef _MULTI_DATAMODEL
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
-#endif
-typedef struct vol_directed_rd32 {
- int32_t vdr_flags;
- offset_t vdr_offset; /* 64-bit element on 32-bit alignment */
- size32_t vdr_nbytes;
- size32_t vdr_bytesread;
- caddr32_t vdr_data;
- int32_t vdr_side;
- char vdr_side_name[VOL_SIDENAME];
-} vol_directed_rd32_t;
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif
-#endif /* _MULTI_DATAMODEL */
-
-/*
- * The ioctl is used to fetch disk's device type, vendor ID,
- * model number/product ID, firmware revision and serial number together.
- *
- * Currently there are two device types - DKD_ATA_TYPE which means the
- * disk is driven by cmdk/ata or dad/uata driver, and DKD_SCSI_TYPE
- * which means the disk is driven by sd/scsi hba driver.
- */
-#define DKIOC_GETDISKID (DKIOC|46)
-
-/* These two labels are for dkd_dtype of dk_disk_id_t */
-#define DKD_ATA_TYPE 0x01 /* ATA disk or legacy mode SATA disk */
-#define DKD_SCSI_TYPE 0x02 /* SCSI disk or native mode SATA disk */
-
-#define DKD_ATA_MODEL 40 /* model number length */
-#define DKD_ATA_FWVER 8 /* firmware revision length */
-#define DKD_ATA_SERIAL 20 /* serial number length */
-
-#define DKD_SCSI_VENDOR 8 /* vendor ID length */
-#define DKD_SCSI_PRODUCT 16 /* product ID length */
-#define DKD_SCSI_REVLEVEL 4 /* revision level length */
-#define DKD_SCSI_SERIAL 12 /* serial number length */
-
-/*
- * The argument type for DKIOC_GETDISKID ioctl.
- */
-typedef struct dk_disk_id {
- uint_t dkd_dtype;
- union {
- struct {
- char dkd_amodel[DKD_ATA_MODEL]; /* 40 bytes */
- char dkd_afwver[DKD_ATA_FWVER]; /* 8 bytes */
- char dkd_aserial[DKD_ATA_SERIAL]; /* 20 bytes */
- } ata_disk_id;
- struct {
- char dkd_svendor[DKD_SCSI_VENDOR]; /* 8 bytes */
- char dkd_sproduct[DKD_SCSI_PRODUCT]; /* 16 bytes */
- char dkd_sfwver[DKD_SCSI_REVLEVEL]; /* 4 bytes */
- char dkd_sserial[DKD_SCSI_SERIAL]; /* 12 bytes */
- } scsi_disk_id;
- } disk_id;
-} dk_disk_id_t;
-
-/*
- * The ioctl is used to update the firmware of device.
- */
-#define DKIOC_UPDATEFW (DKIOC|47)
-
-/* The argument type for DKIOC_UPDATEFW ioctl */
-typedef struct dk_updatefw {
- caddr_t dku_ptrbuf; /* pointer to firmware buf */
- uint_t dku_size; /* firmware buf length */
- uint8_t dku_type; /* firmware update type */
-} dk_updatefw_t;
-
-#ifdef _SYSCALL32
-typedef struct dk_updatefw_32 {
- caddr32_t dku_ptrbuf; /* pointer to firmware buf */
- uint_t dku_size; /* firmware buf length */
- uint8_t dku_type; /* firmware update type */
-} dk_updatefw_32_t;
-#endif /* _SYSCALL32 */
-
-/*
- * firmware update type - temporary or permanent use
- */
-#define FW_TYPE_TEMP 0x0 /* temporary use */
-#define FW_TYPE_PERM 0x1 /* permanent use */
-
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* _OPENSOLARIS_SYS_DKIO_H_ */
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/isa_defs.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/isa_defs.h
index 817521cc2cb9..9eba593fa797 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/isa_defs.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/isa_defs.h
@@ -41,59 +41,6 @@
* The natural byte order of the processor. A pointer to an int points
* to the least/most significant byte of that int.
*
- * _STACK_GROWS_UPWARD / _STACK_GROWS_DOWNWARD:
- * The processor specific direction of stack growth. A push onto the
- * stack increases/decreases the stack pointer, so it stores data at
- * successively higher/lower addresses. (Stackless machines ignored
- * without regrets).
- *
- * _LONG_LONG_HTOL / _LONG_LONG_LTOH:
- * A pointer to a long long points to the most/least significant long
- * within that long long.
- *
- * _BIT_FIELDS_HTOL / _BIT_FIELDS_LTOH:
- * The C compiler assigns bit fields from the high/low to the low/high end
- * of an int (most to least significant vs. least to most significant).
- *
- * _IEEE_754:
- * The processor (or supported implementations of the processor)
- * supports the ieee-754 floating point standard. No other floating
- * point standards are supported (or significant). Any other supported
- * floating point formats are expected to be cased on the ISA processor
- * symbol.
- *
- * _CHAR_IS_UNSIGNED / _CHAR_IS_SIGNED:
- * The C Compiler implements objects of type `char' as `unsigned' or
- * `signed' respectively. This is really an implementation choice of
- * the compiler writer, but it is specified in the ABI and tends to
- * be uniform across compilers for an instruction set architecture.
- * Hence, it has the properties of a processor characteristic.
- *
- * _CHAR_ALIGNMENT / _SHORT_ALIGNMENT / _INT_ALIGNMENT / _LONG_ALIGNMENT /
- * _LONG_LONG_ALIGNMENT / _DOUBLE_ALIGNMENT / _LONG_DOUBLE_ALIGNMENT /
- * _POINTER_ALIGNMENT / _FLOAT_ALIGNMENT:
- * The ABI defines alignment requirements of each of the primitive
- * object types. Some, if not all, may be hardware requirements as
- * well. The values are expressed in "byte-alignment" units.
- *
- * _MAX_ALIGNMENT:
- * The most stringent alignment requirement as specified by the ABI.
- * Equal to the maximum of all the above _XXX_ALIGNMENT values.
- *
- * _ALIGNMENT_REQUIRED:
- * True or false (1 or 0) whether or not the hardware requires the ABI
- * alignment.
- *
- * _LONG_LONG_ALIGNMENT_32
- * The 32-bit ABI supported by a 64-bit kernel may have different
- * alignment requirements for primitive object types. The value of this
- * identifier is expressed in "byte-alignment" units.
- *
- * _HAVE_CPUID_INSN
- * This indicates that the architecture supports the 'cpuid'
- * instruction as defined by Intel. (Intel allows other vendors
- * to extend the instruction for their own purposes.)
- *
*
* Implementation Choices:
*
@@ -112,10 +59,6 @@
* Long/Pointer are 64 bits, Int is 32 bits. This is the chosen
* implementation for 64-bit ABIs such as SPARC V9.
*
- * _I32LPx:
- * A compilation environment where 'int' is 32-bit, and
- * longs and pointers are simply the same size.
- *
* In all cases, Char is 8 bits and Short is 16 bits.
*
* _SUNOS_VTOC_8 / _SUNOS_VTOC_16 / _SVR4_VTOC_16:
@@ -141,78 +84,10 @@
* 16 partitions per disk.
*
*
- * _DMA_USES_PHYSADDR / _DMA_USES_VIRTADDR
- * This describes the type of addresses used by system DMA:
- *
- * _DMA_USES_PHYSADDR:
- * This type of DMA, used in the x86 implementation,
- * requires physical addresses for DMA buffers. The 24-bit
- * addresses used by some legacy boards is the source of the
- * "low-memory" (<16MB) requirement for some devices using DMA.
- *
- * _DMA_USES_VIRTADDR:
- * This method of DMA allows the use of virtual addresses for
- * DMA transfers.
- *
- * _FIRMWARE_NEEDS_FDISK / _NO_FDISK_PRESENT
- * This indicates the presence/absence of an fdisk table.
- *
- * _FIRMWARE_NEEDS_FDISK
- * The fdisk table is required by system firmware. If present,
- * it allows a disk to be subdivided into multiple fdisk
- * partitions, each of which is equivalent to a separate,
- * virtual disk. This enables the co-existence of multiple
- * operating systems on a shared hard disk.
- *
- * _NO_FDISK_PRESENT
- * If the fdisk table is absent, it is assumed that the entire
- * media is allocated for a single operating system.
- *
- * _HAVE_TEM_FIRMWARE
- * Defined if this architecture has the (fallback) option of
- * using prom_* calls for doing I/O if a suitable kernel driver
- * is not available to do it.
- *
- * _DONT_USE_1275_GENERIC_NAMES
- * Controls whether or not device tree node names should
- * comply with the IEEE 1275 "Generic Names" Recommended
- * Practice. With _DONT_USE_GENERIC_NAMES, device-specific
- * names identifying the particular device will be used.
- *
- * __i386_COMPAT
- * This indicates whether the i386 ABI is supported as a *non-native*
- * mode for the platform. When this symbol is defined:
- * - 32-bit xstat-style system calls are enabled
- * - 32-bit xmknod-style system calls are enabled
- * - 32-bit system calls use i386 sizes -and- alignments
- *
- * Note that this is NOT defined for the i386 native environment!
- *
* __x86
* This is ONLY a synonym for defined(__i386) || defined(__amd64)
* which is useful only insofar as these two architectures share
* common attributes. Analogous to __sparc.
- *
- * _PSM_MODULES
- * This indicates whether or not the implementation uses PSM
- * modules for processor support, reading /etc/mach from inside
- * the kernel to extract a list.
- *
- * _RTC_CONFIG
- * This indicates whether or not the implementation uses /etc/rtc_config
- * to configure the real-time clock in the kernel.
- *
- * _UNIX_KRTLD
- * This indicates that the implementation uses a dynamically
- * linked unix + krtld to form the core kernel image at boot
- * time, or (in the absence of this symbol) a prelinked kernel image.
- *
- * _OBP
- * This indicates the firmware interface is OBP.
- *
- * _SOFT_HOSTID
- * This indicates that the implementation obtains the hostid
- * from the file /etc/hostid, rather than from hardware.
*/
#ifdef __cplusplus
@@ -234,53 +109,12 @@ extern "C" {
#endif
/*
- * Define the appropriate "processor characteristics"
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_LTOH
-#define _BIT_FIELDS_LTOH
-#define _IEEE_754
-#define _CHAR_IS_SIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
-#define _LONG_ALIGNMENT 8
-#define _LONG_LONG_ALIGNMENT 8
-#define _DOUBLE_ALIGNMENT 8
-#define _DOUBLE_COMPLEX_ALIGNMENT 8
-#define _LONG_DOUBLE_ALIGNMENT 16
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16
-#define _POINTER_ALIGNMENT 8
-#define _MAX_ALIGNMENT 16
-#define _ALIGNMENT_REQUIRED 1
-
-/*
- * Different alignment constraints for the i386 ABI in compatibility mode
- */
-#define _LONG_LONG_ALIGNMENT_32 4
-
-/*
* Define the appropriate "implementation choices".
*/
#if !defined(_LP64)
#error "_LP64 not defined"
#endif
-#if !defined(_I32LPx)
-#define _I32LPx
-#endif
-#define _MULTI_DATAMODEL
#define _SUNOS_VTOC_16
-#define _DMA_USES_PHYSADDR
-#define _FIRMWARE_NEEDS_FDISK
-#define __i386_COMPAT
-#define _PSM_MODULES
-#define _RTC_CONFIG
-#define _SOFT_HOSTID
-#define _DONT_USE_1275_GENERIC_NAMES
-#define _HAVE_CPUID_INSN
/*
* The feature test macro __i386 is generic for all processors implementing
@@ -298,206 +132,46 @@ extern "C" {
#endif
/*
- * Define the appropriate "processor characteristics"
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_LTOH
-#define _BIT_FIELDS_LTOH
-#define _IEEE_754
-#define _CHAR_IS_SIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
-#define _LONG_ALIGNMENT 4
-#define _LONG_LONG_ALIGNMENT 4
-#define _DOUBLE_ALIGNMENT 4
-#define _DOUBLE_COMPLEX_ALIGNMENT 4
-#define _LONG_DOUBLE_ALIGNMENT 4
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 4
-#define _POINTER_ALIGNMENT 4
-#define _MAX_ALIGNMENT 4
-#define _ALIGNMENT_REQUIRED 0
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
-/*
* Define the appropriate "implementation choices".
*/
#if !defined(_ILP32)
#define _ILP32
#endif
-#if !defined(_I32LPx)
-#define _I32LPx
-#endif
#define _SUNOS_VTOC_16
-#define _DMA_USES_PHYSADDR
-#define _FIRMWARE_NEEDS_FDISK
-#define _PSM_MODULES
-#define _RTC_CONFIG
-#define _SOFT_HOSTID
-#define _DONT_USE_1275_GENERIC_NAMES
-#define _HAVE_CPUID_INSN
#elif defined(__aarch64__)
/*
- * Define the appropriate "processor characteristics"
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_LTOH
-#define _BIT_FIELDS_LTOH
-#define _IEEE_754
-#define _CHAR_IS_UNSIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
-#define _LONG_ALIGNMENT 8
-#define _LONG_LONG_ALIGNMENT 8
-#define _DOUBLE_ALIGNMENT 8
-#define _DOUBLE_COMPLEX_ALIGNMENT 8
-#define _LONG_DOUBLE_ALIGNMENT 16
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16
-#define _POINTER_ALIGNMENT 8
-#define _MAX_ALIGNMENT 16
-#define _ALIGNMENT_REQUIRED 1
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
-/*
* Define the appropriate "implementation choices"
*/
#if !defined(_LP64)
#error "_LP64 not defined"
#endif
#define _SUNOS_VTOC_16
-#define _DMA_USES_PHYSADDR
-#define _FIRMWARE_NEEDS_FDISK
-#define _PSM_MODULES
-#define _RTC_CONFIG
-#define _DONT_USE_1275_GENERIC_NAMES
-#define _HAVE_CPUID_INSN
#elif defined(__riscv)
/*
- * Define the appropriate "processor characteristics"
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_LTOH
-#define _BIT_FIELDS_LTOH
-#define _IEEE_754
-#define _CHAR_IS_UNSIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
-#define _LONG_ALIGNMENT 8
-#define _LONG_LONG_ALIGNMENT 8
-#define _DOUBLE_ALIGNMENT 8
-#define _DOUBLE_COMPLEX_ALIGNMENT 8
-#define _LONG_DOUBLE_ALIGNMENT 16
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16
-#define _POINTER_ALIGNMENT 8
-#define _MAX_ALIGNMENT 16
-#define _ALIGNMENT_REQUIRED 1
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
-/*
* Define the appropriate "implementation choices"
*/
#if !defined(_LP64)
#define _LP64
#endif
#define _SUNOS_VTOC_16
-#define _DMA_USES_PHYSADDR
-#define _FIRMWARE_NEEDS_FDISK
-#define _PSM_MODULES
-#define _RTC_CONFIG
-#define _DONT_USE_1275_GENERIC_NAMES
-#define _HAVE_CPUID_INSN
#elif defined(__arm__)
/*
- * Define the appropriate "processor characteristics"
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_LTOH
-#define _BIT_FIELDS_LTOH
-#define _IEEE_754
-#define _CHAR_IS_SIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
-#define _LONG_ALIGNMENT 4
-#define _LONG_LONG_ALIGNMENT 4
-#define _DOUBLE_ALIGNMENT 4
-#define _DOUBLE_COMPLEX_ALIGNMENT 4
-#define _LONG_DOUBLE_ALIGNMENT 4
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 4
-#define _POINTER_ALIGNMENT 4
-#define _MAX_ALIGNMENT 4
-#define _ALIGNMENT_REQUIRED 0
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
-/*
* Define the appropriate "implementation choices".
*/
#if !defined(_ILP32)
#define _ILP32
#endif
-#if !defined(_I32LPx)
-#define _I32LPx
-#endif
#define _SUNOS_VTOC_16
-#define _DMA_USES_PHYSADDR
-#define _FIRMWARE_NEEDS_FDISK
-#define _PSM_MODULES
-#define _RTC_CONFIG
-#define _DONT_USE_1275_GENERIC_NAMES
-#define _HAVE_CPUID_INSN
#elif defined(__mips__)
-/*
- * Define the appropriate "processor characteristics"
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_LTOH
-#define _BIT_FIELDS_LTOH
-#define _IEEE_754
-#define _CHAR_IS_SIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
#if defined(__mips_n64)
-#define _LONG_ALIGNMENT 8
-#define _LONG_LONG_ALIGNMENT 8
-#define _DOUBLE_ALIGNMENT 8
-#define _DOUBLE_COMPLEX_ALIGNMENT 8
-#define _LONG_DOUBLE_ALIGNMENT 8
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 8
-#define _POINTER_ALIGNMENT 8
-#define _MAX_ALIGNMENT 8
-#define _ALIGNMENT_REQUIRED 0
-
-#define _LONG_LONG_ALIGNMENT_32 _INT_ALIGNMENT
/*
* Define the appropriate "implementation choices".
*/
@@ -505,57 +179,21 @@ extern "C" {
#error "_LP64 not defined"
#endif
#else
-#define _LONG_ALIGNMENT 4
-#define _LONG_LONG_ALIGNMENT 4
-#define _DOUBLE_ALIGNMENT 4
-#define _DOUBLE_COMPLEX_ALIGNMENT 4
-#define _LONG_DOUBLE_ALIGNMENT 4
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 4
-#define _POINTER_ALIGNMENT 4
-#define _MAX_ALIGNMENT 4
-#define _ALIGNMENT_REQUIRED 0
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
/*
* Define the appropriate "implementation choices".
*/
#if !defined(_ILP32)
#define _ILP32
#endif
-#if !defined(_I32LPx)
-#define _I32LPx
-#endif
#endif
#define _SUNOS_VTOC_16
-#define _DMA_USES_PHYSADDR
-#define _FIRMWARE_NEEDS_FDISK
-#define _PSM_MODULES
-#define _RTC_CONFIG
-#define _DONT_USE_1275_GENERIC_NAMES
-#define _HAVE_CPUID_INSN
#elif defined(__powerpc__)
-#if defined(__BIG_ENDIAN__)
-#define _BIT_FIELDS_HTOL
-#else
-#define _BIT_FIELDS_LTOH
-#endif
-
#if !defined(__powerpc)
#define __powerpc
#endif
-#if defined(__powerpc64__)
-#define _LONG_LONG_ALIGNMENT 8
-#define _MULTI_DATAMODEL
-#else
-#define _LONG_LONG_ALIGNMENT 4
-#endif
-#define _LONG_LONG_ALIGNMENT_32 4
-#define _ALIGNMENT_REQUIRED 1
-
#define _SUNOS_VTOC_16 1
/*
@@ -601,33 +239,9 @@ extern "C" {
#endif
/*
- * Define the appropriate "processor characteristics" shared between
- * all Solaris on SPARC systems.
- */
-#define _STACK_GROWS_DOWNWARD
-#define _LONG_LONG_HTOL
-#define _BIT_FIELDS_HTOL
-#define _IEEE_754
-#define _CHAR_IS_SIGNED
-#define _BOOL_ALIGNMENT 1
-#define _CHAR_ALIGNMENT 1
-#define _SHORT_ALIGNMENT 2
-#define _INT_ALIGNMENT 4
-#define _FLOAT_ALIGNMENT 4
-#define _FLOAT_COMPLEX_ALIGNMENT 4
-#define _LONG_LONG_ALIGNMENT 8
-#define _DOUBLE_ALIGNMENT 8
-#define _DOUBLE_COMPLEX_ALIGNMENT 8
-#define _ALIGNMENT_REQUIRED 1
-
-/*
* Define the appropriate "implementation choices" shared between versions.
*/
#define _SUNOS_VTOC_8
-#define _DMA_USES_VIRTADDR
-#define _NO_FDISK_PRESENT
-#define _HAVE_TEM_FIRMWARE
-#define _OBP
/*
* The following set of definitions characterize the implementation of
@@ -636,23 +250,9 @@ extern "C" {
#if defined(__sparcv8)
/*
- * Define the appropriate "processor characteristics"
- */
-#define _LONG_ALIGNMENT 4
-#define _LONG_DOUBLE_ALIGNMENT 8
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 8
-#define _POINTER_ALIGNMENT 4
-#define _MAX_ALIGNMENT 8
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
-/*
* Define the appropriate "implementation choices"
*/
#define _ILP32
-#if !defined(_I32LPx)
-#define _I32LPx
-#endif
/*
* The following set of definitions characterize the implementation of
@@ -661,26 +261,11 @@ extern "C" {
#elif defined(__sparcv9)
/*
- * Define the appropriate "processor characteristics"
- */
-#define _LONG_ALIGNMENT 8
-#define _LONG_DOUBLE_ALIGNMENT 16
-#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16
-#define _POINTER_ALIGNMENT 8
-#define _MAX_ALIGNMENT 16
-
-#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
-
-/*
* Define the appropriate "implementation choices"
*/
#if !defined(_LP64)
#error "_LP64 not defined"
#endif
-#if !defined(_I32LPx)
-#define _I32LPx
-#endif
-#define _MULTI_DATAMODEL
#else
#error "unknown SPARC version"
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/kmem.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/kmem.h
index ae2941b80912..27d290863c0b 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/kmem.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/kmem.h
@@ -57,6 +57,9 @@ extern char *kmem_asprintf(const char *, ...)
extern char *kmem_vasprintf(const char *fmt, va_list ap)
__attribute__((format(printf, 1, 0)));
+extern int kmem_scnprintf(char *restrict str, size_t size,
+ const char *restrict fmt, ...);
+
typedef struct kmem_cache {
char kc_name[32];
#if !defined(KMEM_DEBUG)
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod_os.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod_os.h
index e2815ce9e543..48e8a2adb8d2 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod_os.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod_os.h
@@ -52,17 +52,17 @@
#define ZFS_MODULE_VIRTUAL_PARAM_CALL ZFS_MODULE_PARAM_CALL
-#define param_set_arc_long_args(var) \
- CTLTYPE_ULONG, &var, 0, param_set_arc_long, "LU"
+#define param_set_arc_u64_args(var) \
+ CTLTYPE_U64, &var, 0, param_set_arc_u64, "QU"
#define param_set_arc_int_args(var) \
CTLTYPE_INT, &var, 0, param_set_arc_int, "I"
#define param_set_arc_min_args(var) \
- CTLTYPE_ULONG, NULL, 0, param_set_arc_min, "LU"
+ CTLTYPE_U64, NULL, 0, param_set_arc_min, "QU"
#define param_set_arc_max_args(var) \
- CTLTYPE_ULONG, NULL, 0, param_set_arc_max, "LU"
+ CTLTYPE_U64, NULL, 0, param_set_arc_max, "QU"
#define param_set_arc_free_target_args(var) \
CTLTYPE_UINT, NULL, 0, param_set_arc_free_target, "IU"
@@ -74,22 +74,22 @@
CTLTYPE_STRING, NULL, 0, param_set_deadman_failmode, "A"
#define param_set_deadman_synctime_args(var) \
- CTLTYPE_ULONG, NULL, 0, param_set_deadman_synctime, "LU"
+ CTLTYPE_U64, NULL, 0, param_set_deadman_synctime, "QU"
#define param_set_deadman_ziotime_args(var) \
- CTLTYPE_ULONG, NULL, 0, param_set_deadman_ziotime, "LU"
+ CTLTYPE_U64, NULL, 0, param_set_deadman_ziotime, "QU"
#define param_set_multihost_interval_args(var) \
- CTLTYPE_ULONG, NULL, 0, param_set_multihost_interval, "LU"
+ CTLTYPE_U64, NULL, 0, param_set_multihost_interval, "QU"
#define param_set_slop_shift_args(var) \
CTLTYPE_INT, NULL, 0, param_set_slop_shift, "I"
#define param_set_min_auto_ashift_args(var) \
- CTLTYPE_U64, NULL, 0, param_set_min_auto_ashift, "QU"
+ CTLTYPE_UINT, NULL, 0, param_set_min_auto_ashift, "IU"
#define param_set_max_auto_ashift_args(var) \
- CTLTYPE_U64, NULL, 0, param_set_max_auto_ashift, "QU"
+ CTLTYPE_UINT, NULL, 0, param_set_max_auto_ashift, "IU"
#define fletcher_4_param_set_args(var) \
CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A"
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/sysmacros.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/sysmacros.h
index 1c8475a7092c..3e8841ae66bd 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/sysmacros.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/sysmacros.h
@@ -281,46 +281,6 @@ extern unsigned char bcd_to_byte[256];
#define INCR_COUNT(var, mutex) mutex_enter(mutex), (*(var))++, mutex_exit(mutex)
#define DECR_COUNT(var, mutex) mutex_enter(mutex), (*(var))--, mutex_exit(mutex)
-/*
- * Macros to declare bitfields - the order in the parameter list is
- * Low to High - that is, declare bit 0 first. We only support 8-bit bitfields
- * because if a field crosses a byte boundary it's not likely to be meaningful
- * without reassembly in its nonnative endianness.
- */
-#if defined(_BIT_FIELDS_LTOH)
-#define DECL_BITFIELD2(_a, _b) \
- uint8_t _a, _b
-#define DECL_BITFIELD3(_a, _b, _c) \
- uint8_t _a, _b, _c
-#define DECL_BITFIELD4(_a, _b, _c, _d) \
- uint8_t _a, _b, _c, _d
-#define DECL_BITFIELD5(_a, _b, _c, _d, _e) \
- uint8_t _a, _b, _c, _d, _e
-#define DECL_BITFIELD6(_a, _b, _c, _d, _e, _f) \
- uint8_t _a, _b, _c, _d, _e, _f
-#define DECL_BITFIELD7(_a, _b, _c, _d, _e, _f, _g) \
- uint8_t _a, _b, _c, _d, _e, _f, _g
-#define DECL_BITFIELD8(_a, _b, _c, _d, _e, _f, _g, _h) \
- uint8_t _a, _b, _c, _d, _e, _f, _g, _h
-#elif defined(_BIT_FIELDS_HTOL)
-#define DECL_BITFIELD2(_a, _b) \
- uint8_t _b, _a
-#define DECL_BITFIELD3(_a, _b, _c) \
- uint8_t _c, _b, _a
-#define DECL_BITFIELD4(_a, _b, _c, _d) \
- uint8_t _d, _c, _b, _a
-#define DECL_BITFIELD5(_a, _b, _c, _d, _e) \
- uint8_t _e, _d, _c, _b, _a
-#define DECL_BITFIELD6(_a, _b, _c, _d, _e, _f) \
- uint8_t _f, _e, _d, _c, _b, _a
-#define DECL_BITFIELD7(_a, _b, _c, _d, _e, _f, _g) \
- uint8_t _g, _f, _e, _d, _c, _b, _a
-#define DECL_BITFIELD8(_a, _b, _c, _d, _e, _f, _g, _h) \
- uint8_t _h, _g, _f, _e, _d, _c, _b, _a
-#else
-#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
-#endif /* _BIT_FIELDS_LTOH */
-
#if !defined(_KMEMUSER) && !defined(offsetof)
/* avoid any possibility of clashing with <stddef.h> version */
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/types.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/types.h
index b1308df29503..558843dcaa74 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/types.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/types.h
@@ -105,5 +105,7 @@ typedef u_longlong_t len_t;
typedef longlong_t diskaddr_t;
+typedef void zuserns_t;
+
#include <sys/debug.h>
#endif /* !_OPENSOLARIS_SYS_TYPES_H_ */
diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h
index e0f79a1116b2..483d12ae59a2 100644
--- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h
+++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/vnode.h
@@ -96,16 +96,17 @@ vn_flush_cached_data(vnode_t *vp, boolean_t sync)
if (vp->v_object->flags & OBJ_MIGHTBEDIRTY) {
#endif
int flags = sync ? OBJPC_SYNC : 0;
+ vn_lock(vp, LK_SHARED | LK_RETRY);
zfs_vmobject_wlock(vp->v_object);
vm_object_page_clean(vp->v_object, 0, 0, flags);
zfs_vmobject_wunlock(vp->v_object);
+ VOP_UNLOCK(vp);
}
}
#endif
#define vn_exists(vp) do { } while (0)
#define vn_invalid(vp) do { } while (0)
-#define vn_renamepath(tdvp, svp, tnm, lentnm) do { } while (0)
#define vn_free(vp) do { } while (0)
#define vn_matchops(vp, vops) ((vp)->v_op == &(vops))
@@ -203,15 +204,6 @@ vattr_init_mask(vattr_t *vap)
#define RLIM64_INFINITY 0
-static __inline int
-vn_rename(char *from, char *to, enum uio_seg seg)
-{
-
- ASSERT(seg == UIO_SYSSPACE);
-
- return (kern_renameat(curthread, AT_FDCWD, from, AT_FDCWD, to, seg));
-}
-
#include <sys/vfs.h>
#endif /* _OPENSOLARIS_SYS_VNODE_H_ */
diff --git a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h
index 79b30b5088c4..34757a486028 100644
--- a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h
+++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_ioctl_compat.h
@@ -37,6 +37,15 @@
#include <sys/nvpair.h>
#endif /* _KERNEL */
+/*
+ * Legacy ioctl support allows compatibility with pre-OpenZFS tools on
+ * FreeBSD. The need for it will eventually pass (perhaps after FreeBSD
+ * 12 is well out of support), at which point this code can be removed.
+ * For now, downstream consumers may choose to disable this code by
+ * removing the following define.
+ */
+#define ZFS_LEGACY_SUPPORT
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -82,6 +91,7 @@ typedef struct zfs_iocparm {
} zfs_iocparm_t;
+#ifdef ZFS_LEGACY_SUPPORT
#define LEGACY_MAXPATHLEN 1024
#define LEGACY_MAXNAMELEN 256
@@ -135,6 +145,7 @@ typedef struct zfs_cmd_legacy {
uint64_t zc_createtxg;
zfs_stat_t zc_stat;
} zfs_cmd_legacy_t;
+#endif
#ifdef _KERNEL
@@ -145,10 +156,12 @@ nvlist_t *zfs_ioctl_compat_innvl(zfs_cmd_t *, nvlist_t *, const int,
nvlist_t *zfs_ioctl_compat_outnvl(zfs_cmd_t *, nvlist_t *, const int,
const int);
#endif /* _KERNEL */
+#ifdef ZFS_LEGACY_SUPPORT
int zfs_ioctl_legacy_to_ozfs(int request);
int zfs_ioctl_ozfs_to_legacy(int request);
void zfs_cmd_legacy_to_ozfs(zfs_cmd_legacy_t *src, zfs_cmd_t *dst);
void zfs_cmd_ozfs_to_legacy(zfs_cmd_t *src, zfs_cmd_legacy_t *dst);
+#endif
void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int, const int);
diff --git a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vnops_os.h b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vnops_os.h
index bf5e03b24c06..839ee629a5ab 100644
--- a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vnops_os.h
+++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vnops_os.h
@@ -35,20 +35,23 @@ int dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
int *rbehind, int *rahead, int last_size);
extern int zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags);
extern int zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap,
- znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp);
+ znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns);
extern int zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd,
cred_t *cr, int flags);
-extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
+extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
+ zuserns_t *mnt_ns);
extern int zfs_rename(znode_t *sdzp, const char *snm, znode_t *tdzp,
- const char *tnm, cred_t *cr, int flags);
+ const char *tnm, cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap,
+ zuserns_t *mnt_ns);
extern int zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
- const char *link, znode_t **zpp, cred_t *cr, int flags);
+ const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
extern int zfs_link(znode_t *tdzp, znode_t *sp,
const char *name, cred_t *cr, int flags);
extern int zfs_space(znode_t *zp, int cmd, struct flock *bfp, int flag,
offset_t offset, cred_t *cr);
extern int zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl,
- int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp);
+ int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
+ zuserns_t *mnt_ns);
extern int zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag,
cred_t *cr);
extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h
index 3276796537a4..45de1f4993f1 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h
@@ -126,7 +126,8 @@ typedef int bvec_iterator_t;
#endif
static inline void
-bio_set_flags_failfast(struct block_device *bdev, int *flags)
+bio_set_flags_failfast(struct block_device *bdev, int *flags, bool dev,
+ bool transport, bool driver)
{
#ifdef CONFIG_BUG
/*
@@ -148,7 +149,12 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
#endif /* BLOCK_EXT_MAJOR */
#endif /* CONFIG_BUG */
- *flags |= REQ_FAILFAST_MASK;
+ if (dev)
+ *flags |= REQ_FAILFAST_DEV;
+ if (transport)
+ *flags |= REQ_FAILFAST_TRANSPORT;
+ if (driver)
+ *flags |= REQ_FAILFAST_DRIVER;
}
/*
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h
index 0fbd92458679..4de1118daafa 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/dcache_compat.h
@@ -61,4 +61,25 @@ d_clear_d_op(struct dentry *dentry)
DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE);
}
+/*
+ * Walk and invalidate all dentry aliases of an inode
+ * unless it's a mountpoint
+ */
+static inline void
+zpl_d_drop_aliases(struct inode *inode)
+{
+ struct dentry *dentry;
+ spin_lock(&inode->i_lock);
+#ifdef HAVE_DENTRY_D_U_ALIASES
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+#else
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
+#endif
+ if (!IS_ROOT(dentry) && !d_mountpoint(dentry) &&
+ (dentry->d_inode == inode)) {
+ d_drop(dentry);
+ }
+ }
+ spin_unlock(&inode->i_lock);
+}
#endif /* _ZFS_DCACHE_H */
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h
index a091bbfe179d..67b4fc90653c 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/mod_compat.h
@@ -30,24 +30,20 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-/* Grsecurity kernel API change */
-#ifdef MODULE_PARAM_CALL_CONST
+/*
+ * Despite constifying struct kernel_param_ops, some older kernels define a
+ * `__check_old_set_param()` function in their headers that checks for a
+ * non-constified `->set()`. This has long been fixed in Linux mainline, but
+ * since we support older kernels, we workaround it by using a preprocessor
+ * definition to disable it.
+ */
+#define __check_old_set_param(_) (0)
+
typedef const struct kernel_param zfs_kernel_param_t;
-#else
-typedef struct kernel_param zfs_kernel_param_t;
-#endif
#define ZMOD_RW 0644
#define ZMOD_RD 0444
-#define INT int
-#define LONG long
-/* BEGIN CSTYLED */
-#define UINT uint
-#define ULONG ulong
-/* END CSTYLED */
-#define STRING charp
-
enum scope_prefix_types {
zfs,
zfs_arc,
@@ -81,6 +77,50 @@ enum scope_prefix_types {
};
/*
+ * While we define our own s64/u64 types, there is no reason to reimplement the
+ * existing Linux kernel types, so we use the preprocessor to remap our
+ * "custom" implementations to the kernel ones. This is done because the CPP
+ * does not allow us to write conditional definitions. The fourth definition
+ * exists because the CPP will not allow us to replace things like INT with int
+ * before string concatenation.
+ */
+
+#define spl_param_set_int param_set_int
+#define spl_param_get_int param_get_int
+#define spl_param_ops_int param_ops_int
+#define spl_param_ops_INT param_ops_int
+
+#define spl_param_set_long param_set_long
+#define spl_param_get_long param_get_long
+#define spl_param_ops_long param_ops_long
+#define spl_param_ops_LONG param_ops_long
+
+#define spl_param_set_uint param_set_uint
+#define spl_param_get_uint param_get_uint
+#define spl_param_ops_uint param_ops_uint
+#define spl_param_ops_UINT param_ops_uint
+
+#define spl_param_set_ulong param_set_ulong
+#define spl_param_get_ulong param_get_ulong
+#define spl_param_ops_ulong param_ops_ulong
+#define spl_param_ops_ULONG param_ops_ulong
+
+#define spl_param_set_charp param_set_charp
+#define spl_param_get_charp param_get_charp
+#define spl_param_ops_charp param_ops_charp
+#define spl_param_ops_STRING param_ops_charp
+
+int spl_param_set_s64(const char *val, zfs_kernel_param_t *kp);
+extern int spl_param_get_s64(char *buffer, zfs_kernel_param_t *kp);
+extern const struct kernel_param_ops spl_param_ops_s64;
+#define spl_param_ops_S64 spl_param_ops_s64
+
+extern int spl_param_set_u64(const char *val, zfs_kernel_param_t *kp);
+extern int spl_param_get_u64(char *buffer, zfs_kernel_param_t *kp);
+extern const struct kernel_param_ops spl_param_ops_u64;
+#define spl_param_ops_U64 spl_param_ops_u64
+
+/*
* Declare a module parameter / sysctl node
*
* "scope_prefix" the part of the sysctl / sysfs tree the node resides under
@@ -112,7 +152,8 @@ enum scope_prefix_types {
_Static_assert( \
sizeof (scope_prefix) == sizeof (enum scope_prefix_types), \
"" #scope_prefix " size mismatch with enum scope_prefix_types"); \
- module_param(name_prefix ## name, type, perm); \
+ module_param_cb(name_prefix ## name, &spl_param_ops_ ## type, \
+ &name_prefix ## name, perm); \
MODULE_PARM_DESC(name_prefix ## name, desc)
/*
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/vfs_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/vfs_compat.h
index eeed0a388ce4..fd0b9e8e1068 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/vfs_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/vfs_compat.h
@@ -325,6 +325,19 @@ static inline void zfs_gid_write(struct inode *ip, gid_t gid)
}
/*
+ * 3.15 API change
+ */
+#ifndef RENAME_NOREPLACE
+#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
+#endif
+#ifndef RENAME_EXCHANGE
+#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
+#endif
+#ifndef RENAME_WHITEOUT
+#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
+#endif
+
+/*
* 4.9 API change
*/
#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/xattr_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/xattr_compat.h
index 9b83813db708..ff80fbb06413 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/xattr_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/xattr_compat.h
@@ -146,7 +146,7 @@ fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \
struct dentry *dentry, struct inode *inode, const char *name, \
const void *buffer, size_t size, int flags) \
{ \
- return (__ ## fn(inode, name, buffer, size, flags)); \
+ return (__ ## fn(user_ns, inode, name, buffer, size, flags)); \
}
/*
* 4.7 API change,
@@ -160,7 +160,7 @@ fn(const struct xattr_handler *handler, struct dentry *dentry, \
struct inode *inode, const char *name, const void *buffer, \
size_t size, int flags) \
{ \
- return (__ ## fn(inode, name, buffer, size, flags)); \
+ return (__ ## fn(kcred->user_ns, inode, name, buffer, size, flags));\
}
/*
* 4.4 API change,
@@ -174,7 +174,8 @@ static int \
fn(const struct xattr_handler *handler, struct dentry *dentry, \
const char *name, const void *buffer, size_t size, int flags) \
{ \
- return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
+ return (__ ## fn(kcred->user_ns, dentry->d_inode, name, \
+ buffer, size, flags)); \
}
/*
* 2.6.33 API change,
@@ -187,7 +188,8 @@ static int \
fn(struct dentry *dentry, const char *name, const void *buffer, \
size_t size, int flags, int unused_handler_flags) \
{ \
- return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
+ return (__ ## fn(kcred->user_ns, dentry->d_inode, name, \
+ buffer, size, flags)); \
}
#else
#error "Unsupported kernel"
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/cred.h b/sys/contrib/openzfs/include/os/linux/spl/sys/cred.h
index b7d3f38d70bb..75ad400d312d 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/cred.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/cred.h
@@ -26,11 +26,14 @@
#include <linux/module.h>
#include <linux/cred.h>
+#include <linux/sched.h>
#include <sys/types.h>
#include <sys/vfs.h>
typedef struct cred cred_t;
+extern struct task_struct init_task;
+
#define kcred ((cred_t *)(init_task.cred))
#define CRED() ((cred_t *)current_cred())
@@ -45,6 +48,82 @@ typedef struct cred cred_t;
#define SGID_TO_KGID(x) (KGIDT_INIT(x))
#define KGIDP_TO_SGIDP(x) (&(x)->val)
+/* Check if the user ns is the initial one */
+static inline boolean_t
+zfs_is_init_userns(struct user_namespace *user_ns)
+{
+#if defined(CONFIG_USER_NS)
+ return (user_ns == kcred->user_ns);
+#else
+ return (B_FALSE);
+#endif
+}
+
+static inline struct user_namespace *zfs_i_user_ns(struct inode *inode)
+{
+#ifdef HAVE_SUPER_USER_NS
+ return (inode->i_sb->s_user_ns);
+#else
+ return (kcred->user_ns);
+#endif
+}
+
+static inline boolean_t zfs_no_idmapping(struct user_namespace *mnt_userns,
+ struct user_namespace *fs_userns)
+{
+ return (zfs_is_init_userns(mnt_userns) || mnt_userns == fs_userns);
+}
+
+static inline uid_t zfs_uid_to_vfsuid(struct user_namespace *mnt_userns,
+ struct user_namespace *fs_userns, uid_t uid)
+{
+ if (zfs_no_idmapping(mnt_userns, fs_userns))
+ return (uid);
+ if (!zfs_is_init_userns(fs_userns))
+ uid = from_kuid(fs_userns, KUIDT_INIT(uid));
+ if (uid == (uid_t)-1)
+ return (uid);
+ return (__kuid_val(make_kuid(mnt_userns, uid)));
+}
+
+static inline gid_t zfs_gid_to_vfsgid(struct user_namespace *mnt_userns,
+ struct user_namespace *fs_userns, gid_t gid)
+{
+ if (zfs_no_idmapping(mnt_userns, fs_userns))
+ return (gid);
+ if (!zfs_is_init_userns(fs_userns))
+ gid = from_kgid(fs_userns, KGIDT_INIT(gid));
+ if (gid == (gid_t)-1)
+ return (gid);
+ return (__kgid_val(make_kgid(mnt_userns, gid)));
+}
+
+static inline uid_t zfs_vfsuid_to_uid(struct user_namespace *mnt_userns,
+ struct user_namespace *fs_userns, uid_t uid)
+{
+ if (zfs_no_idmapping(mnt_userns, fs_userns))
+ return (uid);
+ uid = from_kuid(mnt_userns, KUIDT_INIT(uid));
+ if (uid == (uid_t)-1)
+ return (uid);
+ if (zfs_is_init_userns(fs_userns))
+ return (uid);
+ return (__kuid_val(make_kuid(fs_userns, uid)));
+}
+
+static inline gid_t zfs_vfsgid_to_gid(struct user_namespace *mnt_userns,
+ struct user_namespace *fs_userns, gid_t gid)
+{
+ if (zfs_no_idmapping(mnt_userns, fs_userns))
+ return (gid);
+ gid = from_kgid(mnt_userns, KGIDT_INIT(gid));
+ if (gid == (gid_t)-1)
+ return (gid);
+ if (zfs_is_init_userns(fs_userns))
+ return (gid);
+ return (__kgid_val(make_kgid(fs_userns, gid)));
+}
+
extern void crhold(cred_t *cr);
extern void crfree(cred_t *cr);
extern uid_t crgetuid(const cred_t *cr);
@@ -53,5 +132,4 @@ extern gid_t crgetgid(const cred_t *cr);
extern int crgetngroups(const cred_t *cr);
extern gid_t *crgetgroups(const cred_t *cr);
extern int groupmember(gid_t gid, const cred_t *cr);
-
#endif /* _SPL_CRED_H */
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 8ad199808633..007238574fe1 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/debug.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/debug.h
@@ -54,8 +54,21 @@
#define __maybe_unused __attribute__((unused))
#endif
+/*
+ * Without this, we see warnings from objtool during normal Linux builds when
+ * the kernel is built with CONFIG_STACK_VALIDATION=y:
+ *
+ * warning: objtool: tsd_create() falls through to next function __list_add()
+ * warning: objtool: .text: unexpected end of section
+ *
+ * Until the toolchain stops doing this, we must only define this attribute on
+ * spl_panic() when doing static analysis.
+ */
+#if defined(__COVERITY__) || defined(__clang_analyzer__)
+__attribute__((__noreturn__))
+#endif
extern void spl_panic(const char *file, const char *func, int line,
- const char *fmt, ...) __attribute__((__noreturn__));
+ const char *fmt, ...);
extern void spl_dumpstack(void);
static inline int
@@ -122,11 +135,21 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
const int64_t _verify3_right = (int64_t)(RIGHT); \
if (unlikely(!(_verify3_left == _verify3_right))) \
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
- "VERIFY3(0 == " #RIGHT ") " \
+ "VERIFY0(0 == " #RIGHT ") " \
"failed (0 == %lld)\n", \
(long long) (_verify3_right)); \
} while (0)
+#define VERIFY_IMPLY(A, B) \
+ ((void)(likely((!(A)) || (B)) || \
+ spl_assert("(" #A ") implies (" #B ")", \
+ __FILE__, __FUNCTION__, __LINE__)))
+
+#define VERIFY_EQUIV(A, B) \
+ ((void)(likely(!!(A) == !!(B)) || \
+ spl_assert("(" #A ") is equivalent to (" #B ")", \
+ __FILE__, __FUNCTION__, __LINE__)))
+
/*
* Debugging disabled (--disable-debug)
*/
@@ -158,14 +181,8 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
#define ASSERT3P VERIFY3P
#define ASSERT0 VERIFY0
#define ASSERT VERIFY
-#define IMPLY(A, B) \
- ((void)(likely((!(A)) || (B)) || \
- spl_assert("(" #A ") implies (" #B ")", \
- __FILE__, __FUNCTION__, __LINE__)))
-#define EQUIV(A, B) \
- ((void)(likely(!!(A) == !!(B)) || \
- spl_assert("(" #A ") is equivalent to (" #B ")", \
- __FILE__, __FUNCTION__, __LINE__)))
+#define IMPLY VERIFY_IMPLY
+#define EQUIV VERIFY_EQUIV
#endif /* NDEBUG */
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/isa_defs.h b/sys/contrib/openzfs/include/os/linux/spl/sys/isa_defs.h
index a032aae91658..5801ec92bc2b 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/isa_defs.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/isa_defs.h
@@ -47,9 +47,6 @@
#endif
#endif
-#define _ALIGNMENT_REQUIRED 1
-
-
/* i386 arch specific defines */
#elif defined(__i386) || defined(__i386__)
@@ -65,8 +62,6 @@
#define _ILP32
#endif
-#define _ALIGNMENT_REQUIRED 0
-
/* powerpc (ppc64) arch specific defines */
#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__)
@@ -88,12 +83,6 @@
#endif
#endif
-/*
- * Illumos doesn't define _ALIGNMENT_REQUIRED for PPC, so default to 1
- * out of paranoia.
- */
-#define _ALIGNMENT_REQUIRED 1
-
/* arm arch specific defines */
#elif defined(__arm) || defined(__arm__)
@@ -115,12 +104,6 @@
#define _ZFS_BIG_ENDIAN
#endif
-/*
- * Illumos doesn't define _ALIGNMENT_REQUIRED for ARM, so default to 1
- * out of paranoia.
- */
-#define _ALIGNMENT_REQUIRED 1
-
/* aarch64 arch specific defines */
#elif defined(__aarch64__)
@@ -157,7 +140,6 @@
#define _ZFS_BIG_ENDIAN
#define _SUNOS_VTOC_16
-#define _ALIGNMENT_REQUIRED 1
/* s390 arch specific defines */
#elif defined(__s390__)
@@ -173,12 +155,6 @@
#define _ZFS_BIG_ENDIAN
-/*
- * Illumos doesn't define _ALIGNMENT_REQUIRED for s390, so default to 1
- * out of paranoia.
- */
-#define _ALIGNMENT_REQUIRED 1
-
/* MIPS arch specific defines */
#elif defined(__mips__)
@@ -197,18 +173,16 @@
#define _SUNOS_VTOC_16
/*
- * Illumos doesn't define _ALIGNMENT_REQUIRED for MIPS, so default to 1
- * out of paranoia.
- */
-#define _ALIGNMENT_REQUIRED 1
-
-/*
* RISC-V arch specific defines
* only RV64G (including atomic) LP64 is supported yet
*/
-#elif defined(__riscv) && defined(_LP64) && _LP64 && \
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 && \
defined(__riscv_atomic) && __riscv_atomic
+#if !defined(_LP64)
+#define _LP64 1
+#endif
+
#ifndef __riscv__
#define __riscv__
#endif
@@ -221,8 +195,6 @@
#define _SUNOS_VTOC_16
-#define _ALIGNMENT_REQUIRED 1
-
#else
/*
* Currently supported:
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/kmem.h b/sys/contrib/openzfs/include/os/linux/spl/sys/kmem.h
index 86e872fa2492..111924303e16 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/kmem.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/kmem.h
@@ -38,6 +38,8 @@ extern char *kmem_asprintf(const char *fmt, ...)
extern char *kmem_strdup(const char *str);
extern void kmem_strfree(char *str);
+#define kmem_scnprintf scnprintf
+
/*
* Memory allocation interfaces
*/
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h b/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h
index be1f77e43bda..99e3a6fb41c6 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h
@@ -120,6 +120,16 @@ extern uint32_t zone_get_hostid(void *zone);
extern void spl_setup(void);
extern void spl_cleanup(void);
+/*
+ * Only handles the first 4096 majors and first 256 minors. We don't have a
+ * libc for the kernel module so we define this inline.
+ */
+static inline dev_t
+makedev(unsigned int major, unsigned int minor)
+{
+ return ((major & 0xFFF) << 8) | (minor & 0xFF);
+}
+
#define highbit(x) __fls(x)
#define lowbit(x) __ffs(x)
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/types.h b/sys/contrib/openzfs/include/os/linux/spl/sys/types.h
index b44c94518750..cae1bbddf105 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/types.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/types.h
@@ -54,4 +54,7 @@ typedef ulong_t pgcnt_t;
typedef int major_t;
typedef int minor_t;
+struct user_namespace;
+typedef struct user_namespace zuserns_t;
+
#endif /* _SPL_TYPES_H */
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/policy.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/policy.h
index 3bd7ce36b85d..b182da95b8e0 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/policy.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/policy.h
@@ -47,13 +47,14 @@ int secpolicy_vnode_create_gid(const cred_t *);
int secpolicy_vnode_remove(const cred_t *);
int secpolicy_vnode_setdac(const cred_t *, uid_t);
int secpolicy_vnode_setid_retain(struct znode *, const cred_t *, boolean_t);
-int secpolicy_vnode_setids_setgids(const cred_t *, gid_t);
+int secpolicy_vnode_setids_setgids(const cred_t *, gid_t, zuserns_t *,
+ zuserns_t *);
int secpolicy_zinject(const cred_t *);
int secpolicy_zfs(const cred_t *);
int secpolicy_zfs_proc(const cred_t *, proc_t *);
void secpolicy_setid_clear(vattr_t *, cred_t *);
int secpolicy_setid_setsticky_clear(struct inode *, vattr_t *,
- const vattr_t *, cred_t *);
+ const vattr_t *, cred_t *, zuserns_t *, zuserns_t *);
int secpolicy_xvattr(xvattr_t *, uid_t, cred_t *, mode_t);
int secpolicy_vnode_setattr(cred_t *, struct inode *, struct vattr *,
const struct vattr *, int, int (void *, int, cred_t *), void *);
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_acl.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_acl.h
index 6a73545fecda..2c734322267a 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_acl.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_acl.h
@@ -64,7 +64,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
__field(boolean_t, z_is_sa)
__field(boolean_t, z_is_mapped)
__field(boolean_t, z_is_ctldir)
- __field(boolean_t, z_is_stale)
__field(uint32_t, i_uid)
__field(uint32_t, i_gid)
@@ -99,7 +98,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
__entry->z_is_sa = zn->z_is_sa;
__entry->z_is_mapped = zn->z_is_mapped;
__entry->z_is_ctldir = zn->z_is_ctldir;
- __entry->z_is_stale = zn->z_is_stale;
__entry->i_uid = KUID_TO_SUID(ZTOI(zn)->i_uid);
__entry->i_gid = KGID_TO_SGID(ZTOI(zn)->i_gid);
@@ -121,9 +119,8 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
"zn_prefetch %u blksz %u seq %u "
"mapcnt %llu size %llu pflags %llu "
"sync_cnt %u sync_writes_cnt %u async_writes_cnt %u "
- "mode 0x%x is_sa %d is_mapped %d "
- "is_ctldir %d is_stale %d inode { "
- "uid %u gid %u ino %lu nlink %u size %lli "
+ "mode 0x%x is_sa %d is_mapped %d is_ctldir %d "
+ "inode { uid %u gid %u ino %lu nlink %u size %lli "
"blkbits %u bytes %u mode 0x%x generation %x } } "
"ace { type %u flags %u access_mask %u } mask_matched %u",
__entry->z_id, __entry->z_unlinked, __entry->z_atime_dirty,
@@ -132,7 +129,7 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
__entry->z_pflags, __entry->z_sync_cnt,
__entry->z_sync_writes_cnt, __entry->z_async_writes_cnt,
__entry->z_mode, __entry->z_is_sa, __entry->z_is_mapped,
- __entry->z_is_ctldir, __entry->z_is_stale, __entry->i_uid,
+ __entry->z_is_ctldir, __entry->i_uid,
__entry->i_gid, __entry->i_ino, __entry->i_nlink,
__entry->i_size, __entry->i_blkbits,
__entry->i_bytes, __entry->i_mode, __entry->i_generation,
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_common.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_common.h
index 74d77c1c4b21..3d4b1920d598 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_common.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/trace_common.h
@@ -39,10 +39,10 @@
__field(hrtime_t, zio_timestamp) \
__field(hrtime_t, zio_delta) \
__field(uint64_t, zio_delay) \
- __field(enum zio_flag, zio_flags) \
+ __field(zio_flag_t, zio_flags) \
__field(enum zio_stage, zio_stage) \
__field(enum zio_stage, zio_pipeline) \
- __field(enum zio_flag, zio_orig_flags) \
+ __field(zio_flag_t, zio_orig_flags) \
__field(enum zio_stage, zio_orig_stage) \
__field(enum zio_stage, zio_orig_pipeline) \
__field(uint8_t, zio_reexecute) \
@@ -92,7 +92,7 @@
#define ZIO_TP_PRINTK_FMT \
"zio { type %u cmd %i prio %u size %llu orig_size %llu " \
"offset %llu timestamp %llu delta %llu delay %llu " \
- "flags 0x%x stage 0x%x pipeline 0x%x orig_flags 0x%x " \
+ "flags 0x%llx stage 0x%x pipeline 0x%x orig_flags 0x%llx " \
"orig_stage 0x%x orig_pipeline 0x%x reexecute %u " \
"txg %llu error %d ena %llu prop { checksum %u compress %u " \
"type %u level %u copies %u dedup %u dedup_verify %u nopwrite %u } }"
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_dir.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_dir.h
index 91d873ea4b7f..9b2232c68ba4 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_dir.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_dir.h
@@ -52,6 +52,7 @@ extern "C" {
extern int zfs_dirent_lock(zfs_dirlock_t **, znode_t *, char *, znode_t **,
int, int *, pathname_t *);
extern void zfs_dirent_unlock(zfs_dirlock_t *);
+extern int zfs_drop_nlink(znode_t *, dmu_tx_t *, boolean_t *);
extern int zfs_link_create(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int);
extern int zfs_link_destroy(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int,
boolean_t *);
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vnops_os.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vnops_os.h
index 22ca625023b0..197ea9bec500 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vnops_os.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vnops_os.h
@@ -45,22 +45,26 @@ extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp, int flags,
cred_t *cr, int *direntflags, pathname_t *realpnp);
extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
- int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp);
+ int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
+ zuserns_t *mnt_ns);
extern int zfs_tmpfile(struct inode *dip, vattr_t *vapzfs, int excl,
- int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp);
+ int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp,
+ zuserns_t *mnt_ns);
extern int zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags);
extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
- znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp);
+ znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns);
extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
cred_t *cr, int flags);
extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip,
struct kstat *sp);
-extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
+extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
+ zuserns_t *mnt_ns);
extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
- char *tnm, cred_t *cr, int flags);
+ char *tnm, cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap,
+ zuserns_t *mnt_ns);
extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap,
- char *link, znode_t **zpp, cred_t *cr, int flags);
+ char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
extern int zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr);
extern int zfs_link(znode_t *tdzp, znode_t *szp,
char *name, cred_t *cr, int flags);
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h
index 95f08f5416d0..c3ee0ae4a600 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zpl.h
@@ -39,13 +39,18 @@
/* zpl_inode.c */
extern void zpl_vap_init(vattr_t *vap, struct inode *dir,
- umode_t mode, cred_t *cr);
+ umode_t mode, cred_t *cr, zuserns_t *mnt_ns);
extern const struct inode_operations zpl_inode_operations;
+#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
+extern const struct inode_operations_wrapper zpl_dir_inode_operations;
+#else
extern const struct inode_operations zpl_dir_inode_operations;
+#endif
extern const struct inode_operations zpl_symlink_inode_operations;
extern const struct inode_operations zpl_special_inode_operations;
-extern dentry_operations_t zpl_dentry_operations;
+
+/* zpl_file.c */
extern const struct address_space_operations zpl_address_space_operations;
extern const struct file_operations zpl_file_operations;
extern const struct file_operations zpl_dir_file_operations;
diff --git a/sys/contrib/openzfs/include/sys/arc_impl.h b/sys/contrib/openzfs/include/sys/arc_impl.h
index 0f2cd956eb64..03eebafa9952 100644
--- a/sys/contrib/openzfs/include/sys/arc_impl.h
+++ b/sys/contrib/openzfs/include/sys/arc_impl.h
@@ -985,8 +985,8 @@ extern arc_state_t ARC_mfu;
extern arc_state_t ARC_mru;
extern uint_t zfs_arc_pc_percent;
extern uint_t arc_lotsfree_percent;
-extern unsigned long zfs_arc_min;
-extern unsigned long zfs_arc_max;
+extern uint64_t zfs_arc_min;
+extern uint64_t zfs_arc_max;
extern void arc_reduce_target_size(int64_t to_free);
extern boolean_t arc_reclaim_needed(void);
@@ -1003,7 +1003,7 @@ extern void arc_tuning_update(boolean_t);
extern void arc_register_hotplug(void);
extern void arc_unregister_hotplug(void);
-extern int param_set_arc_long(ZFS_MODULE_PARAM_ARGS);
+extern int param_set_arc_u64(ZFS_MODULE_PARAM_ARGS);
extern int param_set_arc_int(ZFS_MODULE_PARAM_ARGS);
extern int param_set_arc_min(ZFS_MODULE_PARAM_ARGS);
extern int param_set_arc_max(ZFS_MODULE_PARAM_ARGS);
diff --git a/sys/contrib/openzfs/include/sys/btree.h b/sys/contrib/openzfs/include/sys/btree.h
index a901d654ef1c..883abb5181c9 100644
--- a/sys/contrib/openzfs/include/sys/btree.h
+++ b/sys/contrib/openzfs/include/sys/btree.h
@@ -65,7 +65,7 @@ extern "C" {
* them, and increased memory overhead. Increasing these values results in
* higher variance in operation time, and reduces memory overhead.
*/
-#define BTREE_CORE_ELEMS 128
+#define BTREE_CORE_ELEMS 126
#define BTREE_LEAF_SIZE 4096
extern kmem_cache_t *zfs_btree_leaf_cache;
@@ -95,9 +95,6 @@ typedef struct zfs_btree_leaf {
uint8_t btl_elems[];
} zfs_btree_leaf_t;
-#define BTREE_LEAF_ESIZE (BTREE_LEAF_SIZE - \
- offsetof(zfs_btree_leaf_t, btl_elems))
-
typedef struct zfs_btree_index {
zfs_btree_hdr_t *bti_node;
uint32_t bti_offset;
@@ -109,14 +106,15 @@ typedef struct zfs_btree_index {
} zfs_btree_index_t;
typedef struct btree {
- zfs_btree_hdr_t *bt_root;
- int64_t bt_height;
+ int (*bt_compar) (const void *, const void *);
size_t bt_elem_size;
+ size_t bt_leaf_size;
uint32_t bt_leaf_cap;
+ int32_t bt_height;
uint64_t bt_num_elems;
uint64_t bt_num_nodes;
+ zfs_btree_hdr_t *bt_root;
zfs_btree_leaf_t *bt_bulk; // non-null if bulk loading
- int (*bt_compar) (const void *, const void *);
} zfs_btree_t;
/*
@@ -132,9 +130,12 @@ void zfs_btree_fini(void);
* compar - function to compare two nodes, it must return exactly: -1, 0, or +1
* -1 for <, 0 for ==, and +1 for >
* size - the value of sizeof(struct my_type)
+ * lsize - custom leaf size
*/
void zfs_btree_create(zfs_btree_t *, int (*) (const void *, const void *),
size_t);
+void zfs_btree_create_custom(zfs_btree_t *, int (*)(const void *, const void *),
+ size_t, size_t);
/*
* Find a node with a matching value in the tree. Returns the matching node
diff --git a/sys/contrib/openzfs/include/sys/dbuf.h b/sys/contrib/openzfs/include/sys/dbuf.h
index 06489ea84bf8..9ba46f0d725f 100644
--- a/sys/contrib/openzfs/include/sys/dbuf.h
+++ b/sys/contrib/openzfs/include/sys/dbuf.h
@@ -190,7 +190,7 @@ typedef struct dbuf_dirty_record {
uint64_t dr_blkid;
abd_t *dr_abd;
zio_prop_t dr_props;
- enum zio_flag dr_flags;
+ zio_flag_t dr_flags;
} dll;
} dt;
} dbuf_dirty_record_t;
@@ -380,7 +380,7 @@ void dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data,
int uncompressed_size, int compressed_size, int byteorder, dmu_tx_t *tx);
int dmu_lightweight_write_by_dnode(dnode_t *dn, uint64_t offset, abd_t *abd,
- const struct zio_prop *zp, enum zio_flag flags, dmu_tx_t *tx);
+ const struct zio_prop *zp, zio_flag_t flags, dmu_tx_t *tx);
void dmu_buf_redact(dmu_buf_t *dbuf, dmu_tx_t *tx);
void dbuf_destroy(dmu_buf_impl_t *db);
diff --git a/sys/contrib/openzfs/include/sys/dmu.h b/sys/contrib/openzfs/include/sys/dmu.h
index d68700d371db..93de991ccd86 100644
--- a/sys/contrib/openzfs/include/sys/dmu.h
+++ b/sys/contrib/openzfs/include/sys/dmu.h
@@ -27,6 +27,7 @@
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright 2013 Saso Kiselkov. All rights reserved.
* Copyright (c) 2017, Intel Corporation.
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -142,6 +143,12 @@ typedef enum dmu_object_byteswap {
#define DMU_OT_IS_DDT(ot) \
((ot) == DMU_OT_DDT_ZAP)
+#define DMU_OT_IS_CRITICAL(ot) \
+ (DMU_OT_IS_METADATA(ot) && \
+ (ot) != DMU_OT_DNODE && \
+ (ot) != DMU_OT_DIRECTORY_CONTENTS && \
+ (ot) != DMU_OT_SA)
+
/* Note: ztest uses DMU_OT_UINT64_OTHER as a proxy for file blocks */
#define DMU_OT_IS_FILE(ot) \
((ot) == DMU_OT_PLAIN_FILE_CONTENTS || (ot) == DMU_OT_UINT64_OTHER)
diff --git a/sys/contrib/openzfs/include/sys/dmu_zfetch.h b/sys/contrib/openzfs/include/sys/dmu_zfetch.h
index ad3bc040756c..0fbc3bacffb9 100644
--- a/sys/contrib/openzfs/include/sys/dmu_zfetch.h
+++ b/sys/contrib/openzfs/include/sys/dmu_zfetch.h
@@ -36,7 +36,7 @@
extern "C" {
#endif
-extern unsigned long zfetch_array_rd_sz;
+extern uint64_t zfetch_array_rd_sz;
struct dnode; /* so we can reference dnode */
diff --git a/sys/contrib/openzfs/include/sys/dsl_deadlist.h b/sys/contrib/openzfs/include/sys/dsl_deadlist.h
index a94bba56ff7a..3feb3bbf062f 100644
--- a/sys/contrib/openzfs/include/sys/dsl_deadlist.h
+++ b/sys/contrib/openzfs/include/sys/dsl_deadlist.h
@@ -84,7 +84,7 @@ typedef struct livelist_condense_entry {
boolean_t cancelled;
} livelist_condense_entry_t;
-extern unsigned long zfs_livelist_max_entries;
+extern uint64_t zfs_livelist_max_entries;
extern int zfs_livelist_min_percent_shared;
typedef int deadlist_iter_t(void *args, dsl_deadlist_entry_t *dle);
diff --git a/sys/contrib/openzfs/include/sys/dsl_pool.h b/sys/contrib/openzfs/include/sys/dsl_pool.h
index 9364106d94b7..abcdc77a4b96 100644
--- a/sys/contrib/openzfs/include/sys/dsl_pool.h
+++ b/sys/contrib/openzfs/include/sys/dsl_pool.h
@@ -57,13 +57,13 @@ struct dsl_scan;
struct dsl_crypto_params;
struct dsl_deadlist;
-extern unsigned long zfs_dirty_data_max;
-extern unsigned long zfs_dirty_data_max_max;
-extern unsigned long zfs_wrlog_data_max;
+extern uint64_t zfs_dirty_data_max;
+extern uint64_t zfs_dirty_data_max_max;
+extern uint64_t zfs_wrlog_data_max;
extern uint_t zfs_dirty_data_max_percent;
extern uint_t zfs_dirty_data_max_max_percent;
extern uint_t zfs_delay_min_dirty_percent;
-extern unsigned long zfs_delay_scale;
+extern uint64_t zfs_delay_scale;
/* These macros are for indexing into the zfs_all_blkstats_t. */
#define DMU_OT_DEFERRED DMU_OT_NONE
diff --git a/sys/contrib/openzfs/include/sys/fs/zfs.h b/sys/contrib/openzfs/include/sys/fs/zfs.h
index b3fecf489eb0..1124604e8c68 100644
--- a/sys/contrib/openzfs/include/sys/fs/zfs.h
+++ b/sys/contrib/openzfs/include/sys/fs/zfs.h
@@ -29,6 +29,7 @@
* Copyright (c) 2019 Datto Inc.
* Portions Copyright 2010 Robert Milkowski
* Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
#ifndef _SYS_FS_ZFS_H
@@ -354,6 +355,7 @@ typedef enum {
VDEV_PROP_BYTES_TRIM,
VDEV_PROP_REMOVING,
VDEV_PROP_ALLOCATING,
+ VDEV_PROP_FAILFAST,
VDEV_NUM_PROPS
} vdev_prop_t;
@@ -501,7 +503,9 @@ typedef enum {
typedef enum {
ZFS_REDUNDANT_METADATA_ALL,
- ZFS_REDUNDANT_METADATA_MOST
+ ZFS_REDUNDANT_METADATA_MOST,
+ ZFS_REDUNDANT_METADATA_SOME,
+ ZFS_REDUNDANT_METADATA_NONE
} zfs_redundant_metadata_type_t;
typedef enum {
diff --git a/sys/contrib/openzfs/include/sys/mmp.h b/sys/contrib/openzfs/include/sys/mmp.h
index ce9c4496a04f..1023334098d8 100644
--- a/sys/contrib/openzfs/include/sys/mmp.h
+++ b/sys/contrib/openzfs/include/sys/mmp.h
@@ -64,7 +64,7 @@ extern void mmp_signal_all_threads(void);
/* Global tuning */
extern int param_set_multihost_interval(ZFS_MODULE_PARAM_ARGS);
-extern ulong_t zfs_multihost_interval;
+extern uint64_t zfs_multihost_interval;
extern uint_t zfs_multihost_fail_intervals;
extern uint_t zfs_multihost_import_intervals;
diff --git a/sys/contrib/openzfs/include/sys/spa.h b/sys/contrib/openzfs/include/sys/spa.h
index 3e68cb8c6511..b260dd32820e 100644
--- a/sys/contrib/openzfs/include/sys/spa.h
+++ b/sys/contrib/openzfs/include/sys/spa.h
@@ -600,7 +600,7 @@ typedef struct blkptr {
/*
* This macro allows code sharing between zfs, libzpool, and mdb.
- * 'func' is either snprintf() or mdb_snprintf().
+ * 'func' is either kmem_scnprintf() or mdb_snprintf().
* 'ws' (whitespace) can be ' ' for single-line format, '\n' for multi-line.
*/
@@ -1218,9 +1218,9 @@ int param_set_deadman_failmode(ZFS_MODULE_PARAM_ARGS);
extern spa_mode_t spa_mode_global;
extern int zfs_deadman_enabled;
-extern unsigned long zfs_deadman_synctime_ms;
-extern unsigned long zfs_deadman_ziotime_ms;
-extern unsigned long zfs_deadman_checktime_ms;
+extern uint64_t zfs_deadman_synctime_ms;
+extern uint64_t zfs_deadman_ziotime_ms;
+extern uint64_t zfs_deadman_checktime_ms;
extern kmem_cache_t *zio_buf_cache[];
extern kmem_cache_t *zio_data_buf_cache[];
diff --git a/sys/contrib/openzfs/include/sys/vdev_impl.h b/sys/contrib/openzfs/include/sys/vdev_impl.h
index b789d2c05d59..3f4b78b947a3 100644
--- a/sys/contrib/openzfs/include/sys/vdev_impl.h
+++ b/sys/contrib/openzfs/include/sys/vdev_impl.h
@@ -299,6 +299,7 @@ struct vdev {
uint64_t vdev_islog; /* is an intent log device */
uint64_t vdev_noalloc; /* device is passivated? */
uint64_t vdev_removing; /* device is being removed? */
+ uint64_t vdev_failfast; /* device failfast setting */
boolean_t vdev_ishole; /* is a hole in the namespace */
uint64_t vdev_top_zap;
vdev_alloc_bias_t vdev_alloc_bias; /* metaslab allocation bias */
@@ -649,8 +650,8 @@ uint64_t vdev_best_ashift(uint64_t logical, uint64_t a, uint64_t b);
/*
* Vdev ashift optimization tunables
*/
-extern uint64_t zfs_vdev_min_auto_ashift;
-extern uint64_t zfs_vdev_max_auto_ashift;
+extern uint_t zfs_vdev_min_auto_ashift;
+extern uint_t zfs_vdev_max_auto_ashift;
int param_set_min_auto_ashift(ZFS_MODULE_PARAM_ARGS);
int param_set_max_auto_ashift(ZFS_MODULE_PARAM_ARGS);
diff --git a/sys/contrib/openzfs/include/sys/zap_impl.h b/sys/contrib/openzfs/include/sys/zap_impl.h
index fab677964e7c..74853f5faceb 100644
--- a/sys/contrib/openzfs/include/sys/zap_impl.h
+++ b/sys/contrib/openzfs/include/sys/zap_impl.h
@@ -66,10 +66,9 @@ typedef struct mzap_phys {
} mzap_phys_t;
typedef struct mzap_ent {
- avl_node_t mze_node;
- int mze_chunkid;
- uint64_t mze_hash;
- uint32_t mze_cd; /* copy from mze_phys->mze_cd */
+ uint32_t mze_hash;
+ uint16_t mze_cd; /* copy from mze_phys->mze_cd */
+ uint16_t mze_chunkid;
} mzap_ent_t;
#define MZE_PHYS(zap, mze) \
@@ -164,7 +163,7 @@ typedef struct zap {
int16_t zap_num_entries;
int16_t zap_num_chunks;
int16_t zap_alloc_next;
- avl_tree_t zap_avl;
+ zfs_btree_t zap_tree;
} zap_micro;
} zap_u;
} zap_t;
@@ -203,7 +202,7 @@ int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
zap_t **zapp);
void zap_unlockdir(zap_t *zap, const void *tag);
void zap_evict_sync(void *dbu);
-zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt);
+zap_name_t *zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt);
void zap_name_free(zap_name_t *zn);
int zap_hashbits(zap_t *zap);
uint32_t zap_maxcd(zap_t *zap);
diff --git a/sys/contrib/openzfs/include/sys/zcp.h b/sys/contrib/openzfs/include/sys/zcp.h
index f0a78f9cb5c4..6301cc08e7ea 100644
--- a/sys/contrib/openzfs/include/sys/zcp.h
+++ b/sys/contrib/openzfs/include/sys/zcp.h
@@ -33,8 +33,8 @@ extern "C" {
#define ZCP_RUN_INFO_KEY "runinfo"
-extern unsigned long zfs_lua_max_instrlimit;
-extern unsigned long zfs_lua_max_memlimit;
+extern uint64_t zfs_lua_max_instrlimit;
+extern uint64_t zfs_lua_max_memlimit;
int zcp_argerror(lua_State *, int, const char *, ...);
diff --git a/sys/contrib/openzfs/include/sys/zfs_acl.h b/sys/contrib/openzfs/include/sys/zfs_acl.h
index c4d2dddd7b1f..82fb98c9fb89 100644
--- a/sys/contrib/openzfs/include/sys/zfs_acl.h
+++ b/sys/contrib/openzfs/include/sys/zfs_acl.h
@@ -206,7 +206,7 @@ struct zfsvfs;
#ifdef _KERNEL
int zfs_acl_ids_create(struct znode *, int, vattr_t *,
- cred_t *, vsecattr_t *, zfs_acl_ids_t *);
+ cred_t *, vsecattr_t *, zfs_acl_ids_t *, zuserns_t *);
void zfs_acl_ids_free(zfs_acl_ids_t *);
boolean_t zfs_acl_ids_overquota(struct zfsvfs *, zfs_acl_ids_t *, uint64_t);
int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
@@ -215,15 +215,16 @@ void zfs_acl_rele(void *);
void zfs_oldace_byteswap(ace_t *, int);
void zfs_ace_byteswap(void *, size_t, boolean_t);
extern boolean_t zfs_has_access(struct znode *zp, cred_t *cr);
-extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *);
+extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *,
+ zuserns_t *);
int zfs_fastaccesschk_execute(struct znode *, cred_t *);
-extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *);
+extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *, zuserns_t *);
extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *);
extern int zfs_acl_access(struct znode *, int, cred_t *);
int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t);
-int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *);
+int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *, zuserns_t *);
int zfs_zaccess_rename(struct znode *, struct znode *,
- struct znode *, struct znode *, cred_t *cr);
+ struct znode *, struct znode *, cred_t *cr, zuserns_t *mnt_ns);
void zfs_acl_free(zfs_acl_t *);
int zfs_vsec_2_aclp(struct zfsvfs *, umode_t, vsecattr_t *, cred_t *,
struct zfs_fuid_info **, zfs_acl_t **);
diff --git a/sys/contrib/openzfs/include/sys/zfs_context.h b/sys/contrib/openzfs/include/sys/zfs_context.h
index d29d7118ff00..6a337b49edf3 100644
--- a/sys/contrib/openzfs/include/sys/zfs_context.h
+++ b/sys/contrib/openzfs/include/sys/zfs_context.h
@@ -695,6 +695,11 @@ extern char *kmem_asprintf(const char *fmt, ...);
#define kmem_strfree(str) kmem_free((str), strlen(str) + 1)
#define kmem_strdup(s) strdup(s)
+#ifndef __cplusplus
+extern int kmem_scnprintf(char *restrict str, size_t size,
+ const char *restrict fmt, ...);
+#endif
+
/*
* Hostname information
*/
diff --git a/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h b/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h
index 0bf9fa6ff193..cb852c5577fd 100644
--- a/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h
+++ b/sys/contrib/openzfs/include/sys/zfs_ioctl_impl.h
@@ -24,7 +24,7 @@
#define _ZFS_IOCTL_IMPL_H_
extern kmutex_t zfsdev_state_lock;
-extern unsigned long zfs_max_nvlist_src_size;
+extern uint64_t zfs_max_nvlist_src_size;
typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
diff --git a/sys/contrib/openzfs/include/sys/zfs_onexit.h b/sys/contrib/openzfs/include/sys/zfs_onexit.h
index 18930fe01c7a..91f49d4cc5a3 100644
--- a/sys/contrib/openzfs/include/sys/zfs_onexit.h
+++ b/sys/contrib/openzfs/include/sys/zfs_onexit.h
@@ -54,7 +54,7 @@ extern void zfs_onexit_destroy(zfs_onexit_t *zo);
extern zfs_file_t *zfs_onexit_fd_hold(int fd, minor_t *minorp);
extern void zfs_onexit_fd_rele(zfs_file_t *);
extern int zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
- uint64_t *action_handle);
+ uintptr_t *action_handle);
#ifdef __cplusplus
}
diff --git a/sys/contrib/openzfs/include/sys/zfs_znode.h b/sys/contrib/openzfs/include/sys/zfs_znode.h
index 7c906050bc47..88d642350691 100644
--- a/sys/contrib/openzfs/include/sys/zfs_znode.h
+++ b/sys/contrib/openzfs/include/sys/zfs_znode.h
@@ -190,7 +190,6 @@ typedef struct znode {
boolean_t z_is_sa; /* are we native sa? */
boolean_t z_is_mapped; /* are we mmap'ed */
boolean_t z_is_ctldir; /* are we .zfs entry */
- boolean_t z_is_stale; /* are we stale due to rollback? */
boolean_t z_suspended; /* extra ref from a suspend? */
uint_t z_blksz; /* block size in bytes */
uint_t z_seq; /* modification sequence number */
@@ -300,6 +299,12 @@ extern void zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
extern void zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
znode_t *sdzp, const char *sname, znode_t *tdzp, const char *dname,
znode_t *szp);
+extern void zfs_log_rename_exchange(zilog_t *zilog, dmu_tx_t *tx,
+ uint64_t txtype, znode_t *sdzp, const char *sname, znode_t *tdzp,
+ const char *dname, znode_t *szp);
+extern void zfs_log_rename_whiteout(zilog_t *zilog, dmu_tx_t *tx,
+ uint64_t txtype, znode_t *sdzp, const char *sname, znode_t *tdzp,
+ const char *dname, znode_t *szp, znode_t *wzp);
extern void zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
znode_t *zp, offset_t off, ssize_t len, int ioflag,
zil_callback_t callback, void *callback_data);
diff --git a/sys/contrib/openzfs/include/sys/zil.h b/sys/contrib/openzfs/include/sys/zil.h
index cec04f120ce3..9ac421043377 100644
--- a/sys/contrib/openzfs/include/sys/zil.h
+++ b/sys/contrib/openzfs/include/sys/zil.h
@@ -164,7 +164,9 @@ typedef enum zil_create {
#define TX_MKDIR_ACL_ATTR 19 /* mkdir with ACL + attrs */
#define TX_WRITE2 20 /* dmu_sync EALREADY write */
#define TX_SETSAXATTR 21 /* Set sa xattrs on file */
-#define TX_MAX_TYPE 22 /* Max transaction type */
+#define TX_RENAME_EXCHANGE 22 /* Atomic swap via renameat2 */
+#define TX_RENAME_WHITEOUT 23 /* Atomic whiteout via renameat2 */
+#define TX_MAX_TYPE 24 /* Max transaction type */
/*
* The transactions for mkdir, symlink, remove, rmdir, link, and rename
@@ -318,6 +320,19 @@ typedef struct {
} lr_rename_t;
typedef struct {
+ lr_rename_t lr_rename; /* common rename portion */
+ /* members related to the whiteout file (based on lr_create_t) */
+ uint64_t lr_wfoid; /* obj id of the new whiteout file */
+ uint64_t lr_wmode; /* mode of object */
+ uint64_t lr_wuid; /* uid of whiteout */
+ uint64_t lr_wgid; /* gid of whiteout */
+ uint64_t lr_wgen; /* generation (txg of creation) */
+ uint64_t lr_wcrtime[2]; /* creation time */
+ uint64_t lr_wrdev; /* always makedev(0, 0) */
+ /* 2 strings: names of source and destination follow this */
+} lr_rename_whiteout_t;
+
+typedef struct {
lr_t lr_common; /* common portion of log record */
uint64_t lr_foid; /* file object to write */
uint64_t lr_offset; /* offset to write to */
@@ -524,10 +539,10 @@ extern zilog_t *zil_open(objset_t *os, zil_get_data_t *get_data,
zil_sums_t *zil_sums);
extern void zil_close(zilog_t *zilog);
-extern void zil_replay(objset_t *os, void *arg,
+extern boolean_t zil_replay(objset_t *os, void *arg,
zil_replay_func_t *const replay_func[TX_MAX_TYPE]);
extern boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx);
-extern void zil_destroy(zilog_t *zilog, boolean_t keep_first);
+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);
diff --git a/sys/contrib/openzfs/include/sys/zio.h b/sys/contrib/openzfs/include/sys/zio.h
index 23fdda457bc3..28ed837d829e 100644
--- a/sys/contrib/openzfs/include/sys/zio.h
+++ b/sys/contrib/openzfs/include/sys/zio.h
@@ -163,32 +163,37 @@ typedef enum zio_suspend_reason {
ZIO_SUSPEND_MMP,
} zio_suspend_reason_t;
-enum zio_flag {
+/*
+ * This was originally an enum type. However, those are 32-bit and there is no
+ * way to make a 64-bit enum type. Since we ran out of bits for flags, we were
+ * forced to upgrade it to a uint64_t.
+ */
+typedef uint64_t zio_flag_t;
/*
* Flags inherited by gang, ddt, and vdev children,
* and that must be equal for two zios to aggregate
*/
- ZIO_FLAG_DONT_AGGREGATE = 1U << 0,
- ZIO_FLAG_IO_REPAIR = 1U << 1,
- ZIO_FLAG_SELF_HEAL = 1U << 2,
- ZIO_FLAG_RESILVER = 1U << 3,
- ZIO_FLAG_SCRUB = 1U << 4,
- ZIO_FLAG_SCAN_THREAD = 1U << 5,
- ZIO_FLAG_PHYSICAL = 1U << 6,
+#define ZIO_FLAG_DONT_AGGREGATE (1ULL << 0)
+#define ZIO_FLAG_IO_REPAIR (1ULL << 1)
+#define ZIO_FLAG_SELF_HEAL (1ULL << 2)
+#define ZIO_FLAG_RESILVER (1ULL << 3)
+#define ZIO_FLAG_SCRUB (1ULL << 4)
+#define ZIO_FLAG_SCAN_THREAD (1ULL << 5)
+#define ZIO_FLAG_PHYSICAL (1ULL << 6)
#define ZIO_FLAG_AGG_INHERIT (ZIO_FLAG_CANFAIL - 1)
/*
* Flags inherited by ddt, gang, and vdev children.
*/
- ZIO_FLAG_CANFAIL = 1U << 7, /* must be first for INHERIT */
- ZIO_FLAG_SPECULATIVE = 1U << 8,
- ZIO_FLAG_CONFIG_WRITER = 1U << 9,
- ZIO_FLAG_DONT_RETRY = 1U << 10,
- ZIO_FLAG_DONT_CACHE = 1U << 11,
- ZIO_FLAG_NODATA = 1U << 12,
- ZIO_FLAG_INDUCE_DAMAGE = 1U << 13,
- ZIO_FLAG_IO_ALLOCATING = 1U << 14,
+#define ZIO_FLAG_CANFAIL (1ULL << 7) /* must be first for INHERIT */
+#define ZIO_FLAG_SPECULATIVE (1ULL << 8)
+#define ZIO_FLAG_CONFIG_WRITER (1ULL << 9)
+#define ZIO_FLAG_DONT_RETRY (1ULL << 10)
+#define ZIO_FLAG_DONT_CACHE (1ULL << 11)
+#define ZIO_FLAG_NODATA (1ULL << 12)
+#define ZIO_FLAG_INDUCE_DAMAGE (1ULL << 13)
+#define ZIO_FLAG_IO_ALLOCATING (1ULL << 14)
#define ZIO_FLAG_DDT_INHERIT (ZIO_FLAG_IO_RETRY - 1)
#define ZIO_FLAG_GANG_INHERIT (ZIO_FLAG_IO_RETRY - 1)
@@ -196,30 +201,29 @@ enum zio_flag {
/*
* Flags inherited by vdev children.
*/
- ZIO_FLAG_IO_RETRY = 1U << 15, /* must be first for INHERIT */
- ZIO_FLAG_PROBE = 1U << 16,
- ZIO_FLAG_TRYHARD = 1U << 17,
- ZIO_FLAG_OPTIONAL = 1U << 18,
+#define ZIO_FLAG_IO_RETRY (1ULL << 15) /* must be first for INHERIT */
+#define ZIO_FLAG_PROBE (1ULL << 16)
+#define ZIO_FLAG_TRYHARD (1ULL << 17)
+#define ZIO_FLAG_OPTIONAL (1ULL << 18)
#define ZIO_FLAG_VDEV_INHERIT (ZIO_FLAG_DONT_QUEUE - 1)
/*
* Flags not inherited by any children.
*/
- ZIO_FLAG_DONT_QUEUE = 1U << 19, /* must be first for INHERIT */
- ZIO_FLAG_DONT_PROPAGATE = 1U << 20,
- ZIO_FLAG_IO_BYPASS = 1U << 21,
- ZIO_FLAG_IO_REWRITE = 1U << 22,
- ZIO_FLAG_RAW_COMPRESS = 1U << 23,
- ZIO_FLAG_RAW_ENCRYPT = 1U << 24,
- ZIO_FLAG_GANG_CHILD = 1U << 25,
- ZIO_FLAG_DDT_CHILD = 1U << 26,
- ZIO_FLAG_GODFATHER = 1U << 27,
- ZIO_FLAG_NOPWRITE = 1U << 28,
- ZIO_FLAG_REEXECUTED = 1U << 29,
- ZIO_FLAG_DELEGATED = 1U << 30,
- ZIO_FLAG_FASTWRITE = 1U << 31,
-};
+#define ZIO_FLAG_DONT_QUEUE (1ULL << 19) /* must be first for INHERIT */
+#define ZIO_FLAG_DONT_PROPAGATE (1ULL << 20)
+#define ZIO_FLAG_IO_BYPASS (1ULL << 21)
+#define ZIO_FLAG_IO_REWRITE (1ULL << 22)
+#define ZIO_FLAG_RAW_COMPRESS (1ULL << 23)
+#define ZIO_FLAG_RAW_ENCRYPT (1ULL << 24)
+#define ZIO_FLAG_GANG_CHILD (1ULL << 25)
+#define ZIO_FLAG_DDT_CHILD (1ULL << 26)
+#define ZIO_FLAG_GODFATHER (1ULL << 27)
+#define ZIO_FLAG_NOPWRITE (1ULL << 28)
+#define ZIO_FLAG_REEXECUTED (1ULL << 29)
+#define ZIO_FLAG_DELEGATED (1ULL << 30)
+#define ZIO_FLAG_FASTWRITE (1ULL << 31)
#define ZIO_FLAG_MUSTSUCCEED 0
#define ZIO_FLAG_RAW (ZIO_FLAG_RAW_COMPRESS | ZIO_FLAG_RAW_ENCRYPT)
@@ -489,10 +493,10 @@ struct zio {
zio_alloc_list_t io_alloc_list;
/* Internal pipeline state */
- enum zio_flag io_flags;
+ zio_flag_t io_flags;
enum zio_stage io_stage;
enum zio_stage io_pipeline;
- enum zio_flag io_orig_flags;
+ zio_flag_t io_orig_flags;
enum zio_stage io_orig_stage;
enum zio_stage io_orig_pipeline;
enum zio_stage io_pipeline_trace;
@@ -529,27 +533,27 @@ enum blk_verify_flag {
extern int zio_bookmark_compare(const void *, const void *);
extern zio_t *zio_null(zio_t *pio, spa_t *spa, vdev_t *vd,
- zio_done_func_t *done, void *priv, enum zio_flag flags);
+ zio_done_func_t *done, void *priv, zio_flag_t flags);
extern zio_t *zio_root(spa_t *spa,
- zio_done_func_t *done, void *priv, enum zio_flag flags);
+ zio_done_func_t *done, void *priv, zio_flag_t flags);
extern void zio_destroy(zio_t *zio);
extern zio_t *zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
struct abd *data, uint64_t lsize, zio_done_func_t *done, void *priv,
- zio_priority_t priority, enum zio_flag flags, const zbookmark_phys_t *zb);
+ zio_priority_t priority, zio_flag_t flags, const zbookmark_phys_t *zb);
extern zio_t *zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
struct abd *data, uint64_t size, uint64_t psize, const zio_prop_t *zp,
zio_done_func_t *ready, zio_done_func_t *children_ready,
zio_done_func_t *physdone, zio_done_func_t *done,
- void *priv, zio_priority_t priority, enum zio_flag flags,
+ void *priv, zio_priority_t priority, zio_flag_t flags,
const zbookmark_phys_t *zb);
extern zio_t *zio_rewrite(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
struct abd *data, uint64_t size, zio_done_func_t *done, void *priv,
- zio_priority_t priority, enum zio_flag flags, zbookmark_phys_t *zb);
+ zio_priority_t priority, zio_flag_t flags, zbookmark_phys_t *zb);
extern void zio_write_override(zio_t *zio, blkptr_t *bp, int copies,
boolean_t nopwrite);
@@ -558,27 +562,27 @@ extern void zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp);
extern zio_t *zio_claim(zio_t *pio, spa_t *spa, uint64_t txg,
const blkptr_t *bp,
- zio_done_func_t *done, void *priv, enum zio_flag flags);
+ zio_done_func_t *done, void *priv, zio_flag_t flags);
extern zio_t *zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
- zio_done_func_t *done, void *priv, enum zio_flag flags);
+ zio_done_func_t *done, void *priv, zio_flag_t flags);
extern zio_t *zio_trim(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
zio_done_func_t *done, void *priv, zio_priority_t priority,
- enum zio_flag flags, enum trim_flag trim_flags);
+ zio_flag_t flags, enum trim_flag trim_flags);
extern zio_t *zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset,
uint64_t size, struct abd *data, int checksum,
zio_done_func_t *done, void *priv, zio_priority_t priority,
- enum zio_flag flags, boolean_t labels);
+ zio_flag_t flags, boolean_t labels);
extern zio_t *zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset,
uint64_t size, struct abd *data, int checksum,
zio_done_func_t *done, void *priv, zio_priority_t priority,
- enum zio_flag flags, boolean_t labels);
+ zio_flag_t flags, boolean_t labels);
extern zio_t *zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg,
- const blkptr_t *bp, enum zio_flag flags);
+ const blkptr_t *bp, zio_flag_t flags);
extern int zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg,
blkptr_t *new_bp, uint64_t size, boolean_t *slog);
@@ -611,12 +615,12 @@ extern void zio_resubmit_stage_async(void *);
extern zio_t *zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd,
uint64_t offset, struct abd *data, uint64_t size, int type,
- zio_priority_t priority, enum zio_flag flags,
+ zio_priority_t priority, zio_flag_t flags,
zio_done_func_t *done, void *priv);
extern zio_t *zio_vdev_delegated_io(vdev_t *vd, uint64_t offset,
struct abd *data, uint64_t size, zio_type_t type, zio_priority_t priority,
- enum zio_flag flags, zio_done_func_t *done, void *priv);
+ zio_flag_t flags, zio_done_func_t *done, void *priv);
extern void zio_vdev_io_bypass(zio_t *zio);
extern void zio_vdev_io_reissue(zio_t *zio);
diff --git a/sys/contrib/openzfs/lib/libefi/rdwr_efi.c b/sys/contrib/openzfs/lib/libefi/rdwr_efi.c
index f159a022496c..739219e0410f 100644
--- a/sys/contrib/openzfs/lib/libefi/rdwr_efi.c
+++ b/sys/contrib/openzfs/lib/libefi/rdwr_efi.c
@@ -423,7 +423,6 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
void *tmp;
length = (int) sizeof (struct dk_gpt) +
(int) sizeof (struct dk_part) * (vptr->efi_nparts - 1);
- nparts = vptr->efi_nparts;
if ((tmp = realloc(vptr, length)) == NULL) {
/* cppcheck-suppress doubleFree */
free(vptr);
@@ -565,10 +564,9 @@ int
efi_rescan(int fd)
{
int retry = 10;
- int error;
/* Notify the kernel a devices partition table has been updated */
- while ((error = ioctl(fd, BLKRRPART)) != 0) {
+ while (ioctl(fd, BLKRRPART) != 0) {
if ((--retry == 0) || (errno != EBUSY)) {
(void) fprintf(stderr, "the kernel failed to rescan "
"the partition table: %d\n", errno);
@@ -1364,7 +1362,7 @@ efi_write(int fd, struct dk_gpt *vtoc)
if (NBLOCKS(vtoc->efi_nparts, vtoc->efi_lbasize) < 34) {
dk_ioc.dki_length = EFI_MIN_ARRAY_SIZE + vtoc->efi_lbasize;
} else {
- dk_ioc.dki_length = NBLOCKS(vtoc->efi_nparts,
+ dk_ioc.dki_length = (len_t)NBLOCKS(vtoc->efi_nparts,
vtoc->efi_lbasize) *
vtoc->efi_lbasize;
}
diff --git a/sys/contrib/openzfs/lib/libshare/os/linux/smb.c b/sys/contrib/openzfs/lib/libshare/os/linux/smb.c
index 157b19aa85f4..0679e82104e2 100644
--- a/sys/contrib/openzfs/lib/libshare/os/linux/smb.c
+++ b/sys/contrib/openzfs/lib/libshare/os/linux/smb.c
@@ -90,21 +90,32 @@ smb_retrieve_shares(void)
/* Go through the directory, looking for shares */
while ((directory = readdir(shares_dir))) {
+ int fd;
+
if (directory->d_name[0] == '.')
continue;
snprintf(file_path, sizeof (file_path),
"%s/%s", SHARE_DIR, directory->d_name);
- if (stat(file_path, &eStat) == -1) {
+ if ((fd = open(file_path, O_RDONLY | O_CLOEXEC)) == -1) {
+ rc = SA_SYSTEM_ERR;
+ goto out;
+ }
+
+ if (fstat(fd, &eStat) == -1) {
+ close(fd);
rc = SA_SYSTEM_ERR;
goto out;
}
- if (!S_ISREG(eStat.st_mode))
+ if (!S_ISREG(eStat.st_mode)) {
+ close(fd);
continue;
+ }
- if ((share_file_fp = fopen(file_path, "re")) == NULL) {
+ if ((share_file_fp = fdopen(fd, "r")) == NULL) {
+ close(fd);
rc = SA_SYSTEM_ERR;
goto out;
}
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h b/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
index 756adff15ac8..114cca4f1545 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/isa_defs.h
@@ -227,9 +227,13 @@ extern "C" {
* RISC-V arch specific defines
* only RV64G (including atomic) LP64 is supported yet
*/
-#elif defined(__riscv) && defined(_LP64) && _LP64 && \
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 && \
defined(__riscv_atomic) && __riscv_atomic
+#if !defined(_LP64)
+#define _LP64 1
+#endif
+
#ifndef __riscv__
#define __riscv__
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/types.h b/sys/contrib/openzfs/lib/libspl/include/sys/types.h
index 5a84123d201f..90e3cf9bdaf8 100644
--- a/sys/contrib/openzfs/lib/libspl/include/sys/types.h
+++ b/sys/contrib/openzfs/lib/libspl/include/sys/types.h
@@ -47,31 +47,6 @@
typedef uint_t zoneid_t;
typedef int projid_t;
-/*
- * Definitions remaining from previous partial support for 64-bit file
- * offsets. This partial support for devices greater than 2gb requires
- * compiler support for long long.
- */
-#ifdef _LONG_LONG_LTOH
-typedef union {
- offset_t _f; /* Full 64 bit offset value */
- struct {
- int32_t _l; /* lower 32 bits of offset value */
- int32_t _u; /* upper 32 bits of offset value */
- } _p;
-} lloff_t;
-#endif
-
-#ifdef _LONG_LONG_HTOL
-typedef union {
- offset_t _f; /* Full 64 bit offset value */
- struct {
- int32_t _u; /* upper 32 bits of offset value */
- int32_t _l; /* lower 32 bits of offset value */
- } _p;
-} lloff_t;
-#endif
-
#include <sys/param.h> /* for NBBY */
#endif
diff --git a/sys/contrib/openzfs/lib/libspl/include/umem.h b/sys/contrib/openzfs/lib/libspl/include/umem.h
index 82976f756b73..77c216721253 100644
--- a/sys/contrib/openzfs/lib/libspl/include/umem.h
+++ b/sys/contrib/openzfs/lib/libspl/include/umem.h
@@ -137,6 +137,21 @@ umem_free(const void *ptr, size_t size __maybe_unused)
free((void *)ptr);
}
+/*
+ * umem_free_aligned was added for supporting portability
+ * with non-POSIX platforms that require a different free
+ * to be used with aligned allocations.
+ */
+static inline void
+umem_free_aligned(void *ptr, size_t size __maybe_unused)
+{
+#ifndef _WIN32
+ free((void *)ptr);
+#else
+ _aligned_free(ptr);
+#endif
+}
+
static inline void
umem_nofail_callback(umem_nofail_callback_t *cb __maybe_unused)
{}
@@ -196,7 +211,10 @@ umem_cache_free(umem_cache_t *cp, void *ptr)
if (cp->cache_destructor)
cp->cache_destructor(ptr, cp->cache_private);
- umem_free(ptr, cp->cache_bufsize);
+ if (cp->cache_align != 0)
+ umem_free_aligned(ptr, cp->cache_bufsize);
+ else
+ umem_free(ptr, cp->cache_bufsize);
}
static inline void
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
index 4f0f73c89b5d..fcef8798c615 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/gethostid.c
@@ -59,6 +59,7 @@ unsigned long
get_system_hostid(void)
{
unsigned long hostid = get_spl_hostid();
+ uint32_t system_hostid;
/*
* We do not use gethostid(3) because it can return a bogus ID,
@@ -69,8 +70,11 @@ get_system_hostid(void)
if (hostid == 0) {
int fd = open("/etc/hostid", O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
- if (read(fd, &hostid, 4) < 0)
+ if (read(fd, &system_hostid, sizeof (system_hostid))
+ != sizeof (system_hostid))
hostid = 0;
+ else
+ hostid = system_hostid;
(void) close(fd);
}
}
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/zone.c b/sys/contrib/openzfs/lib/libspl/os/linux/zone.c
index e37b34975df6..622d04cbc14a 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/zone.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/zone.c
@@ -41,7 +41,7 @@ getzoneid(void)
int c = snprintf(path, sizeof (path), "/proc/self/ns/user");
/* This API doesn't have any error checking... */
- if (c < 0)
+ if (c < 0 || c >= sizeof (path))
return (0);
ssize_t r = readlink(path, buf, sizeof (buf) - 1);
diff --git a/sys/contrib/openzfs/lib/libuutil/uu_avl.c b/sys/contrib/openzfs/lib/libuutil/uu_avl.c
index 12f7bd4bcc72..ef1497b31439 100644
--- a/sys/contrib/openzfs/lib/libuutil/uu_avl.c
+++ b/sys/contrib/openzfs/lib/libuutil/uu_avl.c
@@ -97,8 +97,8 @@ uu_avl_pool_create(const char *name, size_t objsize, size_t nodeoffset,
(void) pthread_mutex_init(&pp->uap_lock, NULL);
- pp->uap_null_avl.ua_next_enc = UU_PTR_ENCODE(&pp->uap_null_avl);
- pp->uap_null_avl.ua_prev_enc = UU_PTR_ENCODE(&pp->uap_null_avl);
+ pp->uap_null_avl.ua_next = &pp->uap_null_avl;
+ pp->uap_null_avl.ua_prev = &pp->uap_null_avl;
(void) pthread_mutex_lock(&uu_apool_list_lock);
pp->uap_next = next = &uu_null_apool;
@@ -114,10 +114,8 @@ void
uu_avl_pool_destroy(uu_avl_pool_t *pp)
{
if (pp->uap_debug) {
- if (pp->uap_null_avl.ua_next_enc !=
- UU_PTR_ENCODE(&pp->uap_null_avl) ||
- pp->uap_null_avl.ua_prev_enc !=
- UU_PTR_ENCODE(&pp->uap_null_avl)) {
+ if (pp->uap_null_avl.ua_next != &pp->uap_null_avl ||
+ pp->uap_null_avl.ua_prev != &pp->uap_null_avl) {
uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has "
"outstanding avls, or is corrupt.\n",
(int)sizeof (pp->uap_name), pp->uap_name,
@@ -224,7 +222,7 @@ uu_avl_create(uu_avl_pool_t *pp, void *parent, uint32_t flags)
}
ap->ua_pool = pp;
- ap->ua_parent_enc = UU_PTR_ENCODE(parent);
+ ap->ua_parent = parent;
ap->ua_debug = pp->uap_debug || (flags & UU_AVL_DEBUG);
ap->ua_index = (pp->uap_last_index = INDEX_NEXT(pp->uap_last_index));
@@ -236,11 +234,11 @@ uu_avl_create(uu_avl_pool_t *pp, void *parent, uint32_t flags)
(void) pthread_mutex_lock(&pp->uap_lock);
next = &pp->uap_null_avl;
- prev = UU_PTR_DECODE(next->ua_prev_enc);
- ap->ua_next_enc = UU_PTR_ENCODE(next);
- ap->ua_prev_enc = UU_PTR_ENCODE(prev);
- next->ua_prev_enc = UU_PTR_ENCODE(ap);
- prev->ua_next_enc = UU_PTR_ENCODE(ap);
+ prev = next->ua_prev;
+ ap->ua_next = next;
+ ap->ua_prev = prev;
+ next->ua_prev = ap;
+ prev->ua_next = ap;
(void) pthread_mutex_unlock(&pp->uap_lock);
return (ap);
@@ -263,11 +261,11 @@ uu_avl_destroy(uu_avl_t *ap)
}
}
(void) pthread_mutex_lock(&pp->uap_lock);
- UU_AVL_PTR(ap->ua_next_enc)->ua_prev_enc = ap->ua_prev_enc;
- UU_AVL_PTR(ap->ua_prev_enc)->ua_next_enc = ap->ua_next_enc;
+ ap->ua_next->ua_prev = ap->ua_prev;
+ ap->ua_prev->ua_next = ap->ua_next;
(void) pthread_mutex_unlock(&pp->uap_lock);
- ap->ua_prev_enc = UU_PTR_ENCODE(NULL);
- ap->ua_next_enc = UU_PTR_ENCODE(NULL);
+ ap->ua_prev = NULL;
+ ap->ua_next = NULL;
ap->ua_pool = NULL;
avl_destroy(&ap->ua_tree);
diff --git a/sys/contrib/openzfs/lib/libuutil/uu_list.c b/sys/contrib/openzfs/lib/libuutil/uu_list.c
index 5ece4b14701e..0ca6f05205e9 100644
--- a/sys/contrib/openzfs/lib/libuutil/uu_list.c
+++ b/sys/contrib/openzfs/lib/libuutil/uu_list.c
@@ -93,8 +93,8 @@ uu_list_pool_create(const char *name, size_t objsize,
(void) pthread_mutex_init(&pp->ulp_lock, NULL);
- pp->ulp_null_list.ul_next_enc = UU_PTR_ENCODE(&pp->ulp_null_list);
- pp->ulp_null_list.ul_prev_enc = UU_PTR_ENCODE(&pp->ulp_null_list);
+ pp->ulp_null_list.ul_next = &pp->ulp_null_list;
+ pp->ulp_null_list.ul_prev = &pp->ulp_null_list;
(void) pthread_mutex_lock(&uu_lpool_list_lock);
pp->ulp_next = next = &uu_null_lpool;
@@ -110,10 +110,8 @@ void
uu_list_pool_destroy(uu_list_pool_t *pp)
{
if (pp->ulp_debug) {
- if (pp->ulp_null_list.ul_next_enc !=
- UU_PTR_ENCODE(&pp->ulp_null_list) ||
- pp->ulp_null_list.ul_prev_enc !=
- UU_PTR_ENCODE(&pp->ulp_null_list)) {
+ if (pp->ulp_null_list.ul_next != &pp->ulp_null_list ||
+ pp->ulp_null_list.ul_prev != &pp->ulp_null_list) {
uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has "
"outstanding lists, or is corrupt.\n",
(int)sizeof (pp->ulp_name), pp->ulp_name,
@@ -202,7 +200,7 @@ uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
}
lp->ul_pool = pp;
- lp->ul_parent_enc = UU_PTR_ENCODE(parent);
+ lp->ul_parent = parent;
lp->ul_offset = pp->ulp_nodeoffset;
lp->ul_debug = pp->ulp_debug || (flags & UU_LIST_DEBUG);
lp->ul_sorted = (flags & UU_LIST_SORTED);
@@ -217,11 +215,11 @@ uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
(void) pthread_mutex_lock(&pp->ulp_lock);
next = &pp->ulp_null_list;
- prev = UU_PTR_DECODE(next->ul_prev_enc);
- lp->ul_next_enc = UU_PTR_ENCODE(next);
- lp->ul_prev_enc = UU_PTR_ENCODE(prev);
- next->ul_prev_enc = UU_PTR_ENCODE(lp);
- prev->ul_next_enc = UU_PTR_ENCODE(lp);
+ prev = next->ul_prev;
+ lp->ul_next = next;
+ lp->ul_prev = prev;
+ next->ul_prev = lp;
+ prev->ul_next = lp;
(void) pthread_mutex_unlock(&pp->ulp_lock);
return (lp);
@@ -250,11 +248,11 @@ uu_list_destroy(uu_list_t *lp)
}
(void) pthread_mutex_lock(&pp->ulp_lock);
- UU_LIST_PTR(lp->ul_next_enc)->ul_prev_enc = lp->ul_prev_enc;
- UU_LIST_PTR(lp->ul_prev_enc)->ul_next_enc = lp->ul_next_enc;
+ lp->ul_next->ul_prev = lp->ul_prev;
+ lp->ul_prev->ul_next = lp->ul_next;
(void) pthread_mutex_unlock(&pp->ulp_lock);
- lp->ul_prev_enc = UU_PTR_ENCODE(NULL);
- lp->ul_next_enc = UU_PTR_ENCODE(NULL);
+ lp->ul_prev = NULL;
+ lp->ul_next = NULL;
lp->ul_pool = NULL;
uu_free(lp);
}
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs.abi b/sys/contrib/openzfs/lib/libzfs/libzfs.abi
index 3471bcac9412..98873784e7dc 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs.abi
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs.abi
@@ -191,6 +191,7 @@
<elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='is_mounted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='is_mpath_whole_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='libpc_error_description' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='libzfs_add_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -234,6 +235,7 @@
<elf-symbol name='membar_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='membar_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='membar_producer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='membar_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='mkdirp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='mountpoint_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='permset_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -3212,7 +3214,8 @@
<enumerator name='VDEV_PROP_BYTES_TRIM' value='38'/>
<enumerator name='VDEV_PROP_REMOVING' value='39'/>
<enumerator name='VDEV_PROP_ALLOCATING' value='40'/>
- <enumerator name='VDEV_NUM_PROPS' value='41'/>
+ <enumerator name='VDEV_PROP_FAILFAST' value='41'/>
+ <enumerator name='VDEV_NUM_PROPS' value='42'/>
</enum-decl>
<typedef-decl name='vdev_prop_t' type-id='1573bec8' id='5aa5c90c'/>
<enum-decl name='vdev_state' id='21566197'>
@@ -4569,7 +4572,32 @@
</data-member>
</class-decl>
<typedef-decl name='importargs_t' type-id='7ac83801' id='7a842a6b'/>
+ <class-decl name='libpc_handle' size-in-bits='8448' is-struct='yes' visibility='default' id='7c8737f0'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='lpc_error' type-id='95e97e5e' visibility='default'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='32'>
+ <var-decl name='lpc_printerr' type-id='c19b74c3' visibility='default'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='64'>
+ <var-decl name='lpc_open_access_error' type-id='c19b74c3' visibility='default'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='96'>
+ <var-decl name='lpc_desc_active' type-id='c19b74c3' visibility='default'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='128'>
+ <var-decl name='lpc_desc' type-id='b54ce520' visibility='default'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='8320'>
+ <var-decl name='lpc_ops' type-id='f095e320' visibility='default'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='8384'>
+ <var-decl name='lpc_lib_handle' type-id='eaa32e2f' visibility='default'/>
+ </data-member>
+ </class-decl>
+ <typedef-decl name='libpc_handle_t' type-id='7c8737f0' id='8a70a786'/>
<pointer-type-def type-id='7a842a6b' size-in-bits='64' id='07ee4a58'/>
+ <pointer-type-def type-id='8a70a786' size-in-bits='64' id='5507783b'/>
<pointer-type-def type-id='b1e62775' size-in-bits='64' id='f095e320'/>
<function-decl name='zpool_read_label' mangled-name='zpool_read_label' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_read_label'>
<parameter type-id='95e97e5e' name='fd'/>
@@ -4578,17 +4606,15 @@
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zpool_search_import' mangled-name='zpool_search_import' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_search_import'>
- <parameter type-id='eaa32e2f' name='hdl'/>
+ <parameter type-id='5507783b' name='hdl'/>
<parameter type-id='07ee4a58' name='import'/>
- <parameter type-id='f095e320' name='pco'/>
<return type-id='5ce45b60'/>
</function-decl>
<function-decl name='zpool_find_config' mangled-name='zpool_find_config' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_find_config'>
- <parameter type-id='eaa32e2f' name='hdl'/>
+ <parameter type-id='5507783b' name='hdl'/>
<parameter type-id='80f4b756' name='target'/>
<parameter type-id='857bb57e' name='configp'/>
<parameter type-id='07ee4a58' name='args'/>
- <parameter type-id='f095e320' name='pco'/>
<return type-id='95e97e5e'/>
</function-decl>
</abi-instr>
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c b/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c
index 133b3b358831..87bc4ea66c5b 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_dataset.c
@@ -2006,7 +2006,7 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
if ((ret = changelist_prefix(cl)) != 0)
goto error;
- if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) {
changelist_free(cl);
return (zfs_standard_error(hdl, errno, errbuf));
} else {
@@ -2087,16 +2087,16 @@ zfs_is_recvd_props_mode(zfs_handle_t *zhp)
}
static void
-zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
+zfs_set_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie)
{
- *cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
+ *cookie = (uintptr_t)zhp->zfs_props;
zhp->zfs_props = zhp->zfs_recvd_props;
}
static void
-zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
+zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie)
{
- zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
+ zhp->zfs_props = (nvlist_t *)*cookie;
*cookie = 0;
}
@@ -2373,7 +2373,7 @@ zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
prop = zfs_name_to_prop(propname);
if (prop != ZPROP_USERPROP) {
- uint64_t cookie;
+ uintptr_t cookie;
if (!nvlist_exists(zhp->zfs_recvd_props, propname))
return (-1);
zfs_set_recvd_props_mode(zhp, &cookie);
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
index 80588a860c18..84e140ede665 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_diff.c
@@ -377,7 +377,7 @@ write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
if (zc.zc_obj > dr->ddr_last) {
break;
}
- err = describe_free(fp, di, zc.zc_obj, fobjname,
+ (void) describe_free(fp, di, zc.zc_obj, fobjname,
MAXPATHLEN);
} else if (errno == ESRCH) {
break;
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
index b9806dc30dac..7f7e19a090bc 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c
@@ -60,9 +60,9 @@
static boolean_t zpool_vdev_is_interior(const char *name);
typedef struct prop_flags {
- int create:1; /* Validate property on creation */
- int import:1; /* Validate property on import */
- int vdevprop:1; /* Validate property as a VDEV property */
+ unsigned int create:1; /* Validate property on creation */
+ unsigned int import:1; /* Validate property on import */
+ unsigned int vdevprop:1; /* Validate property as a VDEV property */
} prop_flags_t;
/*
@@ -2214,7 +2214,6 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), nv);
}
nvlist_free(nv);
- return (0);
}
return (ret);
@@ -2679,7 +2678,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
if (zfs_strcmp_pathname(srchval, val, wholedisk) == 0)
return (nv);
- } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
+ } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0) {
char *type, *idx, *end, *p;
uint64_t id, vdev_id;
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
index d63a9e1a4e0a..3e9f63777424 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
@@ -2117,9 +2117,9 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd,
fnvlist_add_boolean(hdrnv, "raw");
}
- if ((err = gather_nvlist(zhp->zfs_hdl, tofs,
+ if (gather_nvlist(zhp->zfs_hdl, tofs,
from, tosnap, recursive, raw, doall, replicate, skipmissing,
- verbose, backup, holds, props, &fss, fsavlp)) != 0) {
+ verbose, backup, holds, props, &fss, fsavlp) != 0) {
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
errbuf));
}
@@ -4387,7 +4387,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
* prepend a path separator.
*/
int len = strlen(drrb->drr_toname);
- cp = malloc(len + 2);
+ cp = umem_alloc(len + 2, UMEM_NOFAIL);
cp[0] = '/';
(void) strcpy(&cp[1], drrb->drr_toname);
chopprefix = cp;
@@ -4440,7 +4440,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
*/
(void) strlcpy(destsnap, tosnap, sizeof (destsnap));
(void) strlcat(destsnap, chopprefix, sizeof (destsnap));
- free(cp);
+ if (cp != NULL)
+ umem_free(cp, strlen(cp) + 1);
if (!zfs_name_valid(destsnap, ZFS_TYPE_SNAPSHOT)) {
err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
goto out;
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_util.c b/sys/contrib/openzfs/lib/libzfs/libzfs_util.c
index 28dd4f426a96..b4679dbb36fd 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_util.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_util.c
@@ -1249,7 +1249,7 @@ zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
static void
zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
{
- zprop_list_t *pl = cbp->cb_proplist;
+ zprop_list_t *pl;
int i;
char *title;
size_t len;
diff --git a/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c b/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c
index f4900943c4af..d1c1fea7fb68 100644
--- a/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c
+++ b/sys/contrib/openzfs/lib/libzfs/os/freebsd/libzfs_compat.c
@@ -204,6 +204,8 @@ libzfs_error_init(int error)
if (modfind("zfs") < 0) {
size_t len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN,
"Failed to load %s module: "), ZFS_KMOD);
+ if (len >= msglen)
+ len = msglen - 1;
msg += len;
msglen -= len;
}
diff --git a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c
index 16bd9af1bbc8..3fe65e665b9c 100644
--- a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c
+++ b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.c
@@ -235,7 +235,7 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
break;
}
}
- if (zc.zc_nvlist_dst_filled) {
+ if (zc.zc_nvlist_dst_filled && resultp != NULL) {
*resultp = fnvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
zc.zc_nvlist_dst_size);
}
diff --git a/sys/contrib/openzfs/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c b/sys/contrib/openzfs/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c
index 36fbbd88c2ac..72f8f393039a 100644
--- a/sys/contrib/openzfs/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c
+++ b/sys/contrib/openzfs/lib/libzfs_core/os/freebsd/libzfs_core_ioctl.c
@@ -46,8 +46,11 @@ get_zfs_ioctl_version(void)
static int
zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
{
- int newrequest, ret;
+ int ret;
+#ifdef ZFS_LEGACY_SUPPORT
+ int newrequest;
void *zc_c = NULL;
+#endif
unsigned long ncmd;
zfs_iocparm_t zp;
@@ -58,6 +61,7 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
zp.zfs_cmd_size = sizeof (zfs_cmd_t);
zp.zfs_ioctl_version = ZFS_IOCVER_OZFS;
break;
+#ifdef ZFS_LEGACY_SUPPORT
case ZFS_CMD_COMPAT_LEGACY:
newrequest = zfs_ioctl_ozfs_to_legacy(request);
ncmd = _IOWR('Z', newrequest, zfs_iocparm_t);
@@ -67,6 +71,7 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
zp.zfs_cmd_size = sizeof (zfs_cmd_legacy_t);
zp.zfs_ioctl_version = ZFS_IOCVER_LEGACY;
break;
+#endif
default:
abort();
return (EINVAL);
@@ -74,14 +79,18 @@ zcmd_ioctl_compat(int fd, int request, zfs_cmd_t *zc, const int cflag)
ret = ioctl(fd, ncmd, &zp);
if (ret) {
+#ifdef ZFS_LEGACY_SUPPORT
if (zc_c)
free(zc_c);
+#endif
return (ret);
}
+#ifdef ZFS_LEGACY_SUPPORT
if (zc_c) {
zfs_cmd_legacy_to_ozfs(zc_c, zc);
free(zc_c);
}
+#endif
return (ret);
}
@@ -100,9 +109,11 @@ lzc_ioctl_fd(int fd, unsigned long request, zfs_cmd_t *zc)
zfs_ioctl_version = get_zfs_ioctl_version();
switch (zfs_ioctl_version) {
+#ifdef ZFS_LEGACY_SUPPORT
case ZFS_IOCVER_LEGACY:
cflag = ZFS_CMD_COMPAT_LEGACY;
break;
+#endif
case ZFS_IOCVER_OZFS:
cflag = ZFS_CMD_COMPAT_NONE;
break;
diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c
index 1f58acb0404f..77264470baef 100644
--- a/sys/contrib/openzfs/lib/libzpool/kernel.c
+++ b/sys/contrib/openzfs/lib/libzpool/kernel.c
@@ -956,6 +956,35 @@ kmem_asprintf(const char *fmt, ...)
return (buf);
}
+/*
+ * kmem_scnprintf() will return the number of characters that it would have
+ * printed whenever it is limited by value of the size variable, rather than
+ * the number of characters that it did print. This can cause misbehavior on
+ * subsequent uses of the return value, so we define a safe version that will
+ * return the number of characters actually printed, minus the NULL format
+ * character. Subsequent use of this by the safe string functions is safe
+ * whether it is snprintf(), strlcat() or strlcpy().
+ */
+int
+kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ /* Make the 0 case a no-op so that we do not return -1 */
+ if (size == 0)
+ return (0);
+
+ va_start(ap, fmt);
+ n = vsnprintf(str, size, fmt, ap);
+ va_end(ap);
+
+ if (n >= size)
+ n = size - 1;
+
+ return (n);
+}
+
zfs_file_t *
zfs_onexit_fd_hold(int fd, minor_t *minorp)
{
@@ -972,7 +1001,7 @@ zfs_onexit_fd_rele(zfs_file_t *fp)
int
zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
- uint64_t *action_handle)
+ uintptr_t *action_handle)
{
(void) minor, (void) func, (void) data, (void) action_handle;
return (0);
diff --git a/sys/contrib/openzfs/lib/libzpool/util.c b/sys/contrib/openzfs/lib/libzpool/util.c
index 0ce7822a3563..551f1294d31f 100644
--- a/sys/contrib/openzfs/lib/libzpool/util.c
+++ b/sys/contrib/openzfs/lib/libzpool/util.c
@@ -229,13 +229,14 @@ set_global_var(char const *arg)
fprintf(stderr, "Failed to open libzpool.so to set global "
"variable\n");
ret = EIO;
- goto out_dlclose;
+ goto out_free;
}
ret = 0;
out_dlclose:
dlclose(zpoolhdl);
+out_free:
free(varname);
out_ret:
return (ret);
@@ -260,7 +261,9 @@ pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive)
(void) unused, (void) guid;
zfs_iocparm_t zp;
zfs_cmd_t *zc = NULL;
+#ifdef ZFS_LEGACY_SUPPORT
zfs_cmd_legacy_t *zcl = NULL;
+#endif
unsigned long request;
int ret;
@@ -295,6 +298,7 @@ pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive)
umem_free(zc, sizeof (zfs_cmd_t));
break;
+#ifdef ZFS_LEGACY_SUPPORT
case ZFS_IOCVER_LEGACY:
zcl = umem_zalloc(sizeof (zfs_cmd_legacy_t), UMEM_NOFAIL);
@@ -310,6 +314,7 @@ pool_active(void *unused, const char *name, uint64_t guid, boolean_t *isactive)
umem_free(zcl, sizeof (zfs_cmd_legacy_t));
break;
+#endif
default:
fprintf(stderr, "unrecognized zfs ioctl version %d", ver);
exit(1);
diff --git a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c
index 05dbb39954fa..900d5e5bacd2 100644
--- a/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c
+++ b/sys/contrib/openzfs/lib/libzutil/os/linux/zutil_device_path_os.c
@@ -428,7 +428,6 @@ dm_get_underlying_path(const char *dm_name)
char *tmp = NULL;
char *path = NULL;
char *dev_str;
- int size;
char *first_path = NULL;
char *enclosure_path;
@@ -450,7 +449,7 @@ dm_get_underlying_path(const char *dm_name)
else
dev_str = tmp;
- if ((size = asprintf(&tmp, "/sys/block/%s/slaves/", dev_str)) == -1) {
+ if (asprintf(&tmp, "/sys/block/%s/slaves/", dev_str) == -1) {
tmp = NULL;
goto end;
}
@@ -479,8 +478,7 @@ dm_get_underlying_path(const char *dm_name)
if (!enclosure_path)
continue;
- if ((size = asprintf(
- &path, "/dev/%s", ep->d_name)) == -1)
+ if (asprintf(&path, "/dev/%s", ep->d_name) == -1)
path = NULL;
free(enclosure_path);
break;
@@ -499,7 +497,7 @@ end:
* enclosure devices. Throw up out hands and return the first
* underlying path.
*/
- if ((size = asprintf(&path, "/dev/%s", first_path)) == -1)
+ if (asprintf(&path, "/dev/%s", first_path) == -1)
path = NULL;
}
diff --git a/sys/contrib/openzfs/lib/libzutil/zutil_import.c b/sys/contrib/openzfs/lib/libzutil/zutil_import.c
index e3f1c8942564..5d7b4a946c1e 100644
--- a/sys/contrib/openzfs/lib/libzutil/zutil_import.c
+++ b/sys/contrib/openzfs/lib/libzutil/zutil_import.c
@@ -71,6 +71,30 @@
#include "zutil_import.h"
+const char *
+libpc_error_description(libpc_handle_t *hdl)
+{
+ if (hdl->lpc_desc[0] != '\0')
+ return (hdl->lpc_desc);
+
+ switch (hdl->lpc_error) {
+ case LPC_BADCACHE:
+ return (dgettext(TEXT_DOMAIN, "invalid or missing cache file"));
+ case LPC_BADPATH:
+ return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
+ case LPC_NOMEM:
+ return (dgettext(TEXT_DOMAIN, "out of memory"));
+ case LPC_EACCESS:
+ return (dgettext(TEXT_DOMAIN, "some devices require root "
+ "privileges"));
+ case LPC_UNKNOWN:
+ return (dgettext(TEXT_DOMAIN, "unknown error"));
+ default:
+ assert(hdl->lpc_error == 0);
+ return (dgettext(TEXT_DOMAIN, "no error"));
+ }
+}
+
static __attribute__((format(printf, 2, 3))) void
zutil_error_aux(libpc_handle_t *hdl, const char *fmt, ...)
{
@@ -85,28 +109,27 @@ zutil_error_aux(libpc_handle_t *hdl, const char *fmt, ...)
}
static void
-zutil_verror(libpc_handle_t *hdl, const char *error, const char *fmt,
+zutil_verror(libpc_handle_t *hdl, lpc_error_t error, const char *fmt,
va_list ap)
{
char action[1024];
(void) vsnprintf(action, sizeof (action), fmt, ap);
+ hdl->lpc_error = error;
if (hdl->lpc_desc_active)
hdl->lpc_desc_active = B_FALSE;
else
hdl->lpc_desc[0] = '\0';
- if (hdl->lpc_printerr) {
- if (hdl->lpc_desc[0] != '\0')
- error = hdl->lpc_desc;
-
- (void) fprintf(stderr, "%s: %s\n", action, error);
- }
+ if (hdl->lpc_printerr)
+ (void) fprintf(stderr, "%s: %s\n", action,
+ libpc_error_description(hdl));
}
static __attribute__((format(printf, 3, 4))) int
-zutil_error_fmt(libpc_handle_t *hdl, const char *error, const char *fmt, ...)
+zutil_error_fmt(libpc_handle_t *hdl, lpc_error_t error,
+ const char *fmt, ...)
{
va_list ap;
@@ -120,7 +143,7 @@ zutil_error_fmt(libpc_handle_t *hdl, const char *error, const char *fmt, ...)
}
static int
-zutil_error(libpc_handle_t *hdl, const char *error, const char *msg)
+zutil_error(libpc_handle_t *hdl, lpc_error_t error, const char *msg)
{
return (zutil_error_fmt(hdl, error, "%s", msg));
}
@@ -128,7 +151,7 @@ zutil_error(libpc_handle_t *hdl, const char *error, const char *msg)
static int
zutil_no_memory(libpc_handle_t *hdl)
{
- zutil_error(hdl, EZFS_NOMEM, "internal error");
+ zutil_error(hdl, LPC_NOMEM, "internal error");
exit(1);
}
@@ -478,11 +501,9 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok,
uint64_t guid;
uint_t children = 0;
nvlist_t **child = NULL;
- uint_t holes;
uint64_t *hole_array, max_id;
uint_t c;
boolean_t isactive;
- uint64_t hostid;
nvlist_t *nvl;
boolean_t valid_top_config = B_FALSE;
@@ -490,7 +511,8 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok,
goto nomem;
for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
- uint64_t id, max_txg = 0;
+ uint64_t id, max_txg = 0, hostid = 0;
+ uint_t holes = 0;
if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0)
goto nomem;
@@ -912,7 +934,6 @@ zpool_read_label_slow(int fd, nvlist_t **config, int *num_labels)
vdev_phys_t *label;
nvlist_t *expected_config = NULL;
uint64_t expected_guid = 0, size;
- int error;
*config = NULL;
@@ -920,8 +941,9 @@ zpool_read_label_slow(int fd, nvlist_t **config, int *num_labels)
return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
- error = posix_memalign((void **)&label, PAGESIZE, sizeof (*label));
- if (error)
+ label = (vdev_phys_t *)umem_alloc_aligned(sizeof (*label), PAGESIZE,
+ UMEM_DEFAULT);
+ if (label == NULL)
return (-1);
for (l = 0; l < VDEV_LABELS; l++) {
@@ -970,7 +992,7 @@ zpool_read_label_slow(int fd, nvlist_t **config, int *num_labels)
if (num_labels != NULL)
*num_labels = count;
- free(label);
+ umem_free_aligned(label, sizeof (*label));
*config = expected_config;
return (0);
@@ -1001,9 +1023,9 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
- error = posix_memalign((void **)&labels, PAGESIZE,
- VDEV_LABELS * sizeof (*labels));
- if (error)
+ labels = (vdev_phys_t *)umem_alloc_aligned(
+ VDEV_LABELS * sizeof (*labels), PAGESIZE, UMEM_DEFAULT);
+ if (labels == NULL)
return (-1);
memset(aiocbs, 0, sizeof (aiocbs));
@@ -1056,7 +1078,7 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
error = zpool_read_label_slow(fd, config, num_labels);
saved_errno = errno;
}
- free(labels);
+ umem_free_aligned(labels, VDEV_LABELS * sizeof (*labels));
errno = saved_errno;
return (error);
}
@@ -1105,7 +1127,7 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
if (num_labels != NULL)
*num_labels = count;
- free(labels);
+ umem_free_aligned(labels, VDEV_LABELS * sizeof (*labels));
*config = expected_config;
return (0);
@@ -1244,8 +1266,8 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock,
return (0);
zutil_error_aux(hdl, "%s", strerror(error));
- (void) zutil_error_fmt(hdl, EZFS_BADPATH, dgettext(
- TEXT_DOMAIN, "cannot resolve path '%s'"), dir);
+ (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN,
+ "cannot resolve path '%s'"), dir);
return (error);
}
@@ -1253,8 +1275,8 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock,
if (dirp == NULL) {
error = errno;
zutil_error_aux(hdl, "%s", strerror(error));
- (void) zutil_error_fmt(hdl, EZFS_BADPATH,
- dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
+ (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN,
+ "cannot open '%s'"), path);
return (error);
}
@@ -1315,8 +1337,8 @@ zpool_find_import_scan_path(libpc_handle_t *hdl, pthread_mutex_t *lock,
}
zutil_error_aux(hdl, "%s", strerror(error));
- (void) zutil_error_fmt(hdl, EZFS_BADPATH, dgettext(
- TEXT_DOMAIN, "cannot resolve path '%s'"), dir);
+ (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN,
+ "cannot resolve path '%s'"), dir);
goto out;
}
@@ -1353,7 +1375,7 @@ zpool_find_import_scan(libpc_handle_t *hdl, pthread_mutex_t *lock,
continue;
zutil_error_aux(hdl, "%s", strerror(error));
- (void) zutil_error_fmt(hdl, EZFS_BADPATH, dgettext(
+ (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(
TEXT_DOMAIN, "cannot resolve path '%s'"), dir[i]);
goto error;
}
@@ -1574,16 +1596,16 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg)
if ((fd = open(iarg->cachefile, O_RDONLY | O_CLOEXEC)) < 0) {
zutil_error_aux(hdl, "%s", strerror(errno));
- (void) zutil_error(hdl, EZFS_BADCACHE,
- dgettext(TEXT_DOMAIN, "failed to open cache file"));
+ (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN,
+ "failed to open cache file"));
return (NULL);
}
if (fstat64(fd, &statbuf) != 0) {
zutil_error_aux(hdl, "%s", strerror(errno));
(void) close(fd);
- (void) zutil_error(hdl, EZFS_BADCACHE,
- dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
+ (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN,
+ "failed to get size of cache file"));
return (NULL);
}
@@ -1595,8 +1617,7 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg)
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
(void) close(fd);
free(buf);
- (void) zutil_error(hdl, EZFS_BADCACHE,
- dgettext(TEXT_DOMAIN,
+ (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN,
"failed to read cache file contents"));
return (NULL);
}
@@ -1605,8 +1626,7 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg)
if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
free(buf);
- (void) zutil_error(hdl, EZFS_BADCACHE,
- dgettext(TEXT_DOMAIN,
+ (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN,
"invalid or corrupt cache file contents"));
return (NULL);
}
@@ -1777,25 +1797,20 @@ zpool_find_import(libpc_handle_t *hdl, importargs_t *iarg)
nvlist_t *
-zpool_search_import(void *hdl, importargs_t *import, pool_config_ops_t *pco)
+zpool_search_import(libpc_handle_t *hdl, importargs_t *import)
{
- libpc_handle_t handle = { 0 };
nvlist_t *pools = NULL;
- handle.lpc_lib_handle = hdl;
- handle.lpc_ops = pco;
- handle.lpc_printerr = B_TRUE;
-
verify(import->poolname == NULL || import->guid == 0);
if (import->cachefile != NULL)
- pools = zpool_find_import_cached(&handle, import);
+ pools = zpool_find_import_cached(hdl, import);
else
- pools = zpool_find_import(&handle, import);
+ pools = zpool_find_import(hdl, import);
if ((pools == NULL || nvlist_empty(pools)) &&
- handle.lpc_open_access_error && geteuid() != 0) {
- (void) zutil_error(&handle, EZFS_EACESS, dgettext(TEXT_DOMAIN,
+ hdl->lpc_open_access_error && geteuid() != 0) {
+ (void) zutil_error(hdl, LPC_EACCESS, dgettext(TEXT_DOMAIN,
"no pools found"));
}
@@ -1819,8 +1834,8 @@ pool_match(nvlist_t *cfg, char *tgt)
}
int
-zpool_find_config(void *hdl, const char *target, nvlist_t **configp,
- importargs_t *args, pool_config_ops_t *pco)
+zpool_find_config(libpc_handle_t *hdl, const char *target, nvlist_t **configp,
+ importargs_t *args)
{
nvlist_t *pools;
nvlist_t *match = NULL;
@@ -1829,12 +1844,15 @@ zpool_find_config(void *hdl, const char *target, nvlist_t **configp,
int count = 0;
char *targetdup = strdup(target);
+ if (targetdup == NULL)
+ return (ENOMEM);
+
*configp = NULL;
if ((sepp = strpbrk(targetdup, "/@")) != NULL)
*sepp = '\0';
- pools = zpool_search_import(hdl, args, pco);
+ pools = zpool_search_import(hdl, args);
if (pools != NULL) {
nvpair_t *elem = NULL;
diff --git a/sys/contrib/openzfs/lib/libzutil/zutil_import.h b/sys/contrib/openzfs/lib/libzutil/zutil_import.h
index 482315e44130..f851a91132ce 100644
--- a/sys/contrib/openzfs/lib/libzutil/zutil_import.h
+++ b/sys/contrib/openzfs/lib/libzutil/zutil_import.h
@@ -28,26 +28,11 @@
#ifndef _LIBZUTIL_ZUTIL_IMPORT_H_
#define _LIBZUTIL_ZUTIL_IMPORT_H_
-#define EZFS_BADCACHE "invalid or missing cache file"
-#define EZFS_BADPATH "must be an absolute path"
-#define EZFS_NOMEM "out of memory"
-#define EZFS_EACESS "some devices require root privileges"
-
#define IMPORT_ORDER_PREFERRED_1 1
#define IMPORT_ORDER_PREFERRED_2 2
#define IMPORT_ORDER_SCAN_OFFSET 10
#define IMPORT_ORDER_DEFAULT 100
-typedef struct libpc_handle {
- boolean_t lpc_printerr;
- boolean_t lpc_open_access_error;
- boolean_t lpc_desc_active;
- char lpc_desc[1024];
- pool_config_ops_t *lpc_ops;
- void *lpc_lib_handle;
-} libpc_handle_t;
-
-
int label_paths(libpc_handle_t *hdl, nvlist_t *label, char **path,
char **devid);
int zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
diff --git a/sys/contrib/openzfs/man/man4/zfs.4 b/sys/contrib/openzfs/man/man4/zfs.4
index da1aa9c34287..98539a6369e7 100644
--- a/sys/contrib/openzfs/man/man4/zfs.4
+++ b/sys/contrib/openzfs/man/man4/zfs.4
@@ -15,7 +15,7 @@
.\" own identifying information:
.\" Portions Copyright [yyyy] [name of copyright owner]
.\"
-.Dd June 1, 2021
+.Dd November 9, 2022
.Dt ZFS 4
.Os
.
@@ -26,7 +26,7 @@
.Sh DESCRIPTION
The ZFS module supports these parameters:
.Bl -tag -width Ds
-.It Sy dbuf_cache_max_bytes Ns = Ns Sy ULONG_MAX Ns B Pq ulong
+.It Sy dbuf_cache_max_bytes Ns = Ns Sy UINT64_MAX Ns B Pq u64
Maximum size in bytes of the dbuf cache.
The target size is determined by the MIN versus
.No 1/2^ Ns Sy dbuf_cache_shift Pq 1/32nd
@@ -36,7 +36,7 @@ can be observed via the
.Pa /proc/spl/kstat/zfs/dbufstats
kstat.
.
-.It Sy dbuf_metadata_cache_max_bytes Ns = Ns Sy ULONG_MAX Ns B Pq ulong
+.It Sy dbuf_metadata_cache_max_bytes Ns = Ns Sy UINT64_MAX Ns B Pq u64
Maximum size in bytes of the metadata dbuf cache.
The target size is determined by the MIN versus
.No 1/2^ Ns Sy dbuf_metadata_cache_shift Pq 1/64th
@@ -88,16 +88,16 @@ Alias for
Turbo L2ARC warm-up.
When the L2ARC is cold the fill interval will be set as fast as possible.
.
-.It Sy l2arc_feed_min_ms Ns = Ns Sy 200 Pq ulong
+.It Sy l2arc_feed_min_ms Ns = Ns Sy 200 Pq u64
Min feed interval in milliseconds.
Requires
.Sy l2arc_feed_again Ns = Ns Ar 1
and only applicable in related situations.
.
-.It Sy l2arc_feed_secs Ns = Ns Sy 1 Pq ulong
+.It Sy l2arc_feed_secs Ns = Ns Sy 1 Pq u64
Seconds between L2ARC writing.
.
-.It Sy l2arc_headroom Ns = Ns Sy 2 Pq ulong
+.It Sy l2arc_headroom Ns = Ns Sy 2 Pq u64
How far through the ARC lists to search for L2ARC cacheable content,
expressed as a multiplier of
.Sy l2arc_write_max .
@@ -106,7 +106,7 @@ by setting this parameter to
.Sy 0 ,
allowing the full length of ARC lists to be searched for cacheable content.
.
-.It Sy l2arc_headroom_boost Ns = Ns Sy 200 Ns % Pq ulong
+.It Sy l2arc_headroom_boost Ns = Ns Sy 200 Ns % Pq u64
Scales
.Sy l2arc_headroom
by this percentage when L2ARC contents are being successfully compressed
@@ -162,7 +162,7 @@ too many headers on a system with an irrationally large L2ARC
can render it slow or unusable.
This parameter limits L2ARC writes and rebuilds to achieve the target.
.
-.It Sy l2arc_trim_ahead Ns = Ns Sy 0 Ns % Pq ulong
+.It Sy l2arc_trim_ahead Ns = Ns Sy 0 Ns % Pq u64
Trims ahead of the current write size
.Pq Sy l2arc_write_max
on L2ARC devices by this percentage of write size if we have filled the device.
@@ -200,12 +200,12 @@ to enable caching/reading prefetches to/from L2ARC.
.It Sy l2arc_norw Ns = Ns Sy 0 Ns | Ns 1 Pq int
No reads during writes.
.
-.It Sy l2arc_write_boost Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq ulong
+.It Sy l2arc_write_boost Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq u64
Cold L2ARC devices will have
.Sy l2arc_write_max
increased by this amount while they remain cold.
.
-.It Sy l2arc_write_max Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq ulong
+.It Sy l2arc_write_max Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq u64
Max write bytes per interval.
.
.It Sy l2arc_rebuild_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
@@ -215,7 +215,7 @@ or attaching an L2ARC device (e.g. the L2ARC device is slow
in reading stored log metadata, or the metadata
has become somehow fragmented/unusable).
.
-.It Sy l2arc_rebuild_blocks_min_l2size Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq ulong
+.It Sy l2arc_rebuild_blocks_min_l2size Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64
Mininum size of an L2ARC device required in order to write log blocks in it.
The log blocks are used upon importing the pool to rebuild the persistent L2ARC.
.Pp
@@ -224,7 +224,7 @@ For L2ARC devices less than 1 GiB, the amount of data
evicts is significant compared to the amount of restored L2ARC data.
In this case, do not write log blocks in L2ARC in order not to waste space.
.
-.It Sy metaslab_aliquot Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong
+.It Sy metaslab_aliquot Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
Metaslab granularity, in bytes.
This is roughly similar to what would be referred to as the "stripe size"
in traditional RAID arrays.
@@ -235,11 +235,11 @@ before moving on to the next top-level vdev.
Enable metaslab group biasing based on their vdevs' over- or under-utilization
relative to the pool.
.
-.It Sy metaslab_force_ganging Ns = Ns Sy 16777217 Ns B Po 16 MiB + 1 B Pc Pq ulong
+.It Sy metaslab_force_ganging Ns = Ns Sy 16777217 Ns B Po 16 MiB + 1 B Pc Pq u64
Make some blocks above a certain size be gang blocks.
This option is used by the test suite to facilitate testing.
.
-.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq int
+.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
When attempting to log an output nvlist of an ioctl in the on-disk history,
the output will not be stored if it is larger than this size (in bytes).
This must be less than
@@ -299,7 +299,7 @@ this tunable controls which segment is used.
If set, we will use the largest free segment.
If unset, we will use a segment of at least the requested size.
.
-.It Sy zfs_metaslab_max_size_cache_sec Ns = Ns Sy 3600 Ns s Po 1 hour Pc Pq ulong
+.It Sy zfs_metaslab_max_size_cache_sec Ns = Ns Sy 3600 Ns s Po 1 hour Pc Pq u64
When we unload a metaslab, we cache the size of the largest free chunk.
We use that cached size to determine whether or not to load a metaslab
for a given allocation.
@@ -353,14 +353,14 @@ When a vdev is added, target this number of metaslabs per top-level vdev.
.It Sy zfs_vdev_default_ms_shift Ns = Ns Sy 29 Po 512 MiB Pc Pq uint
Default limit for metaslab size.
.
-.It Sy zfs_vdev_max_auto_ashift Ns = Ns Sy 14 Pq ulong
+.It Sy zfs_vdev_max_auto_ashift Ns = Ns Sy 14 Pq uint
Maximum ashift used when optimizing for logical \[->] physical sector size on new
top-level vdevs.
May be increased up to
.Sy ASHIFT_MAX Po 16 Pc ,
but this may negatively impact pool space efficiency.
.
-.It Sy zfs_vdev_min_auto_ashift Ns = Ns Sy ASHIFT_MIN Po 9 Pc Pq ulong
+.It Sy zfs_vdev_min_auto_ashift Ns = Ns Sy ASHIFT_MIN Po 9 Pc Pq uint
Minimum ashift used when creating new top-level vdevs.
.
.It Sy zfs_vdev_min_ms_count Ns = Ns Sy 16 Pq uint
@@ -481,10 +481,10 @@ The default value here was chosen to align with
which is a similar concept when doing
regular reads (but there's no reason it has to be the same).
.
-.It Sy vdev_file_logical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq ulong
+.It Sy vdev_file_logical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq u64
Logical ashift for file-based devices.
.
-.It Sy vdev_file_physical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq ulong
+.It Sy vdev_file_physical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq u64
Physical ashift for file-based devices.
.
.It Sy zap_iterate_prefetch Ns = Ns Sy 1 Ns | Ns 0 Pq int
@@ -493,7 +493,7 @@ prefetch the entire object (all leaf blocks).
However, this is limited by
.Sy dmu_prefetch_max .
.
-.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong
+.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
If prefetching is enabled, disable prefetching for reads larger than this size.
.
.It Sy zfetch_min_distance Ns = Ns Sy 4194304 Ns B Po 4 MiB Pc Pq uint
@@ -537,7 +537,7 @@ depends on kernel configuration.
This is the minimum allocation size that will use scatter (page-based) ABDs.
Smaller allocations will use linear ABDs.
.
-.It Sy zfs_arc_dnode_limit Ns = Ns Sy 0 Ns B Pq ulong
+.It Sy zfs_arc_dnode_limit Ns = Ns Sy 0 Ns B Pq u64
When the number of bytes consumed by dnodes in the ARC exceeds this number of
bytes, try to unpin some of it in response to demand for non-metadata.
This value acts as a ceiling to the amount of dnode metadata, and defaults to
@@ -553,14 +553,14 @@ when the amount of metadata in the ARC exceeds
.Sy zfs_arc_meta_limit
rather than in response to overall demand for non-metadata.
.
-.It Sy zfs_arc_dnode_limit_percent Ns = Ns Sy 10 Ns % Pq ulong
+.It Sy zfs_arc_dnode_limit_percent Ns = Ns Sy 10 Ns % Pq u64
Percentage that can be consumed by dnodes of ARC meta buffers.
.Pp
See also
.Sy zfs_arc_dnode_limit ,
which serves a similar purpose but has a higher priority if nonzero.
.
-.It Sy zfs_arc_dnode_reduce_percent Ns = Ns Sy 10 Ns % Pq ulong
+.It Sy zfs_arc_dnode_reduce_percent Ns = Ns Sy 10 Ns % Pq u64
Percentage of ARC dnodes to try to scan in response to demand for non-metadata
when the number of bytes consumed by dnodes exceeds
.Sy zfs_arc_dnode_limit .
@@ -613,7 +613,7 @@ Setting this value to
.Sy 0
will disable the throttle.
.
-.It Sy zfs_arc_max Ns = Ns Sy 0 Ns B Pq ulong
+.It Sy zfs_arc_max Ns = Ns Sy 0 Ns B Pq u64
Max size of ARC in bytes.
If
.Sy 0 ,
@@ -642,7 +642,7 @@ the free buffers in order to stay below the
This value should not need to be tuned but is available to facilitate
performance analysis.
.
-.It Sy zfs_arc_meta_limit Ns = Ns Sy 0 Ns B Pq ulong
+.It Sy zfs_arc_meta_limit Ns = Ns Sy 0 Ns B Pq u64
The maximum allowed size in bytes that metadata buffers are allowed to
consume in the ARC.
When this limit is reached, metadata buffers will be reclaimed,
@@ -658,14 +658,14 @@ of the ARC may be used for metadata.
This value my be changed dynamically, except that must be set to an explicit value
.Pq cannot be set back to Sy 0 .
.
-.It Sy zfs_arc_meta_limit_percent Ns = Ns Sy 75 Ns % Pq ulong
+.It Sy zfs_arc_meta_limit_percent Ns = Ns Sy 75 Ns % Pq u64
Percentage of ARC buffers that can be used for metadata.
.Pp
See also
.Sy zfs_arc_meta_limit ,
which serves a similar purpose but has a higher priority if nonzero.
.
-.It Sy zfs_arc_meta_min Ns = Ns Sy 0 Ns B Pq ulong
+.It Sy zfs_arc_meta_min Ns = Ns Sy 0 Ns B Pq u64
The minimum allowed size in bytes that metadata buffers may consume in
the ARC.
.
@@ -691,7 +691,7 @@ additional data buffers may be evicted if required
to evict the required number of metadata buffers.
.El
.
-.It Sy zfs_arc_min Ns = Ns Sy 0 Ns B Pq ulong
+.It Sy zfs_arc_min Ns = Ns Sy 0 Ns B Pq u64
Min size of ARC in bytes.
.No If set to Sy 0 , arc_c_min
will default to consuming the larger of
@@ -718,7 +718,7 @@ but that was not proven to be useful.
Number of missing top-level vdevs which will be allowed during
pool import (only in read-only mode).
.
-.It Sy zfs_max_nvlist_src_size Ns = Sy 0 Pq ulong
+.It Sy zfs_max_nvlist_src_size Ns = Sy 0 Pq u64
Maximum size in bytes allowed to be passed as
.Sy zc_nvlist_src_size
for ioctls on
@@ -822,7 +822,7 @@ even with a small average compressed block size of ~8 KiB.
The parameter can be set to 0 (zero) to disable the limit,
and only applies on Linux.
.
-.It Sy zfs_arc_sys_free Ns = Ns Sy 0 Ns B Pq ulong
+.It Sy zfs_arc_sys_free Ns = Ns Sy 0 Ns B Pq u64
The target number of bytes the ARC should leave as free memory on the system.
If zero, equivalent to the bigger of
.Sy 512 KiB No and Sy all_system_memory/64 .
@@ -866,12 +866,12 @@ bytes of memory and if the obsolete space map object uses more than
bytes on-disk.
The condensing process is an attempt to save memory by removing obsolete mappings.
.
-.It Sy zfs_condense_max_obsolete_bytes Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq ulong
+.It Sy zfs_condense_max_obsolete_bytes Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64
Only attempt to condense indirect vdev mappings if the on-disk size
of the obsolete space map object is greater than this number of bytes
.Pq see Sy zfs_condense_indirect_vdevs_enable .
.
-.It Sy zfs_condense_min_mapping_bytes Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq ulong
+.It Sy zfs_condense_min_mapping_bytes Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq u64
Minimum size vdev mapping to attempt to condense
.Pq see Sy zfs_condense_indirect_vdevs_enable .
.
@@ -927,21 +927,21 @@ This can be used to facilitate automatic fail-over
to a properly configured fail-over partner.
.El
.
-.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1 min Pc Pq int
+.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1 min Pc Pq u64
Check time in milliseconds.
This defines the frequency at which we check for hung I/O requests
and potentially invoke the
.Sy zfs_deadman_failmode
behavior.
.
-.It Sy zfs_deadman_synctime_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq ulong
+.It Sy zfs_deadman_synctime_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq u64
Interval in milliseconds after which the deadman is triggered and also
the interval after which a pool sync operation is considered to be "hung".
Once this limit is exceeded the deadman will be invoked every
.Sy zfs_deadman_checktime_ms
milliseconds until the pool sync completes.
.
-.It Sy zfs_deadman_ziotime_ms Ns = Ns Sy 300000 Ns ms Po 5 min Pc Pq ulong
+.It Sy zfs_deadman_ziotime_ms Ns = Ns Sy 300000 Ns ms Po 5 min Pc Pq u64
Interval in milliseconds after which the deadman is triggered and an
individual I/O operation is considered to be "hung".
As long as the operation remains "hung",
@@ -994,15 +994,15 @@ same object.
Rate limit delay and deadman zevents (which report slow I/O operations) to this many per
second.
.
-.It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq ulong
+.It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64
Upper-bound limit for unflushed metadata changes to be held by the
log spacemap in memory, in bytes.
.
-.It Sy zfs_unflushed_max_mem_ppm Ns = Ns Sy 1000 Ns ppm Po 0.1% Pc Pq ulong
+.It Sy zfs_unflushed_max_mem_ppm Ns = Ns Sy 1000 Ns ppm Po 0.1% Pc Pq u64
Part of overall system memory that ZFS allows to be used
for unflushed metadata changes by the log spacemap, in millionths.
.
-.It Sy zfs_unflushed_log_block_max Ns = Ns Sy 131072 Po 128k Pc Pq ulong
+.It Sy zfs_unflushed_log_block_max Ns = Ns Sy 131072 Po 128k Pc Pq u64
Describes the maximum number of log spacemap blocks allowed for each pool.
The default value means that the space in all the log spacemaps
can add up to no more than
@@ -1030,17 +1030,17 @@ one extra logical I/O issued.
This is the reason why this tunable is exposed in terms of blocks rather
than space used.
.
-.It Sy zfs_unflushed_log_block_min Ns = Ns Sy 1000 Pq ulong
+.It Sy zfs_unflushed_log_block_min Ns = Ns Sy 1000 Pq u64
If the number of metaslabs is small and our incoming rate is high,
we could get into a situation that we are flushing all our metaslabs every TXG.
Thus we always allow at least this many log blocks.
.
-.It Sy zfs_unflushed_log_block_pct Ns = Ns Sy 400 Ns % Pq ulong
+.It Sy zfs_unflushed_log_block_pct Ns = Ns Sy 400 Ns % Pq u64
Tunable used to determine the number of blocks that can be used for
the spacemap log, expressed as a percentage of the total number of
unflushed metaslabs in the pool.
.
-.It Sy zfs_unflushed_log_txg_max Ns = Ns Sy 1000 Pq ulong
+.It Sy zfs_unflushed_log_txg_max Ns = Ns Sy 1000 Pq u64
Tunable limiting maximum time in TXGs any metaslab may remain unflushed.
It effectively limits maximum number of unflushed per-TXG spacemap logs
that need to be read after unclean pool export.
@@ -1060,6 +1060,7 @@ will be deleted asynchronously, while smaller files are deleted synchronously.
Decreasing this value will reduce the time spent in an
.Xr unlink 2
system call, at the expense of a longer delay before the freed space is available.
+This only applies on Linux.
.
.It Sy zfs_dirty_data_max Ns = Pq int
Determines the dirty space limit in bytes.
@@ -1185,10 +1186,10 @@ benchmark results by reading this kstat file:
.It Sy zfs_free_bpobj_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
Enable/disable the processing of the free_bpobj object.
.
-.It Sy zfs_async_block_max_blocks Ns = Ns Sy ULONG_MAX Po unlimited Pc Pq ulong
+.It Sy zfs_async_block_max_blocks Ns = Ns Sy UINT64_MAX Po unlimited Pc Pq u64
Maximum number of blocks freed in a single TXG.
.
-.It Sy zfs_max_async_dedup_frees Ns = Ns Sy 100000 Po 10^5 Pc Pq ulong
+.It Sy zfs_max_async_dedup_frees Ns = Ns Sy 100000 Po 10^5 Pc Pq u64
Maximum number of dedup blocks freed in a single TXG.
.
.It Sy zfs_vdev_async_read_max_active Ns = Ns Sy 3 Pq uint
@@ -1248,6 +1249,13 @@ Ideally, this will be at least the sum of each queue's
.Sy max_active .
.No See Sx ZFS I/O SCHEDULER .
.
+.It Sy zfs_vdev_open_timeout_ms Ns = Ns Sy 1000 Pq uint
+Timeout value to wait before determining a device is missing
+during import.
+This is helpful for transient missing paths due
+to links being briefly removed and recreated in response to
+udev events.
+.
.It Sy zfs_vdev_rebuild_max_active Ns = Ns Sy 3 Pq uint
Maximum sequential resilver I/O operations active to each device.
.No See Sx ZFS I/O SCHEDULER .
@@ -1337,6 +1345,19 @@ as fuller devices will tend to be slower than empty devices.
Also see
.Sy zio_dva_throttle_enabled .
.
+.It Sy zfs_vdev_failfast_mask Ns = Ns Sy 1 Pq uint
+Defines if the driver should retire on a given error type.
+The following options may be bitwise-ored together:
+.TS
+box;
+lbz r l l .
+ Value Name Description
+_
+ 1 Device No driver retries on device errors
+ 2 Transport No driver retries on transport errors.
+ 4 Driver No driver retries on driver errors.
+.TE
+.
.It Sy zfs_expire_snapshot Ns = Ns Sy 300 Ns s Pq int
Time before expiring
.Pa .zfs/snapshot .
@@ -1356,7 +1377,7 @@ The following flags may be bitwise-ored together:
.TS
box;
lbz r l l .
- Value Symbolic Name Description
+ Value Name Description
_
1 ZFS_DEBUG_DPRINTF Enable dprintf entries in the debug log.
* 2 ZFS_DEBUG_DBUF_VERIFY Enable extra dbuf verifications.
@@ -1444,22 +1465,22 @@ Similar to
.Sy zfs_free_min_time_ms ,
but for cleanup of old indirection records for removed vdevs.
.
-.It Sy zfs_immediate_write_sz Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq long
+.It Sy zfs_immediate_write_sz Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq s64
Largest data block to write to the ZIL.
Larger blocks will be treated as if the dataset being written to had the
.Sy logbias Ns = Ns Sy throughput
property set.
.
-.It Sy zfs_initialize_value Ns = Ns Sy 16045690984833335022 Po 0xDEADBEEFDEADBEEE Pc Pq ulong
+.It Sy zfs_initialize_value Ns = Ns Sy 16045690984833335022 Po 0xDEADBEEFDEADBEEE Pc Pq u64
Pattern written to vdev free space by
.Xr zpool-initialize 8 .
.
-.It Sy zfs_initialize_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong
+.It Sy zfs_initialize_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
Size of writes used by
.Xr zpool-initialize 8 .
This option is used by the test suite.
.
-.It Sy zfs_livelist_max_entries Ns = Ns Sy 500000 Po 5*10^5 Pc Pq ulong
+.It Sy zfs_livelist_max_entries Ns = Ns Sy 500000 Po 5*10^5 Pc Pq u64
The threshold size (in block pointers) at which we create a new sub-livelist.
Larger sublists are more costly from a memory perspective but the fewer
sublists there are, the lower the cost of insertion.
@@ -1498,11 +1519,11 @@ executing the open context condensing work in
.Fn spa_livelist_condense_cb .
This option is used by the test suite to trigger race conditions.
.
-.It Sy zfs_lua_max_instrlimit Ns = Ns Sy 100000000 Po 10^8 Pc Pq ulong
+.It Sy zfs_lua_max_instrlimit Ns = Ns Sy 100000000 Po 10^8 Pc Pq u64
The maximum execution time limit that can be set for a ZFS channel program,
specified as a number of Lua instructions.
.
-.It Sy zfs_lua_max_memlimit Ns = Ns Sy 104857600 Po 100 MiB Pc Pq ulong
+.It Sy zfs_lua_max_memlimit Ns = Ns Sy 104857600 Po 100 MiB Pc Pq u64
The maximum memory limit that can be set for a ZFS channel program, specified
in bytes.
.
@@ -1511,11 +1532,11 @@ The maximum depth of nested datasets.
This value can be tuned temporarily to
fix existing datasets that exceed the predefined limit.
.
-.It Sy zfs_max_log_walking Ns = Ns Sy 5 Pq ulong
+.It Sy zfs_max_log_walking Ns = Ns Sy 5 Pq u64
The number of past TXGs that the flushing algorithm of the log spacemap
feature uses to estimate incoming log blocks.
.
-.It Sy zfs_max_logsm_summary_length Ns = Ns Sy 10 Pq ulong
+.It Sy zfs_max_logsm_summary_length Ns = Ns Sy 10 Pq u64
Maximum number of rows allowed in the summary of the spacemap log.
.
.It Sy zfs_max_recordsize Ns = Ns Sy 16777216 Po 16 MiB Pc Pq uint
@@ -1534,7 +1555,7 @@ regardless of this setting.
Allow datasets received with redacted send/receive to be mounted.
Normally disabled because these datasets may be missing key data.
.
-.It Sy zfs_min_metaslabs_to_flush Ns = Ns Sy 1 Pq ulong
+.It Sy zfs_min_metaslabs_to_flush Ns = Ns Sy 1 Pq u64
Minimum number of metaslabs to flush per dirty TXG.
.
.It Sy zfs_metaslab_fragmentation_threshold Ns = Ns Sy 70 Ns % Pq uint
@@ -1584,7 +1605,7 @@ into the special allocation class.
Historical statistics for this many latest multihost updates will be available in
.Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /multihost .
.
-.It Sy zfs_multihost_interval Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq ulong
+.It Sy zfs_multihost_interval Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq u64
Used to control the frequency of multihost writes which are performed when the
.Sy multihost
pool property is on.
@@ -1677,7 +1698,7 @@ prefetched during a pool traversal, like
.Nm zfs Cm send
or other data crawling operations.
.
-.It Sy zfs_per_txg_dirty_frees_percent Ns = Ns Sy 30 Ns % Pq ulong
+.It Sy zfs_per_txg_dirty_frees_percent Ns = Ns Sy 30 Ns % Pq u64
Control percentage of dirtied indirect blocks from frees allowed into one TXG.
After this threshold is crossed, additional frees will wait until the next TXG.
.Sy 0 No disables this throttle.
@@ -1705,7 +1726,7 @@ Disable QAT hardware acceleration for AES-GCM encryption.
May be unset after the ZFS modules have been loaded to initialize the QAT
hardware as long as support is compiled in and the QAT driver is present.
.
-.It Sy zfs_vnops_read_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq long
+.It Sy zfs_vnops_read_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
Bytes to read per chunk.
.
.It Sy zfs_read_history Ns = Ns Sy 0 Pq uint
@@ -1715,7 +1736,7 @@ Historical statistics for this many latest reads will be available in
.It Sy zfs_read_history_hits Ns = Ns Sy 0 Ns | Ns 1 Pq int
Include cache hits in read history
.
-.It Sy zfs_rebuild_max_segment Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong
+.It Sy zfs_rebuild_max_segment Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
Maximum read segment size to issue when sequentially resilvering a
top-level vdev.
.
@@ -1725,7 +1746,7 @@ completes in order to verify the checksums of all blocks which have been
resilvered.
This is enabled by default and strongly recommended.
.
-.It Sy zfs_rebuild_vdev_limit Ns = Ns Sy 33554432 Ns B Po 32 MiB Pc Pq ulong
+.It Sy zfs_rebuild_vdev_limit Ns = Ns Sy 33554432 Ns B Po 32 MiB Pc Pq u64
Maximum amount of I/O that can be concurrently issued for a sequential
resilver per leaf device, given in bytes.
.
@@ -2166,7 +2187,7 @@ if a volatile out-of-order write cache is enabled.
Disable intent logging replay.
Can be disabled for recovery from corrupted ZIL.
.
-.It Sy zil_slog_bulk Ns = Ns Sy 786432 Ns B Po 768 KiB Pc Pq ulong
+.It Sy zil_slog_bulk Ns = Ns Sy 786432 Ns B Po 768 KiB Pc Pq u64
Limit SLOG write size per commit executed with synchronous priority.
Any writes above that will be executed with lower (asynchronous) priority
to limit potential SLOG device abuse by single active ZIL writer.
@@ -2276,7 +2297,7 @@ systems with a very large number of zvols.
.It Sy zvol_major Ns = Ns Sy 230 Pq uint
Major number for zvol block devices.
.
-.It Sy zvol_max_discard_blocks Ns = Ns Sy 16384 Pq ulong
+.It Sy zvol_max_discard_blocks Ns = Ns Sy 16384 Pq long
Discard (TRIM) operations done on zvols will be done in batches of this
many blocks, where block size is determined by the
.Sy volblocksize
@@ -2378,6 +2399,10 @@ Defines zvol block devices behaviour when
.It Sy 3
.No equivalent to Sy none
.El
+.
+.It Sy zvol_enforce_quotas Ns = Ns Sy 0 Ns | Ns 1 Pq uint
+Enable strict ZVOL quota enforcement.
+The strict quota enforcement may have a performance impact.
.El
.
.Sh ZFS I/O SCHEDULER
diff --git a/sys/contrib/openzfs/man/man7/vdevprops.7 b/sys/contrib/openzfs/man/man7/vdevprops.7
index b98bda064c70..af5d26f6b486 100644
--- a/sys/contrib/openzfs/man/man7/vdevprops.7
+++ b/sys/contrib/openzfs/man/man7/vdevprops.7
@@ -20,7 +20,7 @@
.\"
.\" Copyright (c) 2021 Klara, Inc.
.\"
-.Dd November 27, 2021
+.Dd October 30, 2022
.Dt VDEVPROPS 7
.Os
.
@@ -121,6 +121,9 @@ dataset.
A text comment up to 8192 characters long
.It Sy bootsize
The amount of space to reserve for the EFI system partition
+.It Sy failfast
+If this device should propage BIO errors back to ZFS, used to disable
+failfast.
.It Sy path
The path to the device for this vdev
.It Sy allocating
diff --git a/sys/contrib/openzfs/man/man7/zfsprops.7 b/sys/contrib/openzfs/man/man7/zfsprops.7
index 93a7bfcc865f..0b7711da88a6 100644
--- a/sys/contrib/openzfs/man/man7/zfsprops.7
+++ b/sys/contrib/openzfs/man/man7/zfsprops.7
@@ -36,8 +36,9 @@
.\" Copyright 2018 Nexenta Systems, Inc.
.\" Copyright 2019 Joyent, Inc.
.\" Copyright (c) 2019, Kjeld Schouten-Lebbing
+.\" Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
.\"
-.Dd May 24, 2021
+.Dd July 21, 2022
.Dt ZFSPROPS 7
.Os
.
@@ -1454,7 +1455,7 @@ affects only files created afterward; existing files are unaffected.
.Pp
This property can also be referred to by its shortened column name,
.Sy recsize .
-.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most
+.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most Ns | Ns Sy some Ns | Ns Sy none
Controls what types of metadata are stored redundantly.
ZFS stores an extra copy of metadata, so that if a single block is corrupted,
the amount of user data lost is limited.
@@ -1486,7 +1487,7 @@ When set to
ZFS stores an extra copy of most types of metadata.
This can improve performance of random writes, because less metadata must be
written.
-In practice, at worst about 100 blocks
+In practice, at worst about 1000 blocks
.Po of
.Sy recordsize
bytes each
@@ -1495,6 +1496,17 @@ of user data can be lost if a single on-disk block is corrupt.
The exact behavior of which metadata blocks are stored redundantly may change in
future releases.
.Pp
+When set to
+.Sy some ,
+ZFS stores an extra copy of only critical metadata.
+This can improve file create performance since less metadata needs to be written.
+If a single on-disk block is corrupt, at worst a single user file can be lost.
+.Pp
+When set to
+.Sy none ,
+ZFS does not store any copies of metadata redundantly.
+If a single on-disk block is corrupt, an entire dataset can be lost.
+.Pp
The default value is
.Sy all .
.It Sy refquota Ns = Ns Ar size Ns | Ns Sy none
diff --git a/sys/contrib/openzfs/man/man8/zfs-hold.8 b/sys/contrib/openzfs/man/man8/zfs-hold.8
index c2c7b7dc26a3..4bc36cb47fc2 100644
--- a/sys/contrib/openzfs/man/man8/zfs-hold.8
+++ b/sys/contrib/openzfs/man/man8/zfs-hold.8
@@ -43,7 +43,7 @@
.Ar tag Ar snapshot Ns …
.Nm zfs
.Cm holds
-.Op Fl rH
+.Op Fl rHp
.Ar snapshot Ns …
.Nm zfs
.Cm release
@@ -76,7 +76,7 @@ of all descendent file systems.
.It Xo
.Nm zfs
.Cm holds
-.Op Fl rH
+.Op Fl rHp
.Ar snapshot Ns …
.Xc
Lists all existing user references for the given snapshot or snapshots.
@@ -86,6 +86,8 @@ Lists the holds that are set on the named descendent snapshots, in addition to
listing the holds on the named snapshot.
.It Fl H
Do not print headers, use tab-delimited output.
+.It Fl p
+Prints holds timestamps as unix epoch timestamps.
.El
.It Xo
.Nm zfs
diff --git a/sys/contrib/openzfs/man/man8/zstream.8 b/sys/contrib/openzfs/man/man8/zstream.8
index dd5342000216..c09a20ad20b6 100644
--- a/sys/contrib/openzfs/man/man8/zstream.8
+++ b/sys/contrib/openzfs/man/man8/zstream.8
@@ -20,7 +20,7 @@
.\"
.\" Copyright (c) 2020 by Delphix. All rights reserved.
.\"
-.Dd March 25, 2022
+.Dd October 4, 2022
.Dt ZSTREAM 8
.Os
.
@@ -43,6 +43,10 @@
.Nm
.Cm token
.Ar resume_token
+.Nm
+.Cm recompress
+.Op Fl l Ar level
+.Ar algorithm
.
.Sh DESCRIPTION
The
@@ -96,6 +100,7 @@ Specify the object number and byte offset of each record that you wish to
decompress.
Optionally specify the compression type.
Valid compression types include
+.Sy off ,
.Sy gzip ,
.Sy lz4 ,
.Sy lzjb ,
@@ -108,6 +113,11 @@ Every record for that object beginning at that offset will be decompressed, if
possible.
It may not be possible, because the record may be corrupted in some but not
all of the stream's snapshots.
+Specifying a compression type of
+.Sy off
+will change the stream's metadata accordingly, without attempting decompression.
+This can be useful if the record is already uncompressed but the metadata
+insists otherwise.
The repaired stream will be written to standard output.
.Bl -tag -width "-v"
.It Fl v
@@ -143,6 +153,27 @@ Therefore, a deduplicated send stream can be received by running:
Verbose.
Print summary of converted records.
.El
+.It Xo
+.Nm
+.Cm recompress
+.Op Fl l Ar level
+.Ar algorithm
+.Xc
+Recompresses a send stream, provided on standard input, using the provided
+algorithm and optional level, and writes the modified stream to standard output.
+All WRITE records in the send stream will be recompressed, unless they fail
+to result in size reduction compared to being left uncompressed.
+The provided algorithm can be any valid value to the
+.Nm compress
+property.
+Note that encrypted send streams cannot be recompressed.
+.Bl -tag -width "-l"
+.It Fl l Ar level
+Specifies compression level.
+Only needed for algorithms where the level is not implied as part of the name
+of the algorithm (e.g. gzip-3 does not require it, while zstd does, if a
+non-default level is desired).
+.El
.El
.
.Sh EXAMPLES
diff --git a/sys/contrib/openzfs/module/Kbuild.in b/sys/contrib/openzfs/module/Kbuild.in
index 7a20e6ee4615..581d50e64b42 100644
--- a/sys/contrib/openzfs/module/Kbuild.in
+++ b/sys/contrib/openzfs/module/Kbuild.in
@@ -150,12 +150,8 @@ $(addprefix $(obj)/icp/,$(ICP_OBJS) $(ICP_OBJS_X86) $(ICP_OBJS_X86_64) \
$(addprefix $(obj)/icp/,$(ICP_OBJS) $(ICP_OBJS_X86) $(ICP_OBJS_X86_64) \
$(ICP_OBJS_ARM64) $(ICP_OBJS_PPC_PPC64)) : ccflags-y += -I$(icp_include)
-# Suppress objtool "can't find jump dest instruction at" warnings. They
-# are caused by the constants which are defined in the text section of the
-# assembly file using .byte instructions (e.g. bswap_mask). The objtool
-# utility tries to interpret them as opcodes and obviously fails doing so.
+# Suppress objtool "return with modified stack frame" warnings.
OBJECT_FILES_NON_STANDARD_aesni-gcm-x86_64.o := y
-OBJECT_FILES_NON_STANDARD_ghash-x86_64.o := y
# Suppress objtool "unsupported stack pointer realignment" warnings. We are
# not using a DRAP register while aligning the stack to a 64 byte boundary.
diff --git a/sys/contrib/openzfs/module/icp/algs/blake3/blake3.c b/sys/contrib/openzfs/module/icp/algs/blake3/blake3.c
index 5f7018598820..604e05847ee6 100644
--- a/sys/contrib/openzfs/module/icp/algs/blake3/blake3.c
+++ b/sys/contrib/openzfs/module/icp/algs/blake3/blake3.c
@@ -189,9 +189,7 @@ static void chunk_state_update(const blake3_ops_t *ops,
input_len -= BLAKE3_BLOCK_LEN;
}
- size_t take = chunk_state_fill_buf(ctx, input, input_len);
- input += take;
- input_len -= take;
+ chunk_state_fill_buf(ctx, input, input_len);
}
static output_t chunk_state_output(const blake3_chunk_state_t *ctx)
diff --git a/sys/contrib/openzfs/module/icp/algs/modes/ccm.c b/sys/contrib/openzfs/module/icp/algs/modes/ccm.c
index ed5498dafaa1..4a8bb9bbc2c8 100644
--- a/sys/contrib/openzfs/module/icp/algs/modes/ccm.c
+++ b/sys/contrib/openzfs/module/icp/algs/modes/ccm.c
@@ -67,7 +67,6 @@ ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
return (CRYPTO_SUCCESS);
}
- lastp = (uint8_t *)ctx->ccm_cb;
crypto_init_ptrs(out, &iov_or_mp, &offset);
mac_buf = (uint8_t *)ctx->ccm_mac_buf;
diff --git a/sys/contrib/openzfs/module/icp/algs/modes/ctr.c b/sys/contrib/openzfs/module/icp/algs/modes/ctr.c
index c116ba3662ba..db6b1c71d5cd 100644
--- a/sys/contrib/openzfs/module/icp/algs/modes/ctr.c
+++ b/sys/contrib/openzfs/module/icp/algs/modes/ctr.c
@@ -60,7 +60,6 @@ ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length,
return (CRYPTO_SUCCESS);
}
- lastp = (uint8_t *)ctx->ctr_cb;
crypto_init_ptrs(out, &iov_or_mp, &offset);
do {
diff --git a/sys/contrib/openzfs/module/icp/algs/modes/gcm.c b/sys/contrib/openzfs/module/icp/algs/modes/gcm.c
index ca328d54a7e6..16ef14b8ccaf 100644
--- a/sys/contrib/openzfs/module/icp/algs/modes/gcm.c
+++ b/sys/contrib/openzfs/module/icp/algs/modes/gcm.c
@@ -118,7 +118,6 @@ gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *ctx, char *data, size_t length,
return (CRYPTO_SUCCESS);
}
- lastp = (uint8_t *)ctx->gcm_cb;
crypto_init_ptrs(out, &iov_or_mp, &offset);
gops = gcm_impl_get_ops();
diff --git a/sys/contrib/openzfs/module/icp/algs/modes/modes.c b/sys/contrib/openzfs/module/icp/algs/modes/modes.c
index b98db0ac14ec..2d1b5ff1a919 100644
--- a/sys/contrib/openzfs/module/icp/algs/modes/modes.c
+++ b/sys/contrib/openzfs/module/icp/algs/modes/modes.c
@@ -106,8 +106,10 @@ crypto_get_ptrs(crypto_data_t *out, void **iov_or_mp, offset_t *current_offset,
} else {
/* one block spans two iovecs */
*out_data_1_len = iov_len - offset;
- if (vec_idx == zfs_uio_iovcnt(uio))
+ if (vec_idx == zfs_uio_iovcnt(uio)) {
+ *out_data_2 = NULL;
return;
+ }
vec_idx++;
zfs_uio_iov_at_index(uio, vec_idx, &iov_base, &iov_len);
*out_data_2 = (uint8_t *)iov_base;
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/aes/aes_amd64.S b/sys/contrib/openzfs/module/icp/asm-x86_64/aes/aes_amd64.S
index f546e8933be1..a0525dd464f5 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/aes/aes_amd64.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/aes/aes_amd64.S
@@ -704,6 +704,7 @@ enc_tab:
ENTRY_NP(aes_encrypt_amd64)
+ ENDBR
#ifdef GLADMAN_INTERFACE
// Original interface
sub $[4*8], %rsp // gnu/linux/opensolaris binary interface
@@ -809,6 +810,7 @@ dec_tab:
ENTRY_NP(aes_decrypt_amd64)
+ ENDBR
#ifdef GLADMAN_INTERFACE
// Original interface
sub $[4*8], %rsp // gnu/linux/opensolaris binary interface
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx2.S b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx2.S
index f4d9cb766d46..cb08430b81ed 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx2.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx2.S
@@ -30,16 +30,6 @@
#define _ASM
#include <sys/asm_linkage.h>
-#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
-#if __has_include(<cet.h>)
-#include <cet.h>
-#endif
-#endif
-
-#if !defined(_CET_ENDBR)
-#define _CET_ENDBR
-#endif
-
.intel_syntax noprefix
.global zfs_blake3_hash_many_avx2
.text
@@ -47,7 +37,7 @@
.type zfs_blake3_hash_many_avx2,@function
.p2align 6
zfs_blake3_hash_many_avx2:
- _CET_ENDBR
+ ENDBR
push r15
push r14
push r13
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx512.S b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx512.S
index 71b5715c88c1..960406ea2c01 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx512.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_avx512.S
@@ -30,16 +30,6 @@
#define _ASM
#include <sys/asm_linkage.h>
-#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
-#if __has_include(<cet.h>)
-#include <cet.h>
-#endif
-#endif
-
-#if !defined(_CET_ENDBR)
-#define _CET_ENDBR
-#endif
-
.intel_syntax noprefix
.global zfs_blake3_hash_many_avx512
.global zfs_blake3_compress_in_place_avx512
@@ -52,7 +42,7 @@
.p2align 6
zfs_blake3_hash_many_avx512:
- _CET_ENDBR
+ ENDBR
push r15
push r14
push r13
@@ -2409,7 +2399,7 @@ zfs_blake3_hash_many_avx512:
jmp 4b
.p2align 6
zfs_blake3_compress_in_place_avx512:
- _CET_ENDBR
+ ENDBR
vmovdqu xmm0, xmmword ptr [rdi]
vmovdqu xmm1, xmmword ptr [rdi+0x10]
movzx eax, r8b
@@ -2491,7 +2481,7 @@ zfs_blake3_compress_in_place_avx512:
.p2align 6
zfs_blake3_compress_xof_avx512:
- _CET_ENDBR
+ ENDBR
vmovdqu xmm0, xmmword ptr [rdi]
vmovdqu xmm1, xmmword ptr [rdi+0x10]
movzx eax, r8b
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse2.S b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse2.S
index 20689a7dcef5..c4290aaa8faf 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse2.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse2.S
@@ -30,16 +30,6 @@
#define _ASM
#include <sys/asm_linkage.h>
-#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
-#if __has_include(<cet.h>)
-#include <cet.h>
-#endif
-#endif
-
-#if !defined(_CET_ENDBR)
-#define _CET_ENDBR
-#endif
-
.intel_syntax noprefix
.global zfs_blake3_hash_many_sse2
.global zfs_blake3_compress_in_place_sse2
@@ -52,7 +42,7 @@
.p2align 6
zfs_blake3_hash_many_sse2:
- _CET_ENDBR
+ ENDBR
push r15
push r14
push r13
@@ -2050,7 +2040,7 @@ zfs_blake3_hash_many_sse2:
.p2align 6
zfs_blake3_compress_in_place_sse2:
- _CET_ENDBR
+ ENDBR
movups xmm0, xmmword ptr [rdi]
movups xmm1, xmmword ptr [rdi+0x10]
movaps xmm2, xmmword ptr [BLAKE3_IV+rip]
@@ -2161,7 +2151,7 @@ zfs_blake3_compress_in_place_sse2:
.p2align 6
zfs_blake3_compress_xof_sse2:
- _CET_ENDBR
+ ENDBR
movups xmm0, xmmword ptr [rdi]
movups xmm1, xmmword ptr [rdi+0x10]
movaps xmm2, xmmword ptr [BLAKE3_IV+rip]
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse41.S b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse41.S
index c5975a4f0877..45b90cc9ed89 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse41.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/blake3/blake3_sse41.S
@@ -30,16 +30,6 @@
#define _ASM
#include <sys/asm_linkage.h>
-#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
-#if __has_include(<cet.h>)
-#include <cet.h>
-#endif
-#endif
-
-#if !defined(_CET_ENDBR)
-#define _CET_ENDBR
-#endif
-
.intel_syntax noprefix
.global zfs_blake3_compress_in_place_sse41
.global zfs_blake3_compress_xof_sse41
@@ -52,7 +42,7 @@
.p2align 6
zfs_blake3_hash_many_sse41:
- _CET_ENDBR
+ ENDBR
push r15
push r14
push r13
@@ -1812,7 +1802,7 @@ zfs_blake3_hash_many_sse41:
jmp 4b
.p2align 6
zfs_blake3_compress_in_place_sse41:
- _CET_ENDBR
+ ENDBR
movups xmm0, xmmword ptr [rdi]
movups xmm1, xmmword ptr [rdi+0x10]
movaps xmm2, xmmword ptr [BLAKE3_IV+rip]
@@ -1911,7 +1901,7 @@ zfs_blake3_compress_in_place_sse41:
RET
.p2align 6
zfs_blake3_compress_xof_sse41:
- _CET_ENDBR
+ ENDBR
movups xmm0, xmmword ptr [rdi]
movups xmm1, xmmword ptr [rdi+0x10]
movaps xmm2, xmmword ptr [BLAKE3_IV+rip]
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S b/sys/contrib/openzfs/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S
index 70e419c2e4ab..cf17b3768712 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/modes/aesni-gcm-x86_64.S
@@ -47,6 +47,9 @@
#if defined(__x86_64__) && defined(HAVE_AVX) && \
defined(HAVE_AES) && defined(HAVE_PCLMULQDQ)
+#define _ASM
+#include <sys/asm_linkage.h>
+
.extern gcm_avx_can_use_movbe
.text
@@ -56,6 +59,7 @@
.align 32
_aesni_ctr32_ghash_6x:
.cfi_startproc
+ ENDBR
vmovdqu 32(%r11),%xmm2
subq $6,%rdx
vpxor %xmm4,%xmm4,%xmm4
@@ -363,7 +367,7 @@ _aesni_ctr32_ghash_6x:
vpxor 16+8(%rsp),%xmm8,%xmm8
vpxor %xmm4,%xmm8,%xmm8
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x
#endif /* ifdef HAVE_MOVBE */
@@ -372,6 +376,7 @@ _aesni_ctr32_ghash_6x:
.align 32
_aesni_ctr32_ghash_no_movbe_6x:
.cfi_startproc
+ ENDBR
vmovdqu 32(%r11),%xmm2
subq $6,%rdx
vpxor %xmm4,%xmm4,%xmm4
@@ -691,7 +696,7 @@ _aesni_ctr32_ghash_no_movbe_6x:
vpxor 16+8(%rsp),%xmm8,%xmm8
vpxor %xmm4,%xmm8,%xmm8
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size _aesni_ctr32_ghash_no_movbe_6x,.-_aesni_ctr32_ghash_no_movbe_6x
@@ -700,6 +705,7 @@ _aesni_ctr32_ghash_no_movbe_6x:
.align 32
aesni_gcm_decrypt:
.cfi_startproc
+ ENDBR
xorq %r10,%r10
cmpq $0x60,%rdx
jb .Lgcm_dec_abort
@@ -810,13 +816,14 @@ aesni_gcm_decrypt:
.cfi_def_cfa_register %rsp
.Lgcm_dec_abort:
movq %r10,%rax
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size aesni_gcm_decrypt,.-aesni_gcm_decrypt
.type _aesni_ctr32_6x,@function
.align 32
_aesni_ctr32_6x:
.cfi_startproc
+ ENDBR
vmovdqu 0-128(%rcx),%xmm4
vmovdqu 32(%r11),%xmm2
leaq -2(%rbp),%r13 // ICP uses 10,12,14 not 9,11,13 for rounds.
@@ -880,7 +887,7 @@ _aesni_ctr32_6x:
vmovups %xmm14,80(%rsi)
leaq 96(%rsi),%rsi
- .byte 0xf3,0xc3
+ RET
.align 32
.Lhandle_ctr32_2:
vpshufb %xmm0,%xmm1,%xmm6
@@ -911,6 +918,7 @@ _aesni_ctr32_6x:
.align 32
aesni_gcm_encrypt:
.cfi_startproc
+ ENDBR
xorq %r10,%r10
cmpq $288,%rdx
jb .Lgcm_enc_abort
@@ -1186,7 +1194,7 @@ aesni_gcm_encrypt:
.cfi_def_cfa_register %rsp
.Lgcm_enc_abort:
movq %r10,%rax
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size aesni_gcm_encrypt,.-aesni_gcm_encrypt
@@ -1239,6 +1247,7 @@ atomic_toggle_boolean_nv:
RET
.size atomic_toggle_boolean_nv,.-atomic_toggle_boolean_nv
+.pushsection .rodata
.align 64
.Lbswap_mask:
.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
@@ -1252,6 +1261,7 @@ atomic_toggle_boolean_nv:
.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
+.popsection
/* Mark the stack non-executable. */
#if defined(__linux__) && defined(__ELF__)
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/modes/ghash-x86_64.S b/sys/contrib/openzfs/module/icp/asm-x86_64/modes/ghash-x86_64.S
index 90cc36b43a78..bf3724a23eae 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/modes/ghash-x86_64.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/modes/ghash-x86_64.S
@@ -97,6 +97,9 @@
#if defined(__x86_64__) && defined(HAVE_AVX) && \
defined(HAVE_AES) && defined(HAVE_PCLMULQDQ)
+#define _ASM
+#include <sys/asm_linkage.h>
+
.text
.globl gcm_gmult_clmul
@@ -104,6 +107,7 @@
.align 16
gcm_gmult_clmul:
.cfi_startproc
+ ENDBR
.L_gmult_clmul:
movdqu (%rdi),%xmm0
movdqa .Lbswap_mask(%rip),%xmm5
@@ -149,7 +153,7 @@ gcm_gmult_clmul:
pxor %xmm1,%xmm0
.byte 102,15,56,0,197
movdqu %xmm0,(%rdi)
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size gcm_gmult_clmul,.-gcm_gmult_clmul
@@ -158,6 +162,7 @@ gcm_gmult_clmul:
.align 32
gcm_init_htab_avx:
.cfi_startproc
+ ENDBR
vzeroupper
vmovdqu (%rsi),%xmm2
@@ -262,7 +267,7 @@ gcm_init_htab_avx:
vmovdqu %xmm5,-16(%rdi)
vzeroupper
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size gcm_init_htab_avx,.-gcm_init_htab_avx
@@ -271,6 +276,7 @@ gcm_init_htab_avx:
.align 32
gcm_gmult_avx:
.cfi_startproc
+ ENDBR
jmp .L_gmult_clmul
.cfi_endproc
.size gcm_gmult_avx,.-gcm_gmult_avx
@@ -279,6 +285,7 @@ gcm_gmult_avx:
.align 32
gcm_ghash_avx:
.cfi_startproc
+ ENDBR
vzeroupper
vmovdqu (%rdi),%xmm10
@@ -649,9 +656,11 @@ gcm_ghash_avx:
vpshufb %xmm13,%xmm10,%xmm10
vmovdqu %xmm10,(%rdi)
vzeroupper
- .byte 0xf3,0xc3
+ RET
.cfi_endproc
.size gcm_ghash_avx,.-gcm_ghash_avx
+
+.pushsection .rodata
.align 64
.Lbswap_mask:
.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
@@ -705,6 +714,7 @@ gcm_ghash_avx:
.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
+.popsection
/* Mark the stack non-executable. */
#if defined(__linux__) && defined(__ELF__)
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S
index 1391bd59a017..60d34b4a3be0 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha256_impl.S
@@ -84,6 +84,7 @@ SHA256TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num)
ENTRY_NP(SHA256TransformBlocks)
.cfi_startproc
+ ENDBR
movq %rsp, %rax
.cfi_def_cfa_register %rax
push %rbx
diff --git a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S
index e61e96957bc6..ed7fb362a1ac 100644
--- a/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S
+++ b/sys/contrib/openzfs/module/icp/asm-x86_64/sha2/sha512_impl.S
@@ -85,6 +85,7 @@ SHA512TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num)
ENTRY_NP(SHA512TransformBlocks)
.cfi_startproc
+ ENDBR
movq %rsp, %rax
.cfi_def_cfa_register %rax
push %rbx
diff --git a/sys/contrib/openzfs/module/icp/include/sys/ia32/asm_linkage.h b/sys/contrib/openzfs/module/icp/include/sys/ia32/asm_linkage.h
index 58964c5d4497..e3e769ffd858 100644
--- a/sys/contrib/openzfs/module/icp/include/sys/ia32/asm_linkage.h
+++ b/sys/contrib/openzfs/module/icp/include/sys/ia32/asm_linkage.h
@@ -30,9 +30,29 @@
#include <sys/stack.h>
#include <sys/trap.h>
-#if defined(__linux__) && defined(CONFIG_SLS)
-#define RET ret; int3
-#else
+#if defined(_KERNEL) && defined(__linux__)
+#include <linux/linkage.h>
+#endif
+
+#ifndef ENDBR
+#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
+/* CSTYLED */
+#if __has_include(<cet.h>)
+
+#include <cet.h>
+
+#ifdef _CET_ENDBR
+#define ENDBR _CET_ENDBR
+#endif /* _CET_ENDBR */
+
+#endif /* <cet.h> */
+#endif /* __ELF__ && __CET__ && __has_include */
+#endif /* !ENDBR */
+
+#ifndef ENDBR
+#define ENDBR
+#endif
+#ifndef RET
#define RET ret
#endif
@@ -122,6 +142,7 @@ extern "C" {
* insert the calls to mcount for profiling. ENTRY_NP is identical, but
* never calls mcount.
*/
+#undef ENTRY
#define ENTRY(x) \
.text; \
.align ASM_ENTRY_ALIGN; \
diff --git a/sys/contrib/openzfs/module/icp/io/sha2_mod.c b/sys/contrib/openzfs/module/icp/io/sha2_mod.c
index fadb58b81881..a58f0982c8c0 100644
--- a/sys/contrib/openzfs/module/icp/io/sha2_mod.c
+++ b/sys/contrib/openzfs/module/icp/io/sha2_mod.c
@@ -737,12 +737,15 @@ sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
*/
if (mechanism->cm_type % 3 == 2) {
if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t))
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- PROV_SHA2_GET_DIGEST_LEN(mechanism,
- PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len);
- if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > sha_digest_len)
+ mechanism->cm_param_len != sizeof (ulong_t)) {
ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ } else {
+ PROV_SHA2_GET_DIGEST_LEN(mechanism,
+ PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len);
+ if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len >
+ sha_digest_len)
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ }
}
if (ret != CRYPTO_SUCCESS) {
diff --git a/sys/contrib/openzfs/module/lua/lapi.c b/sys/contrib/openzfs/module/lua/lapi.c
index 726e5c2ad4bb..703cf4cc2a36 100644
--- a/sys/contrib/openzfs/module/lua/lapi.c
+++ b/sys/contrib/openzfs/module/lua/lapi.c
@@ -250,6 +250,8 @@ LUA_API int lua_type (lua_State *L, int idx) {
LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
+ if (t > 8 || t < 0)
+ return "internal_type_error";
return ttypename(t);
}
@@ -442,7 +444,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
case LUA_TTABLE: return hvalue(o);
case LUA_TLCL: return clLvalue(o);
case LUA_TCCL: return clCvalue(o);
- case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
+ case LUA_TLCF: return cast(void *, cast(uintptr_t, fvalue(o)));
case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
diff --git a/sys/contrib/openzfs/module/lua/ldo.c b/sys/contrib/openzfs/module/lua/ldo.c
index 24677596de12..6bef80514ce2 100644
--- a/sys/contrib/openzfs/module/lua/ldo.c
+++ b/sys/contrib/openzfs/module/lua/ldo.c
@@ -452,7 +452,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
}
res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults;
- L->ci = ci = ci->previous; /* back to caller */
+ L->ci = ci->previous; /* back to caller */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
diff --git a/sys/contrib/openzfs/module/lua/setjmp/setjmp_x86_64.S b/sys/contrib/openzfs/module/lua/setjmp/setjmp_x86_64.S
index fd661d72eedf..7e13fea05dda 100644
--- a/sys/contrib/openzfs/module/lua/setjmp/setjmp_x86_64.S
+++ b/sys/contrib/openzfs/module/lua/setjmp/setjmp_x86_64.S
@@ -23,7 +23,15 @@
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
+#if defined(_KERNEL) && defined(__linux__)
+#include <linux/linkage.h>
+#endif
+
+#ifndef RET
+#define RET ret
+#endif
+#undef ENTRY
#define ENTRY(x) \
.text; \
.align 8; \
@@ -34,13 +42,6 @@ x:
#define SET_SIZE(x) \
.size x, [.-x]
-
-#if defined(__linux__) && defined(CONFIG_SLS)
-#define RET ret; int3
-#else
-#define RET ret
-#endif
-
/*
* Setjmp and longjmp implement non-local gotos using state vectors
* type label_t.
diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c b/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c
index b692ccdf232a..04a5d2869d1b 100644
--- a/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c
+++ b/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c
@@ -1654,13 +1654,13 @@ acl_trivial_create(mode_t mode, boolean_t isdir, ace_t **acl, int *count)
*/
int
ace_trivial_common(void *acep, int aclcnt,
- uint64_t (*walk)(void *, uint64_t, int aclcnt,
+ uintptr_t (*walk)(void *, uintptr_t, int aclcnt,
uint16_t *, uint16_t *, uint32_t *))
{
uint16_t flags;
uint32_t mask;
uint16_t type;
- uint64_t cookie = 0;
+ uintptr_t cookie = 0;
while ((cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask))) {
switch (flags & ACE_TYPE_FLAGS) {
diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c
index 523e10ff6936..eb74720c984a 100644
--- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c
+++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_string.c
@@ -105,3 +105,33 @@ kmem_strfree(char *str)
ASSERT3P(str, !=, NULL);
kmem_free(str, strlen(str) + 1);
}
+
+/*
+ * kmem_scnprintf() will return the number of characters that it would have
+ * printed whenever it is limited by value of the size variable, rather than
+ * the number of characters that it did print. This can cause misbehavior on
+ * subsequent uses of the return value, so we define a safe version that will
+ * return the number of characters actually printed, minus the NULL format
+ * character. Subsequent use of this by the safe string functions is safe
+ * whether it is snprintf(), strlcat() or strlcpy().
+ */
+
+int
+kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ /* Make the 0 case a no-op so that we do not return -1 */
+ if (size == 0)
+ return (0);
+
+ va_start(ap, fmt);
+ n = vsnprintf(str, size, fmt, ap);
+ va_end(ap);
+
+ if (n >= size)
+ n = size - 1;
+
+ return (n);
+}
diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c
index ff11f5d7acb8..a07098afc5b4 100644
--- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c
+++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_vfs.c
@@ -125,7 +125,6 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
struct vfsconf *vfsp;
struct mount *mp;
vnode_t *vp, *mvp;
- struct ucred *pcr, *tcr;
int error;
ASSERT_VOP_ELOCKED(*vpp, "mount_snapshot");
@@ -195,18 +194,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
*/
mp->mnt_flag |= MNT_IGNORE;
- /*
- * XXX: This is evil, but we can't mount a snapshot as a regular user.
- * XXX: Is is safe when snapshot is mounted from within a jail?
- */
- tcr = td->td_ucred;
- pcr = td->td_proc->p_ucred;
- td->td_ucred = kcred;
- td->td_proc->p_ucred = kcred;
error = VFS_MOUNT(mp);
- td->td_ucred = tcr;
- td->td_proc->p_ucred = pcr;
-
if (error != 0) {
/*
* Clear VI_MOUNT and decrement the use count "atomically",
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c b/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c
index 0a19fbba717d..bb3cbc39ec75 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c
@@ -124,7 +124,9 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
int vecnum;
zfs_iocparm_t *zp;
zfs_cmd_t *zc;
+#ifdef ZFS_LEGACY_SUPPORT
zfs_cmd_legacy_t *zcl;
+#endif
int rc, error;
void *uaddr;
@@ -133,7 +135,9 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
zp = (void *)arg;
uaddr = (void *)(uintptr_t)zp->zfs_cmd;
error = 0;
+#ifdef ZFS_LEGACY_SUPPORT
zcl = NULL;
+#endif
if (len != sizeof (zfs_iocparm_t)) {
printf("len %d vecnum: %d sizeof (zfs_cmd_t) %ju\n",
@@ -142,6 +146,7 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
}
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
+#ifdef ZFS_LEGACY_SUPPORT
/*
* Remap ioctl code for legacy user binaries
*/
@@ -157,22 +162,29 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
goto out;
}
zfs_cmd_legacy_to_ozfs(zcl, zc);
- } else if (copyin(uaddr, zc, sizeof (zfs_cmd_t))) {
+ } else
+#endif
+ if (copyin(uaddr, zc, sizeof (zfs_cmd_t))) {
error = SET_ERROR(EFAULT);
goto out;
}
error = zfsdev_ioctl_common(vecnum, zc, 0);
+#ifdef ZFS_LEGACY_SUPPORT
if (zcl) {
zfs_cmd_ozfs_to_legacy(zc, zcl);
rc = copyout(zcl, uaddr, sizeof (*zcl));
- } else {
+ } else
+#endif
+ {
rc = copyout(zc, uaddr, sizeof (*zc));
}
if (error == 0 && rc != 0)
error = SET_ERROR(EFAULT);
out:
+#ifdef ZFS_LEGACY_SUPPORT
if (zcl)
kmem_free(zcl, sizeof (zfs_cmd_legacy_t));
+#endif
kmem_free(zc, sizeof (zfs_cmd_t));
MPASS(tsd_get(rrw_tsd_key) == NULL);
return (error);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c
index 980bb1c0f941..48af1eaf8ea7 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c
@@ -137,11 +137,11 @@ SYSCTL_CONST_STRING(_vfs_zfs_version, OID_AUTO, module, CTLFLAG_RD,
/* arc.c */
int
-param_set_arc_long(SYSCTL_HANDLER_ARGS)
+param_set_arc_u64(SYSCTL_HANDLER_ARGS)
{
int err;
- err = sysctl_handle_long(oidp, arg1, 0, req);
+ err = sysctl_handle_64(oidp, arg1, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
@@ -171,7 +171,7 @@ param_set_arc_max(SYSCTL_HANDLER_ARGS)
int err;
val = zfs_arc_max;
- err = sysctl_handle_long(oidp, &val, 0, req);
+ err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (SET_ERROR(err));
@@ -203,7 +203,7 @@ param_set_arc_min(SYSCTL_HANDLER_ARGS)
int err;
val = zfs_arc_min;
- err = sysctl_handle_long(oidp, &val, 0, req);
+ err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (SET_ERROR(err));
@@ -599,7 +599,7 @@ param_set_multihost_interval(SYSCTL_HANDLER_ARGS)
{
int err;
- err = sysctl_handle_long(oidp, &zfs_multihost_interval, 0, req);
+ err = sysctl_handle_64(oidp, &zfs_multihost_interval, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
@@ -676,7 +676,7 @@ param_set_deadman_synctime(SYSCTL_HANDLER_ARGS)
int err;
val = zfs_deadman_synctime_ms;
- err = sysctl_handle_long(oidp, &val, 0, req);
+ err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
zfs_deadman_synctime_ms = val;
@@ -693,7 +693,7 @@ param_set_deadman_ziotime(SYSCTL_HANDLER_ARGS)
int err;
val = zfs_deadman_ziotime_ms;
- err = sysctl_handle_long(oidp, &val, 0, req);
+ err = sysctl_handle_64(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (err);
zfs_deadman_ziotime_ms = val;
@@ -761,11 +761,11 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, space_map_ibs, CTLFLAG_RWTUN,
int
param_set_min_auto_ashift(SYSCTL_HANDLER_ARGS)
{
- uint64_t val;
+ int val;
int err;
val = zfs_vdev_min_auto_ashift;
- err = sysctl_handle_64(oidp, &val, 0, req);
+ err = sysctl_handle_int(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (SET_ERROR(err));
@@ -779,20 +779,20 @@ param_set_min_auto_ashift(SYSCTL_HANDLER_ARGS)
/* BEGIN CSTYLED */
SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift,
- CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
+ CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_vdev_min_auto_ashift, sizeof (zfs_vdev_min_auto_ashift),
- param_set_min_auto_ashift, "QU",
+ param_set_min_auto_ashift, "IU",
"Min ashift used when creating new top-level vdev. (LEGACY)");
/* END CSTYLED */
int
param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS)
{
- uint64_t val;
+ int val;
int err;
val = zfs_vdev_max_auto_ashift;
- err = sysctl_handle_64(oidp, &val, 0, req);
+ err = sysctl_handle_int(oidp, &val, 0, req);
if (err != 0 || req->newptr == NULL)
return (SET_ERROR(err));
@@ -806,9 +806,9 @@ param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS)
/* BEGIN CSTYLED */
SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift,
- CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
+ CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_vdev_max_auto_ashift, sizeof (zfs_vdev_max_auto_ashift),
- param_set_max_auto_ashift, "QU",
+ param_set_max_auto_ashift, "IU",
"Max ashift used when optimizing for logical -> physical sector size on"
" new top-level vdevs. (LEGACY)");
/* END CSTYLED */
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c
index 73cc6aa48c0b..a65dfec86caf 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_file.c
@@ -40,8 +40,8 @@
static taskq_t *vdev_file_taskq;
-static unsigned long vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
-static unsigned long vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
+static uint_t vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
+static uint_t vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
void
vdev_file_init(void)
@@ -350,7 +350,7 @@ vdev_ops_t vdev_disk_ops = {
#endif
-ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, UINT, ZMOD_RW,
"Logical ashift for file-based devices");
-ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, UINT, ZMOD_RW,
"Physical ashift for file-based devices");
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 963102f3b62a..16bcd338de21 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c
@@ -631,8 +631,8 @@ zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who,
return (NULL);
}
-static uint64_t
-zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
+static uintptr_t
+zfs_ace_walk(void *datap, uintptr_t cookie, int aclcnt,
uint16_t *flags, uint16_t *type, uint32_t *mask)
{
(void) aclcnt;
@@ -642,7 +642,7 @@ zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
acep = zfs_acl_next_ace(aclp, acep, &who, mask,
flags, type);
- return ((uint64_t)(uintptr_t)acep);
+ return ((uintptr_t)acep);
}
/*
@@ -1133,6 +1133,7 @@ zfs_acl_data_locator(void **dataptr, uint32_t *length, uint32_t buflen,
cb->cb_acl_node = list_next(&cb->cb_aclp->z_acl,
cb->cb_acl_node);
}
+ ASSERT3P(cb->cb_acl_node, !=, NULL);
*dataptr = cb->cb_acl_node->z_acldata;
*length = cb->cb_acl_node->z_size;
}
@@ -1618,7 +1619,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
*/
int
zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
- vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
+ vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns)
{
int error;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
@@ -1788,7 +1789,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
if (mask == 0)
return (SET_ERROR(ENOSYS));
- if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
+ if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr, NULL)))
return (error);
mutex_enter(&zp->z_acl_lock);
@@ -1951,7 +1952,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
if (zp->z_pflags & ZFS_IMMUTABLE)
return (SET_ERROR(EPERM));
- if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
+ if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL)))
return (error);
error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp,
@@ -2340,7 +2341,8 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
* can define any form of access.
*/
int
-zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
+zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr,
+ zuserns_t *mnt_ns)
{
uint32_t working_mode;
int error;
@@ -2470,9 +2472,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
* NFSv4-style ZFS ACL format and call zfs_zaccess()
*/
int
-zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
+zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr,
+ zuserns_t *mnt_ns)
{
- return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
+ return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr,
+ mnt_ns));
}
/*
@@ -2483,7 +2487,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
{
int v4_mode = zfs_unix_to_v4(mode >> 6);
- return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
+ return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL));
}
static int
@@ -2539,7 +2543,7 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp,
*
*/
int
-zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
+zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns)
{
uint32_t dzp_working_mode = 0;
uint32_t zp_working_mode = 0;
@@ -2626,7 +2630,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
int
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
- znode_t *tzp, cred_t *cr)
+ znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns)
{
int add_perm;
int error;
@@ -2646,7 +2650,8 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
* to another.
*/
if (ZTOV(szp)->v_type == VDIR && ZTOV(sdzp) != ZTOV(tdzp)) {
- if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr)))
+ if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr,
+ mnt_ns)))
return (error);
}
@@ -2656,19 +2661,19 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
* If that succeeds then check for add_file/add_subdir permissions
*/
- if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
+ if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns)))
return (error);
/*
* If we have a tzp, see if we can delete it?
*/
- if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr)))
+ if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns)))
return (error);
/*
* Now check for add permissions
*/
- error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
+ error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns);
return (error);
}
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 778e4151656d..07232086d52b 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c
@@ -809,7 +809,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xvpp, cred_t *cr)
*xvpp = NULL;
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
- &acl_ids)) != 0)
+ &acl_ids, NULL)) != 0)
return (error);
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, 0)) {
zfs_acl_ids_free(&acl_ids);
@@ -955,7 +955,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
(ZTOV(zp)->v_type == VREG &&
- zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
+ zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0))
return (0);
else
return (secpolicy_vnode_remove(ZTOV(zp), cr));
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c
index d495cc0dc3f1..3ddffec91e83 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/cmn_err.h>
#include <sys/zfs_ioctl_compat.h>
+#ifdef ZFS_LEGACY_SUPPORT
enum zfs_ioc_legacy {
ZFS_IOC_LEGACY_NONE = -1,
ZFS_IOC_LEGACY_FIRST = 0,
@@ -319,7 +320,7 @@ zfs_ioctl_legacy_to_ozfs(int request)
int
zfs_ioctl_ozfs_to_legacy(int request)
{
- if (request > ZFS_IOC_LAST)
+ if (request >= ZFS_IOC_LAST)
return (-1);
if (request > ZFS_IOC_PLATFORM) {
@@ -361,3 +362,4 @@ zfs_cmd_ozfs_to_legacy(zfs_cmd_t *src, zfs_cmd_legacy_t *dst)
sizeof (zfs_cmd_t) - 8 - offsetof(zfs_cmd_t, zc_sendobj));
dst->zc_jailid = src->zc_zoneid;
}
+#endif /* ZFS_LEGACY_SUPPORT */
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 4cb7f63b5230..b4c122bdf4c8 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
@@ -63,6 +63,7 @@
#include <sys/dmu_objset.h>
#include <sys/dsl_dir.h>
#include <sys/jail.h>
+#include <sys/osd.h>
#include <ufs/ufs/quota.h>
#include <sys/zfs_quota.h>
@@ -88,6 +89,20 @@ int zfs_debug_level;
SYSCTL_INT(_vfs_zfs, OID_AUTO, debug, CTLFLAG_RWTUN, &zfs_debug_level, 0,
"Debug level");
+struct zfs_jailparam {
+ int mount_snapshot;
+};
+
+static struct zfs_jailparam zfs_jailparam0 = {
+ .mount_snapshot = 0,
+};
+
+static int zfs_jailparam_slot;
+
+SYSCTL_JAIL_PARAM_SYS_NODE(zfs, CTLFLAG_RW, "Jail ZFS parameters");
+SYSCTL_JAIL_PARAM(_zfs, mount_snapshot, CTLTYPE_INT | CTLFLAG_RW, "I",
+ "Allow mounting snapshots in the .zfs directory for unjailed datasets");
+
SYSCTL_NODE(_vfs_zfs, OID_AUTO, version, CTLFLAG_RD, 0, "ZFS versions");
static int zfs_version_acl = ZFS_ACL_VERSION;
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, acl, CTLFLAG_RD, &zfs_version_acl, 0,
@@ -1298,7 +1313,7 @@ zfs_mount(vfs_t *vfsp)
char *osname;
int error = 0;
int canwrite;
- bool checkpointrewind;
+ bool checkpointrewind, isctlsnap = false;
if (vfs_getopt(vfsp->mnt_optnew, "from", (void **)&osname, NULL))
return (SET_ERROR(EINVAL));
@@ -1313,6 +1328,7 @@ zfs_mount(vfs_t *vfsp)
}
fetch_osname_options(osname, &checkpointrewind);
+ isctlsnap = (zfsctl_is_node(mvp) && strchr(osname, '@') != NULL);
/*
* Check for mount privilege?
@@ -1321,7 +1337,9 @@ zfs_mount(vfs_t *vfsp)
* we have local permission to allow it
*/
error = secpolicy_fs_mount(cr, mvp, vfsp);
- if (error) {
+ if (error && isctlsnap) {
+ secpolicy_fs_mount_clearopts(cr, vfsp);
+ } else if (error) {
if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) != 0)
goto out;
@@ -1358,8 +1376,27 @@ zfs_mount(vfs_t *vfsp)
*/
if (!INGLOBALZONE(curproc) &&
(!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
- error = SET_ERROR(EPERM);
- goto out;
+ boolean_t mount_snapshot = B_FALSE;
+
+ /*
+ * Snapshots may be mounted in .zfs for unjailed datasets
+ * if allowed by the jail param zfs.mount_snapshot.
+ */
+ if (isctlsnap) {
+ struct prison *pr;
+ struct zfs_jailparam *zjp;
+
+ pr = curthread->td_ucred->cr_prison;
+ mtx_lock(&pr->pr_mtx);
+ zjp = osd_jail_get(pr, zfs_jailparam_slot);
+ mtx_unlock(&pr->pr_mtx);
+ if (zjp && zjp->mount_snapshot)
+ mount_snapshot = B_TRUE;
+ }
+ if (!mount_snapshot) {
+ error = SET_ERROR(EPERM);
+ goto out;
+ }
}
vfsp->vfs_flag |= MNT_NFS4ACLS;
@@ -2316,3 +2353,236 @@ zfsvfs_update_fromname(const char *oldname, const char *newname)
mtx_unlock(&mountlist_mtx);
}
#endif
+
+/*
+ * Find a prison with ZFS info.
+ * Return the ZFS info and the (locked) prison.
+ */
+static struct zfs_jailparam *
+zfs_jailparam_find(struct prison *spr, struct prison **prp)
+{
+ struct prison *pr;
+ struct zfs_jailparam *zjp;
+
+ for (pr = spr; ; pr = pr->pr_parent) {
+ mtx_lock(&pr->pr_mtx);
+ if (pr == &prison0) {
+ zjp = &zfs_jailparam0;
+ break;
+ }
+ zjp = osd_jail_get(pr, zfs_jailparam_slot);
+ if (zjp != NULL)
+ break;
+ mtx_unlock(&pr->pr_mtx);
+ }
+ *prp = pr;
+
+ return (zjp);
+}
+
+/*
+ * Ensure a prison has its own ZFS info. If zjpp is non-null, point it to the
+ * ZFS info and lock the prison.
+ */
+static void
+zfs_jailparam_alloc(struct prison *pr, struct zfs_jailparam **zjpp)
+{
+ struct prison *ppr;
+ struct zfs_jailparam *zjp, *nzjp;
+ void **rsv;
+
+ /* If this prison already has ZFS info, return that. */
+ zjp = zfs_jailparam_find(pr, &ppr);
+ if (ppr == pr)
+ goto done;
+
+ /*
+ * Allocate a new info record. Then check again, in case something
+ * changed during the allocation.
+ */
+ mtx_unlock(&ppr->pr_mtx);
+ nzjp = malloc(sizeof (struct zfs_jailparam), M_PRISON, M_WAITOK);
+ rsv = osd_reserve(zfs_jailparam_slot);
+ zjp = zfs_jailparam_find(pr, &ppr);
+ if (ppr == pr) {
+ free(nzjp, M_PRISON);
+ osd_free_reserved(rsv);
+ goto done;
+ }
+ /* Inherit the initial values from the ancestor. */
+ mtx_lock(&pr->pr_mtx);
+ (void) osd_jail_set_reserved(pr, zfs_jailparam_slot, rsv, nzjp);
+ (void) memcpy(nzjp, zjp, sizeof (*zjp));
+ zjp = nzjp;
+ mtx_unlock(&ppr->pr_mtx);
+done:
+ if (zjpp != NULL)
+ *zjpp = zjp;
+ else
+ mtx_unlock(&pr->pr_mtx);
+}
+
+/*
+ * Jail OSD methods for ZFS VFS info.
+ */
+static int
+zfs_jailparam_create(void *obj, void *data)
+{
+ struct prison *pr = obj;
+ struct vfsoptlist *opts = data;
+ int jsys;
+
+ if (vfs_copyopt(opts, "zfs", &jsys, sizeof (jsys)) == 0 &&
+ jsys == JAIL_SYS_INHERIT)
+ return (0);
+ /*
+ * Inherit a prison's initial values from its parent
+ * (different from JAIL_SYS_INHERIT which also inherits changes).
+ */
+ zfs_jailparam_alloc(pr, NULL);
+ return (0);
+}
+
+static int
+zfs_jailparam_get(void *obj, void *data)
+{
+ struct prison *ppr, *pr = obj;
+ struct vfsoptlist *opts = data;
+ struct zfs_jailparam *zjp;
+ int jsys, error;
+
+ zjp = zfs_jailparam_find(pr, &ppr);
+ jsys = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT;
+ error = vfs_setopt(opts, "zfs", &jsys, sizeof (jsys));
+ if (error != 0 && error != ENOENT)
+ goto done;
+ if (jsys == JAIL_SYS_NEW) {
+ error = vfs_setopt(opts, "zfs.mount_snapshot",
+ &zjp->mount_snapshot, sizeof (zjp->mount_snapshot));
+ if (error != 0 && error != ENOENT)
+ goto done;
+ } else {
+ /*
+ * If this prison is inheriting its ZFS info, report
+ * empty/zero parameters.
+ */
+ static int mount_snapshot = 0;
+
+ error = vfs_setopt(opts, "zfs.mount_snapshot",
+ &mount_snapshot, sizeof (mount_snapshot));
+ if (error != 0 && error != ENOENT)
+ goto done;
+ }
+ error = 0;
+done:
+ mtx_unlock(&ppr->pr_mtx);
+ return (error);
+}
+
+static int
+zfs_jailparam_set(void *obj, void *data)
+{
+ struct prison *pr = obj;
+ struct prison *ppr;
+ struct vfsoptlist *opts = data;
+ int error, jsys, mount_snapshot;
+
+ /* Set the parameters, which should be correct. */
+ error = vfs_copyopt(opts, "zfs", &jsys, sizeof (jsys));
+ if (error == ENOENT)
+ jsys = -1;
+ error = vfs_copyopt(opts, "zfs.mount_snapshot", &mount_snapshot,
+ sizeof (mount_snapshot));
+ if (error == ENOENT)
+ mount_snapshot = -1;
+ else
+ jsys = JAIL_SYS_NEW;
+ if (jsys == JAIL_SYS_NEW) {
+ /* "zfs=new" or "zfs.*": the prison gets its own ZFS info. */
+ struct zfs_jailparam *zjp;
+
+ /*
+ * A child jail cannot have more permissions than its parent
+ */
+ if (pr->pr_parent != &prison0) {
+ zjp = zfs_jailparam_find(pr->pr_parent, &ppr);
+ mtx_unlock(&ppr->pr_mtx);
+ if (zjp->mount_snapshot < mount_snapshot) {
+ return (EPERM);
+ }
+ }
+ zfs_jailparam_alloc(pr, &zjp);
+ if (mount_snapshot != -1)
+ zjp->mount_snapshot = mount_snapshot;
+ mtx_unlock(&pr->pr_mtx);
+ } else {
+ /* "zfs=inherit": inherit the parent's ZFS info. */
+ mtx_lock(&pr->pr_mtx);
+ osd_jail_del(pr, zfs_jailparam_slot);
+ mtx_unlock(&pr->pr_mtx);
+ }
+ return (0);
+}
+
+static int
+zfs_jailparam_check(void *obj __unused, void *data)
+{
+ struct vfsoptlist *opts = data;
+ int error, jsys, mount_snapshot;
+
+ /* Check that the parameters are correct. */
+ error = vfs_copyopt(opts, "zfs", &jsys, sizeof (jsys));
+ if (error != ENOENT) {
+ if (error != 0)
+ return (error);
+ if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT)
+ return (EINVAL);
+ }
+ error = vfs_copyopt(opts, "zfs.mount_snapshot", &mount_snapshot,
+ sizeof (mount_snapshot));
+ if (error != ENOENT) {
+ if (error != 0)
+ return (error);
+ if (mount_snapshot != 0 && mount_snapshot != 1)
+ return (EINVAL);
+ }
+ return (0);
+}
+
+static void
+zfs_jailparam_destroy(void *data)
+{
+
+ free(data, M_PRISON);
+}
+
+static void
+zfs_jailparam_sysinit(void *arg __unused)
+{
+ struct prison *pr;
+ osd_method_t methods[PR_MAXMETHOD] = {
+ [PR_METHOD_CREATE] = zfs_jailparam_create,
+ [PR_METHOD_GET] = zfs_jailparam_get,
+ [PR_METHOD_SET] = zfs_jailparam_set,
+ [PR_METHOD_CHECK] = zfs_jailparam_check,
+ };
+
+ zfs_jailparam_slot = osd_jail_register(zfs_jailparam_destroy, methods);
+ /* Copy the defaults to any existing prisons. */
+ sx_slock(&allprison_lock);
+ TAILQ_FOREACH(pr, &allprison, pr_list)
+ zfs_jailparam_alloc(pr, NULL);
+ sx_sunlock(&allprison_lock);
+}
+
+static void
+zfs_jailparam_sysuninit(void *arg __unused)
+{
+
+ osd_jail_deregister(zfs_jailparam_slot);
+}
+
+SYSINIT(zfs_jailparam_sysinit, SI_SUB_DRIVERS, SI_ORDER_ANY,
+ zfs_jailparam_sysinit, NULL);
+SYSUNINIT(zfs_jailparam_sysuninit, SI_SUB_DRIVERS, SI_ORDER_ANY,
+ zfs_jailparam_sysuninit, NULL);
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 fae390a148d6..8a350ab4985c 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
@@ -837,7 +837,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
/*
* Do we have permission to get into attribute directory?
*/
- error = zfs_zaccess(zp, ACE_EXECUTE, 0, B_FALSE, cr);
+ error = zfs_zaccess(zp, ACE_EXECUTE, 0, B_FALSE, cr, NULL);
if (error) {
vrele(ZTOV(zp));
}
@@ -856,7 +856,8 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
cnp->cn_flags &= ~NOEXECCHECK;
} else
#endif
- if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr,
+ NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -1036,6 +1037,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
* flag - large file flag [UNUSED].
* ct - caller context
* vsecp - ACL to be set
+ * mnt_ns - Unused on FreeBSD
*
* OUT: vpp - vnode of created or trunc'd entry.
*
@@ -1047,7 +1049,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
*/
int
zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
- znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp)
+ znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp, zuserns_t *mnt_ns)
{
(void) excl, (void) mode, (void) flag;
znode_t *zp;
@@ -1110,7 +1112,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
* Create a new file object and update the directory
* to reference it.
*/
- if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
goto out;
}
@@ -1126,7 +1128,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
}
if ((error = zfs_acl_ids_create(dzp, 0, vap,
- cr, vsecp, &acl_ids)) != 0)
+ cr, vsecp, &acl_ids, NULL)) != 0)
goto out;
if (S_ISREG(vap->va_mode) || S_ISDIR(vap->va_mode))
@@ -1231,7 +1233,7 @@ zfs_remove_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr)
xattr_obj = 0;
xzp = NULL;
- if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
+ if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
goto out;
}
@@ -1387,6 +1389,7 @@ zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags)
* ct - caller context
* flags - case flags
* vsecp - ACL to be set
+ * mnt_ns - Unused on FreeBSD
*
* OUT: vpp - vnode of created directory.
*
@@ -1398,7 +1401,7 @@ zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags)
*/
int
zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
- cred_t *cr, int flags, vsecattr_t *vsecp)
+ cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns)
{
(void) flags, (void) vsecp;
znode_t *zp;
@@ -1447,7 +1450,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
}
if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
- NULL, &acl_ids)) != 0) {
+ NULL, &acl_ids, NULL)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -1468,7 +1471,8 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
}
ASSERT3P(zp, ==, NULL);
- if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr,
+ mnt_ns))) {
zfs_acl_ids_free(&acl_ids);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -1585,7 +1589,7 @@ zfs_rmdir_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr)
zilog = zfsvfs->z_log;
- if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
+ if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
goto out;
}
@@ -1976,7 +1980,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) &&
(vap->va_uid != crgetuid(cr))) {
if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0,
- skipaclchk, cr))) {
+ skipaclchk, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -2142,7 +2146,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
* flags - ATTR_UTIME set if non-default time values provided.
* - ATTR_NOACLCHECK (CIFS context only).
* cr - credentials of caller.
- * ct - caller context
+ * mnt_ns - Unused on FreeBSD
*
* RETURN: 0 on success, error code on failure.
*
@@ -2150,7 +2154,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
* vp - ctime updated, mtime updated if size changed.
*/
int
-zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
+zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns)
{
vnode_t *vp = ZTOV(zp);
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
@@ -2322,7 +2326,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0,
- skipaclchk, cr);
+ skipaclchk, cr, mnt_ns);
}
if (mask & (AT_UID|AT_GID)) {
@@ -2359,7 +2363,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
((idmask == AT_UID) && take_owner) ||
((idmask == AT_GID) && take_group)) {
if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0,
- skipaclchk, cr) == 0) {
+ skipaclchk, cr, mnt_ns) == 0) {
/*
* Remove setuid/setgid for non-privileged users
*/
@@ -2468,7 +2472,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
}
if (mask & AT_MODE) {
- if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) {
+ if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr,
+ mnt_ns) == 0) {
err = secpolicy_setid_setsticky_clear(vp, vap,
&oldva, cr);
if (err) {
@@ -3264,7 +3269,7 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
* Note that if target and source are the same, this can be
* done in a single check.
*/
- if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)))
+ if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, NULL)))
goto out;
if ((*svpp)->v_type == VDIR) {
@@ -3368,11 +3373,6 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
if (error == 0) {
zfs_log_rename(zilog, tx, TX_RENAME, sdzp,
snm, tdzp, tnm, szp);
-
- /*
- * Update path information for the target vnode
- */
- vn_renamepath(tdvp, *svpp, tnm, strlen(tnm));
} else {
/*
* At this point, we have successfully created
@@ -3415,7 +3415,7 @@ out:
int
zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname,
- cred_t *cr, int flags)
+ cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap, zuserns_t *mnt_ns)
{
struct componentname scn, tcn;
vnode_t *sdvp, *tdvp;
@@ -3423,6 +3423,9 @@ zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname,
int error;
svp = tvp = NULL;
+ if (rflags != 0 || wo_vap != NULL)
+ return (SET_ERROR(EINVAL));
+
sdvp = ZTOV(sdzp);
tdvp = ZTOV(tdzp);
error = zfs_lookup_internal(sdzp, sname, &svp, &scn, DELETE);
@@ -3460,6 +3463,7 @@ fail:
* cr - credentials of caller.
* ct - caller context
* flags - case flags
+ * mnt_ns - Unused on FreeBSD
*
* RETURN: 0 on success, error code on failure.
*
@@ -3468,7 +3472,7 @@ fail:
*/
int
zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
- const char *link, znode_t **zpp, cred_t *cr, int flags)
+ const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns)
{
(void) flags;
znode_t *zp;
@@ -3499,7 +3503,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
}
if ((error = zfs_acl_ids_create(dzp, 0,
- vap, cr, NULL, &acl_ids)) != 0) {
+ vap, cr, NULL, &acl_ids, NULL)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -3514,7 +3518,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
return (error);
}
- if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
zfs_acl_ids_free(&acl_ids);
zfs_exit(zfsvfs, FTAG);
return (error);
@@ -3730,7 +3734,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, const char *name, cred_t *cr,
return (SET_ERROR(EPERM));
}
- if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -3831,7 +3835,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
* On Linux we can get here through truncate_range() which
* operates directly on inodes, so we need to check access rights.
*/
- if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -4607,7 +4611,7 @@ zfs_freebsd_create(struct vop_create_args *ap)
*ap->a_vpp = NULL;
rc = zfs_create(VTOZ(ap->a_dvp), cnp->cn_nameptr, vap, 0, mode,
- &zp, cnp->cn_cred, 0 /* flag */, NULL /* vsecattr */);
+ &zp, cnp->cn_cred, 0 /* flag */, NULL /* vsecattr */, NULL);
if (rc == 0)
*ap->a_vpp = ZTOV(zp);
if (zfsvfs->z_use_namecache &&
@@ -4661,7 +4665,7 @@ zfs_freebsd_mkdir(struct vop_mkdir_args *ap)
*ap->a_vpp = NULL;
rc = zfs_mkdir(VTOZ(ap->a_dvp), ap->a_cnp->cn_nameptr, vap, &zp,
- ap->a_cnp->cn_cred, 0, NULL);
+ ap->a_cnp->cn_cred, 0, NULL, NULL);
if (rc == 0)
*ap->a_vpp = ZTOV(zp);
@@ -4914,7 +4918,7 @@ zfs_freebsd_setattr(struct vop_setattr_args *ap)
xvap.xva_vattr.va_mask |= AT_XVATTR;
XVA_SET_REQ(&xvap, XAT_CREATETIME);
}
- return (zfs_setattr(VTOZ(vp), (vattr_t *)&xvap, 0, cred));
+ return (zfs_setattr(VTOZ(vp), (vattr_t *)&xvap, 0, cred, NULL));
}
#ifndef _SYS_SYSPROTO_H_
@@ -4985,7 +4989,7 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap)
*ap->a_vpp = NULL;
rc = zfs_symlink(VTOZ(ap->a_dvp), cnp->cn_nameptr, vap,
- ap->a_target, &zp, cnp->cn_cred, 0 /* flags */);
+ ap->a_target, &zp, cnp->cn_cred, 0 /* flags */, NULL);
if (rc == 0) {
*ap->a_vpp = ZTOV(zp);
ASSERT_VOP_ELOCKED(ZTOV(zp), __func__);
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
index 6345e9e69d30..6c269480cb4b 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
@@ -298,7 +298,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
sharezp->z_is_sa = zfsvfs->z_use_sa;
VERIFY0(zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr,
- kcred, NULL, &acl_ids));
+ kcred, NULL, &acl_ids, NULL));
zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, &zp, &acl_ids);
ASSERT3P(zp, ==, sharezp);
POINTER_INVALIDATE(&sharezp->z_zfsvfs);
@@ -1773,7 +1773,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
rootzp->z_zfsvfs = zfsvfs;
VERIFY0(zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
- cr, NULL, &acl_ids));
+ cr, NULL, &acl_ids, NULL));
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);
@@ -1949,7 +1949,6 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
} else if (error != ENOENT) {
return (error);
}
- error = 0;
for (;;) {
uint64_t pobj;
diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c
index 0410ddd65a5c..c5e745f7d196 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c
@@ -1735,7 +1735,6 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key,
goto error;
if (locked) {
rw_exit(&key->zk_salt_lock);
- locked = B_FALSE;
}
if (authbuf != NULL)
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 8d2a6d77624b..631e020db9c9 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c
@@ -1386,6 +1386,7 @@ zvol_os_create_minor(const char *name)
uint64_t volsize;
uint64_t volmode, hash;
int error;
+ bool replayed_zil = B_FALSE;
ZFS_LOG(1, "Creating ZVOL %s...", name);
hash = zvol_name_hash(name);
@@ -1490,11 +1491,12 @@ zvol_os_create_minor(const char *name)
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)
- zil_destroy(zv->zv_zilog, B_FALSE);
+ replayed_zil = zil_destroy(zv->zv_zilog, B_FALSE);
else
- zil_replay(os, zv, zvol_replay_vector);
+ replayed_zil = zil_replay(os, zv, zvol_replay_vector);
}
- zil_close(zv->zv_zilog);
+ if (replayed_zil)
+ zil_close(zv->zv_zilog);
zv->zv_zilog = NULL;
/* TODO: prefetch for geom tasting */
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 d0461a9f1298..e87954714e3a 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-condvar.c
@@ -37,7 +37,7 @@
#endif
#define MAX_HRTIMEOUT_SLACK_US 1000
-unsigned int spl_schedule_hrtimeout_slack_us = 0;
+static unsigned int spl_schedule_hrtimeout_slack_us = 0;
static int
param_set_hrtimeout_slack(const char *buf, zfs_kernel_param_t *kp)
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-err.c b/sys/contrib/openzfs/module/os/linux/spl/spl-err.c
index 7d3f6127c4af..29781b9515b2 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-err.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-err.c
@@ -32,7 +32,7 @@
* analysis and other such goodies.
* But we would still default to the current default of not to do that.
*/
-unsigned int spl_panic_halt;
+static unsigned int spl_panic_halt;
/* CSTYLED */
module_param(spl_panic_halt, uint, 0644);
MODULE_PARM_DESC(spl_panic_halt, "Cause kernel panic on assertion failures");
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 bc39ece9a427..71eedf635f73 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-generic.c
@@ -23,6 +23,7 @@
* Solaris Porting Layer (SPL) Generic Implementation.
*/
+#include <sys/isa_defs.h>
#include <sys/sysmacros.h>
#include <sys/systeminfo.h>
#include <sys/vmsystm.h>
@@ -48,6 +49,7 @@
#include <sys/cred.h>
#include <sys/vnode.h>
#include <sys/misc.h>
+#include <linux/mod_compat.h>
unsigned long spl_hostid = 0;
EXPORT_SYMBOL(spl_hostid);
@@ -60,10 +62,10 @@ proc_t p0;
EXPORT_SYMBOL(p0);
/*
- * Xorshift Pseudo Random Number Generator based on work by Sebastiano Vigna
+ * xoshiro256++ 1.0 PRNG by David Blackman and Sebastiano Vigna
*
- * "Further scramblings of Marsaglia's xorshift generators"
- * http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf
+ * "Scrambled Linear Pseudorandom Number Generators∗"
+ * https://vigna.di.unimi.it/ftp/papers/ScrambledLinear.pdf
*
* random_get_pseudo_bytes() is an API function on Illumos whose sole purpose
* is to provide bytes containing random numbers. It is mapped to /dev/urandom
@@ -75,66 +77,85 @@ EXPORT_SYMBOL(p0);
* free of atomic instructions.
*
* A consequence of using a fast PRNG is that using random_get_pseudo_bytes()
- * to generate words larger than 128 bits will paradoxically be limited to
- * `2^128 - 1` possibilities. This is because we have a sequence of `2^128 - 1`
- * 128-bit words and selecting the first will implicitly select the second. If
+ * to generate words larger than 256 bits will paradoxically be limited to
+ * `2^256 - 1` possibilities. This is because we have a sequence of `2^256 - 1`
+ * 256-bit words and selecting the first will implicitly select the second. If
* a caller finds this behavior undesirable, random_get_bytes() should be used
* instead.
*
* XXX: Linux interrupt handlers that trigger within the critical section
- * formed by `s[1] = xp[1];` and `xp[0] = s[0];` and call this function will
+ * formed by `s[3] = xp[3];` and `xp[0] = s[0];` and call this function will
* see the same numbers. Nothing in the code currently calls this in an
* interrupt handler, so this is considered to be okay. If that becomes a
* problem, we could create a set of per-cpu variables for interrupt handlers
* and use them when in_interrupt() from linux/preempt_mask.h evaluates to
* true.
*/
-void __percpu *spl_pseudo_entropy;
+static void __percpu *spl_pseudo_entropy;
/*
- * spl_rand_next()/spl_rand_jump() are copied from the following CC-0 licensed
- * file:
+ * rotl()/spl_rand_next()/spl_rand_jump() are copied from the following CC-0
+ * licensed file:
*
- * http://xorshift.di.unimi.it/xorshift128plus.c
+ * https://prng.di.unimi.it/xoshiro256plusplus.c
*/
+static inline uint64_t rotl(const uint64_t x, int k)
+{
+ return ((x << k) | (x >> (64 - k)));
+}
+
static inline uint64_t
spl_rand_next(uint64_t *s)
{
- uint64_t s1 = s[0];
- const uint64_t s0 = s[1];
- s[0] = s0;
- s1 ^= s1 << 23; // a
- s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
- return (s[1] + s0);
+ const uint64_t result = rotl(s[0] + s[3], 23) + s[0];
+
+ const uint64_t t = s[1] << 17;
+
+ s[2] ^= s[0];
+ s[3] ^= s[1];
+ s[1] ^= s[2];
+ s[0] ^= s[3];
+
+ s[2] ^= t;
+
+ s[3] = rotl(s[3], 45);
+
+ return (result);
}
static inline void
spl_rand_jump(uint64_t *s)
{
- static const uint64_t JUMP[] =
- { 0x8a5cd789635d2dff, 0x121fd2155c472f96 };
+ static const uint64_t JUMP[] = { 0x180ec6d33cfd0aba,
+ 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
uint64_t s0 = 0;
uint64_t s1 = 0;
+ uint64_t s2 = 0;
+ uint64_t s3 = 0;
int i, b;
for (i = 0; i < sizeof (JUMP) / sizeof (*JUMP); i++)
for (b = 0; b < 64; b++) {
if (JUMP[i] & 1ULL << b) {
s0 ^= s[0];
s1 ^= s[1];
+ s2 ^= s[2];
+ s3 ^= s[3];
}
(void) spl_rand_next(s);
}
s[0] = s0;
s[1] = s1;
+ s[2] = s2;
+ s[3] = s3;
}
int
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
{
- uint64_t *xp, s[2];
+ uint64_t *xp, s[4];
ASSERT(ptr);
@@ -142,6 +163,8 @@ random_get_pseudo_bytes(uint8_t *ptr, size_t len)
s[0] = xp[0];
s[1] = xp[1];
+ s[2] = xp[2];
+ s[3] = xp[3];
while (len) {
union {
@@ -153,12 +176,22 @@ random_get_pseudo_bytes(uint8_t *ptr, size_t len)
len -= i;
entropy.ui64 = spl_rand_next(s);
+ /*
+ * xoshiro256++ has low entropy lower bytes, so we copy the
+ * higher order bytes first.
+ */
while (i--)
+#ifdef _ZFS_BIG_ENDIAN
*ptr++ = entropy.byte[i];
+#else
+ *ptr++ = entropy.byte[7 - i];
+#endif
}
xp[0] = s[0];
xp[1] = s[1];
+ xp[2] = s[2];
+ xp[3] = s[3];
put_cpu_ptr(spl_pseudo_entropy);
@@ -518,6 +551,29 @@ ddi_copyin(const void *from, void *to, size_t len, int flags)
}
EXPORT_SYMBOL(ddi_copyin);
+#define define_spl_param(type, fmt) \
+int \
+spl_param_get_##type(char *buf, zfs_kernel_param_t *kp) \
+{ \
+ return (scnprintf(buf, PAGE_SIZE, fmt "\n", \
+ *(type *)kp->arg)); \
+} \
+int \
+spl_param_set_##type(const char *buf, zfs_kernel_param_t *kp) \
+{ \
+ return (kstrto##type(buf, 0, (type *)kp->arg)); \
+} \
+const struct kernel_param_ops spl_param_ops_##type = { \
+ .set = spl_param_set_##type, \
+ .get = spl_param_get_##type, \
+}; \
+EXPORT_SYMBOL(spl_param_get_##type); \
+EXPORT_SYMBOL(spl_param_set_##type); \
+EXPORT_SYMBOL(spl_param_ops_##type);
+
+define_spl_param(s64, "%lld")
+define_spl_param(u64, "%llu")
+
/*
* Post a uevent to userspace whenever a new vdev adds to the pool. It is
* necessary to sync blkid information with udev, which zed daemon uses
@@ -741,10 +797,10 @@ spl_kvmem_init(void)
static int __init
spl_random_init(void)
{
- uint64_t s[2];
+ uint64_t s[4];
int i = 0;
- spl_pseudo_entropy = __alloc_percpu(2 * sizeof (uint64_t),
+ spl_pseudo_entropy = __alloc_percpu(4 * sizeof (uint64_t),
sizeof (uint64_t));
if (!spl_pseudo_entropy)
@@ -752,17 +808,19 @@ spl_random_init(void)
get_random_bytes(s, sizeof (s));
- if (s[0] == 0 && s[1] == 0) {
+ if (s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0) {
if (jiffies != 0) {
s[0] = jiffies;
s[1] = ~0 - jiffies;
+ s[2] = ~jiffies;
+ s[3] = jiffies - ~0;
} else {
- (void) memcpy(s, "improbable seed", sizeof (s));
+ (void) memcpy(s, "improbable seed", 16);
}
printk("SPL: get_random_bytes() returned 0 "
"when generating random seed. Setting initial seed to "
- "0x%016llx%016llx.\n", cpu_to_be64(s[0]),
- cpu_to_be64(s[1]));
+ "0x%016llx%016llx%016llx%016llx.\n", cpu_to_be64(s[0]),
+ cpu_to_be64(s[1]), cpu_to_be64(s[2]), cpu_to_be64(s[3]));
}
for_each_possible_cpu(i) {
@@ -772,6 +830,8 @@ spl_random_init(void)
wordp[0] = s[0];
wordp[1] = s[1];
+ wordp[2] = s[2];
+ wordp[3] = s[3];
}
return (0);
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 e355e2bfc3a0..edd04783b363 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
@@ -151,7 +151,7 @@ MODULE_PARM_DESC(spl_kmem_cache_kmem_threads,
struct list_head spl_kmem_cache_list; /* List of caches */
struct rw_semaphore spl_kmem_cache_sem; /* Cache list lock */
-taskq_t *spl_kmem_cache_taskq; /* Task queue for aging / reclaim */
+static taskq_t *spl_kmem_cache_taskq; /* Task queue for aging / reclaim */
static void spl_cache_shrink(spl_kmem_cache_t *skc, void *obj);
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-procfs-list.c b/sys/contrib/openzfs/module/os/linux/spl/spl-procfs-list.c
index a4a24dcae2bd..5e073950d61a 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-procfs-list.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-procfs-list.c
@@ -23,9 +23,9 @@
*/
#include <sys/list.h>
-#include <sys/mutex.h>
#include <sys/procfs_list.h>
#include <linux/proc_fs.h>
+#include <sys/mutex.h>
/*
* A procfs_list is a wrapper around a linked list which implements the seq_file
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c b/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c
index abf4dca585b2..84497359ce2e 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c
@@ -1048,7 +1048,6 @@ taskq_create(const char *name, int threads_arg, pri_t pri,
ASSERT(name != NULL);
ASSERT(minalloc >= 0);
- ASSERT(maxalloc <= INT_MAX);
ASSERT(!(flags & (TASKQ_CPR_SAFE))); /* Unsupported */
/* Scale the number of threads using nthreads as a percentage */
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-zone.c b/sys/contrib/openzfs/module/os/linux/spl/spl-zone.c
index 9421f81bf0c8..b489179f1257 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-zone.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-zone.c
@@ -25,7 +25,6 @@
*/
#include <sys/types.h>
-#include <sys/mutex.h>
#include <sys/sysmacros.h>
#include <sys/kmem.h>
#include <linux/file.h>
@@ -37,6 +36,8 @@
#include <linux/proc_ns.h>
#endif
+#include <sys/mutex.h>
+
static kmutex_t zone_datasets_lock;
static struct list_head zone_datasets;
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 2ab85f8cccd0..16530d82693e 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/abd_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/abd_os.c
@@ -132,7 +132,7 @@ static abd_stats_t abd_stats = {
{ "scatter_sg_table_retry", KSTAT_DATA_UINT64 },
};
-struct {
+static struct {
wmsum_t abdstat_struct_size;
wmsum_t abdstat_linear_cnt;
wmsum_t abdstat_linear_data_size;
@@ -597,10 +597,8 @@ abd_free_chunks(abd_t *abd)
struct scatterlist *sg;
abd_for_each_sg(abd, sg, n, i) {
- for (int j = 0; j < sg->length; j += PAGESIZE) {
- struct page *p = nth_page(sg_page(sg), j >> PAGE_SHIFT);
- umem_free(p, PAGESIZE);
- }
+ struct page *p = nth_page(sg_page(sg), 0);
+ umem_free_aligned(p, PAGESIZE);
}
abd_free_sg_table(abd);
}
@@ -706,7 +704,7 @@ abd_free_zero_scatter(void)
__free_page(abd_zero_page);
#endif /* HAVE_ZERO_PAGE_GPL_ONLY */
#else
- umem_free(abd_zero_page, PAGESIZE);
+ umem_free_aligned(abd_zero_page, PAGESIZE);
#endif /* _KERNEL */
}
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/arc_os.c b/sys/contrib/openzfs/module/os/linux/zfs/arc_os.c
index eaaf7d0bb746..6f730e9ddd83 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/arc_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/arc_os.c
@@ -358,11 +358,11 @@ arc_lowmem_fini(void)
}
int
-param_set_arc_long(const char *buf, zfs_kernel_param_t *kp)
+param_set_arc_u64(const char *buf, zfs_kernel_param_t *kp)
{
int error;
- error = param_set_long(buf, kp);
+ error = spl_param_set_u64(buf, kp);
if (error < 0)
return (SET_ERROR(error));
@@ -374,13 +374,13 @@ param_set_arc_long(const char *buf, zfs_kernel_param_t *kp)
int
param_set_arc_min(const char *buf, zfs_kernel_param_t *kp)
{
- return (param_set_arc_long(buf, kp));
+ return (param_set_arc_u64(buf, kp));
}
int
param_set_arc_max(const char *buf, zfs_kernel_param_t *kp)
{
- return (param_set_arc_long(buf, kp));
+ return (param_set_arc_u64(buf, kp));
}
int
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/mmp_os.c b/sys/contrib/openzfs/module/os/linux/zfs/mmp_os.c
index d502127b5ba3..7e5bd392437e 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/mmp_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/mmp_os.c
@@ -30,7 +30,7 @@ param_set_multihost_interval(const char *val, zfs_kernel_param_t *kp)
{
int ret;
- ret = param_set_ulong(val, kp);
+ ret = spl_param_set_u64(val, kp);
if (ret < 0)
return (ret);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/policy.c b/sys/contrib/openzfs/module/os/linux/zfs/policy.c
index a69618978622..eaf38df864d3 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/policy.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/policy.c
@@ -214,8 +214,10 @@ secpolicy_vnode_setid_retain(struct znode *zp __maybe_unused, const cred_t *cr,
* Determine that subject can set the file setgid flag.
*/
int
-secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid)
+secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid, zuserns_t *mnt_ns,
+ zuserns_t *fs_ns)
{
+ gid = zfs_gid_to_vfsgid(mnt_ns, fs_ns, gid);
#if defined(CONFIG_USER_NS)
if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid)))
return (EPERM);
@@ -284,8 +286,11 @@ secpolicy_setid_clear(vattr_t *vap, cred_t *cr)
* Determine that subject can set the file setid flags.
*/
static int
-secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
+secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner, zuserns_t *mnt_ns,
+ zuserns_t *fs_ns)
{
+ owner = zfs_uid_to_vfsuid(mnt_ns, fs_ns, owner);
+
if (crgetuid(cr) == owner)
return (0);
@@ -310,13 +315,13 @@ secpolicy_vnode_stky_modify(const cred_t *cr)
int
secpolicy_setid_setsticky_clear(struct inode *ip, vattr_t *vap,
- const vattr_t *ovap, cred_t *cr)
+ const vattr_t *ovap, cred_t *cr, zuserns_t *mnt_ns, zuserns_t *fs_ns)
{
int error;
if ((vap->va_mode & S_ISUID) != 0 &&
(error = secpolicy_vnode_setid_modify(cr,
- ovap->va_uid)) != 0) {
+ ovap->va_uid, mnt_ns, fs_ns)) != 0) {
return (error);
}
@@ -334,7 +339,8 @@ secpolicy_setid_setsticky_clear(struct inode *ip, vattr_t *vap,
* group-id bit.
*/
if ((vap->va_mode & S_ISGID) != 0 &&
- secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) {
+ secpolicy_vnode_setids_setgids(cr, ovap->va_gid,
+ mnt_ns, fs_ns) != 0) {
vap->va_mode &= ~S_ISGID;
}
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/spa_misc_os.c b/sys/contrib/openzfs/module/os/linux/zfs/spa_misc_os.c
index f999df3b7db9..3efc8b9644fd 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/spa_misc_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/spa_misc_os.c
@@ -60,7 +60,7 @@ param_set_deadman_ziotime(const char *val, zfs_kernel_param_t *kp)
{
int error;
- error = param_set_ulong(val, kp);
+ error = spl_param_set_u64(val, kp);
if (error < 0)
return (SET_ERROR(error));
@@ -74,7 +74,7 @@ param_set_deadman_synctime(const char *val, zfs_kernel_param_t *kp)
{
int error;
- error = param_set_ulong(val, kp);
+ error = spl_param_set_u64(val, kp);
if (error < 0)
return (SET_ERROR(error));
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 0fed09df5203..4f33009f14d4 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
@@ -56,7 +56,7 @@ static void *zfs_vdev_holder = VDEV_HOLDER;
* device is missing. The missing path may be transient since the links
* can be briefly removed and recreated in response to udev events.
*/
-static unsigned zfs_vdev_open_timeout_ms = 1000;
+static uint_t zfs_vdev_open_timeout_ms = 1000;
/*
* Size of the "reserved" partition, in blocks.
@@ -74,6 +74,12 @@ typedef struct dio_request {
struct bio *dr_bio[0]; /* Attached bio's */
} dio_request_t;
+/*
+ * BIO request failfast mask.
+ */
+
+static unsigned int zfs_vdev_failfast_mask = 1;
+
static fmode_t
vdev_bdev_mode(spa_mode_t spa_mode)
{
@@ -173,7 +179,7 @@ vdev_disk_error(zio_t *zio)
* which is safe from any context.
*/
printk(KERN_WARNING "zio pool=%s vdev=%s error=%d type=%d "
- "offset=%llu size=%llu flags=%x\n", spa_name(zio->io_spa),
+ "offset=%llu size=%llu flags=%llu\n", spa_name(zio->io_spa),
zio->io_vd->vdev_path, zio->io_error, zio->io_type,
(u_longlong_t)zio->io_offset, (u_longlong_t)zio->io_size,
zio->io_flags);
@@ -659,8 +665,11 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
retry:
dr = vdev_disk_dio_alloc(bio_count);
- if (zio && !(zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)))
- bio_set_flags_failfast(bdev, &flags);
+ if (zio && !(zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)) &&
+ zio->io_vd->vdev_failfast == B_TRUE) {
+ bio_set_flags_failfast(bdev, &flags, zfs_vdev_failfast_mask & 1,
+ zfs_vdev_failfast_mask & 2, zfs_vdev_failfast_mask & 4);
+ }
dr->dr_zio = zio;
@@ -1006,17 +1015,17 @@ MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler");
int
param_set_min_auto_ashift(const char *buf, zfs_kernel_param_t *kp)
{
- uint64_t val;
+ uint_t val;
int error;
- error = kstrtoull(buf, 0, &val);
+ error = kstrtouint(buf, 0, &val);
if (error < 0)
return (SET_ERROR(error));
if (val < ASHIFT_MIN || val > zfs_vdev_max_auto_ashift)
return (SET_ERROR(-EINVAL));
- error = param_set_ulong(buf, kp);
+ error = param_set_uint(buf, kp);
if (error < 0)
return (SET_ERROR(error));
@@ -1026,19 +1035,25 @@ param_set_min_auto_ashift(const char *buf, zfs_kernel_param_t *kp)
int
param_set_max_auto_ashift(const char *buf, zfs_kernel_param_t *kp)
{
- uint64_t val;
+ uint_t val;
int error;
- error = kstrtoull(buf, 0, &val);
+ error = kstrtouint(buf, 0, &val);
if (error < 0)
return (SET_ERROR(error));
if (val > ASHIFT_MAX || val < zfs_vdev_min_auto_ashift)
return (SET_ERROR(-EINVAL));
- error = param_set_ulong(buf, kp);
+ error = param_set_uint(buf, kp);
if (error < 0)
return (SET_ERROR(error));
return (0);
}
+
+ZFS_MODULE_PARAM(zfs_vdev, zfs_vdev_, open_timeout_ms, UINT, ZMOD_RW,
+ "Timeout before determining that a device is missing");
+
+ZFS_MODULE_PARAM(zfs_vdev, zfs_vdev_, failfast_mask, UINT, ZMOD_RW,
+ "Defines failfast mask: 1 - device, 2 - transport, 4 - driver");
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/vdev_file.c b/sys/contrib/openzfs/module/os/linux/zfs/vdev_file.c
index 46e412f6eeb4..5abc0426d1a7 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/vdev_file.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/vdev_file.c
@@ -53,8 +53,8 @@ static taskq_t *vdev_file_taskq;
* impact the vdev_ashift setting which can only be set at vdev creation
* time.
*/
-static unsigned long vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
-static unsigned long vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
+static uint_t vdev_file_logical_ashift = SPA_MINBLOCKSHIFT;
+static uint_t vdev_file_physical_ashift = SPA_MINBLOCKSHIFT;
static void
vdev_file_hold(vdev_t *vd)
@@ -376,7 +376,7 @@ vdev_ops_t vdev_disk_ops = {
#endif
-ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, UINT, ZMOD_RW,
"Logical ashift for file-based devices");
-ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, UINT, ZMOD_RW,
"Physical ashift for file-based devices");
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 5935403b49d0..7d14863c56c4 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c
@@ -629,18 +629,18 @@ zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who,
return (NULL);
}
-static uint64_t
-zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
+static uintptr_t
+zfs_ace_walk(void *datap, uintptr_t cookie, int aclcnt,
uint16_t *flags, uint16_t *type, uint32_t *mask)
{
(void) aclcnt;
zfs_acl_t *aclp = datap;
- zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)(uintptr_t)cookie;
+ zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)cookie;
uint64_t who;
acep = zfs_acl_next_ace(aclp, acep, &who, mask,
flags, type);
- return ((uint64_t)(uintptr_t)acep);
+ return ((uintptr_t)acep);
}
/*
@@ -1163,6 +1163,7 @@ zfs_acl_data_locator(void **dataptr, uint32_t *length, uint32_t buflen,
cb->cb_acl_node = list_next(&cb->cb_aclp->z_acl,
cb->cb_acl_node);
}
+ ASSERT3P(cb->cb_acl_node, !=, NULL);
*dataptr = cb->cb_acl_node->z_acldata;
*length = cb->cb_acl_node->z_size;
}
@@ -1284,7 +1285,7 @@ acl_trivial_access_masks(mode_t mode, boolean_t isdir, trivial_acl_t *masks)
*/
static int
ace_trivial_common(void *acep, int aclcnt,
- uint64_t (*walk)(void *, uint64_t, int aclcnt,
+ uintptr_t (*walk)(void *, uintptr_t, int,
uint16_t *, uint16_t *, uint32_t *))
{
uint16_t flags;
@@ -1801,7 +1802,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, umode_t va_mode, zfs_acl_t *paclp,
*/
int
zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
- vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
+ vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns)
{
int error;
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
@@ -1888,8 +1889,10 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
acl_ids->z_mode |= S_ISGID;
} else {
if ((acl_ids->z_mode & S_ISGID) &&
- secpolicy_vnode_setids_setgids(cr, gid) != 0)
+ secpolicy_vnode_setids_setgids(cr, gid, mnt_ns,
+ zfs_i_user_ns(ZTOI(dzp))) != 0) {
acl_ids->z_mode &= ~S_ISGID;
+ }
}
if (acl_ids->z_aclp == NULL) {
@@ -1977,7 +1980,8 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
if (mask == 0)
return (SET_ERROR(ENOSYS));
- if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
+ if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr,
+ kcred->user_ns)))
return (error);
mutex_enter(&zp->z_acl_lock);
@@ -2136,7 +2140,8 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
if (zp->z_pflags & ZFS_IMMUTABLE)
return (SET_ERROR(EPERM));
- if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
+ if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr,
+ kcred->user_ns)))
return (error);
error = zfs_vsec_2_aclp(zfsvfs, ZTOI(zp)->i_mode, vsecp, cr, &fuidp,
@@ -2282,7 +2287,7 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
*/
static int
zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
- boolean_t anyaccess, cred_t *cr)
+ boolean_t anyaccess, cred_t *cr, zuserns_t *mnt_ns)
{
zfsvfs_t *zfsvfs = ZTOZSB(zp);
zfs_acl_t *aclp;
@@ -2298,7 +2303,13 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
uid_t gowner;
uid_t fowner;
- zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
+ if (mnt_ns) {
+ fowner = zfs_uid_to_vfsuid(mnt_ns, zfs_i_user_ns(ZTOI(zp)),
+ KUID_TO_SUID(ZTOI(zp)->i_uid));
+ gowner = zfs_gid_to_vfsgid(mnt_ns, zfs_i_user_ns(ZTOI(zp)),
+ KGID_TO_SGID(ZTOI(zp)->i_gid));
+ } else
+ zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
mutex_enter(&zp->z_acl_lock);
@@ -2409,7 +2420,8 @@ zfs_has_access(znode_t *zp, cred_t *cr)
{
uint32_t have = ACE_ALL_PERMS;
- if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
+ if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr,
+ kcred->user_ns) != 0) {
uid_t owner;
owner = zfs_fuid_map_id(ZTOZSB(zp),
@@ -2439,7 +2451,8 @@ zfs_has_access(znode_t *zp, cred_t *cr)
* we want to avoid that here.
*/
static int
-zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr)
+zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr,
+ zuserns_t *mnt_ns)
{
int err, mask;
int unmapped = 0;
@@ -2453,7 +2466,10 @@ zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr)
}
#if defined(HAVE_IOPS_PERMISSION_USERNS)
- err = generic_permission(cr->user_ns, ZTOI(zp), mask);
+ if (mnt_ns)
+ err = generic_permission(mnt_ns, ZTOI(zp), mask);
+ else
+ err = generic_permission(cr->user_ns, ZTOI(zp), mask);
#else
err = generic_permission(ZTOI(zp), mask);
#endif
@@ -2468,7 +2484,7 @@ zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr)
static int
zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
- boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
+ boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr, zuserns_t *mnt_ns)
{
zfsvfs_t *zfsvfs = ZTOZSB(zp);
int err;
@@ -2518,20 +2534,20 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
}
if (zp->z_pflags & ZFS_ACL_TRIVIAL)
- return (zfs_zaccess_trivial(zp, working_mode, cr));
+ return (zfs_zaccess_trivial(zp, working_mode, cr, mnt_ns));
- return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
+ return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr, mnt_ns));
}
static int
zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
- cred_t *cr)
+ cred_t *cr, zuserns_t *mnt_ns)
{
if (*working_mode != ACE_WRITE_DATA)
return (SET_ERROR(EACCES));
return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode,
- check_privs, B_FALSE, cr));
+ check_privs, B_FALSE, cr, mnt_ns));
}
int
@@ -2598,7 +2614,8 @@ slow:
DTRACE_PROBE(zfs__fastpath__execute__access__miss);
if ((error = zfs_enter(ZTOZSB(zdp), FTAG)) != 0)
return (error);
- error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
+ error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr,
+ kcred->user_ns);
zfs_exit(ZTOZSB(zdp), FTAG);
return (error);
}
@@ -2610,7 +2627,8 @@ slow:
* can define any form of access.
*/
int
-zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
+zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr,
+ zuserns_t *mnt_ns)
{
uint32_t working_mode;
int error;
@@ -2649,8 +2667,10 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
}
}
- owner = zfs_fuid_map_id(ZTOZSB(zp), KUID_TO_SUID(ZTOI(zp)->i_uid),
- cr, ZFS_OWNER);
+ owner = zfs_uid_to_vfsuid(mnt_ns, zfs_i_user_ns(ZTOI(zp)),
+ KUID_TO_SUID(ZTOI(zp)->i_uid));
+ owner = zfs_fuid_map_id(ZTOZSB(zp), owner, cr, ZFS_OWNER);
+
/*
* Map the bits required to the standard inode flags
* S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits
@@ -2675,7 +2695,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
needed_bits |= S_IXUSR;
if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
- &check_privs, skipaclchk, cr)) == 0) {
+ &check_privs, skipaclchk, cr, mnt_ns)) == 0) {
if (is_attr)
zrele(xzp);
return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
@@ -2689,7 +2709,8 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
}
if (error && (flags & V_APPEND)) {
- error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr);
+ error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr,
+ mnt_ns);
}
if (error && check_privs) {
@@ -2756,9 +2777,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
* NFSv4-style ZFS ACL format and call zfs_zaccess()
*/
int
-zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
+zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr,
+ zuserns_t *mnt_ns)
{
- return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
+ return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr,
+ mnt_ns));
}
/*
@@ -2769,7 +2792,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
{
int v4_mode = zfs_unix_to_v4(mode >> 6);
- return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
+ return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, kcred->user_ns));
}
/* See zfs_zaccess_delete() */
@@ -2846,7 +2869,7 @@ static const boolean_t zfs_write_implies_delete_child = B_TRUE;
* zfs_write_implies_delete_child
*/
int
-zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
+zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns)
{
uint32_t wanted_dirperms;
uint32_t dzp_working_mode = 0;
@@ -2873,7 +2896,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
* (This is part of why we're checking the target first.)
*/
zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode,
- &zpcheck_privs, B_FALSE, cr);
+ &zpcheck_privs, B_FALSE, cr, mnt_ns);
if (zp_error == EACCES) {
/* We hit a DENY ACE. */
if (!zpcheck_privs)
@@ -2895,7 +2918,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
if (zfs_write_implies_delete_child)
wanted_dirperms |= ACE_WRITE_DATA;
dzp_error = zfs_zaccess_common(dzp, wanted_dirperms,
- &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
+ &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr, mnt_ns);
if (dzp_error == EACCES) {
/* We hit a DENY ACE. */
if (!dzpcheck_privs)
@@ -2977,7 +3000,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
int
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
- znode_t *tzp, cred_t *cr)
+ znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns)
{
int add_perm;
int error;
@@ -2999,21 +3022,21 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
* If that succeeds then check for add_file/add_subdir permissions
*/
- if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
+ if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns)))
return (error);
/*
* If we have a tzp, see if we can delete it?
*/
if (tzp) {
- if ((error = zfs_zaccess_delete(tdzp, tzp, cr)))
+ if ((error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns)))
return (error);
}
/*
* Now check for add permissions
*/
- error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
+ error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns);
return (error);
}
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 4ae0a65370e5..519f13212fac 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
@@ -487,7 +487,6 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
zp->z_is_sa = B_FALSE;
zp->z_is_mapped = B_FALSE;
zp->z_is_ctldir = B_TRUE;
- zp->z_is_stale = B_FALSE;
zp->z_sa_hdl = NULL;
zp->z_blksz = 0;
zp->z_seq = 0;
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_debug.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_debug.c
index 819416b68d5f..e5a600250659 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_debug.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_debug.c
@@ -35,7 +35,7 @@ typedef struct zfs_dbgmsg {
static procfs_list_t zfs_dbgmsgs;
static uint_t zfs_dbgmsg_size = 0;
-uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
+static uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
/*
* Internal ZFS debug messages are enabled by default.
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 6738d237b923..85aa94d8df6a 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_dir.c
@@ -926,6 +926,74 @@ zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx,
return (error);
}
+static int
+zfs_drop_nlink_locked(znode_t *zp, dmu_tx_t *tx, boolean_t *unlinkedp)
+{
+ zfsvfs_t *zfsvfs = ZTOZSB(zp);
+ int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
+ boolean_t unlinked = B_FALSE;
+ sa_bulk_attr_t bulk[3];
+ uint64_t mtime[2], ctime[2];
+ uint64_t links;
+ int count = 0;
+ int error;
+
+ if (zp_is_dir && !zfs_dirempty(zp))
+ return (SET_ERROR(ENOTEMPTY));
+
+ if (ZTOI(zp)->i_nlink <= zp_is_dir) {
+ zfs_panic_recover("zfs: link count on %lu is %u, "
+ "should be at least %u", zp->z_id,
+ (int)ZTOI(zp)->i_nlink, zp_is_dir + 1);
+ set_nlink(ZTOI(zp), zp_is_dir + 1);
+ }
+ drop_nlink(ZTOI(zp));
+ if (ZTOI(zp)->i_nlink == zp_is_dir) {
+ zp->z_unlinked = B_TRUE;
+ clear_nlink(ZTOI(zp));
+ unlinked = B_TRUE;
+ } else {
+ SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs),
+ NULL, &ctime, sizeof (ctime));
+ SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs),
+ NULL, &zp->z_pflags, sizeof (zp->z_pflags));
+ zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime,
+ ctime);
+ }
+ links = ZTOI(zp)->i_nlink;
+ 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);
+
+ if (unlinkedp != NULL)
+ *unlinkedp = unlinked;
+ else if (unlinked)
+ zfs_unlinked_add(zp, tx);
+
+ return (0);
+}
+
+/*
+ * Forcefully drop an nlink reference from (zp) and mark it for deletion if it
+ * was the last link. This *must* only be done to znodes which have already
+ * been zfs_link_destroy()'d with ZRENAMING. This is explicitly only used in
+ * the error path of zfs_rename(), where we have to correct the nlink count if
+ * we failed to link the target as well as failing to re-link the original
+ * znodes.
+ */
+int
+zfs_drop_nlink(znode_t *zp, dmu_tx_t *tx, boolean_t *unlinkedp)
+{
+ int error;
+
+ mutex_enter(&zp->z_lock);
+ error = zfs_drop_nlink_locked(zp, tx, unlinkedp);
+ mutex_exit(&zp->z_lock);
+
+ return (error);
+}
+
/*
* Unlink zp from dl, and mark zp for deletion if this was the last link. Can
* fail if zp is a mount point (EBUSY) or a non-empty directory (ENOTEMPTY).
@@ -966,31 +1034,9 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
return (error);
}
- if (ZTOI(zp)->i_nlink <= zp_is_dir) {
- zfs_panic_recover("zfs: link count on %lu is %u, "
- "should be at least %u", zp->z_id,
- (int)ZTOI(zp)->i_nlink, zp_is_dir + 1);
- set_nlink(ZTOI(zp), zp_is_dir + 1);
- }
- drop_nlink(ZTOI(zp));
- if (ZTOI(zp)->i_nlink == zp_is_dir) {
- zp->z_unlinked = B_TRUE;
- clear_nlink(ZTOI(zp));
- unlinked = B_TRUE;
- } else {
- SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs),
- NULL, &ctime, sizeof (ctime));
- SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs),
- NULL, &zp->z_pflags, sizeof (zp->z_pflags));
- zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime,
- ctime);
- }
- links = ZTOI(zp)->i_nlink;
- 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);
- count = 0;
- ASSERT(error == 0);
+ /* The only error is !zfs_dirempty() and we checked earlier. */
+ error = zfs_drop_nlink_locked(zp, tx, &unlinked);
+ ASSERT3U(error, ==, 0);
mutex_exit(&zp->z_lock);
} else {
error = zfs_dropname(dl, zp, dzp, tx, flag);
@@ -1066,11 +1112,12 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr)
*xzpp = NULL;
- if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
+ if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr,
+ kcred->user_ns)))
return (error);
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
- &acl_ids)) != 0)
+ &acl_ids, kcred->user_ns)) != 0)
return (error);
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zp->z_projid)) {
zfs_acl_ids_free(&acl_ids);
@@ -1218,7 +1265,8 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
cr, ZFS_OWNER);
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
- zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0)
+ zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr,
+ kcred->user_ns) == 0)
return (0);
else
return (secpolicy_vnode_remove(cr));
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c
index da80428402cd..bc753614be27 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_file_os.c
@@ -246,7 +246,7 @@ zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
{
loff_t rc;
- if (*offp < 0 || *offp > MAXOFFSET_T)
+ if (*offp < 0)
return (EINVAL);
rc = vfs_llseek(fp, *offp, whence);
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 4a2091f3c396..e2431fe8a803 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_sysfs.c
@@ -279,11 +279,11 @@ zprop_sysfs_show(const char *attr_name, const zprop_desc_t *property,
for (int i = 0; i < ARRAY_SIZE(type_map); i++) {
if (type_map[i].ztm_type & property->pd_types) {
- len += snprintf(buf + len, buflen - len, "%s ",
- type_map[i].ztm_name);
+ len += kmem_scnprintf(buf + len, buflen - len,
+ "%s ", type_map[i].ztm_name);
}
}
- len += snprintf(buf + len, buflen - len, "\n");
+ len += kmem_scnprintf(buf + len, buflen - len, "\n");
return (len);
}
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 64d6b4616e1c..c921e587c75c 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
@@ -1522,7 +1522,6 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
sb->s_op = &zpl_super_operations;
sb->s_xattr = zpl_xattr_handlers;
sb->s_export_op = &zpl_export_operations;
- sb->s_d_op = &zpl_dentry_operations;
/* Set features for file system. */
zfs_set_fuid_feature(zfsvfs);
@@ -1556,6 +1555,7 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
error = zfs_root(zfsvfs, &root_inode);
if (error) {
(void) zfs_umount(sb);
+ zfsvfs = NULL; /* avoid double-free; first in zfs_umount */
goto out;
}
@@ -1563,6 +1563,7 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
sb->s_root = d_make_root(root_inode);
if (sb->s_root == NULL) {
(void) zfs_umount(sb);
+ zfsvfs = NULL; /* avoid double-free; first in zfs_umount */
error = SET_ERROR(ENOMEM);
goto out;
}
@@ -1879,8 +1880,8 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
zp = list_next(&zfsvfs->z_all_znodes, zp)) {
err2 = zfs_rezget(zp);
if (err2) {
+ zpl_d_drop_aliases(ZTOI(zp));
remove_inode_hash(ZTOI(zp));
- zp->z_is_stale = B_TRUE;
}
/* see comment in zfs_suspend_fs() */
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 1ff88c121a79..29d62837a82a 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
@@ -476,7 +476,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
*/
if ((error = zfs_zaccess(*zpp, ACE_EXECUTE, 0,
- B_TRUE, cr))) {
+ B_TRUE, cr, kcred->user_ns))) {
zrele(*zpp);
*zpp = NULL;
}
@@ -494,7 +494,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
* Check accessibility of directory.
*/
- if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr,
+ kcred->user_ns))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -526,6 +527,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
* cr - credentials of caller.
* flag - file flag.
* vsecp - ACL to be set
+ * mnt_ns - user namespace of the mount
*
* OUT: zpp - znode of created or trunc'd entry.
*
@@ -537,7 +539,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
*/
int
zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
- int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp)
+ int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
+ zuserns_t *mnt_ns)
{
znode_t *zp;
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
@@ -624,7 +627,8 @@ top:
* Create a new file object and update the directory
* to reference it.
*/
- if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr,
+ mnt_ns))) {
if (have_acl)
zfs_acl_ids_free(&acl_ids);
goto out;
@@ -643,7 +647,7 @@ top:
}
if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap,
- cr, vsecp, &acl_ids)) != 0)
+ cr, vsecp, &acl_ids, mnt_ns)) != 0)
goto out;
have_acl = B_TRUE;
@@ -738,7 +742,8 @@ top:
/*
* Verify requested access to file.
*/
- if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr))) {
+ if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr,
+ mnt_ns))) {
goto out;
}
@@ -782,7 +787,8 @@ out:
int
zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl,
- int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp)
+ int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp,
+ zuserns_t *mnt_ns)
{
(void) excl, (void) mode, (void) flag;
znode_t *zp = NULL, *dzp = ITOZ(dip);
@@ -829,14 +835,14 @@ top:
* Create a new file object and update the directory
* to reference it.
*/
- if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
if (have_acl)
zfs_acl_ids_free(&acl_ids);
goto out;
}
if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap,
- cr, vsecp, &acl_ids)) != 0)
+ cr, vsecp, &acl_ids, mnt_ns)) != 0)
goto out;
have_acl = B_TRUE;
@@ -967,7 +973,7 @@ top:
return (error);
}
- if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
+ if ((error = zfs_zaccess_delete(dzp, zp, cr, kcred->user_ns))) {
goto out;
}
@@ -1147,6 +1153,7 @@ out:
* cr - credentials of caller.
* flags - case flags.
* vsecp - ACL to be set
+ * mnt_ns - user namespace of the mount
*
* OUT: zpp - znode of created directory.
*
@@ -1159,7 +1166,7 @@ out:
*/
int
zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
- cred_t *cr, int flags, vsecattr_t *vsecp)
+ cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns)
{
znode_t *zp;
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
@@ -1216,7 +1223,7 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
}
if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
- vsecp, &acl_ids)) != 0) {
+ vsecp, &acl_ids, mnt_ns)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -1237,7 +1244,8 @@ top:
return (error);
}
- if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr,
+ mnt_ns))) {
zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl);
zfs_exit(zfsvfs, FTAG);
@@ -1379,7 +1387,7 @@ top:
return (error);
}
- if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
+ if ((error = zfs_zaccess_delete(dzp, zp, cr, kcred->user_ns))) {
goto out;
}
@@ -1811,6 +1819,7 @@ next:
* flags - ATTR_UTIME set if non-default time values provided.
* - ATTR_NOACLCHECK (CIFS context only).
* cr - credentials of caller.
+ * mnt_ns - user namespace of the mount
*
* RETURN: 0 if success
* error code if failure
@@ -1819,7 +1828,7 @@ next:
* ip - ctime updated, mtime updated if size changed.
*/
int
-zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
+zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns)
{
struct inode *ip;
zfsvfs_t *zfsvfs = ZTOZSB(zp);
@@ -1968,7 +1977,8 @@ top:
*/
if (mask & ATTR_SIZE) {
- err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr);
+ err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr,
+ mnt_ns);
if (err)
goto out3;
@@ -1993,13 +2003,15 @@ top:
XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0,
- skipaclchk, cr);
+ skipaclchk, cr, mnt_ns);
}
if (mask & (ATTR_UID|ATTR_GID)) {
int idmask = (mask & (ATTR_UID|ATTR_GID));
int take_owner;
int take_group;
+ uid_t uid;
+ gid_t gid;
/*
* NOTE: even if a new mode is being set,
@@ -2013,9 +2025,13 @@ top:
* Take ownership or chgrp to group we are a member of
*/
- take_owner = (mask & ATTR_UID) && (vap->va_uid == crgetuid(cr));
+ uid = zfs_uid_to_vfsuid((struct user_namespace *)mnt_ns,
+ zfs_i_user_ns(ip), vap->va_uid);
+ gid = zfs_gid_to_vfsgid((struct user_namespace *)mnt_ns,
+ zfs_i_user_ns(ip), vap->va_gid);
+ take_owner = (mask & ATTR_UID) && (uid == crgetuid(cr));
take_group = (mask & ATTR_GID) &&
- zfs_groupmember(zfsvfs, vap->va_gid, cr);
+ zfs_groupmember(zfsvfs, gid, cr);
/*
* If both ATTR_UID and ATTR_GID are set then take_owner and
@@ -2031,7 +2047,7 @@ top:
((idmask == ATTR_UID) && take_owner) ||
((idmask == ATTR_GID) && take_group)) {
if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0,
- skipaclchk, cr) == 0) {
+ skipaclchk, cr, mnt_ns) == 0) {
/*
* Remove setuid/setgid for non-privileged users
*/
@@ -2144,12 +2160,12 @@ top:
mutex_exit(&zp->z_lock);
if (mask & ATTR_MODE) {
- if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) {
+ if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr,
+ mnt_ns) == 0) {
err = secpolicy_setid_setsticky_clear(ip, vap,
- &oldva, cr);
+ &oldva, cr, mnt_ns, zfs_i_user_ns(ip));
if (err)
goto out3;
-
trim_mask |= ATTR_MODE;
} else {
need_policy = TRUE;
@@ -2640,6 +2656,9 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
* tnm - New entry name.
* cr - credentials of caller.
* flags - case flags
+ * rflags - RENAME_* flags
+ * wa_vap - attributes for RENAME_WHITEOUT (must be a char 0:0).
+ * mnt_ns - user namespace of the mount
*
* RETURN: 0 on success, error code on failure.
*
@@ -2648,7 +2667,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
*/
int
zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
- cred_t *cr, int flags)
+ cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap, zuserns_t *mnt_ns)
{
znode_t *szp, *tzp;
zfsvfs_t *zfsvfs = ZTOZSB(sdzp);
@@ -2660,10 +2679,33 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
int error = 0;
int zflg = 0;
boolean_t waited = B_FALSE;
+ /* Needed for whiteout inode creation. */
+ boolean_t fuid_dirtied;
+ zfs_acl_ids_t acl_ids;
+ boolean_t have_acl = B_FALSE;
+ znode_t *wzp = NULL;
+
if (snm == NULL || tnm == NULL)
return (SET_ERROR(EINVAL));
+ if (rflags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
+ return (SET_ERROR(EINVAL));
+
+ /* Already checked by Linux VFS, but just to make sure. */
+ if (rflags & RENAME_EXCHANGE &&
+ (rflags & (RENAME_NOREPLACE | RENAME_WHITEOUT)))
+ return (SET_ERROR(EINVAL));
+
+ /*
+ * Make sure we only get wo_vap iff. RENAME_WHITEOUT and that it's the
+ * right kind of vattr_t for the whiteout file. These are set
+ * internally by ZFS so should never be incorrect.
+ */
+ VERIFY_EQUIV(rflags & RENAME_WHITEOUT, wo_vap != NULL);
+ VERIFY_IMPLY(wo_vap, wo_vap->va_mode == S_IFCHR);
+ VERIFY_IMPLY(wo_vap, wo_vap->va_rdev == makedevice(0, 0));
+
if ((error = zfs_enter_verify_zp(zfsvfs, sdzp, FTAG)) != 0)
return (error);
zilog = zfsvfs->z_log;
@@ -2840,8 +2882,7 @@ top:
* Note that if target and source are the same, this can be
* done in a single check.
*/
-
- if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)))
+ if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, mnt_ns)))
goto out;
if (S_ISDIR(ZTOI(szp)->i_mode)) {
@@ -2857,17 +2898,19 @@ top:
* Does target exist?
*/
if (tzp) {
+ if (rflags & RENAME_NOREPLACE) {
+ error = SET_ERROR(EEXIST);
+ goto out;
+ }
/*
- * Source and target must be the same type.
+ * Source and target must be the same type (unless exchanging).
*/
- if (S_ISDIR(ZTOI(szp)->i_mode)) {
- if (!S_ISDIR(ZTOI(tzp)->i_mode)) {
- error = SET_ERROR(ENOTDIR);
- goto out;
- }
- } else {
- if (S_ISDIR(ZTOI(tzp)->i_mode)) {
- error = SET_ERROR(EISDIR);
+ if (!(rflags & RENAME_EXCHANGE)) {
+ boolean_t s_is_dir = S_ISDIR(ZTOI(szp)->i_mode) != 0;
+ boolean_t t_is_dir = S_ISDIR(ZTOI(tzp)->i_mode) != 0;
+
+ if (s_is_dir != t_is_dir) {
+ error = SET_ERROR(s_is_dir ? ENOTDIR : EISDIR);
goto out;
}
}
@@ -2880,12 +2923,43 @@ top:
error = 0;
goto out;
}
+ } else if (rflags & RENAME_EXCHANGE) {
+ /* Target must exist for RENAME_EXCHANGE. */
+ error = SET_ERROR(ENOENT);
+ goto out;
+ }
+
+ /* Set up inode creation for RENAME_WHITEOUT. */
+ if (rflags & RENAME_WHITEOUT) {
+ /*
+ * Whiteout files are not regular files or directories, so to
+ * match zfs_create() we do not inherit the project id.
+ */
+ uint64_t wo_projid = ZFS_DEFAULT_PROJID;
+
+ error = zfs_zaccess(sdzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns);
+ if (error)
+ goto out;
+
+ if (!have_acl) {
+ error = zfs_acl_ids_create(sdzp, 0, wo_vap, cr, NULL,
+ &acl_ids, mnt_ns);
+ if (error)
+ goto out;
+ have_acl = B_TRUE;
+ }
+
+ if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, wo_projid)) {
+ error = SET_ERROR(EDQUOT);
+ goto out;
+ }
}
tx = dmu_tx_create(zfsvfs->z_os);
dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE);
dmu_tx_hold_sa(tx, sdzp->z_sa_hdl, B_FALSE);
- dmu_tx_hold_zap(tx, sdzp->z_id, FALSE, snm);
+ dmu_tx_hold_zap(tx, sdzp->z_id,
+ (rflags & RENAME_EXCHANGE) ? TRUE : FALSE, snm);
dmu_tx_hold_zap(tx, tdzp->z_id, TRUE, tnm);
if (sdzp != tdzp) {
dmu_tx_hold_sa(tx, tdzp->z_sa_hdl, B_FALSE);
@@ -2895,7 +2969,21 @@ top:
dmu_tx_hold_sa(tx, tzp->z_sa_hdl, B_FALSE);
zfs_sa_upgrade_txholds(tx, tzp);
}
+ if (rflags & RENAME_WHITEOUT) {
+ dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
+ ZFS_SA_BASE_ATTR_SIZE);
+ dmu_tx_hold_zap(tx, sdzp->z_id, TRUE, snm);
+ dmu_tx_hold_sa(tx, sdzp->z_sa_hdl, B_FALSE);
+ if (!zfsvfs->z_use_sa &&
+ acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) {
+ dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
+ 0, acl_ids.z_aclp->z_acl_bytes);
+ }
+ }
+ fuid_dirtied = zfsvfs->z_fuid_dirty;
+ if (fuid_dirtied)
+ zfs_fuid_txhold(zfsvfs, tx);
zfs_sa_upgrade_txholds(tx, szp);
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
@@ -2925,58 +3013,110 @@ top:
return (error);
}
- if (tzp) /* Attempt to remove the existing target */
- error = zfs_link_destroy(tdl, tzp, tx, zflg, NULL);
+ /*
+ * Unlink the source.
+ */
+ szp->z_pflags |= ZFS_AV_MODIFIED;
+ if (tdzp->z_pflags & ZFS_PROJINHERIT)
+ szp->z_pflags |= ZFS_PROJINHERIT;
+
+ error = sa_update(szp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs),
+ (void *)&szp->z_pflags, sizeof (uint64_t), tx);
+ VERIFY0(error);
- if (error == 0) {
- error = zfs_link_create(tdl, szp, tx, ZRENAMING);
- if (error == 0) {
- szp->z_pflags |= ZFS_AV_MODIFIED;
- if (tdzp->z_pflags & ZFS_PROJINHERIT)
- szp->z_pflags |= ZFS_PROJINHERIT;
-
- error = sa_update(szp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs),
- (void *)&szp->z_pflags, sizeof (uint64_t), tx);
+ error = zfs_link_destroy(sdl, szp, tx, ZRENAMING, NULL);
+ if (error)
+ goto commit;
+
+ /*
+ * Unlink the target.
+ */
+ if (tzp) {
+ int tzflg = zflg;
+
+ if (rflags & RENAME_EXCHANGE) {
+ /* This inode will be re-linked soon. */
+ tzflg |= ZRENAMING;
+
+ tzp->z_pflags |= ZFS_AV_MODIFIED;
+ if (sdzp->z_pflags & ZFS_PROJINHERIT)
+ tzp->z_pflags |= ZFS_PROJINHERIT;
+
+ error = sa_update(tzp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs),
+ (void *)&tzp->z_pflags, sizeof (uint64_t), tx);
ASSERT0(error);
+ }
+ error = zfs_link_destroy(tdl, tzp, tx, tzflg, NULL);
+ if (error)
+ goto commit_link_szp;
+ }
- error = zfs_link_destroy(sdl, szp, tx, ZRENAMING, NULL);
- if (error == 0) {
- zfs_log_rename(zilog, tx, TX_RENAME |
- (flags & FIGNORECASE ? TX_CI : 0), sdzp,
- sdl->dl_name, tdzp, tdl->dl_name, szp);
- } else {
- /*
- * At this point, we have successfully created
- * the target name, but have failed to remove
- * the source name. Since the create was done
- * with the ZRENAMING flag, there are
- * complications; for one, the link count is
- * wrong. The easiest way to deal with this
- * is to remove the newly created target, and
- * return the original error. This must
- * succeed; fortunately, it is very unlikely to
- * fail, since we just created it.
- */
- VERIFY3U(zfs_link_destroy(tdl, szp, tx,
- ZRENAMING, NULL), ==, 0);
- }
- } else {
- /*
- * If we had removed the existing target, subsequent
- * call to zfs_link_create() to add back the same entry
- * but, the new dnode (szp) should not fail.
- */
- ASSERT(tzp == NULL);
+ /*
+ * Create the new target links:
+ * * We always link the target.
+ * * RENAME_EXCHANGE: Link the old target to the source.
+ * * RENAME_WHITEOUT: Create a whiteout inode in-place of the source.
+ */
+ error = zfs_link_create(tdl, szp, tx, ZRENAMING);
+ if (error) {
+ /*
+ * If we have removed the existing target, a subsequent call to
+ * zfs_link_create() to add back the same entry, but with a new
+ * dnode (szp), should not fail.
+ */
+ ASSERT3P(tzp, ==, NULL);
+ goto commit_link_tzp;
+ }
+
+ switch (rflags & (RENAME_EXCHANGE | RENAME_WHITEOUT)) {
+ case RENAME_EXCHANGE:
+ error = zfs_link_create(sdl, tzp, tx, ZRENAMING);
+ /*
+ * The same argument as zfs_link_create() failing for
+ * szp applies here, since the source directory must
+ * have had an entry we are replacing.
+ */
+ ASSERT0(error);
+ if (error)
+ goto commit_unlink_td_szp;
+ break;
+ case RENAME_WHITEOUT:
+ zfs_mknode(sdzp, wo_vap, tx, cr, 0, &wzp, &acl_ids);
+ error = zfs_link_create(sdl, wzp, tx, ZNEW);
+ if (error) {
+ zfs_znode_delete(wzp, tx);
+ remove_inode_hash(ZTOI(wzp));
+ goto commit_unlink_td_szp;
}
+ break;
}
+ if (fuid_dirtied)
+ zfs_fuid_sync(zfsvfs, tx);
+
+ switch (rflags & (RENAME_EXCHANGE | RENAME_WHITEOUT)) {
+ case RENAME_EXCHANGE:
+ zfs_log_rename_exchange(zilog, tx,
+ (flags & FIGNORECASE ? TX_CI : 0), sdzp, sdl->dl_name,
+ tdzp, tdl->dl_name, szp);
+ break;
+ case RENAME_WHITEOUT:
+ zfs_log_rename_whiteout(zilog, tx,
+ (flags & FIGNORECASE ? TX_CI : 0), sdzp, sdl->dl_name,
+ tdzp, tdl->dl_name, szp, wzp);
+ break;
+ default:
+ ASSERT0(rflags & ~RENAME_NOREPLACE);
+ zfs_log_rename(zilog, tx, (flags & FIGNORECASE ? TX_CI : 0),
+ sdzp, sdl->dl_name, tdzp, tdl->dl_name, szp);
+ break;
+ }
+
+commit:
dmu_tx_commit(tx);
out:
- if (zl != NULL)
- zfs_rename_unlock(&zl);
-
- zfs_dirent_unlock(sdl);
- zfs_dirent_unlock(tdl);
+ if (have_acl)
+ zfs_acl_ids_free(&acl_ids);
zfs_znode_update_vfs(sdzp);
if (sdzp == tdzp)
@@ -2987,16 +3127,57 @@ out:
zfs_znode_update_vfs(szp);
zrele(szp);
+ if (wzp) {
+ zfs_znode_update_vfs(wzp);
+ zrele(wzp);
+ }
if (tzp) {
zfs_znode_update_vfs(tzp);
zrele(tzp);
}
+ if (zl != NULL)
+ zfs_rename_unlock(&zl);
+
+ zfs_dirent_unlock(sdl);
+ zfs_dirent_unlock(tdl);
+
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0);
zfs_exit(zfsvfs, FTAG);
return (error);
+
+ /*
+ * Clean-up path for broken link state.
+ *
+ * At this point we are in a (very) bad state, so we need to do our
+ * best to correct the state. In particular, all of the nlinks are
+ * wrong because we were destroying and creating links with ZRENAMING.
+ *
+ * In some form, all of these operations have to resolve the state:
+ *
+ * * link_destroy() *must* succeed. Fortunately, this is very likely
+ * since we only just created it.
+ *
+ * * link_create()s are allowed to fail (though they shouldn't because
+ * we only just unlinked them and are putting the entries back
+ * during clean-up). But if they fail, we can just forcefully drop
+ * the nlink value to (at the very least) avoid broken nlink values
+ * -- though in the case of non-empty directories we will have to
+ * panic (otherwise we'd have a leaked directory with a broken ..).
+ */
+commit_unlink_td_szp:
+ VERIFY0(zfs_link_destroy(tdl, szp, tx, ZRENAMING, NULL));
+commit_link_tzp:
+ if (tzp) {
+ if (zfs_link_create(tdl, tzp, tx, ZRENAMING))
+ VERIFY0(zfs_drop_nlink(tzp, tx, NULL));
+ }
+commit_link_szp:
+ if (zfs_link_create(sdl, szp, tx, ZRENAMING))
+ VERIFY0(zfs_drop_nlink(szp, tx, NULL));
+ goto commit;
}
/*
@@ -3008,6 +3189,7 @@ out:
* link - Name for new symlink entry.
* cr - credentials of caller.
* flags - case flags
+ * mnt_ns - user namespace of the mount
*
* OUT: zpp - Znode for new symbolic link.
*
@@ -3018,7 +3200,7 @@ out:
*/
int
zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
- znode_t **zpp, cred_t *cr, int flags)
+ znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns)
{
znode_t *zp;
zfs_dirlock_t *dl;
@@ -3056,7 +3238,7 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
}
if ((error = zfs_acl_ids_create(dzp, 0,
- vap, cr, NULL, &acl_ids)) != 0) {
+ vap, cr, NULL, &acl_ids, mnt_ns)) != 0) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -3073,7 +3255,7 @@ top:
return (error);
}
- if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
zfs_acl_ids_free(&acl_ids);
zfs_dirent_unlock(dl);
zfs_exit(zfsvfs, FTAG);
@@ -3325,7 +3507,8 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
return (SET_ERROR(EPERM));
}
- if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr,
+ kcred->user_ns))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
@@ -3951,7 +4134,8 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
* On Linux we can get here through truncate_range() which
* operates directly on inodes, so we need to check access rights.
*/
- if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
+ if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr,
+ kcred->user_ns))) {
zfs_exit(zfsvfs, FTAG);
return (error);
}
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c
index 73c21b6c00a8..662147ab4722 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c
@@ -422,7 +422,12 @@ zfs_inode_set_ops(zfsvfs_t *zfsvfs, struct inode *ip)
break;
case S_IFDIR:
+#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
+ ip->i_flags |= S_IOPS_WRAPPER;
+ ip->i_op = &zpl_dir_inode_operations.ops;
+#else
ip->i_op = &zpl_dir_inode_operations;
+#endif
ip->i_fop = &zpl_dir_file_operations;
ITOZ(ip)->z_zn_prefetch = B_TRUE;
break;
@@ -552,7 +557,6 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
zp->z_atime_dirty = B_FALSE;
zp->z_is_mapped = B_FALSE;
zp->z_is_ctldir = B_FALSE;
- zp->z_is_stale = B_FALSE;
zp->z_suspended = B_FALSE;
zp->z_sa_hdl = NULL;
zp->z_mapcnt = 0;
@@ -1960,7 +1964,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
}
VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
- cr, NULL, &acl_ids));
+ cr, NULL, &acl_ids, kcred->user_ns));
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);
@@ -2136,7 +2140,6 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
} else if (error != ENOENT) {
return (error);
}
- error = 0;
for (;;) {
uint64_t pobj = 0;
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c b/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c
index 671300932384..6f2bf7ed7569 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c
@@ -231,6 +231,7 @@ zio_crypt_key_init(uint64_t crypt, zio_crypt_key_t *key)
keydata_len = zio_crypt_table[crypt].ci_keylen;
memset(key, 0, sizeof (zio_crypt_key_t));
+ rw_init(&key->zk_salt_lock, NULL, RW_DEFAULT, NULL);
/* fill keydata buffers and salt with random data */
ret = random_get_bytes((uint8_t *)&key->zk_guid, sizeof (uint64_t));
@@ -282,7 +283,6 @@ zio_crypt_key_init(uint64_t crypt, zio_crypt_key_t *key)
key->zk_crypt = crypt;
key->zk_version = ZIO_CRYPT_KEY_CURRENT_VERSION;
key->zk_salt_count = 0;
- rw_init(&key->zk_salt_lock, NULL, RW_DEFAULT, NULL);
return (0);
@@ -1968,7 +1968,6 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key,
if (locked) {
rw_exit(&key->zk_salt_lock);
- locked = B_FALSE;
}
if (authbuf != NULL)
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c
index 837629e4a5e0..f0779c81dc75 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c
@@ -371,7 +371,11 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
- zpl_vap_init(vap, dip, mode | S_IFDIR, cr);
+#ifdef HAVE_IOPS_MKDIR_USERNS
+ zpl_vap_init(vap, dip, mode | S_IFDIR, cr, user_ns);
+#else
+ zpl_vap_init(vap, dip, mode | S_IFDIR, cr, kcred->user_ns);
+#endif
error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
if (error == 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 25fc6b223297..c56e3691e70a 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
@@ -1085,7 +1085,7 @@ zpl_ioctl_setflags(struct file *filp, void __user *arg)
crhold(cr);
cookie = spl_fstrans_mark();
- err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
+ err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, kcred->user_ns);
spl_fstrans_unmark(cookie);
crfree(cr);
@@ -1133,7 +1133,7 @@ zpl_ioctl_setxattr(struct file *filp, void __user *arg)
crhold(cr);
cookie = spl_fstrans_mark();
- err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
+ err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, kcred->user_ns);
spl_fstrans_unmark(cookie);
crfree(cr);
@@ -1221,7 +1221,7 @@ zpl_ioctl_setdosflags(struct file *filp, void __user *arg)
crhold(cr);
cookie = spl_fstrans_mark();
- err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
+ err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, kcred->user_ns);
spl_fstrans_unmark(cookie);
crfree(cr);
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 7578753ed8ce..93eae7201506 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c
@@ -24,6 +24,7 @@
*/
+#include <sys/sysmacros.h>
#include <sys/zfs_ctldir.h>
#include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h>
@@ -33,7 +34,6 @@
#include <sys/zpl.h>
#include <sys/file.h>
-
static struct dentry *
zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{
@@ -112,18 +112,22 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
}
void
-zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
+zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr,
+ zuserns_t *mnt_ns)
{
vap->va_mask = ATTR_MODE;
vap->va_mode = mode;
- vap->va_uid = crgetuid(cr);
- if (dir && dir->i_mode & S_ISGID) {
+ vap->va_uid = zfs_vfsuid_to_uid((struct user_namespace *)mnt_ns,
+ zfs_i_user_ns(dir), crgetuid(cr));
+
+ if (dir->i_mode & S_ISGID) {
vap->va_gid = KGID_TO_SGID(dir->i_gid);
if (S_ISDIR(mode))
vap->va_mode |= S_ISGID;
} else {
- vap->va_gid = crgetgid(cr);
+ vap->va_gid = zfs_vfsgid_to_gid((struct user_namespace *)mnt_ns,
+ zfs_i_user_ns(dir), crgetgid(cr));
}
}
@@ -140,14 +144,17 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
vattr_t *vap;
int error;
fstrans_cookie_t cookie;
+#ifndef HAVE_IOPS_CREATE_USERNS
+ zuserns_t *user_ns = kcred->user_ns;
+#endif
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
- zpl_vap_init(vap, dir, mode, cr);
+ zpl_vap_init(vap, dir, mode, cr, user_ns);
cookie = spl_fstrans_mark();
error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
- mode, &zp, cr, 0, NULL);
+ mode, &zp, cr, 0, NULL, user_ns);
if (error == 0) {
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error == 0)
@@ -184,6 +191,9 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
vattr_t *vap;
int error;
fstrans_cookie_t cookie;
+#ifndef HAVE_IOPS_MKNOD_USERNS
+ zuserns_t *user_ns = kcred->user_ns;
+#endif
/*
* We currently expect Linux to supply rdev=0 for all sockets
@@ -194,12 +204,12 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
- zpl_vap_init(vap, dir, mode, cr);
+ zpl_vap_init(vap, dir, mode, cr, user_ns);
vap->va_rdev = rdev;
cookie = spl_fstrans_mark();
error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
- mode, &zp, cr, 0, NULL);
+ mode, &zp, cr, 0, NULL, user_ns);
if (error == 0) {
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error == 0)
@@ -236,6 +246,9 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
vattr_t *vap;
int error;
fstrans_cookie_t cookie;
+#ifndef HAVE_TMPFILE_USERNS
+ zuserns_t *userns = kcred->user_ns;
+#endif
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
@@ -245,10 +258,10 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
*/
if (!IS_POSIXACL(dir))
mode &= ~current_umask();
- zpl_vap_init(vap, dir, mode, cr);
+ zpl_vap_init(vap, dir, mode, cr, userns);
cookie = spl_fstrans_mark();
- error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL);
+ error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL, userns);
if (error == 0) {
/* d_tmpfile will do drop_nlink, so we should set it first */
set_nlink(ip, 1);
@@ -311,13 +324,17 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
znode_t *zp;
int error;
fstrans_cookie_t cookie;
+#ifndef HAVE_IOPS_MKDIR_USERNS
+ zuserns_t *user_ns = kcred->user_ns;
+#endif
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
- zpl_vap_init(vap, dir, mode | S_IFDIR, cr);
+ zpl_vap_init(vap, dir, mode | S_IFDIR, cr, user_ns);
cookie = spl_fstrans_mark();
- error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL);
+ error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL,
+ user_ns);
if (error == 0) {
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error == 0)
@@ -439,7 +456,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
int error;
fstrans_cookie_t cookie;
+#ifdef HAVE_SETATTR_PREPARE_USERNS
+ error = zpl_setattr_prepare(user_ns, dentry, ia);
+#else
error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
+#endif
if (error)
return (error);
@@ -447,8 +468,20 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK;
vap->va_mode = ia->ia_mode;
- vap->va_uid = KUID_TO_SUID(ia->ia_uid);
- vap->va_gid = KGID_TO_SGID(ia->ia_gid);
+ if (ia->ia_valid & ATTR_UID)
+#ifdef HAVE_IATTR_VFSID
+ vap->va_uid = zfs_vfsuid_to_uid(user_ns, zfs_i_user_ns(ip),
+ __vfsuid_val(ia->ia_vfsuid));
+#else
+ vap->va_uid = KUID_TO_SUID(ia->ia_uid);
+#endif
+ if (ia->ia_valid & ATTR_GID)
+#ifdef HAVE_IATTR_VFSID
+ vap->va_gid = zfs_vfsgid_to_gid(user_ns, zfs_i_user_ns(ip),
+ __vfsgid_val(ia->ia_vfsgid));
+#else
+ vap->va_gid = KGID_TO_SGID(ia->ia_gid);
+#endif
vap->va_size = ia->ia_size;
vap->va_atime = ia->ia_atime;
vap->va_mtime = ia->ia_mtime;
@@ -458,7 +491,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
ip->i_atime = zpl_inode_timestamp_truncate(ia->ia_atime, ip);
cookie = spl_fstrans_mark();
- error = -zfs_setattr(ITOZ(ip), vap, 0, cr);
+#ifdef HAVE_SETATTR_PREPARE_USERNS
+ error = -zfs_setattr(ITOZ(ip), vap, 0, cr, user_ns);
+#else
+ error = -zfs_setattr(ITOZ(ip), vap, 0, cr, kcred->user_ns);
+#endif
if (!error && (ia->ia_valid & ATTR_MODE))
error = zpl_chmod_acl(ip);
@@ -474,32 +511,42 @@ static int
#ifdef HAVE_IOPS_RENAME_USERNS
zpl_rename2(struct user_namespace *user_ns, struct inode *sdip,
struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
- unsigned int flags)
+ unsigned int rflags)
#else
zpl_rename2(struct inode *sdip, struct dentry *sdentry,
- struct inode *tdip, struct dentry *tdentry, unsigned int flags)
+ struct inode *tdip, struct dentry *tdentry, unsigned int rflags)
#endif
{
cred_t *cr = CRED();
+ vattr_t *wo_vap = NULL;
int error;
fstrans_cookie_t cookie;
-
- /* We don't have renameat2(2) support */
- if (flags)
- return (-EINVAL);
+#ifndef HAVE_IOPS_RENAME_USERNS
+ zuserns_t *user_ns = kcred->user_ns;
+#endif
crhold(cr);
+ if (rflags & RENAME_WHITEOUT) {
+ wo_vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
+ zpl_vap_init(wo_vap, sdip, S_IFCHR, cr, user_ns);
+ wo_vap->va_rdev = makedevice(0, 0);
+ }
+
cookie = spl_fstrans_mark();
error = -zfs_rename(ITOZ(sdip), dname(sdentry), ITOZ(tdip),
- dname(tdentry), cr, 0);
+ dname(tdentry), cr, 0, rflags, wo_vap, user_ns);
spl_fstrans_unmark(cookie);
+ if (wo_vap)
+ kmem_free(wo_vap, sizeof (vattr_t));
crfree(cr);
ASSERT3S(error, <=, 0);
return (error);
}
-#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
+#if !defined(HAVE_IOPS_RENAME_USERNS) && \
+ !defined(HAVE_RENAME_WANTS_FLAGS) && \
+ !defined(HAVE_RENAME2)
static int
zpl_rename(struct inode *sdip, struct dentry *sdentry,
struct inode *tdip, struct dentry *tdentry)
@@ -521,14 +568,17 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
znode_t *zp;
int error;
fstrans_cookie_t cookie;
+#ifndef HAVE_IOPS_SYMLINK_USERNS
+ zuserns_t *user_ns = kcred->user_ns;
+#endif
crhold(cr);
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
- zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr);
+ zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr, user_ns);
cookie = spl_fstrans_mark();
error = -zfs_symlink(ITOZ(dir), dname(dentry), vap,
- (char *)name, &zp, cr, 0);
+ (char *)name, &zp, cr, 0, user_ns);
if (error == 0) {
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error) {
@@ -698,46 +748,6 @@ out:
return (error);
}
-static int
-#ifdef HAVE_D_REVALIDATE_NAMEIDATA
-zpl_revalidate(struct dentry *dentry, struct nameidata *nd)
-{
- unsigned int flags = (nd ? nd->flags : 0);
-#else
-zpl_revalidate(struct dentry *dentry, unsigned int flags)
-{
-#endif /* HAVE_D_REVALIDATE_NAMEIDATA */
- /* CSTYLED */
- zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
- int error;
-
- if (flags & LOOKUP_RCU)
- return (-ECHILD);
-
- /*
- * After a rollback negative dentries created before the rollback
- * time must be invalidated. Otherwise they can obscure files which
- * are only present in the rolled back dataset.
- */
- if (dentry->d_inode == NULL) {
- spin_lock(&dentry->d_lock);
- error = time_before(dentry->d_time, zfsvfs->z_rollback_time);
- spin_unlock(&dentry->d_lock);
-
- if (error)
- return (0);
- }
-
- /*
- * The dentry may reference a stale inode if a mounted file system
- * was rolled back to a point in time where the object didn't exist.
- */
- if (dentry->d_inode && ITOZ(dentry->d_inode)->z_is_stale)
- return (0);
-
- return (1);
-}
-
const struct inode_operations zpl_inode_operations = {
.setattr = zpl_setattr,
.getattr = zpl_getattr,
@@ -755,7 +765,12 @@ const struct inode_operations zpl_inode_operations = {
#endif /* CONFIG_FS_POSIX_ACL */
};
+#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
+const struct inode_operations_wrapper zpl_dir_inode_operations = {
+ .ops = {
+#else
const struct inode_operations zpl_dir_inode_operations = {
+#endif
.create = zpl_create,
.lookup = zpl_lookup,
.link = zpl_link,
@@ -764,7 +779,9 @@ const struct inode_operations zpl_dir_inode_operations = {
.mkdir = zpl_mkdir,
.rmdir = zpl_rmdir,
.mknod = zpl_mknod,
-#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
+#ifdef HAVE_RENAME2
+ .rename2 = zpl_rename2,
+#elif defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
.rename = zpl_rename2,
#else
.rename = zpl_rename,
@@ -786,6 +803,10 @@ const struct inode_operations zpl_dir_inode_operations = {
#endif /* HAVE_SET_ACL */
.get_acl = zpl_get_acl,
#endif /* CONFIG_FS_POSIX_ACL */
+#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
+ },
+ .rename2 = zpl_rename2,
+#endif
};
const struct inode_operations zpl_symlink_inode_operations = {
@@ -826,7 +847,3 @@ const struct inode_operations zpl_special_inode_operations = {
.get_acl = zpl_get_acl,
#endif /* CONFIG_FS_POSIX_ACL */
};
-
-dentry_operations_t zpl_dentry_operations = {
- .d_revalidate = zpl_revalidate,
-};
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 e3945a2a05fe..63ba731dd804 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_super.c
@@ -374,7 +374,11 @@ const struct super_operations zpl_super_operations = {
struct file_system_type zpl_fs_type = {
.owner = THIS_MODULE,
.name = ZFS_DRIVER,
+#if defined(HAVE_IDMAP_MNT_API)
+ .fs_flags = FS_USERNS_MOUNT | FS_ALLOW_IDMAP,
+#else
.fs_flags = FS_USERNS_MOUNT,
+#endif
.mount = zpl_mount,
.kill_sb = zpl_kill_sb,
};
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 a010667adfa8..99d9b3793f29 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_xattr.c
@@ -499,7 +499,7 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
vap->va_gid = crgetgid(cr);
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
- cr, 0, NULL);
+ cr, 0, NULL, kcred->user_ns);
if (error)
goto out;
}
@@ -738,9 +738,11 @@ __zpl_xattr_user_get(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get);
static int
-__zpl_xattr_user_set(struct inode *ip, const char *name,
+__zpl_xattr_user_set(struct user_namespace *user_ns,
+ struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
+ (void) user_ns;
int error = 0;
/* xattr_resolve_name will do this for us if this is defined */
#ifndef HAVE_XATTR_HANDLER_NAME
@@ -846,9 +848,11 @@ __zpl_xattr_trusted_get(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get);
static int
-__zpl_xattr_trusted_set(struct inode *ip, const char *name,
+__zpl_xattr_trusted_set(struct user_namespace *user_ns,
+ struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
+ (void) user_ns;
char *xattr_name;
int error;
@@ -914,9 +918,11 @@ __zpl_xattr_security_get(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get);
static int
-__zpl_xattr_security_set(struct inode *ip, const char *name,
+__zpl_xattr_security_set(struct user_namespace *user_ns,
+ struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
+ (void) user_ns;
char *xattr_name;
int error;
/* xattr_resolve_name will do this for us if this is defined */
@@ -940,7 +946,7 @@ zpl_xattr_security_init_impl(struct inode *ip, const struct xattr *xattrs,
int error = 0;
for (xattr = xattrs; xattr->name != NULL; xattr++) {
- error = __zpl_xattr_security_set(ip,
+ error = __zpl_xattr_security_set(NULL, ip,
xattr->name, xattr->value, xattr->value_len, 0);
if (error < 0)
@@ -1300,7 +1306,8 @@ __zpl_xattr_acl_get_default(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_acl_get_default);
static int
-__zpl_xattr_acl_set_access(struct inode *ip, const char *name,
+__zpl_xattr_acl_set_access(struct user_namespace *mnt_ns,
+ struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
struct posix_acl *acl;
@@ -1314,8 +1321,14 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
+#if defined(HAVE_XATTR_SET_USERNS)
+ if (!zpl_inode_owner_or_capable(mnt_ns, ip))
+ return (-EPERM);
+#else
+ (void) mnt_ns;
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
return (-EPERM);
+#endif
if (value) {
acl = zpl_acl_from_xattr(value, size);
@@ -1339,7 +1352,8 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
ZPL_XATTR_SET_WRAPPER(zpl_xattr_acl_set_access);
static int
-__zpl_xattr_acl_set_default(struct inode *ip, const char *name,
+__zpl_xattr_acl_set_default(struct user_namespace *mnt_ns,
+ struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
struct posix_acl *acl;
@@ -1353,8 +1367,14 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
+#if defined(HAVE_XATTR_SET_USERNS)
+ if (!zpl_inode_owner_or_capable(mnt_ns, ip))
+ return (-EPERM);
+#else
+ (void) mnt_ns;
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
return (-EPERM);
+#endif
if (value) {
acl = zpl_acl_from_xattr(value, size);
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 0d4e0dcd5a3d..01e6456207b0 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -114,7 +114,7 @@ struct zvol_state_os {
boolean_t use_blk_mq;
};
-taskq_t *zvol_taskq;
+static taskq_t *zvol_taskq;
static struct ida zvol_ida;
typedef struct zv_request_stack {
@@ -1279,6 +1279,7 @@ zvol_os_create_minor(const char *name)
int error = 0;
int idx;
uint64_t hash = zvol_name_hash(name);
+ bool replayed_zil = B_FALSE;
if (zvol_inhibit_dev)
return (0);
@@ -1420,11 +1421,12 @@ zvol_os_create_minor(const char *name)
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)
- zil_destroy(zv->zv_zilog, B_FALSE);
+ replayed_zil = zil_destroy(zv->zv_zilog, B_FALSE);
else
- zil_replay(os, zv, zvol_replay_vector);
+ replayed_zil = zil_replay(os, zv, zvol_replay_vector);
}
- zil_close(zv->zv_zilog);
+ if (replayed_zil)
+ zil_close(zv->zv_zilog);
zv->zv_zilog = NULL;
/*
diff --git a/sys/contrib/openzfs/module/zcommon/zfs_prop.c b/sys/contrib/openzfs/module/zcommon/zfs_prop.c
index 0e91304ecd4b..9c65702b8d43 100644
--- a/sys/contrib/openzfs/module/zcommon/zfs_prop.c
+++ b/sys/contrib/openzfs/module/zcommon/zfs_prop.c
@@ -25,6 +25,7 @@
* Copyright 2016, Joyent, Inc.
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, Allan Jude
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -369,6 +370,8 @@ zfs_prop_init(void)
static const zprop_index_t redundant_metadata_table[] = {
{ "all", ZFS_REDUNDANT_METADATA_ALL },
{ "most", ZFS_REDUNDANT_METADATA_MOST },
+ { "some", ZFS_REDUNDANT_METADATA_SOME },
+ { "none", ZFS_REDUNDANT_METADATA_NONE },
{ NULL }
};
@@ -388,7 +391,7 @@ zfs_prop_init(void)
zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata",
ZFS_REDUNDANT_METADATA_ALL,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
- "all | most", "REDUND_MD",
+ "all | most | some | none", "REDUND_MD",
redundant_metadata_table, sfeatures);
zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
@@ -745,6 +748,8 @@ zfs_prop_init(void)
boolean_t
zfs_prop_delegatable(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
zprop_desc_t *pd = &zfs_prop_table[prop];
/* The mlslabel property is never delegatable. */
@@ -855,6 +860,8 @@ zfs_prop_valid_for_type(int prop, zfs_type_t types, boolean_t headcheck)
zprop_type_t
zfs_prop_get_type(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_proptype);
}
@@ -864,6 +871,8 @@ zfs_prop_get_type(zfs_prop_t prop)
boolean_t
zfs_prop_readonly(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
zfs_prop_table[prop].pd_attr == PROP_ONETIME ||
zfs_prop_table[prop].pd_attr == PROP_ONETIME_DEFAULT);
@@ -875,6 +884,8 @@ zfs_prop_readonly(zfs_prop_t prop)
boolean_t
zfs_prop_visible(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_visible &&
zfs_prop_table[prop].pd_zfs_mod_supported);
}
@@ -885,6 +896,8 @@ zfs_prop_visible(zfs_prop_t prop)
boolean_t
zfs_prop_setonce(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_attr == PROP_ONETIME ||
zfs_prop_table[prop].pd_attr == PROP_ONETIME_DEFAULT);
}
@@ -892,12 +905,16 @@ zfs_prop_setonce(zfs_prop_t prop)
const char *
zfs_prop_default_string(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_strdefault);
}
uint64_t
zfs_prop_default_numeric(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_numdefault);
}
@@ -908,6 +925,8 @@ zfs_prop_default_numeric(zfs_prop_t prop)
const char *
zfs_prop_to_name(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_name);
}
@@ -917,6 +936,8 @@ zfs_prop_to_name(zfs_prop_t prop)
boolean_t
zfs_prop_inheritable(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_attr == PROP_INHERIT ||
zfs_prop_table[prop].pd_attr == PROP_ONETIME);
}
@@ -969,6 +990,8 @@ zfs_prop_valid_keylocation(const char *str, boolean_t encrypted)
const char *
zfs_prop_values(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_values);
}
@@ -980,6 +1003,8 @@ zfs_prop_values(zfs_prop_t prop)
int
zfs_prop_is_string(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
}
@@ -991,6 +1016,8 @@ zfs_prop_is_string(zfs_prop_t prop)
const char *
zfs_prop_column_name(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_colname);
}
@@ -1001,6 +1028,8 @@ zfs_prop_column_name(zfs_prop_t prop)
boolean_t
zfs_prop_align_right(zfs_prop_t prop)
{
+ ASSERT3S(prop, >=, 0);
+ ASSERT3S(prop, <, ZFS_NUM_PROPS);
return (zfs_prop_table[prop].pd_rightalign);
}
diff --git a/sys/contrib/openzfs/module/zcommon/zpool_prop.c b/sys/contrib/openzfs/module/zcommon/zpool_prop.c
index 4737bd628ddf..285b97909631 100644
--- a/sys/contrib/openzfs/module/zcommon/zpool_prop.c
+++ b/sys/contrib/openzfs/module/zcommon/zpool_prop.c
@@ -420,6 +420,9 @@ vdev_prop_init(void)
boolean_na_table, sfeatures);
/* default index properties */
+ zprop_register_index(VDEV_PROP_FAILFAST, "failfast", B_TRUE,
+ PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", "FAILFAST", boolean_table,
+ sfeatures);
/* hidden properties */
zprop_register_hidden(VDEV_PROP_NAME, "name", PROP_TYPE_STRING,
diff --git a/sys/contrib/openzfs/module/zfs/abd.c b/sys/contrib/openzfs/module/zfs/abd.c
index 11a1e5112544..d4921d0ba7db 100644
--- a/sys/contrib/openzfs/module/zfs/abd.c
+++ b/sys/contrib/openzfs/module/zfs/abd.c
@@ -667,15 +667,15 @@ abd_return_buf(abd_t *abd, void *buf, size_t n)
{
abd_verify(abd);
ASSERT3U(abd->abd_size, >=, n);
+#ifdef ZFS_DEBUG
+ (void) zfs_refcount_remove_many(&abd->abd_children, n, buf);
+#endif
if (abd_is_linear(abd)) {
ASSERT3P(buf, ==, abd_to_buf(abd));
} else {
ASSERT0(abd_cmp_buf(abd, buf, n));
zio_buf_free(buf, n);
}
-#ifdef ZFS_DEBUG
- (void) zfs_refcount_remove_many(&abd->abd_children, n, buf);
-#endif
}
void
diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c
index 33865f715b0f..f51f427c1bfd 100644
--- a/sys/contrib/openzfs/module/zfs/arc.c
+++ b/sys/contrib/openzfs/module/zfs/arc.c
@@ -419,12 +419,12 @@ boolean_t arc_warm;
/*
* These tunables are for performance analysis.
*/
-unsigned long zfs_arc_max = 0;
-unsigned long zfs_arc_min = 0;
-unsigned long zfs_arc_meta_limit = 0;
-unsigned long zfs_arc_meta_min = 0;
-static unsigned long zfs_arc_dnode_limit = 0;
-static unsigned long zfs_arc_dnode_reduce_percent = 10;
+uint64_t zfs_arc_max = 0;
+uint64_t zfs_arc_min = 0;
+uint64_t zfs_arc_meta_limit = 0;
+uint64_t zfs_arc_meta_min = 0;
+static uint64_t zfs_arc_dnode_limit = 0;
+static uint_t zfs_arc_dnode_reduce_percent = 10;
static uint_t zfs_arc_grow_retry = 0;
static uint_t zfs_arc_shrink_shift = 0;
static uint_t zfs_arc_p_min_shift = 0;
@@ -449,17 +449,17 @@ int zfs_compressed_arc_enabled = B_TRUE;
* ARC will evict meta buffers that exceed arc_meta_limit. This
* tunable make arc_meta_limit adjustable for different workloads.
*/
-static unsigned long zfs_arc_meta_limit_percent = 75;
+static uint64_t zfs_arc_meta_limit_percent = 75;
/*
* Percentage that can be consumed by dnodes of ARC meta buffers.
*/
-static unsigned long zfs_arc_dnode_limit_percent = 10;
+static uint_t zfs_arc_dnode_limit_percent = 10;
/*
* These tunables are Linux-specific
*/
-static unsigned long zfs_arc_sys_free = 0;
+static uint64_t zfs_arc_sys_free = 0;
static uint_t zfs_arc_min_prefetch_ms = 0;
static uint_t zfs_arc_min_prescient_prefetch_ms = 0;
static int zfs_arc_p_dampener_disable = 1;
@@ -781,12 +781,12 @@ uint64_t zfs_crc64_table[256];
#define L2ARC_FEED_TYPES 4
/* L2ARC Performance Tunables */
-unsigned long l2arc_write_max = L2ARC_WRITE_SIZE; /* def max write size */
-unsigned long l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra warmup write */
-unsigned long l2arc_headroom = L2ARC_HEADROOM; /* # of dev writes */
-unsigned long l2arc_headroom_boost = L2ARC_HEADROOM_BOOST;
-unsigned long l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */
-unsigned long l2arc_feed_min_ms = L2ARC_FEED_MIN_MS; /* min interval msecs */
+uint64_t l2arc_write_max = L2ARC_WRITE_SIZE; /* def max write size */
+uint64_t l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra warmup write */
+uint64_t l2arc_headroom = L2ARC_HEADROOM; /* # of dev writes */
+uint64_t l2arc_headroom_boost = L2ARC_HEADROOM_BOOST;
+uint64_t l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */
+uint64_t l2arc_feed_min_ms = L2ARC_FEED_MIN_MS; /* min interval msecs */
int l2arc_noprefetch = B_TRUE; /* don't cache prefetch bufs */
int l2arc_feed_again = B_TRUE; /* turbo warmup */
int l2arc_norw = B_FALSE; /* no reads during writes */
@@ -909,7 +909,7 @@ static int l2arc_mfuonly = 0;
* will vary depending of how well the specific device handles
* these commands.
*/
-static unsigned long l2arc_trim_ahead = 0;
+static uint64_t l2arc_trim_ahead = 0;
/*
* Performance tuning of L2ARC persistence:
@@ -925,7 +925,7 @@ static unsigned long l2arc_trim_ahead = 0;
* not to waste space.
*/
static int l2arc_rebuild_enabled = B_TRUE;
-static unsigned long l2arc_rebuild_blocks_min_l2size = 1024 * 1024 * 1024;
+static uint64_t l2arc_rebuild_blocks_min_l2size = 1024 * 1024 * 1024;
/* L2ARC persistence rebuild control routines. */
void l2arc_rebuild_vdev(vdev_t *vd, boolean_t reopen);
@@ -3939,7 +3939,7 @@ arc_evict_hdr(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, uint64_t *real_evicted)
* dropping from L1+L2 cached to L2-only,
* realloc to remove the L1 header.
*/
- hdr = arc_hdr_realloc(hdr, hdr_full_cache,
+ (void) arc_hdr_realloc(hdr, hdr_full_cache,
hdr_l2only_cache);
*real_evicted += HDR_FULL_SIZE - HDR_L2ONLY_SIZE;
} else {
@@ -4469,7 +4469,7 @@ restart:
* meta buffers. Requests to the upper layers will be made with
* increasingly large scan sizes until the ARC is below the limit.
*/
- if (meta_used > arc_meta_limit) {
+ if (meta_used > arc_meta_limit || arc_available_memory() < 0) {
if (type == ARC_BUFC_DATA) {
type = ARC_BUFC_METADATA;
} else {
@@ -5136,7 +5136,7 @@ arc_adapt(int bytes, arc_state_t *state)
if (!zfs_arc_p_dampener_disable)
mult = MIN(mult, 10); /* avoid wild arc_p adjustment */
- arc_p = MIN(arc_c - arc_p_min, arc_p + bytes * mult);
+ arc_p = MIN(arc_c - arc_p_min, arc_p + (uint64_t)bytes * mult);
} else if (state == arc_mfu_ghost) {
uint64_t delta;
@@ -5173,7 +5173,7 @@ arc_adapt(int bytes, arc_state_t *state)
atomic_add_64(&arc_c, (int64_t)bytes);
if (arc_c > arc_c_max)
arc_c = arc_c_max;
- else if (state == arc_anon)
+ else if (state == arc_anon && arc_p < arc_c >> 1)
atomic_add_64(&arc_p, (int64_t)bytes);
if (arc_p > arc_c)
arc_p = arc_c;
@@ -5386,7 +5386,8 @@ arc_get_data_impl(arc_buf_hdr_t *hdr, uint64_t size, const void *tag,
if (aggsum_upper_bound(&arc_sums.arcstat_size) < arc_c &&
hdr->b_l1hdr.b_state == arc_anon &&
(zfs_refcount_count(&arc_anon->arcs_size) +
- zfs_refcount_count(&arc_mru->arcs_size) > arc_p))
+ zfs_refcount_count(&arc_mru->arcs_size) > arc_p &&
+ arc_p < arc_c >> 1))
arc_p = MIN(arc_c, arc_p + size);
}
}
@@ -8539,6 +8540,7 @@ l2arc_dev_get_next(void)
else if (next == first)
break;
+ ASSERT3P(next, !=, NULL);
} while (vdev_is_dead(next->l2ad_vdev) || next->l2ad_rebuild ||
next->l2ad_trim_all);
@@ -11076,20 +11078,20 @@ EXPORT_SYMBOL(arc_add_prune_callback);
EXPORT_SYMBOL(arc_remove_prune_callback);
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min, param_set_arc_min,
- param_get_ulong, ZMOD_RW, "Minimum ARC size in bytes");
+ spl_param_get_u64, ZMOD_RW, "Minimum ARC size in bytes");
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_max,
- param_get_ulong, ZMOD_RW, "Maximum ARC size in bytes");
+ spl_param_get_u64, ZMOD_RW, "Maximum ARC size in bytes");
-ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_long,
- param_get_ulong, ZMOD_RW, "Metadata limit for ARC size in bytes");
+ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_u64,
+ spl_param_get_u64, ZMOD_RW, "Metadata limit for ARC size in bytes");
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit_percent,
- param_set_arc_long, param_get_ulong, ZMOD_RW,
+ param_set_arc_int, param_get_uint, ZMOD_RW,
"Percent of ARC size for ARC meta limit");
-ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_min, param_set_arc_long,
- param_get_ulong, ZMOD_RW, "Minimum ARC metadata size in bytes");
+ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_min, param_set_arc_u64,
+ spl_param_get_u64, ZMOD_RW, "Minimum ARC metadata size in bytes");
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, meta_prune, INT, ZMOD_RW,
"Meta objects to scan for prune");
@@ -11128,25 +11130,25 @@ ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min_prescient_prefetch_ms,
param_set_arc_int, param_get_uint, ZMOD_RW,
"Min life of prescient prefetched block in ms");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_max, U64, ZMOD_RW,
"Max write bytes per interval");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_boost, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_boost, U64, ZMOD_RW,
"Extra write bytes during device warmup");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom, U64, ZMOD_RW,
"Number of max device writes to precache");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom_boost, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom_boost, U64, ZMOD_RW,
"Compressed l2arc_headroom multiplier");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, trim_ahead, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, trim_ahead, U64, ZMOD_RW,
"TRIM ahead L2ARC write size multiplier");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_secs, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_secs, U64, ZMOD_RW,
"Seconds between L2ARC writing");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_min_ms, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_min_ms, U64, ZMOD_RW,
"Min feed interval in milliseconds");
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, noprefetch, INT, ZMOD_RW,
@@ -11164,7 +11166,7 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, meta_percent, UINT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_enabled, INT, ZMOD_RW,
"Rebuild the L2ARC when importing a pool");
-ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_blocks_min_l2size, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_blocks_min_l2size, U64, ZMOD_RW,
"Min size in bytes to write rebuild log blocks in L2ARC");
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, mfuonly, INT, ZMOD_RW,
@@ -11176,17 +11178,17 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, exclude_special, INT, ZMOD_RW,
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, lotsfree_percent, param_set_arc_int,
param_get_uint, ZMOD_RW, "System free memory I/O throttle in bytes");
-ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, sys_free, param_set_arc_long,
- param_get_ulong, ZMOD_RW, "System free memory target size in bytes");
+ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, sys_free, param_set_arc_u64,
+ spl_param_get_u64, ZMOD_RW, "System free memory target size in bytes");
-ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, dnode_limit, param_set_arc_long,
- param_get_ulong, ZMOD_RW, "Minimum bytes of dnodes in ARC");
+ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, dnode_limit, param_set_arc_u64,
+ spl_param_get_u64, ZMOD_RW, "Minimum bytes of dnodes in ARC");
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, dnode_limit_percent,
- param_set_arc_long, param_get_ulong, ZMOD_RW,
+ param_set_arc_int, param_get_uint, ZMOD_RW,
"Percent of ARC meta buffers for dnodes");
-ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, dnode_reduce_percent, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, dnode_reduce_percent, UINT, ZMOD_RW,
"Percentage of excess dnodes to try to unpin");
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, eviction_pct, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/btree.c b/sys/contrib/openzfs/module/zfs/btree.c
index f0a9222a4308..4c25afaa8199 100644
--- a/sys/contrib/openzfs/module/zfs/btree.c
+++ b/sys/contrib/openzfs/module/zfs/btree.c
@@ -102,7 +102,7 @@ zfs_btree_poison_node(zfs_btree_t *tree, zfs_btree_hdr_t *hdr)
(void) memset(leaf->btl_elems, 0x0f, hdr->bth_first * size);
(void) memset(leaf->btl_elems +
(hdr->bth_first + hdr->bth_count) * size, 0x0f,
- BTREE_LEAF_ESIZE -
+ tree->bt_leaf_size - offsetof(zfs_btree_leaf_t, btl_elems) -
(hdr->bth_first + hdr->bth_count) * size);
}
#endif
@@ -173,16 +173,44 @@ zfs_btree_fini(void)
kmem_cache_destroy(zfs_btree_leaf_cache);
}
+static void *
+zfs_btree_leaf_alloc(zfs_btree_t *tree)
+{
+ if (tree->bt_leaf_size == BTREE_LEAF_SIZE)
+ return (kmem_cache_alloc(zfs_btree_leaf_cache, KM_SLEEP));
+ else
+ return (kmem_alloc(tree->bt_leaf_size, KM_SLEEP));
+}
+
+static void
+zfs_btree_leaf_free(zfs_btree_t *tree, void *ptr)
+{
+ if (tree->bt_leaf_size == BTREE_LEAF_SIZE)
+ return (kmem_cache_free(zfs_btree_leaf_cache, ptr));
+ else
+ return (kmem_free(ptr, tree->bt_leaf_size));
+}
+
void
zfs_btree_create(zfs_btree_t *tree, int (*compar) (const void *, const void *),
size_t size)
{
- ASSERT3U(size, <=, BTREE_LEAF_ESIZE / 2);
+ zfs_btree_create_custom(tree, compar, size, BTREE_LEAF_SIZE);
+}
+
+void
+zfs_btree_create_custom(zfs_btree_t *tree,
+ int (*compar) (const void *, const void *),
+ size_t size, size_t lsize)
+{
+ size_t esize = lsize - offsetof(zfs_btree_leaf_t, btl_elems);
+ ASSERT3U(size, <=, esize / 2);
memset(tree, 0, sizeof (*tree));
tree->bt_compar = compar;
tree->bt_elem_size = size;
- tree->bt_leaf_cap = P2ALIGN(BTREE_LEAF_ESIZE / size, 2);
+ tree->bt_leaf_size = lsize;
+ tree->bt_leaf_cap = P2ALIGN(esize / size, 2);
tree->bt_height = -1;
tree->bt_bulk = NULL;
}
@@ -290,7 +318,7 @@ zfs_btree_find(zfs_btree_t *tree, const void *value, zfs_btree_index_t *where)
zfs_btree_core_t *node = NULL;
uint32_t child = 0;
- uint64_t depth = 0;
+ uint32_t depth = 0;
/*
* Iterate down the tree, finding which child the value should be in
@@ -811,8 +839,7 @@ zfs_btree_insert_into_leaf(zfs_btree_t *tree, zfs_btree_leaf_t *leaf,
move_count++;
}
tree->bt_num_nodes++;
- zfs_btree_leaf_t *new_leaf = kmem_cache_alloc(zfs_btree_leaf_cache,
- KM_SLEEP);
+ zfs_btree_leaf_t *new_leaf = zfs_btree_leaf_alloc(tree);
zfs_btree_hdr_t *new_hdr = &new_leaf->btl_hdr;
new_hdr->bth_parent = leaf->btl_hdr.bth_parent;
new_hdr->bth_first = (tree->bt_bulk ? 0 : capacity / 4) +
@@ -1078,8 +1105,7 @@ zfs_btree_add_idx(zfs_btree_t *tree, const void *value,
ASSERT0(where->bti_offset);
tree->bt_num_nodes++;
- zfs_btree_leaf_t *leaf = kmem_cache_alloc(zfs_btree_leaf_cache,
- KM_SLEEP);
+ zfs_btree_leaf_t *leaf = zfs_btree_leaf_alloc(tree);
tree->bt_root = &leaf->btl_hdr;
tree->bt_height++;
@@ -1378,7 +1404,7 @@ zfs_btree_node_destroy(zfs_btree_t *tree, zfs_btree_hdr_t *node)
{
tree->bt_num_nodes--;
if (!zfs_btree_is_core(node)) {
- kmem_cache_free(zfs_btree_leaf_cache, node);
+ zfs_btree_leaf_free(tree, node);
} else {
kmem_free(node, sizeof (zfs_btree_core_t) +
BTREE_CORE_ELEMS * tree->bt_elem_size);
@@ -1991,7 +2017,7 @@ zfs_btree_verify_counts(zfs_btree_t *tree)
*/
static uint64_t
zfs_btree_verify_height_helper(zfs_btree_t *tree, zfs_btree_hdr_t *hdr,
- int64_t height)
+ int32_t height)
{
if (!zfs_btree_is_core(hdr)) {
VERIFY0(height);
@@ -2117,8 +2143,10 @@ zfs_btree_verify_poison_helper(zfs_btree_t *tree, zfs_btree_hdr_t *hdr)
zfs_btree_leaf_t *leaf = (zfs_btree_leaf_t *)hdr;
for (size_t i = 0; i < hdr->bth_first * size; i++)
VERIFY3U(leaf->btl_elems[i], ==, 0x0f);
+ size_t esize = tree->bt_leaf_size -
+ offsetof(zfs_btree_leaf_t, btl_elems);
for (size_t i = (hdr->bth_first + hdr->bth_count) * size;
- i < BTREE_LEAF_ESIZE; i++)
+ i < esize; i++)
VERIFY3U(leaf->btl_elems[i], ==, 0x0f);
} else {
zfs_btree_core_t *node = (zfs_btree_core_t *)hdr;
diff --git a/sys/contrib/openzfs/module/zfs/dataset_kstats.c b/sys/contrib/openzfs/module/zfs/dataset_kstats.c
index b63f42a21e44..57b8faf213eb 100644
--- a/sys/contrib/openzfs/module/zfs/dataset_kstats.c
+++ b/sys/contrib/openzfs/module/zfs/dataset_kstats.c
@@ -128,8 +128,13 @@ dataset_kstats_create(dataset_kstats_t *dk, objset_t *objset)
" snprintf() for kstat name returned %d",
(unsigned long long)dmu_objset_id(objset), n);
return (SET_ERROR(EINVAL));
+ } else if (n >= KSTAT_STRLEN) {
+ zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
+ "kstat name length (%d) exceeds limit (%d)",
+ (unsigned long long)dmu_objset_id(objset),
+ n, KSTAT_STRLEN);
+ return (SET_ERROR(ENAMETOOLONG));
}
- ASSERT3U(n, <, KSTAT_STRLEN);
kstat_t *kstat = kstat_create(kstat_module_name, 0, kstat_name,
"dataset", KSTAT_TYPE_NAMED,
diff --git a/sys/contrib/openzfs/module/zfs/dbuf.c b/sys/contrib/openzfs/module/zfs/dbuf.c
index db1123d37d98..7982d9702896 100644
--- a/sys/contrib/openzfs/module/zfs/dbuf.c
+++ b/sys/contrib/openzfs/module/zfs/dbuf.c
@@ -227,8 +227,8 @@ typedef struct dbuf_cache {
dbuf_cache_t dbuf_caches[DB_CACHE_MAX];
/* Size limits for the caches */
-static unsigned long dbuf_cache_max_bytes = ULONG_MAX;
-static unsigned long dbuf_metadata_cache_max_bytes = ULONG_MAX;
+static uint64_t dbuf_cache_max_bytes = UINT64_MAX;
+static uint64_t dbuf_metadata_cache_max_bytes = UINT64_MAX;
/* Set the default sizes of the caches to log2 fraction of arc size */
static uint_t dbuf_cache_shift = 5;
@@ -1549,7 +1549,6 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags,
uint32_t aflags = ARC_FLAG_NOWAIT;
int err, zio_flags;
- err = zio_flags = 0;
DB_DNODE_ENTER(db);
dn = DB_DNODE(db);
ASSERT(!zfs_refcount_is_zero(&db->db_holds));
@@ -2687,6 +2686,7 @@ dbuf_override_impl(dmu_buf_impl_t *db, const blkptr_t *bp, dmu_tx_t *tx)
dbuf_dirty_record_t *dr;
dr = list_head(&db->db_dirty_records);
+ ASSERT3P(dr, !=, NULL);
ASSERT3U(dr->dr_txg, ==, tx->tx_txg);
dl = &dr->dt.dl;
dl->dr_overridden_by = *bp;
@@ -2748,6 +2748,7 @@ dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data,
dmu_buf_will_not_fill(dbuf, tx);
dr = list_head(&db->db_dirty_records);
+ ASSERT3P(dr, !=, NULL);
ASSERT3U(dr->dr_txg, ==, tx->tx_txg);
dl = &dr->dt.dl;
encode_embedded_bp_compressed(&dl->dr_overridden_by,
@@ -5120,7 +5121,7 @@ EXPORT_SYMBOL(dmu_buf_set_user_ie);
EXPORT_SYMBOL(dmu_buf_get_user);
EXPORT_SYMBOL(dmu_buf_get_blkptr);
-ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, max_bytes, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, max_bytes, U64, ZMOD_RW,
"Maximum size in bytes of the dbuf cache.");
ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, hiwater_pct, UINT, ZMOD_RW,
@@ -5129,7 +5130,7 @@ ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, hiwater_pct, UINT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, lowater_pct, UINT, ZMOD_RW,
"Percentage below dbuf_cache_max_bytes when dbuf eviction stops.");
-ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_max_bytes, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_max_bytes, U64, ZMOD_RW,
"Maximum size in bytes of dbuf metadata cache.");
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, cache_shift, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/dmu.c b/sys/contrib/openzfs/module/zfs/dmu.c
index 9e67eb51f415..45304e7ddf7a 100644
--- a/sys/contrib/openzfs/module/zfs/dmu.c
+++ b/sys/contrib/openzfs/module/zfs/dmu.c
@@ -28,6 +28,7 @@
* Copyright (c) 2019 Datto Inc.
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, Allan Jude
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
#include <sys/dmu.h>
@@ -70,7 +71,7 @@ static int zfs_nopwrite_enabled = 1;
* will wait until the next TXG.
* A value of zero will disable this throttle.
*/
-static unsigned long zfs_per_txg_dirty_frees_percent = 30;
+static uint_t zfs_per_txg_dirty_frees_percent = 30;
/*
* Enable/disable forcing txg sync when dirty checking for holes with lseek().
@@ -1435,7 +1436,7 @@ dmu_return_arcbuf(arc_buf_t *buf)
*/
int
dmu_lightweight_write_by_dnode(dnode_t *dn, uint64_t offset, abd_t *abd,
- const zio_prop_t *zp, enum zio_flag flags, dmu_tx_t *tx)
+ const zio_prop_t *zp, zio_flag_t flags, dmu_tx_t *tx)
{
dbuf_dirty_record_t *dr =
dbuf_dirty_lightweight(dn, dbuf_whichblock(dn, 0, offset), tx);
@@ -1992,12 +1993,22 @@ dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
ZCHECKSUM_FLAG_EMBEDDED))
checksum = ZIO_CHECKSUM_FLETCHER_4;
- if (os->os_redundant_metadata == ZFS_REDUNDANT_METADATA_ALL ||
- (os->os_redundant_metadata ==
- ZFS_REDUNDANT_METADATA_MOST &&
- (level >= zfs_redundant_metadata_most_ditto_level ||
- DMU_OT_IS_METADATA(type) || (wp & WP_SPILL))))
+ switch (os->os_redundant_metadata) {
+ case ZFS_REDUNDANT_METADATA_ALL:
copies++;
+ break;
+ case ZFS_REDUNDANT_METADATA_MOST:
+ if (level >= zfs_redundant_metadata_most_ditto_level ||
+ DMU_OT_IS_METADATA(type) || (wp & WP_SPILL))
+ copies++;
+ break;
+ case ZFS_REDUNDANT_METADATA_SOME:
+ if (DMU_OT_IS_CRITICAL(type))
+ copies++;
+ break;
+ case ZFS_REDUNDANT_METADATA_NONE:
+ break;
+ }
} else if (wp & WP_NOFILL) {
ASSERT(level == 0);
@@ -2355,7 +2366,7 @@ EXPORT_SYMBOL(dmu_ot);
ZFS_MODULE_PARAM(zfs, zfs_, nopwrite_enabled, INT, ZMOD_RW,
"Enable NOP writes");
-ZFS_MODULE_PARAM(zfs, zfs_, per_txg_dirty_frees_percent, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, per_txg_dirty_frees_percent, UINT, ZMOD_RW,
"Percentage of dirtied blocks from frees in one TXG");
ZFS_MODULE_PARAM(zfs, zfs_, dmu_offset_next_sync, INT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/dmu_objset.c b/sys/contrib/openzfs/module/zfs/dmu_objset.c
index 4c20afcdb9c6..c17c829a04d8 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_objset.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_objset.c
@@ -32,6 +32,7 @@
* Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
* Copyright (c) 2019, Klara Inc.
* Copyright (c) 2019, Allan Jude
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -287,7 +288,9 @@ redundant_metadata_changed_cb(void *arg, uint64_t newval)
* Inheritance and range checking should have been done by now.
*/
ASSERT(newval == ZFS_REDUNDANT_METADATA_ALL ||
- newval == ZFS_REDUNDANT_METADATA_MOST);
+ newval == ZFS_REDUNDANT_METADATA_MOST ||
+ newval == ZFS_REDUNDANT_METADATA_SOME ||
+ newval == ZFS_REDUNDANT_METADATA_NONE);
os->os_redundant_metadata = newval;
}
@@ -479,7 +482,7 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
arc_flags_t aflags = ARC_FLAG_WAIT;
zbookmark_phys_t zb;
int size;
- enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
+ zio_flag_t zio_flags = ZIO_FLAG_CANFAIL;
SET_BOOKMARK(&zb, ds ? ds->ds_object : DMU_META_OBJSET,
ZB_ROOT_OBJECT, ZB_ROOT_LEVEL, ZB_ROOT_BLKID);
diff --git a/sys/contrib/openzfs/module/zfs/dmu_recv.c b/sys/contrib/openzfs/module/zfs/dmu_recv.c
index a9e4a6745905..339fb149a49f 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_recv.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_recv.c
@@ -646,7 +646,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
* so add the DS_HOLD_FLAG_DECRYPT flag only if we are dealing
* with a dataset we may encrypt.
*/
- if (drba->drba_dcp != NULL &&
+ if (drba->drba_dcp == NULL ||
drba->drba_dcp->cp_crypt != ZIO_CRYPT_OFF) {
dsflags |= DS_HOLD_FLAG_DECRYPT;
}
@@ -1344,7 +1344,7 @@ do_corrective_recv(struct receive_writer_arg *rwa, struct drr_write *drrw,
dnode_t *dn;
abd_t *abd = rrd->abd;
zio_cksum_t bp_cksum = bp->blk_cksum;
- enum zio_flag flags = ZIO_FLAG_SPECULATIVE |
+ zio_flag_t flags = ZIO_FLAG_SPECULATIVE |
ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_RETRY | ZIO_FLAG_CANFAIL;
if (rwa->raw)
@@ -2186,7 +2186,7 @@ flush_write_batch_impl(struct receive_writer_arg *rwa)
zio_prop_t zp;
dmu_write_policy(rwa->os, dn, 0, 0, &zp);
- enum zio_flag zio_flags = 0;
+ zio_flag_t zio_flags = 0;
if (rwa->raw) {
zp.zp_encrypt = B_TRUE;
diff --git a/sys/contrib/openzfs/module/zfs/dmu_send.c b/sys/contrib/openzfs/module/zfs/dmu_send.c
index 4ee3ffc352b8..ccb7eb20756d 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_send.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_send.c
@@ -934,7 +934,7 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
ASSERT3U(range->start_blkid + 1, ==, range->end_blkid);
if (BP_GET_TYPE(bp) == DMU_OT_SA) {
arc_flags_t aflags = ARC_FLAG_WAIT;
- enum zio_flag zioflags = ZIO_FLAG_CANFAIL;
+ zio_flag_t zioflags = ZIO_FLAG_CANFAIL;
if (dscp->dsc_featureflags & DMU_BACKUP_FEATURE_RAW) {
ASSERT(BP_IS_PROTECTED(bp));
@@ -1654,7 +1654,7 @@ issue_data_read(struct send_reader_thread_arg *srta, struct send_range *range)
!split_large_blocks && !BP_SHOULD_BYTESWAP(bp) &&
!BP_IS_EMBEDDED(bp) && !DMU_OT_IS_METADATA(BP_GET_TYPE(bp));
- enum zio_flag zioflags = ZIO_FLAG_CANFAIL;
+ zio_flag_t zioflags = ZIO_FLAG_CANFAIL;
if (srta->featureflags & DMU_BACKUP_FEATURE_RAW) {
zioflags |= ZIO_FLAG_RAW;
@@ -2511,8 +2511,7 @@ dmu_send_impl(struct dmu_send_params *dspp)
}
if (featureflags & DMU_BACKUP_FEATURE_RAW) {
- uint64_t ivset_guid = (ancestor_zb != NULL) ?
- ancestor_zb->zbm_ivset_guid : 0;
+ uint64_t ivset_guid = ancestor_zb->zbm_ivset_guid;
nvlist_t *keynvl = NULL;
ASSERT(os->os_encrypted);
@@ -2716,6 +2715,10 @@ dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap,
dspp.numfromredactsnaps = NUM_SNAPS_NOT_REDACTED;
err = dmu_send_impl(&dspp);
}
+ if (dspp.fromredactsnaps)
+ kmem_free(dspp.fromredactsnaps,
+ dspp.numfromredactsnaps * sizeof (uint64_t));
+
dsl_dataset_rele(dspp.to_ds, FTAG);
return (err);
}
@@ -2924,6 +2927,10 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok,
/* dmu_send_impl will call dsl_pool_rele for us. */
err = dmu_send_impl(&dspp);
} else {
+ if (dspp.fromredactsnaps)
+ kmem_free(dspp.fromredactsnaps,
+ dspp.numfromredactsnaps *
+ sizeof (uint64_t));
dsl_pool_rele(dspp.dp, FTAG);
}
} else {
diff --git a/sys/contrib/openzfs/module/zfs/dmu_traverse.c b/sys/contrib/openzfs/module/zfs/dmu_traverse.c
index 2ed75640f68d..377634c72bba 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_traverse.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_traverse.c
@@ -111,6 +111,7 @@ traverse_zil_record(zilog_t *zilog, const lr_t *lrc, void *arg,
if (claim_txg == 0 || bp->blk_birth < claim_txg)
return (0);
+ ASSERT3U(BP_GET_LSIZE(bp), !=, 0);
SET_BOOKMARK(&zb, td->td_objset, lr->lr_foid,
ZB_ZIL_LEVEL, lr->lr_offset / BP_GET_LSIZE(bp));
@@ -670,7 +671,7 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp,
/* See comment on ZIL traversal in dsl_scan_visitds. */
if (ds != NULL && !ds->ds_is_snapshot && !BP_IS_HOLE(rootbp)) {
- enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
+ zio_flag_t zio_flags = ZIO_FLAG_CANFAIL;
uint32_t flags = ARC_FLAG_WAIT;
objset_phys_t *osp;
arc_buf_t *buf;
diff --git a/sys/contrib/openzfs/module/zfs/dmu_zfetch.c b/sys/contrib/openzfs/module/zfs/dmu_zfetch.c
index 101d2ee7b7a2..1d63d7de65a1 100644
--- a/sys/contrib/openzfs/module/zfs/dmu_zfetch.c
+++ b/sys/contrib/openzfs/module/zfs/dmu_zfetch.c
@@ -58,7 +58,7 @@ unsigned int zfetch_max_distance = 64 * 1024 * 1024;
/* max bytes to prefetch indirects for per stream (default 64MB) */
unsigned int zfetch_max_idistance = 64 * 1024 * 1024;
/* max number of bytes in an array_read in which we allow prefetching (1MB) */
-unsigned long zfetch_array_rd_sz = 1024 * 1024;
+uint64_t zfetch_array_rd_sz = 1024 * 1024;
typedef struct zfetch_stats {
kstat_named_t zfetchstat_hits;
@@ -565,5 +565,5 @@ ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_distance, UINT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_idistance, UINT, ZMOD_RW,
"Max bytes to prefetch indirects for per stream");
-ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, array_rd_sz, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, array_rd_sz, U64, ZMOD_RW,
"Number of bytes in a array_read");
diff --git a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
index 8ca7ba8957aa..b95c94beff1f 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_bookmark.c
@@ -229,7 +229,6 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp,
switch (error) {
case ESRCH:
/* happy path: new bmark doesn't exist, proceed after switch */
- error = 0;
break;
case 0:
error = SET_ERROR(EEXIST);
diff --git a/sys/contrib/openzfs/module/zfs/dsl_crypt.c b/sys/contrib/openzfs/module/zfs/dsl_crypt.c
index ce2e6ce742a2..382de208b01d 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_crypt.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_crypt.c
@@ -2671,6 +2671,7 @@ spa_do_crypt_objset_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj,
objset_phys_t *osp = buf;
uint8_t portable_mac[ZIO_OBJSET_MAC_LEN];
uint8_t local_mac[ZIO_OBJSET_MAC_LEN];
+ const uint8_t zeroed_mac[ZIO_OBJSET_MAC_LEN] = {0};
/* look up the key from the spa's keystore */
ret = spa_keystore_lookup_key(spa, dsobj, FTAG, &dck);
@@ -2696,8 +2697,21 @@ spa_do_crypt_objset_mac_abd(boolean_t generate, spa_t *spa, uint64_t dsobj,
if (memcmp(portable_mac, osp->os_portable_mac,
ZIO_OBJSET_MAC_LEN) != 0 ||
memcmp(local_mac, osp->os_local_mac, ZIO_OBJSET_MAC_LEN) != 0) {
- abd_return_buf(abd, buf, datalen);
- return (SET_ERROR(ECKSUM));
+ /*
+ * If the MAC is zeroed out, we failed to decrypt it.
+ * This should only arise, at least on Linux,
+ * if we hit edge case handling for useraccounting, since we
+ * shouldn't get here without bailing out on error earlier
+ * otherwise.
+ *
+ * So if we're in that case, we can just fall through and
+ * special-casing noticing that it's zero will handle it
+ * elsewhere, since we can just regenerate it.
+ */
+ if (memcmp(local_mac, zeroed_mac, ZIO_OBJSET_MAC_LEN) != 0) {
+ abd_return_buf(abd, buf, datalen);
+ return (SET_ERROR(ECKSUM));
+ }
}
abd_return_buf(abd, buf, datalen);
diff --git a/sys/contrib/openzfs/module/zfs/dsl_dataset.c b/sys/contrib/openzfs/module/zfs/dsl_dataset.c
index 7a066b786cd0..c7577fc584af 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_dataset.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_dataset.c
@@ -3421,7 +3421,8 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx)
conflicting_snaps = B_TRUE;
} else if (err == ESRCH) {
err = 0;
- } else if (err != 0) {
+ }
+ if (err != 0) {
goto out;
}
}
diff --git a/sys/contrib/openzfs/module/zfs/dsl_deadlist.c b/sys/contrib/openzfs/module/zfs/dsl_deadlist.c
index 1ecae0fe3865..2b33446e66af 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_deadlist.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_deadlist.c
@@ -92,7 +92,7 @@
* will be loaded into memory and shouldn't take up an inordinate amount of
* space. We settled on ~500000 entries, corresponding to roughly 128M.
*/
-unsigned long zfs_livelist_max_entries = 500000;
+uint64_t zfs_livelist_max_entries = 500000;
/*
* We can approximate how much of a performance gain a livelist will give us
@@ -542,6 +542,7 @@ dsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx)
dle = avl_find(&dl->dl_tree, &dle_tofind, NULL);
ASSERT3P(dle, !=, NULL);
dle_prev = AVL_PREV(&dl->dl_tree, dle);
+ ASSERT3P(dle_prev, !=, NULL);
dle_enqueue_subobj(dl, dle_prev, dle->dle_bpobj.bpo_object, tx);
@@ -1039,7 +1040,7 @@ dsl_process_sub_livelist(bpobj_t *bpobj, bplist_t *to_free, zthr_t *t,
return (err);
}
-ZFS_MODULE_PARAM(zfs_livelist, zfs_livelist_, max_entries, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_livelist, zfs_livelist_, max_entries, U64, ZMOD_RW,
"Size to start the next sub-livelist in a livelist");
ZFS_MODULE_PARAM(zfs_livelist, zfs_livelist_, min_percent_shared, INT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/dsl_dir.c b/sys/contrib/openzfs/module/zfs/dsl_dir.c
index d93c7f08c1c2..c1afaa6aaf82 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_dir.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_dir.c
@@ -54,6 +54,15 @@
#include "zfs_prop.h"
/*
+ * This controls if we verify the ZVOL quota or not.
+ * Currently, quotas are not implemented for ZVOLs.
+ * The quota size is the size of the ZVOL.
+ * The size of the volume already implies the ZVOL size quota.
+ * The quota mechanism can introduce a significant performance drop.
+ */
+static int zvol_enforce_quotas = B_TRUE;
+
+/*
* Filesystem and Snapshot Limits
* ------------------------------
*
@@ -815,6 +824,18 @@ dsl_fs_ss_limit_check(dsl_dir_t *dd, uint64_t delta, zfs_prop_t prop,
ASSERT(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
prop == ZFS_PROP_SNAPSHOT_LIMIT);
+ if (prop == ZFS_PROP_SNAPSHOT_LIMIT) {
+ /*
+ * We don't enforce the limit for temporary snapshots. This is
+ * indicated by a NULL cred_t argument.
+ */
+ if (cr == NULL)
+ return (0);
+
+ count_prop = DD_FIELD_SNAPSHOT_COUNT;
+ } else {
+ count_prop = DD_FIELD_FILESYSTEM_COUNT;
+ }
/*
* If we're allowed to change the limit, don't enforce the limit
* e.g. this can happen if a snapshot is taken by an administrative
@@ -834,19 +855,6 @@ dsl_fs_ss_limit_check(dsl_dir_t *dd, uint64_t delta, zfs_prop_t prop,
if (delta == 0)
return (0);
- if (prop == ZFS_PROP_SNAPSHOT_LIMIT) {
- /*
- * We don't enforce the limit for temporary snapshots. This is
- * indicated by a NULL cred_t argument.
- */
- if (cr == NULL)
- return (0);
-
- count_prop = DD_FIELD_SNAPSHOT_COUNT;
- } else {
- count_prop = DD_FIELD_FILESYSTEM_COUNT;
- }
-
/*
* If an ancestor has been provided, stop checking the limit once we
* hit that dir. We need this during rename so that we don't overcount
@@ -1268,6 +1276,7 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree,
uint64_t quota;
struct tempreserve *tr;
int retval;
+ uint64_t ext_quota;
uint64_t ref_rsrv;
top_of_function:
@@ -1311,7 +1320,9 @@ top_of_function:
* If this transaction will result in a net free of space,
* we want to let it through.
*/
- if (ignorequota || netfree || dsl_dir_phys(dd)->dd_quota == 0)
+ if (ignorequota || netfree || dsl_dir_phys(dd)->dd_quota == 0 ||
+ (tx->tx_objset && dmu_objset_type(tx->tx_objset) == DMU_OST_ZVOL &&
+ zvol_enforce_quotas == B_FALSE))
quota = UINT64_MAX;
else
quota = dsl_dir_phys(dd)->dd_quota;
@@ -1343,7 +1354,16 @@ top_of_function:
* on-disk is over quota and there are no pending changes
* or deferred frees (which may free up space for us).
*/
- if (used_on_disk + est_inflight >= quota) {
+ ext_quota = quota >> 5;
+ if (quota == UINT64_MAX)
+ ext_quota = 0;
+
+ if (used_on_disk >= quota) {
+ /* Quota exceeded */
+ mutex_exit(&dd->dd_lock);
+ DMU_TX_STAT_BUMP(dmu_tx_quota);
+ return (retval);
+ } else if (used_on_disk + est_inflight >= quota + ext_quota) {
if (est_inflight > 0 || used_on_disk < quota) {
retval = SET_ERROR(ERESTART);
} else {
@@ -1390,10 +1410,9 @@ top_of_function:
ignorequota = (dsl_dir_phys(dd)->dd_head_dataset_obj == 0);
first = B_FALSE;
goto top_of_function;
-
- } else {
- return (0);
}
+
+ return (0);
}
/*
@@ -2474,3 +2493,7 @@ dsl_dir_cancel_waiters(dsl_dir_t *dd)
EXPORT_SYMBOL(dsl_dir_set_quota);
EXPORT_SYMBOL(dsl_dir_set_reservation);
#endif
+
+/* CSTYLED */
+ZFS_MODULE_PARAM(zfs, , zvol_enforce_quotas, INT, ZMOD_RW,
+ "Enable strict ZVOL quota enforcment");
diff --git a/sys/contrib/openzfs/module/zfs/dsl_pool.c b/sys/contrib/openzfs/module/zfs/dsl_pool.c
index 4fd3722a051e..5ca918a87ee1 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_pool.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_pool.c
@@ -99,8 +99,8 @@
* capped at zfs_dirty_data_max_max. It can also be overridden with a module
* parameter.
*/
-unsigned long zfs_dirty_data_max = 0;
-unsigned long zfs_dirty_data_max_max = 0;
+uint64_t zfs_dirty_data_max = 0;
+uint64_t zfs_dirty_data_max_max = 0;
uint_t zfs_dirty_data_max_percent = 10;
uint_t zfs_dirty_data_max_max_percent = 25;
@@ -109,7 +109,7 @@ uint_t zfs_dirty_data_max_max_percent = 25;
* when approaching the limit until log data is cleared out after txg sync.
* It only counts TX_WRITE log with WR_COPIED or WR_NEED_COPY.
*/
-unsigned long zfs_wrlog_data_max = 0;
+uint64_t zfs_wrlog_data_max = 0;
/*
* If there's at least this much dirty data (as a percentage of
@@ -138,7 +138,7 @@ uint_t zfs_delay_min_dirty_percent = 60;
* Note: zfs_delay_scale * zfs_dirty_data_max must be < 2^64, due to the
* multiply in dmu_tx_delay().
*/
-unsigned long zfs_delay_scale = 1000 * 1000 * 1000 / 2000;
+uint64_t zfs_delay_scale = 1000 * 1000 * 1000 / 2000;
/*
* This determines the number of threads used by the dp_sync_taskq.
@@ -331,7 +331,6 @@ dsl_pool_open(dsl_pool_t *dp)
/*
* We might not have created the remap bpobj yet.
*/
- err = 0;
} else {
goto out;
}
@@ -1465,20 +1464,20 @@ ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max_max_percent, UINT, ZMOD_RD,
ZFS_MODULE_PARAM(zfs, zfs_, delay_min_dirty_percent, UINT, ZMOD_RW,
"Transaction delay threshold");
-ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max, U64, ZMOD_RW,
"Determines the dirty space limit");
-ZFS_MODULE_PARAM(zfs, zfs_, wrlog_data_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, wrlog_data_max, U64, ZMOD_RW,
"The size limit of write-transaction zil log data");
/* zfs_dirty_data_max_max only applied at module load in arc_init(). */
-ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max_max, ULONG, ZMOD_RD,
+ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max_max, U64, ZMOD_RD,
"zfs_dirty_data_max upper bound in bytes");
ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_sync_percent, UINT, ZMOD_RW,
"Dirty data txg sync threshold as a percentage of zfs_dirty_data_max");
-ZFS_MODULE_PARAM(zfs, zfs_, delay_scale, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, delay_scale, U64, ZMOD_RW,
"How quickly delay approaches infinity");
ZFS_MODULE_PARAM(zfs, zfs_, sync_taskq_batch_pct, INT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/dsl_prop.c b/sys/contrib/openzfs/module/zfs/dsl_prop.c
index 610e887b3fba..d1c0059092b1 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_prop.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_prop.c
@@ -23,6 +23,7 @@
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 Martin Matuska. All rights reserved.
* Copyright 2019 Joyent, Inc.
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
#include <sys/zfs_context.h>
@@ -41,6 +42,7 @@
#define ZPROP_INHERIT_SUFFIX "$inherit"
#define ZPROP_RECVD_SUFFIX "$recvd"
+#define ZPROP_IUV_SUFFIX "$iuv"
static int
dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
@@ -69,6 +71,17 @@ dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
return (0);
}
+static int
+dsl_prop_known_index(zfs_prop_t prop, uint64_t value)
+{
+ const char *str = NULL;
+ if (prop != ZPROP_CONT && prop != ZPROP_INVAL &&
+ zfs_prop_get_type(prop) == PROP_TYPE_INDEX)
+ return (!zfs_prop_index_to_string(prop, value, &str));
+
+ return (-1);
+}
+
int
dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
int intsz, int numints, void *buf, char *setpoint, boolean_t snapshot)
@@ -81,6 +94,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
boolean_t inheriting = B_FALSE;
char *inheritstr;
char *recvdstr;
+ char *iuvstr;
ASSERT(dsl_pool_config_held(dd->dd_pool));
@@ -91,6 +105,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
inheritable = (prop == ZPROP_USERPROP || zfs_prop_inheritable(prop));
inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
+ iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
/*
* Note: dd may become NULL, therefore we shouldn't dereference it
@@ -105,6 +120,18 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
inheriting = B_TRUE;
}
+ /* Check for a iuv value. */
+ err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
+ iuvstr, intsz, numints, buf);
+ if (dsl_prop_known_index(zfs_name_to_prop(propname),
+ *(uint64_t *)buf) != 1)
+ err = ENOENT;
+ if (err != ENOENT) {
+ if (setpoint != NULL && err == 0)
+ dsl_dir_name(dd, setpoint);
+ break;
+ }
+
/* Check for a local value. */
err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
propname, intsz, numints, buf);
@@ -155,6 +182,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
kmem_strfree(inheritstr);
kmem_strfree(recvdstr);
+ kmem_strfree(iuvstr);
return (err);
}
@@ -647,6 +675,45 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
dsl_dir_rele(dd, FTAG);
}
+
+/*
+ * For newer values in zfs index type properties, we add a new key
+ * propname$iuv (iuv = Ignore Unknown Values) to the properties zap object
+ * to store the new property value and store the default value in the
+ * existing prop key. So that the propname$iuv key is ignored by the older zfs
+ * versions and the default property value from the existing prop key is
+ * used.
+ */
+static void
+dsl_prop_set_iuv(objset_t *mos, uint64_t zapobj, const char *propname,
+ int intsz, int numints, const void *value, dmu_tx_t *tx)
+{
+ char *iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
+ boolean_t iuv = B_FALSE;
+ zfs_prop_t prop = zfs_name_to_prop(propname);
+
+ switch (prop) {
+ case ZFS_PROP_REDUNDANT_METADATA:
+ if (*(uint64_t *)value == ZFS_REDUNDANT_METADATA_SOME ||
+ *(uint64_t *)value == ZFS_REDUNDANT_METADATA_NONE)
+ iuv = B_TRUE;
+ break;
+ default:
+ break;
+ }
+
+ if (iuv) {
+ VERIFY0(zap_update(mos, zapobj, iuvstr, intsz, numints,
+ value, tx));
+ uint64_t val = zfs_prop_default_numeric(prop);
+ VERIFY0(zap_update(mos, zapobj, propname, intsz, numints,
+ &val, tx));
+ } else {
+ zap_remove(mos, zapobj, iuvstr, tx);
+ }
+ kmem_strfree(iuvstr);
+}
+
void
dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
zprop_source_t source, int intsz, int numints, const void *value,
@@ -659,6 +726,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
const char *valstr = NULL;
char *inheritstr;
char *recvdstr;
+ char *iuvstr;
char *tbuf = NULL;
int err;
uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
@@ -692,6 +760,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
+ iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX);
switch ((int)source) {
case ZPROP_SRC_NONE:
@@ -709,11 +778,14 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
/*
* remove propname$inherit
* set propname -> value
+ * set propname$iuv -> new property value
*/
err = zap_remove(mos, zapobj, inheritstr, tx);
ASSERT(err == 0 || err == ENOENT);
VERIFY0(zap_update(mos, zapobj, propname,
intsz, numints, value, tx));
+ (void) dsl_prop_set_iuv(mos, zapobj, propname, intsz,
+ numints, value, tx);
break;
case ZPROP_SRC_INHERITED:
/*
@@ -723,6 +795,8 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
*/
err = zap_remove(mos, zapobj, propname, tx);
ASSERT(err == 0 || err == ENOENT);
+ err = zap_remove(mos, zapobj, iuvstr, tx);
+ ASSERT(err == 0 || err == ENOENT);
if (version >= SPA_VERSION_RECVD_PROPS &&
dsl_prop_get_int_ds(ds, ZPROP_HAS_RECVD, &dummy) == 0) {
dummy = 0;
@@ -763,6 +837,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
kmem_strfree(inheritstr);
kmem_strfree(recvdstr);
+ kmem_strfree(iuvstr);
/*
* If we are left with an empty snap zap we can destroy it.
@@ -1012,6 +1087,14 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
propname = za.za_name;
source = setpoint;
+
+ /* Skip if iuv entries are preset. */
+ valstr = kmem_asprintf("%s%s", propname,
+ ZPROP_IUV_SUFFIX);
+ err = zap_contains(mos, propobj, valstr);
+ kmem_strfree(valstr);
+ if (err == 0)
+ continue;
} else if (strcmp(suffix, ZPROP_INHERIT_SUFFIX) == 0) {
/* Skip explicitly inherited entries. */
continue;
@@ -1044,6 +1127,16 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
source = ((flags & DSL_PROP_GET_INHERITING) ?
setpoint : ZPROP_SOURCE_VAL_RECVD);
+ } else if (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0) {
+ (void) strlcpy(buf, za.za_name,
+ MIN(sizeof (buf), suffix - za.za_name + 1));
+ propname = buf;
+ source = setpoint;
+ prop = zfs_name_to_prop(propname);
+
+ if (dsl_prop_known_index(prop,
+ za.za_first_integer) != 1)
+ continue;
} else {
/*
* For backward compatibility, skip suffixes we don't
diff --git a/sys/contrib/openzfs/module/zfs/dsl_scan.c b/sys/contrib/openzfs/module/zfs/dsl_scan.c
index f0cd1feaf55b..03c2aa313af0 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_scan.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_scan.c
@@ -147,13 +147,13 @@ static int zfs_scan_strict_mem_lim = B_FALSE;
* overload the drives with I/O, since that is protected by
* zfs_vdev_scrub_max_active.
*/
-static unsigned long zfs_scan_vdev_limit = 4 << 20;
+static uint64_t zfs_scan_vdev_limit = 4 << 20;
static uint_t zfs_scan_issue_strategy = 0;
/* don't queue & sort zios, go direct */
static int zfs_scan_legacy = B_FALSE;
-static unsigned long zfs_scan_max_ext_gap = 2 << 20; /* in bytes */
+static uint64_t zfs_scan_max_ext_gap = 2 << 20; /* in bytes */
/*
* fill_weight is non-tunable at runtime, so we copy it at module init from
@@ -192,9 +192,9 @@ static int zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */
static int zfs_no_scrub_prefetch = B_FALSE; /* set to disable scrub prefetch */
static const enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE;
/* max number of blocks to free in a single TXG */
-static unsigned long zfs_async_block_max_blocks = ULONG_MAX;
+static uint64_t zfs_async_block_max_blocks = UINT64_MAX;
/* max number of dedup blocks to free in a single TXG */
-static unsigned long zfs_max_async_dedup_frees = 100000;
+static uint64_t zfs_max_async_dedup_frees = 100000;
/* set to disable resilver deferring */
static int zfs_resilver_disable_defer = B_FALSE;
@@ -1470,6 +1470,7 @@ dsl_scan_zil_record(zilog_t *zilog, const lr_t *lrc, void *arg,
if (claim_txg == 0 || bp->blk_birth < claim_txg)
return (0);
+ ASSERT3U(BP_GET_LSIZE(bp), !=, 0);
SET_BOOKMARK(&zb, zh->zh_log.blk_cksum.zc_word[ZIL_ZC_OBJSET],
lr->lr_foid, ZB_ZIL_LEVEL,
lr->lr_offset / BP_GET_LSIZE(bp));
@@ -4446,7 +4447,7 @@ dsl_scan_assess_vdev(dsl_pool_t *dp, vdev_t *vd)
spa_async_request(dp->dp_spa, SPA_ASYNC_RESILVER);
}
-ZFS_MODULE_PARAM(zfs, zfs_, scan_vdev_limit, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, scan_vdev_limit, U64, ZMOD_RW,
"Max bytes in flight per leaf vdev for scrubs and resilvers");
ZFS_MODULE_PARAM(zfs, zfs_, scrub_min_time_ms, UINT, ZMOD_RW,
@@ -4470,10 +4471,10 @@ ZFS_MODULE_PARAM(zfs, zfs_, no_scrub_io, INT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs, zfs_, no_scrub_prefetch, INT, ZMOD_RW,
"Set to disable scrub prefetching");
-ZFS_MODULE_PARAM(zfs, zfs_, async_block_max_blocks, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, async_block_max_blocks, U64, ZMOD_RW,
"Max number of blocks freed in one txg");
-ZFS_MODULE_PARAM(zfs, zfs_, max_async_dedup_frees, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, max_async_dedup_frees, U64, ZMOD_RW,
"Max number of dedup blocks freed in one txg");
ZFS_MODULE_PARAM(zfs, zfs_, free_bpobj_enabled, INT, ZMOD_RW,
@@ -4494,7 +4495,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, scan_legacy, INT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs, zfs_, scan_checkpoint_intval, UINT, ZMOD_RW,
"Scan progress on-disk checkpointing interval");
-ZFS_MODULE_PARAM(zfs, zfs_, scan_max_ext_gap, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, scan_max_ext_gap, U64, ZMOD_RW,
"Max gap in bytes between sequential scrub / resilver I/Os");
ZFS_MODULE_PARAM(zfs, zfs_, scan_mem_lim_soft_fact, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/fm.c b/sys/contrib/openzfs/module/zfs/fm.c
index 32b5cf8facd1..3f05d759770b 100644
--- a/sys/contrib/openzfs/module/zfs/fm.c
+++ b/sys/contrib/openzfs/module/zfs/fm.c
@@ -955,6 +955,7 @@ fm_fmri_hc_create(nvlist_t *fmri, int version, const nvlist_t *auth,
}
atomic_inc_64(
&erpt_kstat_data.fmri_set_failed.value.ui64);
+ va_end(ap);
return;
}
}
diff --git a/sys/contrib/openzfs/module/zfs/metaslab.c b/sys/contrib/openzfs/module/zfs/metaslab.c
index efcfeecd778e..c624833bc981 100644
--- a/sys/contrib/openzfs/module/zfs/metaslab.c
+++ b/sys/contrib/openzfs/module/zfs/metaslab.c
@@ -51,12 +51,12 @@
* operation, we will try to write this amount of data to each disk before
* moving on to the next top-level vdev.
*/
-static unsigned long metaslab_aliquot = 1024 * 1024;
+static uint64_t metaslab_aliquot = 1024 * 1024;
/*
* For testing, make some blocks above a certain size be gang blocks.
*/
-unsigned long metaslab_force_ganging = SPA_MAXBLOCKSIZE + 1;
+uint64_t metaslab_force_ganging = SPA_MAXBLOCKSIZE + 1;
/*
* In pools where the log space map feature is not enabled we touch
@@ -286,7 +286,7 @@ static const int max_disabled_ms = 3;
* Time (in seconds) to respect ms_max_size when the metaslab is not loaded.
* To avoid 64-bit overflow, don't set above UINT32_MAX.
*/
-static unsigned long zfs_metaslab_max_size_cache_sec = 1 * 60 * 60; /* 1 hour */
+static uint64_t zfs_metaslab_max_size_cache_sec = 1 * 60 * 60; /* 1 hour */
/*
* Maximum percentage of memory to use on storing loaded metaslabs. If loading
@@ -5131,8 +5131,7 @@ metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
if (vd != NULL && vd->vdev_mg != NULL) {
mg = vdev_get_mg(vd, mc);
- if (flags & METASLAB_HINTBP_AVOID &&
- mg->mg_next != NULL)
+ if (flags & METASLAB_HINTBP_AVOID)
mg = mg->mg_next;
} else {
mg = mca->mca_rotor;
@@ -5201,12 +5200,11 @@ top:
ASSERT(mg->mg_initialized);
/*
- * Avoid writing single-copy data to a failing,
+ * Avoid writing single-copy data to an unhealthy,
* non-redundant vdev, unless we've already tried all
* other vdevs.
*/
- if ((vd->vdev_stat.vs_write_errors > 0 ||
- vd->vdev_state < VDEV_STATE_HEALTHY) &&
+ if (vd->vdev_state < VDEV_STATE_HEALTHY &&
d == 0 && !try_hard && vd->vdev_children == 0) {
metaslab_trace_add(zal, mg, NULL, psize, d,
TRACE_VDEV_ERROR, allocator);
@@ -6203,7 +6201,7 @@ metaslab_unflushed_txg(metaslab_t *ms)
return (ms->ms_unflushed_txg);
}
-ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, aliquot, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, aliquot, U64, ZMOD_RW,
"Allocation granularity (a.k.a. stripe size)");
ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, debug_load, INT, ZMOD_RW,
@@ -6251,7 +6249,7 @@ ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, segment_weight_enabled, INT,
ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, switch_threshold, INT, ZMOD_RW,
"Segment-based metaslab selection maximum buckets before switching");
-ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, force_ganging, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, force_ganging, U64, ZMOD_RW,
"Blocks larger than this size are forced to be gang blocks");
ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, df_max_search, UINT, ZMOD_RW,
@@ -6260,7 +6258,7 @@ ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, df_max_search, UINT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, df_use_largest_segment, INT, ZMOD_RW,
"When looking in size tree, use largest segment instead of exact fit");
-ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, max_size_cache_sec, ULONG,
+ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, max_size_cache_sec, U64,
ZMOD_RW, "How long to trust the cached max chunk size of a metaslab");
ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, mem_limit, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/mmp.c b/sys/contrib/openzfs/module/zfs/mmp.c
index 92fd6c422330..ef0e01df390f 100644
--- a/sys/contrib/openzfs/module/zfs/mmp.c
+++ b/sys/contrib/openzfs/module/zfs/mmp.c
@@ -156,7 +156,7 @@
* vary with the I/O load and this observed value is the ub_mmp_delay which is
* stored in the uberblock. The minimum allowed value is 100 ms.
*/
-ulong_t zfs_multihost_interval = MMP_DEFAULT_INTERVAL;
+uint64_t zfs_multihost_interval = MMP_DEFAULT_INTERVAL;
/*
* Used to control the duration of the activity test on import. Smaller values
@@ -303,8 +303,10 @@ mmp_next_leaf(spa_t *spa)
do {
leaf = list_next(&spa->spa_leaf_list, leaf);
- if (leaf == NULL)
+ if (leaf == NULL) {
leaf = list_head(&spa->spa_leaf_list);
+ ASSERT3P(leaf, !=, NULL);
+ }
/*
* We skip unwritable, offline, detached, and dRAID spare
@@ -548,11 +550,11 @@ mmp_thread(void *arg)
uint32_t mmp_fail_intervals = MMP_FAIL_INTVS_OK(
zfs_multihost_fail_intervals);
hrtime_t mmp_fail_ns = mmp_fail_intervals * mmp_interval;
- boolean_t last_spa_suspended = suspended;
- boolean_t last_spa_multihost = multihost;
- uint64_t last_mmp_interval = mmp_interval;
- uint32_t last_mmp_fail_intervals = mmp_fail_intervals;
- hrtime_t last_mmp_fail_ns = mmp_fail_ns;
+ boolean_t last_spa_suspended;
+ boolean_t last_spa_multihost;
+ uint64_t last_mmp_interval;
+ uint32_t last_mmp_fail_intervals;
+ hrtime_t last_mmp_fail_ns;
callb_cpr_t cpr;
int skip_wait = 0;
@@ -734,7 +736,7 @@ mmp_signal_all_threads(void)
/* BEGIN CSTYLED */
ZFS_MODULE_PARAM_CALL(zfs_multihost, zfs_multihost_, interval,
- param_set_multihost_interval, param_get_ulong, ZMOD_RW,
+ param_set_multihost_interval, spl_param_get_u64, ZMOD_RW,
"Milliseconds between mmp writes to each leaf");
/* END CSTYLED */
diff --git a/sys/contrib/openzfs/module/zfs/range_tree.c b/sys/contrib/openzfs/module/zfs/range_tree.c
index a2923d1664c7..894c30fcae16 100644
--- a/sys/contrib/openzfs/module/zfs/range_tree.c
+++ b/sys/contrib/openzfs/module/zfs/range_tree.c
@@ -369,6 +369,7 @@ range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
* invalid as soon as we do any mutating btree operations.
*/
rs_after = zfs_btree_find(&rt->rt_root, &tmp, &where_after);
+ ASSERT3P(rs_after, !=, NULL);
rs_set_start_raw(rs_after, rt, before_start);
rs_set_fill(rs_after, rt, after_fill + before_fill + fill);
rs = rs_after;
diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c
index cc367745e486..fe7051db2737 100644
--- a/sys/contrib/openzfs/module/zfs/spa.c
+++ b/sys/contrib/openzfs/module/zfs/spa.c
@@ -218,7 +218,7 @@ static int spa_load_print_vdev_tree = B_FALSE;
* there are also risks of performing an inadvertent rewind as we might be
* missing all the vdevs with the latest uberblocks.
*/
-unsigned long zfs_max_missing_tvds = 0;
+uint64_t zfs_max_missing_tvds = 0;
/*
* The parameters below are similar to zfs_max_missing_tvds but are only
@@ -5267,7 +5267,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
* If we've recovered the pool, pass back any information we
* gathered while doing the load.
*/
- if (state == SPA_LOAD_RECOVER) {
+ if (state == SPA_LOAD_RECOVER && config != NULL) {
fnvlist_add_nvlist(*config, ZPOOL_CONFIG_LOAD_INFO,
spa->spa_load_info);
}
@@ -6803,8 +6803,8 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
pvd = oldvd->vdev_parent;
- if ((error = spa_config_parse(spa, &newrootvd, nvroot, NULL, 0,
- VDEV_ALLOC_ATTACH)) != 0)
+ if (spa_config_parse(spa, &newrootvd, nvroot, NULL, 0,
+ VDEV_ALLOC_ATTACH) != 0)
return (spa_vdev_exit(spa, NULL, txg, EINVAL));
if (newrootvd->vdev_children != 1)
@@ -6819,10 +6819,12 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
return (spa_vdev_exit(spa, newrootvd, txg, error));
/*
- * Spares can't replace logs
+ * log, dedup and special vdevs should not be replaced by spares.
*/
- if (oldvd->vdev_top->vdev_islog && newvd->vdev_isspare)
+ if ((oldvd->vdev_top->vdev_alloc_bias != VDEV_BIAS_NONE ||
+ oldvd->vdev_top->vdev_islog) && newvd->vdev_isspare) {
return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+ }
/*
* A dRAID spare can only replace a child of its parent dRAID vdev.
@@ -7160,7 +7162,7 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
* it may be that the unwritability of the disk is the reason
* it's being detached!
*/
- error = vdev_label_init(vd, 0, VDEV_LABEL_REMOVE);
+ (void) vdev_label_init(vd, 0, VDEV_LABEL_REMOVE);
/*
* Remove vd from its parent and compact the parent's children.
@@ -8867,36 +8869,36 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
spa_history_log_internal(spa, "set", tx,
"%s=%lld", nvpair_name(elem),
(longlong_t)intval);
- } else {
- ASSERT(0); /* not allowed */
- }
- switch (prop) {
- case ZPOOL_PROP_DELEGATION:
- spa->spa_delegation = intval;
- break;
- case ZPOOL_PROP_BOOTFS:
- spa->spa_bootfs = intval;
- break;
- case ZPOOL_PROP_FAILUREMODE:
- spa->spa_failmode = intval;
- break;
- case ZPOOL_PROP_AUTOTRIM:
- spa->spa_autotrim = intval;
- spa_async_request(spa,
- SPA_ASYNC_AUTOTRIM_RESTART);
- break;
- case ZPOOL_PROP_AUTOEXPAND:
- spa->spa_autoexpand = intval;
- if (tx->tx_txg != TXG_INITIAL)
+ switch (prop) {
+ case ZPOOL_PROP_DELEGATION:
+ spa->spa_delegation = intval;
+ break;
+ case ZPOOL_PROP_BOOTFS:
+ spa->spa_bootfs = intval;
+ break;
+ case ZPOOL_PROP_FAILUREMODE:
+ spa->spa_failmode = intval;
+ break;
+ case ZPOOL_PROP_AUTOTRIM:
+ spa->spa_autotrim = intval;
spa_async_request(spa,
- SPA_ASYNC_AUTOEXPAND);
- break;
- case ZPOOL_PROP_MULTIHOST:
- spa->spa_multihost = intval;
- break;
- default:
- break;
+ SPA_ASYNC_AUTOTRIM_RESTART);
+ break;
+ case ZPOOL_PROP_AUTOEXPAND:
+ spa->spa_autoexpand = intval;
+ if (tx->tx_txg != TXG_INITIAL)
+ spa_async_request(spa,
+ SPA_ASYNC_AUTOEXPAND);
+ break;
+ case ZPOOL_PROP_MULTIHOST:
+ spa->spa_multihost = intval;
+ break;
+ default:
+ break;
+ }
+ } else {
+ ASSERT(0); /* not allowed */
}
}
@@ -10016,7 +10018,7 @@ ZFS_MODULE_PARAM(zfs_zio, zio_, taskq_batch_tpq, UINT, ZMOD_RD,
"Number of threads per IO worker taskqueue");
/* BEGIN CSTYLED */
-ZFS_MODULE_PARAM(zfs, zfs_, max_missing_tvds, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, max_missing_tvds, U64, ZMOD_RW,
"Allow importing pool with up to this number of missing top-level "
"vdevs (in read-only mode)");
/* END CSTYLED */
diff --git a/sys/contrib/openzfs/module/zfs/spa_checkpoint.c b/sys/contrib/openzfs/module/zfs/spa_checkpoint.c
index a837b1ce97ec..b588f7041e5c 100644
--- a/sys/contrib/openzfs/module/zfs/spa_checkpoint.c
+++ b/sys/contrib/openzfs/module/zfs/spa_checkpoint.c
@@ -158,7 +158,7 @@
* amount of checkpointed data that has been freed within them while
* the pool had a checkpoint.
*/
-static unsigned long zfs_spa_discard_memory_limit = 16 * 1024 * 1024;
+static uint64_t zfs_spa_discard_memory_limit = 16 * 1024 * 1024;
int
spa_checkpoint_get_stats(spa_t *spa, pool_checkpoint_stat_t *pcs)
@@ -631,7 +631,7 @@ EXPORT_SYMBOL(spa_checkpoint_discard_thread);
EXPORT_SYMBOL(spa_checkpoint_discard_thread_check);
/* BEGIN CSTYLED */
-ZFS_MODULE_PARAM(zfs_spa, zfs_spa_, discard_memory_limit, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_spa, zfs_spa_, discard_memory_limit, U64, ZMOD_RW,
"Limit for memory used in prefetching the checkpoint space map done "
"on each vdev while discarding the checkpoint");
/* END CSTYLED */
diff --git a/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c b/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c
index 4ecce8214f6a..2878e68c6e4b 100644
--- a/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c
+++ b/sys/contrib/openzfs/module/zfs/spa_log_spacemap.c
@@ -188,13 +188,13 @@ static const unsigned long zfs_log_sm_blksz = 1ULL << 17;
* (thus the _ppm suffix; reads as "parts per million"). As an example,
* the default of 1000 allows 0.1% of memory to be used.
*/
-static unsigned long zfs_unflushed_max_mem_ppm = 1000;
+static uint64_t zfs_unflushed_max_mem_ppm = 1000;
/*
* Specific hard-limit in memory that ZFS allows to be used for
* unflushed changes.
*/
-static unsigned long zfs_unflushed_max_mem_amt = 1ULL << 30;
+static uint64_t zfs_unflushed_max_mem_amt = 1ULL << 30;
/*
* The following tunable determines the number of blocks that can be used for
@@ -243,33 +243,33 @@ static unsigned long zfs_unflushed_max_mem_amt = 1ULL << 30;
* provide upper and lower bounds for the log block limit.
* [see zfs_unflushed_log_block_{min,max}]
*/
-static unsigned long zfs_unflushed_log_block_pct = 400;
+static uint_t zfs_unflushed_log_block_pct = 400;
/*
* If the number of metaslabs is small and our incoming rate is high, we could
* get into a situation that we are flushing all our metaslabs every TXG. Thus
* we always allow at least this many log blocks.
*/
-static unsigned long zfs_unflushed_log_block_min = 1000;
+static uint64_t zfs_unflushed_log_block_min = 1000;
/*
* If the log becomes too big, the import time of the pool can take a hit in
* terms of performance. Thus we have a hard limit in the size of the log in
* terms of blocks.
*/
-static unsigned long zfs_unflushed_log_block_max = (1ULL << 17);
+static uint64_t zfs_unflushed_log_block_max = (1ULL << 17);
/*
* Also we have a hard limit in the size of the log in terms of dirty TXGs.
*/
-static unsigned long zfs_unflushed_log_txg_max = 1000;
+static uint64_t zfs_unflushed_log_txg_max = 1000;
/*
* Max # of rows allowed for the log_summary. The tradeoff here is accuracy and
* stability of the flushing algorithm (longer summary) vs its runtime overhead
* (smaller summary is faster to traverse).
*/
-static unsigned long zfs_max_logsm_summary_length = 10;
+static uint64_t zfs_max_logsm_summary_length = 10;
/*
* Tunable that sets the lower bound on the metaslabs to flush every TXG.
@@ -282,7 +282,7 @@ static unsigned long zfs_max_logsm_summary_length = 10;
* The point of this tunable is to be used in extreme cases where we really
* want to flush more metaslabs than our adaptable heuristic plans to flush.
*/
-static unsigned long zfs_min_metaslabs_to_flush = 1;
+static uint64_t zfs_min_metaslabs_to_flush = 1;
/*
* Tunable that specifies how far in the past do we want to look when trying to
@@ -293,7 +293,7 @@ static unsigned long zfs_min_metaslabs_to_flush = 1;
* average over all the blocks that we walk
* [see spa_estimate_incoming_log_blocks].
*/
-static unsigned long zfs_max_log_walking = 5;
+static uint64_t zfs_max_log_walking = 5;
/*
* This tunable exists solely for testing purposes. It ensures that the log
@@ -507,6 +507,7 @@ void
spa_log_summary_decrement_blkcount(spa_t *spa, uint64_t blocks_gone)
{
log_summary_entry_t *e = list_head(&spa->spa_log_summary);
+ ASSERT3P(e, !=, NULL);
if (e->lse_txgcount > 0)
e->lse_txgcount--;
for (; e != NULL; e = list_head(&spa->spa_log_summary)) {
@@ -690,7 +691,8 @@ spa_estimate_metaslabs_to_flush(spa_t *spa)
* based on the incoming rate until we exceed it.
*/
if (available_blocks >= 0 && available_txgs >= 0) {
- uint64_t skip_txgs = MIN(available_txgs + 1,
+ uint64_t skip_txgs = (incoming == 0) ?
+ available_txgs + 1 : MIN(available_txgs + 1,
(available_blocks / incoming) + 1);
available_blocks -= (skip_txgs * incoming);
available_txgs -= skip_txgs;
@@ -1356,34 +1358,34 @@ spa_ld_log_spacemaps(spa_t *spa)
}
/* BEGIN CSTYLED */
-ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_amt, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_amt, U64, ZMOD_RW,
"Specific hard-limit in memory that ZFS allows to be used for "
"unflushed changes");
-ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_ppm, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_ppm, U64, ZMOD_RW,
"Percentage of the overall system memory that ZFS allows to be "
"used for unflushed changes (value is calculated over 1000000 for "
"finer granularity)");
-ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_max, U64, ZMOD_RW,
"Hard limit (upper-bound) in the size of the space map log "
"in terms of blocks.");
-ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_min, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_min, U64, ZMOD_RW,
"Lower-bound limit for the maximum amount of blocks allowed in "
"log spacemap (see zfs_unflushed_log_block_max)");
-ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_txg_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_txg_max, U64, ZMOD_RW,
"Hard limit (upper-bound) in the size of the space map log "
"in terms of dirty TXGs.");
-ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_pct, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_pct, UINT, ZMOD_RW,
"Tunable used to determine the number of blocks that can be used for "
"the spacemap log, expressed as a percentage of the total number of "
"metaslabs in the pool (e.g. 400 means the number of log blocks is "
"capped at 4 times the number of metaslabs)");
-ZFS_MODULE_PARAM(zfs, zfs_, max_log_walking, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, max_log_walking, U64, ZMOD_RW,
"The number of past TXGs that the flushing algorithm of the log "
"spacemap feature uses to estimate incoming log blocks");
@@ -1392,8 +1394,8 @@ ZFS_MODULE_PARAM(zfs, zfs_, keep_log_spacemaps_at_export, INT, ZMOD_RW,
"during pool export/destroy");
/* END CSTYLED */
-ZFS_MODULE_PARAM(zfs, zfs_, max_logsm_summary_length, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, max_logsm_summary_length, U64, ZMOD_RW,
"Maximum number of rows allowed in the summary of the spacemap log");
-ZFS_MODULE_PARAM(zfs, zfs_, min_metaslabs_to_flush, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, min_metaslabs_to_flush, U64, ZMOD_RW,
"Minimum number of metaslabs to flush per dirty TXG");
diff --git a/sys/contrib/openzfs/module/zfs/spa_misc.c b/sys/contrib/openzfs/module/zfs/spa_misc.c
index 102070013404..ca55d55405d3 100644
--- a/sys/contrib/openzfs/module/zfs/spa_misc.c
+++ b/sys/contrib/openzfs/module/zfs/spa_misc.c
@@ -304,20 +304,20 @@ int zfs_free_leak_on_eio = B_FALSE;
* has not completed in zfs_deadman_synctime_ms is considered "hung" resulting
* in one of three behaviors controlled by zfs_deadman_failmode.
*/
-unsigned long zfs_deadman_synctime_ms = 600000UL; /* 10 min. */
+uint64_t zfs_deadman_synctime_ms = 600000UL; /* 10 min. */
/*
* This value controls the maximum amount of time zio_wait() will block for an
* outstanding IO. By default this is 300 seconds at which point the "hung"
* behavior will be applied as described for zfs_deadman_synctime_ms.
*/
-unsigned long zfs_deadman_ziotime_ms = 300000UL; /* 5 min. */
+uint64_t zfs_deadman_ziotime_ms = 300000UL; /* 5 min. */
/*
* Check time in milliseconds. This defines the frequency at which we check
* for hung I/O.
*/
-unsigned long zfs_deadman_checktime_ms = 60000UL; /* 1 min. */
+uint64_t zfs_deadman_checktime_ms = 60000UL; /* 1 min. */
/*
* By default the deadman is enabled.
@@ -1536,7 +1536,7 @@ snprintf_blkptr(char *buf, size_t buflen, const blkptr_t *bp)
compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
}
- SNPRINTF_BLKPTR(snprintf, ' ', buf, buflen, bp, type, checksum,
+ SNPRINTF_BLKPTR(kmem_scnprintf, ' ', buf, buflen, bp, type, checksum,
compress);
}
@@ -2922,7 +2922,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, recover, INT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs, zfs_, free_leak_on_eio, INT, ZMOD_RW,
"Set to ignore IO errors during free and permanently leak the space");
-ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, checktime_ms, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, checktime_ms, U64, ZMOD_RW,
"Dead I/O check interval in milliseconds");
ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, enabled, INT, ZMOD_RW,
@@ -2943,11 +2943,11 @@ ZFS_MODULE_PARAM_CALL(zfs_deadman, zfs_deadman_, failmode,
"Failmode for deadman timer");
ZFS_MODULE_PARAM_CALL(zfs_deadman, zfs_deadman_, synctime_ms,
- param_set_deadman_synctime, param_get_ulong, ZMOD_RW,
+ param_set_deadman_synctime, spl_param_get_u64, ZMOD_RW,
"Pool sync expiration time in milliseconds");
ZFS_MODULE_PARAM_CALL(zfs_deadman, zfs_deadman_, ziotime_ms,
- param_set_deadman_ziotime, param_get_ulong, ZMOD_RW,
+ param_set_deadman_ziotime, spl_param_get_u64, ZMOD_RW,
"IO expiration time in milliseconds");
ZFS_MODULE_PARAM(zfs, zfs_, special_class_metadata_reserve_pct, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/vdev.c b/sys/contrib/openzfs/module/zfs/vdev.c
index 66cec052b669..4520ca31b7d7 100644
--- a/sys/contrib/openzfs/module/zfs/vdev.c
+++ b/sys/contrib/openzfs/module/zfs/vdev.c
@@ -144,8 +144,8 @@ int zfs_nocacheflush = 0;
* be forced by vdev logical ashift or by user via ashift property, but won't
* be set automatically as a performance optimization.
*/
-uint64_t zfs_vdev_max_auto_ashift = 14;
-uint64_t zfs_vdev_min_auto_ashift = ASHIFT_MIN;
+uint_t zfs_vdev_max_auto_ashift = 14;
+uint_t zfs_vdev_min_auto_ashift = ASHIFT_MIN;
void
vdev_dbgmsg(vdev_t *vd, const char *fmt, ...)
@@ -3563,6 +3563,26 @@ vdev_load(vdev_t *vd)
}
}
+ if (vd == vd->vdev_top && vd->vdev_top_zap != 0) {
+ spa_t *spa = vd->vdev_spa;
+ uint64_t failfast;
+
+ error = zap_lookup(spa->spa_meta_objset, vd->vdev_top_zap,
+ vdev_prop_to_name(VDEV_PROP_FAILFAST), sizeof (failfast),
+ 1, &failfast);
+ if (error == 0) {
+ vd->vdev_failfast = failfast & 1;
+ } else if (error == ENOENT) {
+ vd->vdev_failfast = vdev_prop_default_numeric(
+ VDEV_PROP_FAILFAST);
+ } else {
+ vdev_dbgmsg(vd,
+ "vdev_load: zap_lookup(top_zap=%llu) "
+ "failed [error=%d]",
+ (u_longlong_t)vd->vdev_top_zap, error);
+ }
+ }
+
/*
* Load any rebuild state from the top-level vdev zap.
*/
@@ -5648,7 +5668,7 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
nvpair_t *elem = NULL;
uint64_t vdev_guid;
nvlist_t *nvprops;
- int error;
+ int error = 0;
ASSERT(vd != NULL);
@@ -5709,6 +5729,13 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
else
error = spa_vdev_alloc(spa, vdev_guid);
break;
+ case VDEV_PROP_FAILFAST:
+ if (nvpair_value_uint64(elem, &intval) != 0) {
+ error = EINVAL;
+ break;
+ }
+ vd->vdev_failfast = intval & 1;
+ break;
default:
/* Most processing is done in vdev_props_set_sync */
break;
@@ -6022,6 +6049,25 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
vdev_prop_add_list(outnvl, propname, strval,
intval, src);
break;
+ case VDEV_PROP_FAILFAST:
+ src = ZPROP_SRC_LOCAL;
+ strval = NULL;
+
+ err = zap_lookup(mos, objid, nvpair_name(elem),
+ sizeof (uint64_t), 1, &intval);
+ if (err == ENOENT) {
+ intval = vdev_prop_default_numeric(
+ prop);
+ err = 0;
+ } else if (err) {
+ break;
+ }
+ if (intval == vdev_prop_default_numeric(prop))
+ src = ZPROP_SRC_DEFAULT;
+
+ vdev_prop_add_list(outnvl, propname, strval,
+ intval, src);
+ break;
/* Text Properties */
case VDEV_PROP_COMMENT:
/* Exists in the ZAP below */
@@ -6078,7 +6124,6 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
strval = NULL;
zprop_source_t src = ZPROP_SRC_DEFAULT;
propname = za.za_name;
- prop = vdev_name_to_prop(propname);
switch (za.za_integer_length) {
case 8:
@@ -6156,11 +6201,11 @@ ZFS_MODULE_PARAM(zfs, zfs_, embedded_slog_min_ms, UINT, ZMOD_RW,
/* BEGIN CSTYLED */
ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, min_auto_ashift,
- param_set_min_auto_ashift, param_get_ulong, ZMOD_RW,
+ param_set_min_auto_ashift, param_get_uint, ZMOD_RW,
"Minimum ashift used when creating new top-level vdevs");
ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, max_auto_ashift,
- param_set_max_auto_ashift, param_get_ulong, ZMOD_RW,
+ param_set_max_auto_ashift, param_get_uint, ZMOD_RW,
"Maximum ashift used when optimizing for logical -> physical sector "
"size on new top-level vdevs");
/* END CSTYLED */
diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect.c b/sys/contrib/openzfs/module/zfs/vdev_indirect.c
index 0ca0c245e952..814a1f0efe4c 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_indirect.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_indirect.c
@@ -189,14 +189,14 @@ static uint_t zfs_condense_indirect_obsolete_pct = 25;
* consumed by the obsolete space map; the default of 1GB is small enough
* that we typically don't mind "wasting" it.
*/
-static unsigned long zfs_condense_max_obsolete_bytes = 1024 * 1024 * 1024;
+static uint64_t zfs_condense_max_obsolete_bytes = 1024 * 1024 * 1024;
/*
* Don't bother condensing if the mapping uses less than this amount of
* memory. The default of 128KB is considered a "trivial" amount of
* memory and not worth reducing.
*/
-static unsigned long zfs_condense_min_mapping_bytes = 128 * 1024;
+static uint64_t zfs_condense_min_mapping_bytes = 128 * 1024;
/*
* This is used by the test suite so that it can ensure that certain
@@ -1319,6 +1319,7 @@ vdev_indirect_io_start(zio_t *zio)
vdev_indirect_gather_splits, zio);
indirect_split_t *first = list_head(&iv->iv_splits);
+ ASSERT3P(first, !=, NULL);
if (first->is_size == zio->io_size) {
/*
* This is not a split block; we are pointing to the entire
@@ -1891,11 +1892,11 @@ ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, indirect_obsolete_pct, UINT,
"Minimum obsolete percent of bytes in the mapping "
"to attempt condensing");
-ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, min_mapping_bytes, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, min_mapping_bytes, U64, ZMOD_RW,
"Don't bother condensing if the mapping uses less than this amount of "
"memory");
-ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, max_obsolete_bytes, ULONG,
+ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, max_obsolete_bytes, U64,
ZMOD_RW,
"Minimum size obsolete spacemap to attempt condensing");
diff --git a/sys/contrib/openzfs/module/zfs/vdev_initialize.c b/sys/contrib/openzfs/module/zfs/vdev_initialize.c
index 965fb7ef0593..75beb0cc3d12 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_initialize.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_initialize.c
@@ -36,17 +36,13 @@
/*
* Value that is written to disk during initialization.
*/
-#ifdef _ILP32
-static unsigned long zfs_initialize_value = 0xdeadbeefUL;
-#else
-static unsigned long zfs_initialize_value = 0xdeadbeefdeadbeeeULL;
-#endif
+static uint64_t zfs_initialize_value = 0xdeadbeefdeadbeeeULL;
/* maximum number of I/Os outstanding per leaf vdev */
static const int zfs_initialize_limit = 1;
/* size of initializing writes; default 1MiB, see zfs_remove_max_segment */
-static unsigned long zfs_initialize_chunk_size = 1024 * 1024;
+static uint64_t zfs_initialize_chunk_size = 1024 * 1024;
static boolean_t
vdev_initialize_should_stop(vdev_t *vd)
@@ -261,15 +257,9 @@ vdev_initialize_block_fill(void *buf, size_t len, void *unused)
(void) unused;
ASSERT0(len % sizeof (uint64_t));
-#ifdef _ILP32
- for (uint64_t i = 0; i < len; i += sizeof (uint32_t)) {
- *(uint32_t *)((char *)(buf) + i) = zfs_initialize_value;
- }
-#else
for (uint64_t i = 0; i < len; i += sizeof (uint64_t)) {
*(uint64_t *)((char *)(buf) + i) = zfs_initialize_value;
}
-#endif
return (0);
}
@@ -765,8 +755,8 @@ EXPORT_SYMBOL(vdev_initialize_stop_all);
EXPORT_SYMBOL(vdev_initialize_stop_wait);
EXPORT_SYMBOL(vdev_initialize_restart);
-ZFS_MODULE_PARAM(zfs, zfs_, initialize_value, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, initialize_value, U64, ZMOD_RW,
"Value written during zpool initialize");
-ZFS_MODULE_PARAM(zfs, zfs_, initialize_chunk_size, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, initialize_chunk_size, U64, ZMOD_RW,
"Size in bytes of writes by zpool initialize");
diff --git a/sys/contrib/openzfs/module/zfs/vdev_queue.c b/sys/contrib/openzfs/module/zfs/vdev_queue.c
index 1acb89cea393..ec55674393ce 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_queue.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_queue.c
@@ -605,7 +605,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
int maxblocksize;
boolean_t stretch = B_FALSE;
avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type);
- enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
+ zio_flag_t flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
uint64_t next_offset;
abd_t *abd;
@@ -725,6 +725,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
* after our span is mandatory.
*/
dio = AVL_NEXT(t, last);
+ ASSERT3P(dio, !=, NULL);
dio->io_flags &= ~ZIO_FLAG_OPTIONAL;
} else {
/* do not include the optional i/o */
@@ -756,6 +757,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
do {
dio = nio;
nio = AVL_NEXT(t, dio);
+ ASSERT3P(dio, !=, NULL);
zio_add_child(dio, aio);
vdev_queue_io_remove(vq, dio);
diff --git a/sys/contrib/openzfs/module/zfs/vdev_raidz_math.c b/sys/contrib/openzfs/module/zfs/vdev_raidz_math.c
index f74a76a8d5ba..2980f8acfbd7 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_raidz_math.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_raidz_math.c
@@ -285,17 +285,17 @@ raidz_math_kstat_headers(char *buf, size_t size)
{
ASSERT3U(size, >=, RAIDZ_KSTAT_LINE_LEN);
- ssize_t off = snprintf(buf, size, "%-17s", "implementation");
+ ssize_t off = kmem_scnprintf(buf, size, "%-17s", "implementation");
for (int i = 0; i < ARRAY_SIZE(raidz_gen_name); i++)
- off += snprintf(buf + off, size - off, "%-16s",
+ off += kmem_scnprintf(buf + off, size - off, "%-16s",
raidz_gen_name[i]);
for (int i = 0; i < ARRAY_SIZE(raidz_rec_name); i++)
- off += snprintf(buf + off, size - off, "%-16s",
+ off += kmem_scnprintf(buf + off, size - off, "%-16s",
raidz_rec_name[i]);
- (void) snprintf(buf + off, size - off, "\n");
+ (void) kmem_scnprintf(buf + off, size - off, "\n");
return (0);
}
@@ -311,34 +311,35 @@ raidz_math_kstat_data(char *buf, size_t size, void *data)
ASSERT3U(size, >=, RAIDZ_KSTAT_LINE_LEN);
if (cstat == fstat) {
- off += snprintf(buf + off, size - off, "%-17s", "fastest");
+ off += kmem_scnprintf(buf + off, size - off, "%-17s",
+ "fastest");
for (i = 0; i < ARRAY_SIZE(raidz_gen_name); i++) {
int id = fstat->gen[i];
- off += snprintf(buf + off, size - off, "%-16s",
+ off += kmem_scnprintf(buf + off, size - off, "%-16s",
raidz_supp_impl[id]->name);
}
for (i = 0; i < ARRAY_SIZE(raidz_rec_name); i++) {
int id = fstat->rec[i];
- off += snprintf(buf + off, size - off, "%-16s",
+ off += kmem_scnprintf(buf + off, size - off, "%-16s",
raidz_supp_impl[id]->name);
}
} else {
ptrdiff_t id = cstat - raidz_impl_kstats;
- off += snprintf(buf + off, size - off, "%-17s",
+ off += kmem_scnprintf(buf + off, size - off, "%-17s",
raidz_supp_impl[id]->name);
for (i = 0; i < ARRAY_SIZE(raidz_gen_name); i++)
- off += snprintf(buf + off, size - off, "%-16llu",
+ off += kmem_scnprintf(buf + off, size - off, "%-16llu",
(u_longlong_t)cstat->gen[i]);
for (i = 0; i < ARRAY_SIZE(raidz_rec_name); i++)
- off += snprintf(buf + off, size - off, "%-16llu",
+ off += kmem_scnprintf(buf + off, size - off, "%-16llu",
(u_longlong_t)cstat->rec[i]);
}
- (void) snprintf(buf + off, size - off, "\n");
+ (void) kmem_scnprintf(buf + off, size - off, "\n");
return (0);
}
diff --git a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
index 1ce578e228d8..1f56275c853b 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c
@@ -22,6 +22,7 @@
*
* Copyright (c) 2018, Intel Corporation.
* Copyright (c) 2020 by Lawrence Livermore National Security, LLC.
+ * Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
*/
#include <sys/vdev_impl.h>
@@ -103,7 +104,7 @@
* Size of rebuild reads; defaults to 1MiB per data disk and is capped at
* SPA_MAXBLOCKSIZE.
*/
-static unsigned long zfs_rebuild_max_segment = 1024 * 1024;
+static uint64_t zfs_rebuild_max_segment = 1024 * 1024;
/*
* Maximum number of parallelly executed bytes per leaf vdev caused by a
@@ -121,7 +122,7 @@ static unsigned long zfs_rebuild_max_segment = 1024 * 1024;
* With a value of 32MB the sequential resilver write rate was measured at
* 800MB/s sustained while rebuilding to a distributed spare.
*/
-static unsigned long zfs_rebuild_vdev_limit = 32 << 20;
+static uint64_t zfs_rebuild_vdev_limit = 32 << 20;
/*
* Automatically start a pool scrub when the last active sequential resilver
@@ -134,6 +135,7 @@ static int zfs_rebuild_scrub_enabled = 1;
* For vdev_rebuild_initiate_sync() and vdev_rebuild_reset_sync().
*/
static __attribute__((noreturn)) void vdev_rebuild_thread(void *arg);
+static void vdev_rebuild_reset_sync(void *arg, dmu_tx_t *tx);
/*
* Clear the per-vdev rebuild bytes value for a vdev tree.
@@ -307,6 +309,17 @@ vdev_rebuild_complete_sync(void *arg, dmu_tx_t *tx)
vdev_rebuild_phys_t *vrp = &vr->vr_rebuild_phys;
mutex_enter(&vd->vdev_rebuild_lock);
+
+ /*
+ * Handle a second device failure if it occurs after all rebuild I/O
+ * has completed but before this sync task has been executed.
+ */
+ if (vd->vdev_rebuild_reset_wanted) {
+ mutex_exit(&vd->vdev_rebuild_lock);
+ vdev_rebuild_reset_sync(arg, tx);
+ return;
+ }
+
vrp->vrp_rebuild_state = VDEV_REBUILD_COMPLETE;
vrp->vrp_end_time = gethrestime_sec();
@@ -760,7 +773,6 @@ vdev_rebuild_thread(void *arg)
ASSERT(vd->vdev_rebuilding);
ASSERT(spa_feature_is_active(spa, SPA_FEATURE_DEVICE_REBUILD));
ASSERT3B(vd->vdev_rebuild_cancel_wanted, ==, B_FALSE);
- ASSERT3B(vd->vdev_rebuild_reset_wanted, ==, B_FALSE);
vdev_rebuild_t *vr = &vd->vdev_rebuild_config;
vdev_rebuild_phys_t *vrp = &vr->vr_rebuild_phys;
@@ -1138,10 +1150,10 @@ vdev_rebuild_get_stats(vdev_t *tvd, vdev_rebuild_stat_t *vrs)
return (error);
}
-ZFS_MODULE_PARAM(zfs, zfs_, rebuild_max_segment, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, rebuild_max_segment, U64, ZMOD_RW,
"Max segment size in bytes of rebuild reads");
-ZFS_MODULE_PARAM(zfs, zfs_, rebuild_vdev_limit, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, rebuild_vdev_limit, U64, ZMOD_RW,
"Max bytes in flight per leaf vdev for sequential resilvers");
ZFS_MODULE_PARAM(zfs, zfs_, rebuild_scrub_enabled, INT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/vdev_trim.c b/sys/contrib/openzfs/module/zfs/vdev_trim.c
index 5905d9a07571..5b5076c8722c 100644
--- a/sys/contrib/openzfs/module/zfs/vdev_trim.c
+++ b/sys/contrib/openzfs/module/zfs/vdev_trim.c
@@ -1188,12 +1188,11 @@ vdev_autotrim_thread(void *arg)
mutex_exit(&vd->vdev_autotrim_lock);
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
- uint64_t extent_bytes_max = zfs_trim_extent_bytes_max;
- uint64_t extent_bytes_min = zfs_trim_extent_bytes_min;
-
while (!vdev_autotrim_should_stop(vd)) {
int txgs_per_trim = MAX(zfs_trim_txg_batch, 1);
boolean_t issued_trim = B_FALSE;
+ uint64_t extent_bytes_max = zfs_trim_extent_bytes_max;
+ uint64_t extent_bytes_min = zfs_trim_extent_bytes_min;
/*
* All of the metaslabs are divided in to groups of size
diff --git a/sys/contrib/openzfs/module/zfs/zap_leaf.c b/sys/contrib/openzfs/module/zfs/zap_leaf.c
index 25c2d5163a26..2e8489c7dfcf 100644
--- a/sys/contrib/openzfs/module/zfs/zap_leaf.c
+++ b/sys/contrib/openzfs/module/zfs/zap_leaf.c
@@ -646,7 +646,7 @@ zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd,
* form of the name. But all callers have one of these on hand anyway,
* so might as well take advantage. A cleaner but slower interface
* would accept neither argument, and compute the normalized name as
- * needed (using zap_name_alloc(zap_entry_read_name(zeh))).
+ * needed (using zap_name_alloc_str(zap_entry_read_name(zeh))).
*/
boolean_t
zap_entry_normalization_conflict(zap_entry_handle_t *zeh, zap_name_t *zn,
@@ -667,7 +667,7 @@ zap_entry_normalization_conflict(zap_entry_handle_t *zeh, zap_name_t *zn,
continue;
if (zn == NULL) {
- zn = zap_name_alloc(zap, name, MT_NORMALIZE);
+ zn = zap_name_alloc_str(zap, name, MT_NORMALIZE);
allocdzn = B_TRUE;
}
if (zap_leaf_array_match(zeh->zeh_leaf, zn,
diff --git a/sys/contrib/openzfs/module/zfs/zap_micro.c b/sys/contrib/openzfs/module/zfs/zap_micro.c
index 58a5c9f600b7..606f426404cc 100644
--- a/sys/contrib/openzfs/module/zfs/zap_micro.c
+++ b/sys/contrib/openzfs/module/zfs/zap_micro.c
@@ -33,7 +33,7 @@
#include <sys/zap.h>
#include <sys/zap_impl.h>
#include <sys/zap_leaf.h>
-#include <sys/avl.h>
+#include <sys/btree.h>
#include <sys/arc.h>
#include <sys/dmu_objset.h>
@@ -92,7 +92,7 @@ zap_hash(zap_name_t *zn)
wp++, i++) {
uint64_t word = *wp;
- for (int j = 0; j < zn->zn_key_intlen; j++) {
+ for (int j = 0; j < 8; j++) {
h = (h >> 8) ^
zfs_crc64_table[(h ^ word) & 0xFF];
word >>= NBBY;
@@ -162,18 +162,25 @@ zap_match(zap_name_t *zn, const char *matchname)
}
}
+static zap_name_t *
+zap_name_alloc(zap_t *zap)
+{
+ zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
+ zn->zn_zap = zap;
+ return (zn);
+}
+
void
zap_name_free(zap_name_t *zn)
{
kmem_free(zn, sizeof (zap_name_t));
}
-zap_name_t *
-zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt)
+static int
+zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt)
{
- zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
+ zap_t *zap = zn->zn_zap;
- zn->zn_zap = zap;
zn->zn_key_intlen = sizeof (*key);
zn->zn_key_orig = key;
zn->zn_key_orig_numints = strlen(zn->zn_key_orig) + 1;
@@ -194,17 +201,13 @@ zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt)
* what the hash is computed from.
*/
if (zap_normalize(zap, key, zn->zn_normbuf,
- zap->zap_normflags) != 0) {
- zap_name_free(zn);
- return (NULL);
- }
+ zap->zap_normflags) != 0)
+ return (SET_ERROR(ENOTSUP));
zn->zn_key_norm = zn->zn_normbuf;
zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1;
} else {
- if (mt != 0) {
- zap_name_free(zn);
- return (NULL);
- }
+ if (mt != 0)
+ return (SET_ERROR(ENOTSUP));
zn->zn_key_norm = zn->zn_key_orig;
zn->zn_key_norm_numints = zn->zn_key_orig_numints;
}
@@ -217,13 +220,22 @@ zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt)
* what the matching is based on. (Not the hash!)
*/
if (zap_normalize(zap, key, zn->zn_normbuf,
- zn->zn_normflags) != 0) {
- zap_name_free(zn);
- return (NULL);
- }
+ zn->zn_normflags) != 0)
+ return (SET_ERROR(ENOTSUP));
zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1;
}
+ return (0);
+}
+
+zap_name_t *
+zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt)
+{
+ zap_name_t *zn = zap_name_alloc(zap);
+ if (zap_name_init_str(zn, key, mt) != 0) {
+ zap_name_free(zn);
+ return (NULL);
+ }
return (zn);
}
@@ -277,45 +289,46 @@ mze_compare(const void *arg1, const void *arg2)
const mzap_ent_t *mze1 = arg1;
const mzap_ent_t *mze2 = arg2;
- int cmp = TREE_CMP(mze1->mze_hash, mze2->mze_hash);
- if (likely(cmp))
- return (cmp);
-
- return (TREE_CMP(mze1->mze_cd, mze2->mze_cd));
+ return (TREE_CMP((uint64_t)(mze1->mze_hash) << 32 | mze1->mze_cd,
+ (uint64_t)(mze2->mze_hash) << 32 | mze2->mze_cd));
}
static void
-mze_insert(zap_t *zap, int chunkid, uint64_t hash)
+mze_insert(zap_t *zap, uint16_t chunkid, uint64_t hash)
{
+ mzap_ent_t mze;
+
ASSERT(zap->zap_ismicro);
ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
- mzap_ent_t *mze = kmem_alloc(sizeof (mzap_ent_t), KM_SLEEP);
- mze->mze_chunkid = chunkid;
- mze->mze_hash = hash;
- mze->mze_cd = MZE_PHYS(zap, mze)->mze_cd;
- ASSERT(MZE_PHYS(zap, mze)->mze_name[0] != 0);
- avl_add(&zap->zap_m.zap_avl, mze);
+ mze.mze_chunkid = chunkid;
+ ASSERT0(hash & 0xffffffff);
+ mze.mze_hash = hash >> 32;
+ ASSERT3U(MZE_PHYS(zap, &mze)->mze_cd, <=, 0xffff);
+ mze.mze_cd = (uint16_t)MZE_PHYS(zap, &mze)->mze_cd;
+ ASSERT(MZE_PHYS(zap, &mze)->mze_name[0] != 0);
+ zfs_btree_add(&zap->zap_m.zap_tree, &mze);
}
static mzap_ent_t *
-mze_find(zap_name_t *zn)
+mze_find(zap_name_t *zn, zfs_btree_index_t *idx)
{
mzap_ent_t mze_tofind;
mzap_ent_t *mze;
- avl_index_t idx;
- avl_tree_t *avl = &zn->zn_zap->zap_m.zap_avl;
+ zfs_btree_t *tree = &zn->zn_zap->zap_m.zap_tree;
ASSERT(zn->zn_zap->zap_ismicro);
ASSERT(RW_LOCK_HELD(&zn->zn_zap->zap_rwlock));
- mze_tofind.mze_hash = zn->zn_hash;
+ ASSERT0(zn->zn_hash & 0xffffffff);
+ mze_tofind.mze_hash = zn->zn_hash >> 32;
mze_tofind.mze_cd = 0;
- mze = avl_find(avl, &mze_tofind, &idx);
+ mze = zfs_btree_find(tree, &mze_tofind, idx);
if (mze == NULL)
- mze = avl_nearest(avl, idx, AVL_AFTER);
- for (; mze && mze->mze_hash == zn->zn_hash; mze = AVL_NEXT(avl, mze)) {
+ mze = zfs_btree_next(tree, idx, idx);
+ for (; mze && mze->mze_hash == mze_tofind.mze_hash;
+ mze = zfs_btree_next(tree, idx, idx)) {
ASSERT3U(mze->mze_cd, ==, MZE_PHYS(zn->zn_zap, mze)->mze_cd);
if (zap_match(zn, MZE_PHYS(zn->zn_zap, mze)->mze_name))
return (mze);
@@ -328,18 +341,21 @@ static uint32_t
mze_find_unused_cd(zap_t *zap, uint64_t hash)
{
mzap_ent_t mze_tofind;
- avl_index_t idx;
- avl_tree_t *avl = &zap->zap_m.zap_avl;
+ zfs_btree_index_t idx;
+ zfs_btree_t *tree = &zap->zap_m.zap_tree;
ASSERT(zap->zap_ismicro);
ASSERT(RW_LOCK_HELD(&zap->zap_rwlock));
+ ASSERT0(hash & 0xffffffff);
+ hash >>= 32;
mze_tofind.mze_hash = hash;
mze_tofind.mze_cd = 0;
uint32_t cd = 0;
- for (mzap_ent_t *mze = avl_find(avl, &mze_tofind, &idx);
- mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
+ for (mzap_ent_t *mze = zfs_btree_find(tree, &mze_tofind, &idx);
+ mze && mze->mze_hash == hash;
+ mze = zfs_btree_next(tree, &idx, &idx)) {
if (mze->mze_cd != cd)
break;
cd++;
@@ -364,16 +380,18 @@ mze_canfit_fzap_leaf(zap_name_t *zn, uint64_t hash)
{
zap_t *zap = zn->zn_zap;
mzap_ent_t mze_tofind;
- mzap_ent_t *mze;
- avl_index_t idx;
- avl_tree_t *avl = &zap->zap_m.zap_avl;
+ zfs_btree_index_t idx;
+ zfs_btree_t *tree = &zap->zap_m.zap_tree;
uint32_t mzap_ents = 0;
+ ASSERT0(hash & 0xffffffff);
+ hash >>= 32;
mze_tofind.mze_hash = hash;
mze_tofind.mze_cd = 0;
- for (mze = avl_find(avl, &mze_tofind, &idx);
- mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
+ for (mzap_ent_t *mze = zfs_btree_find(tree, &mze_tofind, &idx);
+ mze && mze->mze_hash == hash;
+ mze = zfs_btree_next(tree, &idx, &idx)) {
mzap_ents++;
}
@@ -384,24 +402,10 @@ mze_canfit_fzap_leaf(zap_name_t *zn, uint64_t hash)
}
static void
-mze_remove(zap_t *zap, mzap_ent_t *mze)
-{
- ASSERT(zap->zap_ismicro);
- ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
-
- avl_remove(&zap->zap_m.zap_avl, mze);
- kmem_free(mze, sizeof (mzap_ent_t));
-}
-
-static void
mze_destroy(zap_t *zap)
{
- mzap_ent_t *mze;
- void *avlcookie = NULL;
-
- while ((mze = avl_destroy_nodes(&zap->zap_m.zap_avl, &avlcookie)))
- kmem_free(mze, sizeof (mzap_ent_t));
- avl_destroy(&zap->zap_m.zap_avl);
+ zfs_btree_clear(&zap->zap_m.zap_tree);
+ zfs_btree_destroy(&zap->zap_m.zap_tree);
}
static zap_t *
@@ -448,21 +452,26 @@ mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
zap->zap_salt = zap_m_phys(zap)->mz_salt;
zap->zap_normflags = zap_m_phys(zap)->mz_normflags;
zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1;
- avl_create(&zap->zap_m.zap_avl, mze_compare,
- sizeof (mzap_ent_t), offsetof(mzap_ent_t, mze_node));
- for (int i = 0; i < zap->zap_m.zap_num_chunks; i++) {
+ /*
+ * Reduce B-tree leaf from 4KB to 512 bytes to reduce memmove()
+ * overhead on massive inserts below. It still allows to store
+ * 62 entries before we have to add 2KB B-tree core node.
+ */
+ zfs_btree_create_custom(&zap->zap_m.zap_tree, mze_compare,
+ sizeof (mzap_ent_t), 512);
+
+ zap_name_t *zn = zap_name_alloc(zap);
+ for (uint16_t i = 0; i < zap->zap_m.zap_num_chunks; i++) {
mzap_ent_phys_t *mze =
&zap_m_phys(zap)->mz_chunk[i];
if (mze->mze_name[0]) {
- zap_name_t *zn;
-
zap->zap_m.zap_num_entries++;
- zn = zap_name_alloc(zap, mze->mze_name, 0);
+ zap_name_init_str(zn, mze->mze_name, 0);
mze_insert(zap, i, zn->zn_hash);
- zap_name_free(zn);
}
}
+ zap_name_free(zn);
} else {
zap->zap_salt = zap_f_phys(zap)->zap_salt;
zap->zap_normflags = zap_f_phys(zap)->zap_normflags;
@@ -657,24 +666,25 @@ mzap_upgrade(zap_t **zapp, const void *tag, dmu_tx_t *tx, zap_flags_t flags)
dprintf("upgrading obj=%llu with %u chunks\n",
(u_longlong_t)zap->zap_object, nchunks);
- /* XXX destroy the avl later, so we can use the stored hash value */
+ /* XXX destroy the tree later, so we can use the stored hash value */
mze_destroy(zap);
fzap_upgrade(zap, tx, flags);
+ zap_name_t *zn = zap_name_alloc(zap);
for (int i = 0; i < nchunks; i++) {
mzap_ent_phys_t *mze = &mzp->mz_chunk[i];
if (mze->mze_name[0] == 0)
continue;
dprintf("adding %s=%llu\n",
mze->mze_name, (u_longlong_t)mze->mze_value);
- zap_name_t *zn = zap_name_alloc(zap, mze->mze_name, 0);
+ zap_name_init_str(zn, mze->mze_name, 0);
/* If we fail here, we would end up losing entries */
VERIFY0(fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd,
tag, tx));
zap = zn->zn_zap; /* fzap_add_cd() may change zap */
- zap_name_free(zn);
}
+ zap_name_free(zn);
vmem_free(mzp, sz);
*zapp = zap;
return (0);
@@ -916,22 +926,23 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
* See also the comment above zap_entry_normalization_conflict().
*/
static boolean_t
-mzap_normalization_conflict(zap_t *zap, zap_name_t *zn, mzap_ent_t *mze)
+mzap_normalization_conflict(zap_t *zap, zap_name_t *zn, mzap_ent_t *mze,
+ zfs_btree_index_t *idx)
{
- int direction = AVL_BEFORE;
boolean_t allocdzn = B_FALSE;
+ mzap_ent_t *other;
+ zfs_btree_index_t oidx;
if (zap->zap_normflags == 0)
return (B_FALSE);
-again:
- for (mzap_ent_t *other = avl_walk(&zap->zap_m.zap_avl, mze, direction);
+ for (other = zfs_btree_prev(&zap->zap_m.zap_tree, idx, &oidx);
other && other->mze_hash == mze->mze_hash;
- other = avl_walk(&zap->zap_m.zap_avl, other, direction)) {
+ other = zfs_btree_prev(&zap->zap_m.zap_tree, &oidx, &oidx)) {
if (zn == NULL) {
- zn = zap_name_alloc(zap, MZE_PHYS(zap, mze)->mze_name,
- MT_NORMALIZE);
+ zn = zap_name_alloc_str(zap,
+ MZE_PHYS(zap, mze)->mze_name, MT_NORMALIZE);
allocdzn = B_TRUE;
}
if (zap_match(zn, MZE_PHYS(zap, other)->mze_name)) {
@@ -941,9 +952,20 @@ again:
}
}
- if (direction == AVL_BEFORE) {
- direction = AVL_AFTER;
- goto again;
+ for (other = zfs_btree_next(&zap->zap_m.zap_tree, idx, &oidx);
+ other && other->mze_hash == mze->mze_hash;
+ other = zfs_btree_next(&zap->zap_m.zap_tree, &oidx, &oidx)) {
+
+ if (zn == NULL) {
+ zn = zap_name_alloc_str(zap,
+ MZE_PHYS(zap, mze)->mze_name, MT_NORMALIZE);
+ allocdzn = B_TRUE;
+ }
+ if (zap_match(zn, MZE_PHYS(zap, other)->mze_name)) {
+ if (allocdzn)
+ zap_name_free(zn);
+ return (B_TRUE);
+ }
}
if (allocdzn)
@@ -971,7 +993,7 @@ zap_lookup_impl(zap_t *zap, const char *name,
{
int err = 0;
- zap_name_t *zn = zap_name_alloc(zap, name, mt);
+ zap_name_t *zn = zap_name_alloc_str(zap, name, mt);
if (zn == NULL)
return (SET_ERROR(ENOTSUP));
@@ -979,7 +1001,8 @@ zap_lookup_impl(zap_t *zap, const char *name,
err = fzap_lookup(zn, integer_size, num_integers, buf,
realname, rn_len, ncp);
} else {
- mzap_ent_t *mze = mze_find(zn);
+ zfs_btree_index_t idx;
+ mzap_ent_t *mze = mze_find(zn, &idx);
if (mze == NULL) {
err = SET_ERROR(ENOENT);
} else {
@@ -990,11 +1013,13 @@ zap_lookup_impl(zap_t *zap, const char *name,
} else {
*(uint64_t *)buf =
MZE_PHYS(zap, mze)->mze_value;
- (void) strlcpy(realname,
- MZE_PHYS(zap, mze)->mze_name, rn_len);
+ if (realname != NULL)
+ (void) strlcpy(realname,
+ MZE_PHYS(zap, mze)->mze_name,
+ rn_len);
if (ncp) {
*ncp = mzap_normalization_conflict(zap,
- zn, mze);
+ zn, mze, &idx);
}
}
}
@@ -1031,7 +1056,7 @@ zap_prefetch(objset_t *os, uint64_t zapobj, const char *name)
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err)
return (err);
- zn = zap_name_alloc(zap, name, 0);
+ zn = zap_name_alloc_str(zap, name, 0);
if (zn == NULL) {
zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
@@ -1134,7 +1159,7 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err != 0)
return (err);
- zap_name_t *zn = zap_name_alloc(zap, name, 0);
+ zap_name_t *zn = zap_name_alloc_str(zap, name, 0);
if (zn == NULL) {
zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
@@ -1142,7 +1167,8 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
if (!zap->zap_ismicro) {
err = fzap_length(zn, integer_size, num_integers);
} else {
- mzap_ent_t *mze = mze_find(zn);
+ zfs_btree_index_t idx;
+ mzap_ent_t *mze = mze_find(zn, &idx);
if (mze == NULL) {
err = SET_ERROR(ENOENT);
} else {
@@ -1182,7 +1208,7 @@ static void
mzap_addent(zap_name_t *zn, uint64_t value)
{
zap_t *zap = zn->zn_zap;
- int start = zap->zap_m.zap_alloc_next;
+ uint16_t start = zap->zap_m.zap_alloc_next;
ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
@@ -1198,7 +1224,7 @@ mzap_addent(zap_name_t *zn, uint64_t value)
ASSERT(cd < zap_maxcd(zap));
again:
- for (int i = start; i < zap->zap_m.zap_num_chunks; i++) {
+ for (uint16_t i = start; i < zap->zap_m.zap_num_chunks; i++) {
mzap_ent_phys_t *mze = &zap_m_phys(zap)->mz_chunk[i];
if (mze->mze_name[0] == 0) {
mze->mze_value = value;
@@ -1229,7 +1255,7 @@ zap_add_impl(zap_t *zap, const char *key,
const uint64_t *intval = val;
int err = 0;
- zap_name_t *zn = zap_name_alloc(zap, key, 0);
+ zap_name_t *zn = zap_name_alloc_str(zap, key, 0);
if (zn == NULL) {
zap_unlockdir(zap, tag);
return (SET_ERROR(ENOTSUP));
@@ -1247,7 +1273,8 @@ zap_add_impl(zap_t *zap, const char *key,
}
zap = zn->zn_zap; /* fzap_add() may change zap */
} else {
- if (mze_find(zn) != NULL) {
+ zfs_btree_index_t idx;
+ if (mze_find(zn, &idx) != NULL) {
err = SET_ERROR(EEXIST);
} else {
mzap_addent(zn, *intval);
@@ -1327,7 +1354,7 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err != 0)
return (err);
- zap_name_t *zn = zap_name_alloc(zap, name, 0);
+ zap_name_t *zn = zap_name_alloc_str(zap, name, 0);
if (zn == NULL) {
zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
@@ -1348,7 +1375,8 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
}
zap = zn->zn_zap; /* fzap_update() may change zap */
} else {
- mzap_ent_t *mze = mze_find(zn);
+ zfs_btree_index_t idx;
+ mzap_ent_t *mze = mze_find(zn, &idx);
if (mze != NULL) {
MZE_PHYS(zap, mze)->mze_value = *intval;
} else {
@@ -1398,20 +1426,20 @@ zap_remove_impl(zap_t *zap, const char *name,
{
int err = 0;
- zap_name_t *zn = zap_name_alloc(zap, name, mt);
+ zap_name_t *zn = zap_name_alloc_str(zap, name, mt);
if (zn == NULL)
return (SET_ERROR(ENOTSUP));
if (!zap->zap_ismicro) {
err = fzap_remove(zn, tx);
} else {
- mzap_ent_t *mze = mze_find(zn);
+ zfs_btree_index_t idx;
+ mzap_ent_t *mze = mze_find(zn, &idx);
if (mze == NULL) {
err = SET_ERROR(ENOENT);
} else {
zap->zap_m.zap_num_entries--;
- memset(&zap_m_phys(zap)->mz_chunk[mze->mze_chunkid], 0,
- sizeof (mzap_ent_phys_t));
- mze_remove(zap, mze);
+ memset(MZE_PHYS(zap, mze), 0, sizeof (mzap_ent_phys_t));
+ zfs_btree_remove_idx(&zap->zap_m.zap_tree, &idx);
}
}
zap_name_free(zn);
@@ -1582,29 +1610,30 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
if (!zc->zc_zap->zap_ismicro) {
err = fzap_cursor_retrieve(zc->zc_zap, zc, za);
} else {
- avl_index_t idx;
+ zfs_btree_index_t idx;
mzap_ent_t mze_tofind;
- mze_tofind.mze_hash = zc->zc_hash;
+ mze_tofind.mze_hash = zc->zc_hash >> 32;
mze_tofind.mze_cd = zc->zc_cd;
- mzap_ent_t *mze =
- avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
+ mzap_ent_t *mze = zfs_btree_find(&zc->zc_zap->zap_m.zap_tree,
+ &mze_tofind, &idx);
if (mze == NULL) {
- mze = avl_nearest(&zc->zc_zap->zap_m.zap_avl,
- idx, AVL_AFTER);
+ mze = zfs_btree_next(&zc->zc_zap->zap_m.zap_tree,
+ &idx, &idx);
}
if (mze) {
mzap_ent_phys_t *mzep = MZE_PHYS(zc->zc_zap, mze);
ASSERT3U(mze->mze_cd, ==, mzep->mze_cd);
za->za_normalization_conflict =
- mzap_normalization_conflict(zc->zc_zap, NULL, mze);
+ mzap_normalization_conflict(zc->zc_zap, NULL,
+ mze, &idx);
za->za_integer_length = 8;
za->za_num_integers = 1;
za->za_first_integer = mzep->mze_value;
(void) strlcpy(za->za_name, mzep->mze_name,
sizeof (za->za_name));
- zc->zc_hash = mze->mze_hash;
+ zc->zc_hash = (uint64_t)mze->mze_hash << 32;
zc->zc_cd = mze->mze_cd;
err = 0;
} else {
diff --git a/sys/contrib/openzfs/module/zfs/zcp.c b/sys/contrib/openzfs/module/zfs/zcp.c
index fe90242ca40d..5ebf1bbbc8cc 100644
--- a/sys/contrib/openzfs/module/zfs/zcp.c
+++ b/sys/contrib/openzfs/module/zfs/zcp.c
@@ -109,8 +109,8 @@
#define ZCP_NVLIST_MAX_DEPTH 20
static const uint64_t zfs_lua_check_instrlimit_interval = 100;
-unsigned long zfs_lua_max_instrlimit = ZCP_MAX_INSTRLIMIT;
-unsigned long zfs_lua_max_memlimit = ZCP_MAX_MEMLIMIT;
+uint64_t zfs_lua_max_instrlimit = ZCP_MAX_INSTRLIMIT;
+uint64_t zfs_lua_max_memlimit = ZCP_MAX_MEMLIMIT;
/*
* Forward declarations for mutually recursive functions
@@ -277,9 +277,9 @@ zcp_table_to_nvlist(lua_State *state, int index, int depth)
}
break;
case LUA_TNUMBER:
- VERIFY3U(sizeof (buf), >,
- snprintf(buf, sizeof (buf), "%lld",
- (longlong_t)lua_tonumber(state, -2)));
+ (void) snprintf(buf, sizeof (buf), "%lld",
+ (longlong_t)lua_tonumber(state, -2));
+
key = buf;
if (saw_str_could_collide) {
key_could_collide = B_TRUE;
@@ -1443,8 +1443,8 @@ zcp_parse_args(lua_State *state, const char *fname, const zcp_arg_t *pargs,
}
}
-ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_instrlimit, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_instrlimit, U64, ZMOD_RW,
"Max instruction limit that can be specified for a channel program");
-ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_memlimit, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_memlimit, U64, ZMOD_RW,
"Max memory limit that can be specified for a channel program");
diff --git a/sys/contrib/openzfs/module/zfs/zcp_get.c b/sys/contrib/openzfs/module/zfs/zcp_get.c
index cd17374eb422..f28266b8095f 100644
--- a/sys/contrib/openzfs/module/zfs/zcp_get.c
+++ b/sys/contrib/openzfs/module/zfs/zcp_get.c
@@ -467,7 +467,8 @@ get_zap_prop(lua_State *state, dsl_dataset_t *ds, zfs_prop_t zfs_prop)
} else {
error = dsl_prop_get_ds(ds, prop_name, sizeof (numval),
1, &numval, setpoint);
-
+ if (error != 0)
+ goto out;
#ifdef _KERNEL
/* Fill in temporary value for prop, if applicable */
(void) zfs_get_temporary_prop(ds, zfs_prop, &numval, setpoint);
@@ -489,6 +490,7 @@ get_zap_prop(lua_State *state, dsl_dataset_t *ds, zfs_prop_t zfs_prop)
(void) lua_pushnumber(state, numval);
}
}
+out:
kmem_free(strval, ZAP_MAXVALUELEN);
if (error == 0)
get_prop_src(state, setpoint, zfs_prop);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_chksum.c b/sys/contrib/openzfs/module/zfs/zfs_chksum.c
index 74b4cb8d2e63..4a9a36d87e66 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_chksum.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_chksum.c
@@ -81,15 +81,15 @@ chksum_kstat_headers(char *buf, size_t size)
{
ssize_t off = 0;
- off += snprintf(buf + off, size, "%-23s", "implementation");
- off += snprintf(buf + off, size - off, "%8s", "1k");
- off += snprintf(buf + off, size - off, "%8s", "4k");
- off += snprintf(buf + off, size - off, "%8s", "16k");
- off += snprintf(buf + off, size - off, "%8s", "64k");
- off += snprintf(buf + off, size - off, "%8s", "256k");
- off += snprintf(buf + off, size - off, "%8s", "1m");
- off += snprintf(buf + off, size - off, "%8s", "4m");
- (void) snprintf(buf + off, size - off, "%8s\n", "16m");
+ off += kmem_scnprintf(buf + off, size, "%-23s", "implementation");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "1k");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "4k");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "16k");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "64k");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "256k");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "1m");
+ off += kmem_scnprintf(buf + off, size - off, "%8s", "4m");
+ (void) kmem_scnprintf(buf + off, size - off, "%8s\n", "16m");
return (0);
}
@@ -102,23 +102,23 @@ chksum_kstat_data(char *buf, size_t size, void *data)
char b[24];
cs = (chksum_stat_t *)data;
- snprintf(b, 23, "%s-%s", cs->name, cs->impl);
- off += snprintf(buf + off, size - off, "%-23s", b);
- off += snprintf(buf + off, size - off, "%8llu",
+ kmem_scnprintf(b, 23, "%s-%s", cs->name, cs->impl);
+ off += kmem_scnprintf(buf + off, size - off, "%-23s", b);
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs1k);
- off += snprintf(buf + off, size - off, "%8llu",
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs4k);
- off += snprintf(buf + off, size - off, "%8llu",
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs16k);
- off += snprintf(buf + off, size - off, "%8llu",
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs64k);
- off += snprintf(buf + off, size - off, "%8llu",
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs256k);
- off += snprintf(buf + off, size - off, "%8llu",
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs1m);
- off += snprintf(buf + off, size - off, "%8llu",
+ off += kmem_scnprintf(buf + off, size - off, "%8llu",
(u_longlong_t)cs->bs4m);
- (void) snprintf(buf + off, size - off, "%8llu\n",
+ (void) kmem_scnprintf(buf + off, size - off, "%8llu\n",
(u_longlong_t)cs->bs16m);
return (0);
diff --git a/sys/contrib/openzfs/module/zfs/zfs_fm.c b/sys/contrib/openzfs/module/zfs/zfs_fm.c
index 06aa1214ace8..fd0dc7d69bf8 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_fm.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_fm.c
@@ -253,7 +253,6 @@ void
zfs_ereport_clear(spa_t *spa, vdev_t *vd)
{
uint64_t vdev_guid, pool_guid;
- int cnt = 0;
ASSERT(vd != NULL || spa != NULL);
if (vd == NULL) {
@@ -277,7 +276,6 @@ zfs_ereport_clear(spa_t *spa, vdev_t *vd)
avl_remove(&recent_events_tree, entry);
list_remove(&recent_events_list, entry);
kmem_free(entry, sizeof (*entry));
- cnt++;
}
}
diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
index c3266c09306b..a5168b937588 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
@@ -229,14 +229,14 @@ static zfsdev_state_t *zfsdev_state_list;
* for zc->zc_nvlist_src_size, since we will need to allocate that much memory.
* Defaults to 0=auto which is handled by platform code.
*/
-unsigned long zfs_max_nvlist_src_size = 0;
+uint64_t zfs_max_nvlist_src_size = 0;
/*
* When logging the output nvlist of an ioctl in the on-disk history, limit
* the logged size to this many bytes. This must be less than DMU_MAX_ACCESS.
* This applies primarily to zfs_ioc_channel_program().
*/
-static unsigned long zfs_history_output_max = 1024 * 1024;
+static uint64_t zfs_history_output_max = 1024 * 1024;
uint_t zfs_fsyncer_key;
uint_t zfs_allow_log_key;
@@ -7884,8 +7884,8 @@ zfs_kmod_fini(void)
tsd_destroy(&zfs_allow_log_key);
}
-ZFS_MODULE_PARAM(zfs, zfs_, max_nvlist_src_size, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, max_nvlist_src_size, U64, ZMOD_RW,
"Maximum size in bytes allowed for src nvlist passed with ZFS ioctls");
-ZFS_MODULE_PARAM(zfs, zfs_, history_output_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, history_output_max, U64, ZMOD_RW,
"Maximum size in bytes of ZFS ioctl output that will be logged");
diff --git a/sys/contrib/openzfs/module/zfs/zfs_log.c b/sys/contrib/openzfs/module/zfs/zfs_log.c
index c92044337bce..77bf9140d52d 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_log.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_log.c
@@ -494,6 +494,29 @@ zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
zil_itx_assign(zilog, itx, tx);
}
+static void
+do_zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *sdzp,
+ const char *sname, znode_t *tdzp, const char *dname, znode_t *szp)
+{
+ itx_t *itx;
+ lr_rename_t *lr;
+ size_t snamesize = strlen(sname) + 1;
+ size_t dnamesize = strlen(dname) + 1;
+
+ if (zil_replaying(zilog, tx))
+ return;
+
+ itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
+ lr = (lr_rename_t *)&itx->itx_lr;
+ lr->lr_sdoid = sdzp->z_id;
+ lr->lr_tdoid = tdzp->z_id;
+ memcpy((char *)(lr + 1), sname, snamesize);
+ memcpy((char *)(lr + 1) + snamesize, dname, dnamesize);
+ itx->itx_oid = szp->z_id;
+
+ zil_itx_assign(zilog, itx, tx);
+}
+
/*
* Handles TX_RENAME transactions.
*/
@@ -501,18 +524,71 @@ void
zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *sdzp,
const char *sname, znode_t *tdzp, const char *dname, znode_t *szp)
{
+ txtype |= TX_RENAME;
+ do_zfs_log_rename(zilog, tx, txtype, sdzp, sname, tdzp, dname, szp);
+}
+
+/*
+ * Handles TX_RENAME_EXCHANGE transactions.
+ */
+void
+zfs_log_rename_exchange(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+ znode_t *sdzp, const char *sname, znode_t *tdzp, const char *dname,
+ znode_t *szp)
+{
+ txtype |= TX_RENAME_EXCHANGE;
+ do_zfs_log_rename(zilog, tx, txtype, sdzp, sname, tdzp, dname, szp);
+}
+
+/*
+ * Handles TX_RENAME_WHITEOUT transactions.
+ *
+ * Unfortunately we cannot reuse do_zfs_log_rename because we we need to call
+ * zfs_mknode() on replay which requires stashing bits as with TX_CREATE.
+ */
+void
+zfs_log_rename_whiteout(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
+ znode_t *sdzp, const char *sname, znode_t *tdzp, const char *dname,
+ znode_t *szp, znode_t *wzp)
+{
itx_t *itx;
- lr_rename_t *lr;
+ lr_rename_whiteout_t *lr;
size_t snamesize = strlen(sname) + 1;
size_t dnamesize = strlen(dname) + 1;
if (zil_replaying(zilog, tx))
return;
+ txtype |= TX_RENAME_WHITEOUT;
itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
- lr = (lr_rename_t *)&itx->itx_lr;
- lr->lr_sdoid = sdzp->z_id;
- lr->lr_tdoid = tdzp->z_id;
+ lr = (lr_rename_whiteout_t *)&itx->itx_lr;
+ lr->lr_rename.lr_sdoid = sdzp->z_id;
+ lr->lr_rename.lr_tdoid = tdzp->z_id;
+
+ /*
+ * RENAME_WHITEOUT will create an entry at the source znode, so we need
+ * to store the same data that the equivalent call to zfs_log_create()
+ * would.
+ */
+ lr->lr_wfoid = wzp->z_id;
+ LR_FOID_SET_SLOTS(lr->lr_wfoid, wzp->z_dnodesize >> DNODE_SHIFT);
+ (void) sa_lookup(wzp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(wzp)), &lr->lr_wgen,
+ sizeof (uint64_t));
+ (void) sa_lookup(wzp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(wzp)),
+ lr->lr_wcrtime, sizeof (uint64_t) * 2);
+ lr->lr_wmode = wzp->z_mode;
+ lr->lr_wuid = (uint64_t)KUID_TO_SUID(ZTOUID(wzp));
+ lr->lr_wgid = (uint64_t)KGID_TO_SGID(ZTOGID(wzp));
+
+ /*
+ * This rdev will always be makdevice(0, 0) but because the ZIL log and
+ * replay code needs to be platform independent (and there is no
+ * platform independent makdev()) we need to copy the one created
+ * during the rename operation.
+ */
+ (void) sa_lookup(wzp->z_sa_hdl, SA_ZPL_RDEV(ZTOZSB(wzp)), &lr->lr_wrdev,
+ sizeof (lr->lr_wrdev));
+
memcpy((char *)(lr + 1), sname, snamesize);
memcpy((char *)(lr + 1) + snamesize, dname, dnamesize);
itx->itx_oid = szp->z_id;
@@ -525,7 +601,7 @@ zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *sdzp,
* called as soon as the write is on stable storage (be it via a DMU sync or a
* ZIL commit).
*/
-static long zfs_immediate_write_sz = 32768;
+static int64_t zfs_immediate_write_sz = 32768;
void
zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
@@ -815,5 +891,5 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
zil_itx_assign(zilog, itx, tx);
}
-ZFS_MODULE_PARAM(zfs, zfs_, immediate_write_sz, LONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, immediate_write_sz, S64, ZMOD_RW,
"Largest data block to write to zil");
diff --git a/sys/contrib/openzfs/module/zfs/zfs_onexit.c b/sys/contrib/openzfs/module/zfs/zfs_onexit.c
index dfcdeeb5b46f..63acf7ab2e4d 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_onexit.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_onexit.c
@@ -151,7 +151,7 @@ zfs_onexit_minor_to_state(minor_t minor, zfs_onexit_t **zo)
*/
int
zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
- uint64_t *action_handle)
+ uintptr_t *action_handle)
{
zfs_onexit_t *zo;
zfs_onexit_action_node_t *ap;
@@ -170,7 +170,7 @@ zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
list_insert_tail(&zo->zo_actions, ap);
mutex_exit(&zo->zo_lock);
if (action_handle)
- *action_handle = (uint64_t)(uintptr_t)ap;
+ *action_handle = (uintptr_t)ap;
return (0);
}
diff --git a/sys/contrib/openzfs/module/zfs/zfs_replay.c b/sys/contrib/openzfs/module/zfs/zfs_replay.c
index 379e1d1a7b57..0293e46d5858 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_replay.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_replay.c
@@ -386,8 +386,13 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
lr->lr_uid, lr->lr_gid);
}
+#if defined(__linux__)
error = zfs_create(dzp, name, &xva.xva_vattr,
- 0, 0, &zp, kcred, vflg, &vsec);
+ 0, 0, &zp, kcred, vflg, &vsec, kcred->user_ns);
+#else
+ error = zfs_create(dzp, name, &xva.xva_vattr,
+ 0, 0, &zp, kcred, vflg, &vsec, NULL);
+#endif
break;
case TX_MKDIR_ACL:
aclstart = (caddr_t)(lracl + 1);
@@ -416,8 +421,13 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
(void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
lr->lr_uid, lr->lr_gid);
}
+#if defined(__linux__)
+ error = zfs_mkdir(dzp, name, &xva.xva_vattr,
+ &zp, kcred, vflg, &vsec, kcred->user_ns);
+#else
error = zfs_mkdir(dzp, name, &xva.xva_vattr,
- &zp, kcred, vflg, &vsec);
+ &zp, kcred, vflg, &vsec, NULL);
+#endif
break;
default:
error = SET_ERROR(ENOTSUP);
@@ -527,8 +537,13 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
if (name == NULL)
name = (char *)start;
+#if defined(__linux__)
+ error = zfs_create(dzp, name, &xva.xva_vattr,
+ 0, 0, &zp, kcred, vflg, NULL, kcred->user_ns);
+#else
error = zfs_create(dzp, name, &xva.xva_vattr,
- 0, 0, &zp, kcred, vflg, NULL);
+ 0, 0, &zp, kcred, vflg, NULL, NULL);
+#endif
break;
case TX_MKDIR_ATTR:
lrattr = (lr_attr_t *)(caddr_t)(lr + 1);
@@ -545,8 +560,14 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
if (name == NULL)
name = (char *)(lr + 1);
+#if defined(__linux__)
+ error = zfs_mkdir(dzp, name, &xva.xva_vattr,
+ &zp, kcred, vflg, NULL, kcred->user_ns);
+#else
error = zfs_mkdir(dzp, name, &xva.xva_vattr,
- &zp, kcred, vflg, NULL);
+ &zp, kcred, vflg, NULL, NULL);
+#endif
+
break;
case TX_MKXATTR:
error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &zp, kcred);
@@ -554,8 +575,13 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
case TX_SYMLINK:
name = (char *)(lr + 1);
link = name + strlen(name) + 1;
+#if defined(__linux__)
+ error = zfs_symlink(dzp, name, &xva.xva_vattr,
+ link, &zp, kcred, vflg, kcred->user_ns);
+#else
error = zfs_symlink(dzp, name, &xva.xva_vattr,
- link, &zp, kcred, vflg);
+ link, &zp, kcred, vflg, NULL);
+#endif
break;
default:
error = SET_ERROR(ENOTSUP);
@@ -643,18 +669,21 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
}
static int
-zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
+do_zfs_replay_rename(zfsvfs_t *zfsvfs, lr_rename_t *lr, char *sname,
+ char *tname, uint64_t rflags, vattr_t *wo_vap)
{
- zfsvfs_t *zfsvfs = arg1;
- lr_rename_t *lr = arg2;
- char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
- char *tname = sname + strlen(sname) + 1;
znode_t *sdzp, *tdzp;
- int error;
- int vflg = 0;
+ int error, vflg = 0;
- if (byteswap)
- byteswap_uint64_array(lr, sizeof (*lr));
+ /* Only Linux currently supports RENAME_* flags. */
+#ifdef __linux__
+ VERIFY0(rflags & ~(RENAME_EXCHANGE | RENAME_WHITEOUT));
+
+ /* wo_vap must be non-NULL iff. we're doing RENAME_WHITEOUT */
+ VERIFY_EQUIV(rflags & RENAME_WHITEOUT, wo_vap != NULL);
+#else
+ VERIFY0(rflags);
+#endif
if ((error = zfs_zget(zfsvfs, lr->lr_sdoid, &sdzp)) != 0)
return (error);
@@ -667,7 +696,13 @@ zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
if (lr->lr_common.lrc_txtype & TX_CI)
vflg |= FIGNORECASE;
- error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg);
+#if defined(__linux__)
+ error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg, rflags,
+ wo_vap, kcred->user_ns);
+#else
+ error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg, rflags,
+ wo_vap, NULL);
+#endif
zrele(tdzp);
zrele(sdzp);
@@ -675,6 +710,86 @@ zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
}
static int
+zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
+{
+ zfsvfs_t *zfsvfs = arg1;
+ lr_rename_t *lr = arg2;
+ char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
+ char *tname = sname + strlen(sname) + 1;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, 0, NULL));
+}
+
+static int
+zfs_replay_rename_exchange(void *arg1, void *arg2, boolean_t byteswap)
+{
+#ifdef __linux__
+ zfsvfs_t *zfsvfs = arg1;
+ lr_rename_t *lr = arg2;
+ char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
+ char *tname = sname + strlen(sname) + 1;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, RENAME_EXCHANGE,
+ NULL));
+#else
+ return (SET_ERROR(ENOTSUP));
+#endif
+}
+
+static int
+zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
+{
+#ifdef __linux__
+ zfsvfs_t *zfsvfs = arg1;
+ lr_rename_whiteout_t *lr = arg2;
+ int error;
+ /* sname and tname follow lr_rename_whiteout_t */
+ char *sname = (char *)(lr + 1);
+ char *tname = sname + strlen(sname) + 1;
+ /* For the whiteout file. */
+ xvattr_t xva;
+ uint64_t objid;
+ uint64_t dnodesize;
+
+ if (byteswap)
+ byteswap_uint64_array(lr, sizeof (*lr));
+
+ objid = LR_FOID_GET_OBJ(lr->lr_wfoid);
+ dnodesize = LR_FOID_GET_SLOTS(lr->lr_wfoid) << DNODE_SHIFT;
+
+ xva_init(&xva);
+ zfs_init_vattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID,
+ lr->lr_wmode, lr->lr_wuid, lr->lr_wgid, lr->lr_wrdev, objid);
+
+ /*
+ * As with TX_CREATE, RENAME_WHITEOUT ends up in zfs_mknode(), which
+ * assigns the object's creation time, generation number, and dnode
+ * slot count. The generic zfs_rename() has no concept of these
+ * attributes, so we smuggle the values inside the vattr's otherwise
+ * unused va_ctime, va_nblocks, and va_fsid fields.
+ */
+ ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_wcrtime);
+ xva.xva_vattr.va_nblocks = lr->lr_wgen;
+ xva.xva_vattr.va_fsid = dnodesize;
+
+ error = dnode_try_claim(zfsvfs->z_os, objid, dnodesize >> DNODE_SHIFT);
+ if (error)
+ return (error);
+
+ return (do_zfs_replay_rename(zfsvfs, &lr->lr_rename, sname, tname,
+ RENAME_WHITEOUT, &xva.xva_vattr));
+#else
+ return (SET_ERROR(ENOTSUP));
+#endif
+}
+
+static int
zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
{
zfsvfs_t *zfsvfs = arg1;
@@ -860,7 +975,11 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start,
lr->lr_uid, lr->lr_gid);
- error = zfs_setattr(zp, vap, 0, kcred);
+#if defined(__linux__)
+ error = zfs_setattr(zp, vap, 0, kcred, kcred->user_ns);
+#else
+ error = zfs_setattr(zp, vap, 0, kcred, NULL);
+#endif
zfs_fuid_info_free(zfsvfs->z_fuid_replay);
zfsvfs->z_fuid_replay = NULL;
@@ -1069,4 +1188,6 @@ zil_replay_func_t *const zfs_replay_vector[TX_MAX_TYPE] = {
zfs_replay_create_acl, /* TX_MKDIR_ACL_ATTR */
zfs_replay_write2, /* TX_WRITE2 */
zfs_replay_setsaxattr, /* TX_SETSAXATTR */
+ zfs_replay_rename_exchange, /* TX_RENAME_EXCHANGE */
+ zfs_replay_rename_whiteout, /* TX_RENAME_WHITEOUT */
};
diff --git a/sys/contrib/openzfs/module/zfs/zfs_vnops.c b/sys/contrib/openzfs/module/zfs/zfs_vnops.c
index 57f03f116273..45ecb0773260 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_vnops.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_vnops.c
@@ -64,7 +64,7 @@ zfs_fsync(znode_t *zp, int syncflag, cred_t *cr)
int error = 0;
zfsvfs_t *zfsvfs = ZTOZSB(zp);
- (void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt);
+ (void) tsd_set(zfs_fsyncer_key, (void *)(uintptr_t)zfs_fsync_sync_cnt);
if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
if ((error = zfs_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
@@ -168,15 +168,25 @@ zfs_access(znode_t *zp, int mode, int flag, cred_t *cr)
return (error);
if (flag & V_ACE_MASK)
- error = zfs_zaccess(zp, mode, flag, B_FALSE, cr);
+#if defined(__linux__)
+ error = zfs_zaccess(zp, mode, flag, B_FALSE, cr,
+ kcred->user_ns);
+#else
+ error = zfs_zaccess(zp, mode, flag, B_FALSE, cr,
+ NULL);
+#endif
else
- error = zfs_zaccess_rwx(zp, mode, flag, cr);
+#if defined(__linux__)
+ error = zfs_zaccess_rwx(zp, mode, flag, cr, kcred->user_ns);
+#else
+ error = zfs_zaccess_rwx(zp, mode, flag, cr, NULL);
+#endif
zfs_exit(zfsvfs, FTAG);
return (error);
}
-static unsigned long zfs_vnops_read_chunk_size = 1024 * 1024; /* Tunable */
+static uint64_t zfs_vnops_read_chunk_size = 1024 * 1024; /* Tunable */
/*
* Read bytes from specified file into supplied buffer.
@@ -991,5 +1001,5 @@ EXPORT_SYMBOL(zfs_write);
EXPORT_SYMBOL(zfs_getsecattr);
EXPORT_SYMBOL(zfs_setsecattr);
-ZFS_MODULE_PARAM(zfs_vnops, zfs_vnops_, read_chunk_size, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_vnops, zfs_vnops_, read_chunk_size, U64, ZMOD_RW,
"Bytes to read per chunk");
diff --git a/sys/contrib/openzfs/module/zfs/zil.c b/sys/contrib/openzfs/module/zfs/zil.c
index dc5b8018e16e..02e6f4b83b9c 100644
--- a/sys/contrib/openzfs/module/zfs/zil.c
+++ b/sys/contrib/openzfs/module/zfs/zil.c
@@ -132,7 +132,7 @@ static int zil_nocacheflush = 0;
* Any writes above that will be executed with lower (asynchronous) priority
* to limit potential SLOG device abuse by single active ZIL writer.
*/
-static unsigned long zil_slog_bulk = 768 * 1024;
+static uint64_t zil_slog_bulk = 768 * 1024;
static kmem_cache_t *zil_lwb_cache;
static kmem_cache_t *zil_zcw_cache;
@@ -237,7 +237,7 @@ static int
zil_read_log_block(zilog_t *zilog, boolean_t decrypt, const blkptr_t *bp,
blkptr_t *nbp, void *dst, char **end)
{
- enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
+ zio_flag_t zio_flags = ZIO_FLAG_CANFAIL;
arc_flags_t aflags = ARC_FLAG_WAIT;
arc_buf_t *abuf = NULL;
zbookmark_phys_t zb;
@@ -315,7 +315,7 @@ zil_read_log_block(zilog_t *zilog, boolean_t decrypt, const blkptr_t *bp,
static int
zil_read_log_data(zilog_t *zilog, const lr_write_t *lr, void *wbuf)
{
- enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
+ zio_flag_t zio_flags = ZIO_FLAG_CANFAIL;
const blkptr_t *bp = &lr->lr_blkptr;
arc_flags_t aflags = ARC_FLAG_WAIT;
arc_buf_t *abuf = NULL;
@@ -339,6 +339,7 @@ zil_read_log_data(zilog_t *zilog, const lr_write_t *lr, void *wbuf)
if (wbuf == NULL)
zio_flags |= ZIO_FLAG_RAW;
+ ASSERT3U(BP_GET_LSIZE(bp), !=, 0);
SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os), lr->lr_foid,
ZB_ZIL_LEVEL, lr->lr_offset / BP_GET_LSIZE(bp));
@@ -479,8 +480,18 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
error = zil_read_log_block(zilog, decrypt, &blk, &next_blk,
lrbuf, &end);
- if (error != 0)
+ if (error != 0) {
+ if (claimed) {
+ char name[ZFS_MAX_DATASET_NAME_LEN];
+
+ dmu_objset_name(zilog->zl_os, name);
+
+ cmn_err(CE_WARN, "ZFS read log block error %d, "
+ "dataset %s, seq 0x%llx\n", error, name,
+ (u_longlong_t)blk_seq);
+ }
break;
+ }
for (lrp = lrbuf; lrp < end; lrp += reclen) {
lr_t *lr = (lr_t *)lrp;
@@ -504,10 +515,6 @@ done:
zilog->zl_parse_blk_count = blk_count;
zilog->zl_parse_lr_count = lr_count;
- ASSERT(!claimed || !(zh->zh_flags & ZIL_CLAIM_LR_SEQ_VALID) ||
- (max_blk_seq == claim_blk_seq && max_lr_seq == claim_lr_seq) ||
- (decrypt && error == EIO));
-
zil_bp_tree_fini(zilog);
zio_buf_free(lrbuf, SPA_OLD_MAXBLOCKSIZE);
@@ -758,11 +765,9 @@ zil_commit_activate_saxattr_feature(zilog_t *zilog)
uint64_t txg = 0;
dmu_tx_t *tx = NULL;
- if (spa_feature_is_enabled(zilog->zl_spa,
- SPA_FEATURE_ZILSAXATTR) &&
+ if (spa_feature_is_enabled(zilog->zl_spa, SPA_FEATURE_ZILSAXATTR) &&
dmu_objset_type(zilog->zl_os) != DMU_OST_ZVOL &&
- !dsl_dataset_feature_is_active(ds,
- SPA_FEATURE_ZILSAXATTR)) {
+ !dsl_dataset_feature_is_active(ds, SPA_FEATURE_ZILSAXATTR)) {
tx = dmu_tx_create(zilog->zl_os);
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
dsl_dataset_dirty(ds, tx);
@@ -882,8 +887,9 @@ zil_create(zilog_t *zilog)
* txg_wait_synced() here either when keep_first is set, because both
* zil_create() and zil_destroy() will wait for any in-progress destroys
* to complete.
+ * Return B_TRUE if there were any entries to replay.
*/
-void
+boolean_t
zil_destroy(zilog_t *zilog, boolean_t keep_first)
{
const zil_header_t *zh = zilog->zl_header;
@@ -899,7 +905,7 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
zilog->zl_old_header = *zh; /* debugging aid */
if (BP_IS_HOLE(&zh->zh_log))
- return;
+ return (B_FALSE);
tx = dmu_tx_create(zilog->zl_os);
VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
@@ -932,6 +938,8 @@ zil_destroy(zilog_t *zilog, boolean_t keep_first)
mutex_exit(&zilog->zl_lock);
dmu_tx_commit(tx);
+
+ return (B_TRUE);
}
void
@@ -3844,8 +3852,9 @@ zil_incr_blks(zilog_t *zilog, const blkptr_t *bp, void *arg, uint64_t claim_txg)
/*
* If this dataset has a non-empty intent log, replay it and destroy it.
+ * Return B_TRUE if there were any entries to replay.
*/
-void
+boolean_t
zil_replay(objset_t *os, void *arg,
zil_replay_func_t *const replay_func[TX_MAX_TYPE])
{
@@ -3854,8 +3863,7 @@ zil_replay(objset_t *os, void *arg,
zil_replay_arg_t zr;
if ((zh->zh_flags & ZIL_REPLAY_NEEDED) == 0) {
- zil_destroy(zilog, B_TRUE);
- return;
+ return (zil_destroy(zilog, B_TRUE));
}
zr.zr_replay = replay_func;
@@ -3878,6 +3886,8 @@ zil_replay(objset_t *os, void *arg,
zil_destroy(zilog, B_FALSE);
txg_wait_synced(zilog->zl_dmu_pool, zilog->zl_destroy_txg);
zilog->zl_replay = B_FALSE;
+
+ return (B_TRUE);
}
boolean_t
@@ -3945,7 +3955,7 @@ ZFS_MODULE_PARAM(zfs_zil, zil_, replay_disable, INT, ZMOD_RW,
ZFS_MODULE_PARAM(zfs_zil, zil_, nocacheflush, INT, ZMOD_RW,
"Disable ZIL cache flushes");
-ZFS_MODULE_PARAM(zfs_zil, zil_, slog_bulk, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs_zil, zil_, slog_bulk, U64, ZMOD_RW,
"Limit in bytes slog sync writes per commit");
ZFS_MODULE_PARAM(zfs_zil, zil_, maxblocksize, UINT, ZMOD_RW,
diff --git a/sys/contrib/openzfs/module/zfs/zio.c b/sys/contrib/openzfs/module/zfs/zio.c
index c2e3c6169fa3..928e28813931 100644
--- a/sys/contrib/openzfs/module/zfs/zio.c
+++ b/sys/contrib/openzfs/module/zfs/zio.c
@@ -512,8 +512,9 @@ zio_decrypt(zio_t *zio, abd_t *data, uint64_t size)
/*
* If this is an authenticated block, just check the MAC. It would be
- * nice to separate this out into its own flag, but for the moment
- * enum zio_flag is out of bits.
+ * nice to separate this out into its own flag, but when this was done,
+ * we had run out of bits in what is now zio_flag_t. Future cleanup
+ * could make this a flag bit.
*/
if (BP_IS_AUTHENTICATED(bp)) {
if (ot == DMU_OT_OBJSET) {
@@ -802,7 +803,7 @@ static zio_t *
zio_create(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
abd_t *data, uint64_t lsize, uint64_t psize, zio_done_func_t *done,
void *private, zio_type_t type, zio_priority_t priority,
- enum zio_flag flags, vdev_t *vd, uint64_t offset,
+ zio_flag_t flags, vdev_t *vd, uint64_t offset,
const zbookmark_phys_t *zb, enum zio_stage stage,
enum zio_stage pipeline)
{
@@ -901,7 +902,7 @@ zio_destroy(zio_t *zio)
zio_t *
zio_null(zio_t *pio, spa_t *spa, vdev_t *vd, zio_done_func_t *done,
- void *private, enum zio_flag flags)
+ void *private, zio_flag_t flags)
{
zio_t *zio;
@@ -913,7 +914,7 @@ zio_null(zio_t *pio, spa_t *spa, vdev_t *vd, zio_done_func_t *done,
}
zio_t *
-zio_root(spa_t *spa, zio_done_func_t *done, void *private, enum zio_flag flags)
+zio_root(spa_t *spa, zio_done_func_t *done, void *private, zio_flag_t flags)
{
return (zio_null(NULL, spa, NULL, done, private, flags));
}
@@ -1099,7 +1100,7 @@ zfs_dva_valid(spa_t *spa, const dva_t *dva, const blkptr_t *bp)
zio_t *
zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
abd_t *data, uint64_t size, zio_done_func_t *done, void *private,
- zio_priority_t priority, enum zio_flag flags, const zbookmark_phys_t *zb)
+ zio_priority_t priority, zio_flag_t flags, const zbookmark_phys_t *zb)
{
zio_t *zio;
@@ -1117,7 +1118,7 @@ zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
abd_t *data, uint64_t lsize, uint64_t psize, const zio_prop_t *zp,
zio_done_func_t *ready, zio_done_func_t *children_ready,
zio_done_func_t *physdone, zio_done_func_t *done,
- void *private, zio_priority_t priority, enum zio_flag flags,
+ void *private, zio_priority_t priority, zio_flag_t flags,
const zbookmark_phys_t *zb)
{
zio_t *zio;
@@ -1160,7 +1161,7 @@ zio_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
zio_t *
zio_rewrite(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, abd_t *data,
uint64_t size, zio_done_func_t *done, void *private,
- zio_priority_t priority, enum zio_flag flags, zbookmark_phys_t *zb)
+ zio_priority_t priority, zio_flag_t flags, zbookmark_phys_t *zb)
{
zio_t *zio;
@@ -1203,7 +1204,6 @@ zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp)
*/
if (BP_IS_EMBEDDED(bp))
return;
- metaslab_check_free(spa, bp);
/*
* Frees that are for the currently-syncing txg, are not going to be
@@ -1220,6 +1220,7 @@ zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp)
txg != spa->spa_syncing_txg ||
(spa_sync_pass(spa) >= zfs_sync_pass_deferred_free &&
!spa_feature_is_active(spa, SPA_FEATURE_LOG_SPACEMAP))) {
+ 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);
@@ -1233,7 +1234,7 @@ zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp)
*/
zio_t *
zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
- enum zio_flag flags)
+ zio_flag_t flags)
{
ASSERT(!BP_IS_HOLE(bp));
ASSERT(spa_syncing_txg(spa) == txg);
@@ -1266,7 +1267,7 @@ zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
zio_t *
zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
- zio_done_func_t *done, void *private, enum zio_flag flags)
+ zio_done_func_t *done, void *private, zio_flag_t flags)
{
zio_t *zio;
@@ -1303,7 +1304,7 @@ zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
zio_t *
zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
- zio_done_func_t *done, void *private, enum zio_flag flags)
+ zio_done_func_t *done, void *private, zio_flag_t flags)
{
zio_t *zio;
int c;
@@ -1328,7 +1329,7 @@ zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd,
zio_t *
zio_trim(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
zio_done_func_t *done, void *private, zio_priority_t priority,
- enum zio_flag flags, enum trim_flag trim_flags)
+ zio_flag_t flags, enum trim_flag trim_flags)
{
zio_t *zio;
@@ -1348,7 +1349,7 @@ zio_trim(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
zio_t *
zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
abd_t *data, int checksum, zio_done_func_t *done, void *private,
- zio_priority_t priority, enum zio_flag flags, boolean_t labels)
+ zio_priority_t priority, zio_flag_t flags, boolean_t labels)
{
zio_t *zio;
@@ -1369,7 +1370,7 @@ zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
zio_t *
zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
abd_t *data, int checksum, zio_done_func_t *done, void *private,
- zio_priority_t priority, enum zio_flag flags, boolean_t labels)
+ zio_priority_t priority, zio_flag_t flags, boolean_t labels)
{
zio_t *zio;
@@ -1406,7 +1407,7 @@ zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
zio_t *
zio_vdev_child_io(zio_t *pio, blkptr_t *bp, vdev_t *vd, uint64_t offset,
abd_t *data, uint64_t size, int type, zio_priority_t priority,
- enum zio_flag flags, zio_done_func_t *done, void *private)
+ zio_flag_t flags, zio_done_func_t *done, void *private)
{
enum zio_stage pipeline = ZIO_VDEV_CHILD_PIPELINE;
zio_t *zio;
@@ -1480,7 +1481,7 @@ zio_vdev_child_io(zio_t *pio, blkptr_t *bp, vdev_t *vd, uint64_t offset,
zio_t *
zio_vdev_delegated_io(vdev_t *vd, uint64_t offset, abd_t *data, uint64_t size,
- zio_type_t type, zio_priority_t priority, enum zio_flag flags,
+ zio_type_t type, zio_priority_t priority, zio_flag_t flags,
zio_done_func_t *done, void *private)
{
zio_t *zio;
@@ -2030,7 +2031,7 @@ zio_deadman_impl(zio_t *pio, int ziodepth)
"delta=%llu queued=%llu io=%llu "
"path=%s "
"last=%llu type=%d "
- "priority=%d flags=0x%x stage=0x%x "
+ "priority=%d flags=0x%llx stage=0x%x "
"pipeline=0x%x pipeline-trace=0x%x "
"objset=%llu object=%llu "
"level=%llu blkid=%llu "
@@ -2040,8 +2041,8 @@ zio_deadman_impl(zio_t *pio, int ziodepth)
(u_longlong_t)delta, pio->io_delta, pio->io_delay,
vd ? vd->vdev_path : "NULL",
vq ? vq->vq_io_complete_ts : 0, pio->io_type,
- pio->io_priority, pio->io_flags, pio->io_stage,
- pio->io_pipeline, pio->io_pipeline_trace,
+ pio->io_priority, (u_longlong_t)pio->io_flags,
+ pio->io_stage, pio->io_pipeline, pio->io_pipeline_trace,
(u_longlong_t)zb->zb_objset, (u_longlong_t)zb->zb_object,
(u_longlong_t)zb->zb_level, (u_longlong_t)zb->zb_blkid,
(u_longlong_t)pio->io_offset, (u_longlong_t)pio->io_size,
@@ -3360,7 +3361,7 @@ zio_ddt_write(zio_t *zio)
return (zio);
}
-ddt_entry_t *freedde; /* for debugging */
+static ddt_entry_t *freedde; /* for debugging */
static zio_t *
zio_ddt_free(zio_t *zio)
diff --git a/sys/contrib/openzfs/module/zfs/zio_compress.c b/sys/contrib/openzfs/module/zfs/zio_compress.c
index 4c9cbc962093..0fb91ac81522 100644
--- a/sys/contrib/openzfs/module/zfs/zio_compress.c
+++ b/sys/contrib/openzfs/module/zfs/zio_compress.c
@@ -44,7 +44,7 @@
* If nonzero, every 1/X decompression attempts will fail, simulating
* an undetected memory error.
*/
-unsigned long zio_decompress_fail_fraction = 0;
+static unsigned long zio_decompress_fail_fraction = 0;
/*
* Compression vectors.
diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c
index 2e2860ff0212..20578a8223b2 100644
--- a/sys/contrib/openzfs/module/zfs/zvol.c
+++ b/sys/contrib/openzfs/module/zfs/zvol.c
@@ -514,6 +514,8 @@ zil_replay_func_t *const zvol_replay_vector[TX_MAX_TYPE] = {
zvol_replay_err, /* TX_MKDIR_ACL_ATTR */
zvol_replay_err, /* TX_WRITE2 */
zvol_replay_err, /* TX_SETSAXATTR */
+ zvol_replay_err, /* TX_RENAME_EXCHANGE */
+ zvol_replay_err, /* TX_RENAME_WHITEOUT */
};
/*
@@ -1026,8 +1028,7 @@ zvol_add_clones(const char *dsname, list_t *minors_list)
out:
if (dd != NULL)
dsl_dir_rele(dd, FTAG);
- if (dp != NULL)
- dsl_pool_rele(dp, FTAG);
+ dsl_pool_rele(dp, FTAG);
}
/*
diff --git a/sys/contrib/openzfs/scripts/Makefile.am b/sys/contrib/openzfs/scripts/Makefile.am
index 79719e621b69..4175d27ea32a 100644
--- a/sys/contrib/openzfs/scripts/Makefile.am
+++ b/sys/contrib/openzfs/scripts/Makefile.am
@@ -1,11 +1,4 @@
scriptsdir = $(datadir)/$(PACKAGE)
-dist_scripts_SCRIPTS = \
- %D%/zfs-helpers.sh \
- %D%/zfs-tests.sh \
- %D%/zfs.sh \
- %D%/zimport.sh \
- %D%/zloop.sh
-
dist_noinst_SCRIPTS = \
%D%/commitcheck.sh \
%D%/common.sh.in \
@@ -18,6 +11,19 @@ dist_noinst_SCRIPTS = \
%D%/paxcheck.sh \
%D%/zfs-tests-color.sh
+scripts_scripts = \
+ %D%/zfs-helpers.sh \
+ %D%/zfs-tests.sh \
+ %D%/zfs.sh \
+ %D%/zimport.sh \
+ %D%/zloop.sh
+
+if CONFIG_USER
+dist_scripts_SCRIPTS = $(scripts_scripts)
+else
+dist_noinst_SCRIPTS += $(scripts_scripts)
+endif
+
dist_noinst_DATA += \
%D%/cstyle.pl \
%D%/enum-extract.pl \
diff --git a/sys/contrib/openzfs/scripts/cstyle.pl b/sys/contrib/openzfs/scripts/cstyle.pl
index ca7f027051cc..d47fd3362408 100755
--- a/sys/contrib/openzfs/scripts/cstyle.pl
+++ b/sys/contrib/openzfs/scripts/cstyle.pl
@@ -498,9 +498,6 @@ line: while (<$filehandle>) {
if (/\S\*\/[^)]|\S\*\/$/ && !/$lint_re/) {
err("missing blank before close comment");
}
- if (/\/\/\S/) { # C++ comments
- err("missing blank after start comment");
- }
# check for unterminated single line comments, but allow them when
# they are used to comment out the argument list of a function
# declaration.
@@ -534,7 +531,15 @@ line: while (<$filehandle>) {
# multiple comments on the same line.
#
s/\/\*.*?\*\///g;
- s/\/\/.*$//; # C++ comments
+ s/\/\/(?:\s.*)?$//; # Valid C++ comments
+
+ # After stripping correctly spaced comments, check for (and strip) comments
+ # without a blank. By checking this after clearing out C++ comments that
+ # correctly have a blank, we guarantee URIs in a C++ comment will not cause
+ # an error.
+ if (s!//.*$!!) { # C++ comments
+ err("missing blank after start comment");
+ }
# delete any trailing whitespace; we have already checked for that.
s/\s*$//;
diff --git a/sys/contrib/openzfs/scripts/debian-packaging.sh b/sys/contrib/openzfs/scripts/debian-packaging.sh
new file mode 100755
index 000000000000..9cd042fa44da
--- /dev/null
+++ b/sys/contrib/openzfs/scripts/debian-packaging.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+#
+# This script can be used to invoke OpenZFS build from native Debian
+# packaging.
+#
+
+print_help ()
+{
+ echo "Usage: $(basename $0) [OPTIONS]"
+ echo
+ echo "Options:"
+ echo " -b, --build Build OpenZFS from Debian Packaging"
+ echo " -c, --clean Clean the workspace"
+}
+
+if [ "$#" -ne 1 ]; then
+ print_help
+ exit 1
+fi
+
+case $1 in
+ -b|--build)
+ cp -r contrib/debian debian
+ debuild -i -us -uc -b && fakeroot debian/rules override_dh_binary-modules
+ ;;
+ -c|--clean)
+ fakeroot debian/rules override_dh_auto_clean
+ rm -rf debian
+ ;;
+ *)
+ print_help
+ ;;
+esac
+
+exit 0
diff --git a/sys/contrib/openzfs/scripts/enum-extract.pl b/sys/contrib/openzfs/scripts/enum-extract.pl
index 5112cc807f67..5dc2e3455145 100755
--- a/sys/contrib/openzfs/scripts/enum-extract.pl
+++ b/sys/contrib/openzfs/scripts/enum-extract.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
my $usage = <<EOT;
usage: config-enum enum [file ...]
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index 65b64f4fa8cd..73ca69993149 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -838,12 +838,12 @@ tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos',
'rsend_026_neg', 'rsend_027_pos', 'rsend_028_neg', 'rsend_029_neg',
'rsend_030_pos', 'send-c_verify_ratio', 'send-c_verify_contents',
'send-c_props', 'send-c_incremental', 'send-c_volume',
- 'send-c_zstreamdump', 'send-c_lz4_disabled', 'send-c_recv_lz4_disabled',
- 'send-c_mixed_compression', 'send-c_stream_size_estimate',
- 'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
- 'send-c_recv_dedup', 'send-L_toggle', 'send_encrypted_hierarchy',
- 'send_encrypted_props', 'send_encrypted_truncated_files',
- 'send_freeobjects', 'send_realloc_files',
+ 'send-c_zstream_recompress', 'send-c_zstreamdump', 'send-c_lz4_disabled',
+ 'send-c_recv_lz4_disabled', 'send-c_mixed_compression',
+ 'send-c_stream_size_estimate', 'send-c_embedded_blocks', 'send-c_resume',
+ 'send-cpL_varied_recsize', 'send-c_recv_dedup', 'send-L_toggle',
+ 'send_encrypted_hierarchy', 'send_encrypted_props',
+ 'send_encrypted_truncated_files', 'send_freeobjects', 'send_realloc_files',
'send_realloc_encrypted_files', 'send_spill_block', 'send_holds',
'send_hole_birth', 'send_mixed_raw', 'send-wR_encrypted_zvol',
'send_partial_dataset', 'send_invalid', 'send_doall',
@@ -911,7 +911,7 @@ tests = [
'userquota_007_pos', 'userquota_008_pos', 'userquota_009_pos',
'userquota_010_pos', 'userquota_011_pos', 'userquota_012_neg',
'userspace_001_pos', 'userspace_002_pos', 'userspace_encrypted',
- 'userspace_send_encrypted']
+ 'userspace_send_encrypted', 'userspace_encrypted_13709']
tags = ['functional', 'userquota']
[tests/functional/vdev_zaps]
diff --git a/sys/contrib/openzfs/tests/runfiles/linux.run b/sys/contrib/openzfs/tests/runfiles/linux.run
index 09dfb5eb1e1d..52e824a888f2 100644
--- a/sys/contrib/openzfs/tests/runfiles/linux.run
+++ b/sys/contrib/openzfs/tests/runfiles/linux.run
@@ -157,6 +157,10 @@ tags = ['functional', 'projectquota']
tests = ['read_dos_attrs_001', 'write_dos_attrs_001']
tags = ['functional', 'dos_attributes']
+[tests/functional/renameat2:Linux]
+tests = ['renameat2_noreplace', 'renameat2_exchange', 'renameat2_whiteout']
+tags = ['functional', 'renameat2']
+
[tests/functional/rsend:Linux]
tests = ['send_realloc_dnode_size', 'send_encrypted_files']
tags = ['functional', 'rsend']
@@ -194,3 +198,7 @@ tags = ['functional', 'userquota']
tests = ['zvol_misc_fua']
tags = ['functional', 'zvol', 'zvol_misc']
+[tests/functional/idmap_mount:Linux]
+tests = ['idmap_mount_001', 'idmap_mount_002', 'idmap_mount_003',
+ 'idmap_mount_004', 'idmap_mount_005']
+tags = ['functional', 'idmap_mount']
diff --git a/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in b/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in
index bf7cf22b61fc..66b041b6e2a9 100755
--- a/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in
+++ b/sys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in
@@ -70,6 +70,11 @@ exec_reason = 'Test user execute permissions required for utilities'
python_deps_reason = 'Python modules missing: python3-cffi'
#
+# Some tests require that the kernel supports renameat2 syscall.
+#
+renameat2_reason = 'Kernel renameat2 support required'
+
+#
# Some tests require the O_TMPFILE flag which was first introduced in the
# 3.11 kernel.
#
@@ -132,6 +137,10 @@ na_reason = "Not applicable"
#
ci_reason = 'CI runner doesn\'t have all requirements'
+#
+# Idmapped mount is only supported in kernel version >= 5.12
+#
+idmap_reason = 'Idmapped mount needs kernel 5.12+'
#
# These tests are known to fail, thus we use this list to prevent these
@@ -227,6 +236,7 @@ maybe = {
'pool_checkpoint/checkpoint_discard_busy': ['FAIL', 11946],
'projectquota/setup': ['SKIP', exec_reason],
'removal/removal_condense_export': ['FAIL', known_reason],
+ 'renameat2/setup': ['SKIP', renameat2_reason],
'reservation/reservation_008_pos': ['FAIL', 7741],
'reservation/reservation_018_pos': ['FAIL', 5642],
'snapshot/clone_001_pos': ['FAIL', known_reason],
@@ -270,6 +280,11 @@ elif sys.platform.startswith('linux'):
'mmp/mmp_inactive_import': ['FAIL', known_reason],
'zvol/zvol_misc/zvol_misc_snapdev': ['FAIL', 12621],
'zvol/zvol_misc/zvol_misc_volmode': ['FAIL', known_reason],
+ 'idmap_mount/idmap_mount_001': ['SKIP', idmap_reason],
+ 'idmap_mount/idmap_mount_002': ['SKIP', idmap_reason],
+ 'idmap_mount/idmap_mount_003': ['SKIP', idmap_reason],
+ 'idmap_mount/idmap_mount_004': ['SKIP', idmap_reason],
+ 'idmap_mount/idmap_mount_005': ['SKIP', idmap_reason],
})
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore b/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
index 1fd54c1dd510..f68f58072818 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/.gitignore
@@ -27,6 +27,7 @@
/randwritecomp
/read_dos_attributes
/readmmap
+/renameat2
/rename_dir
/rm_lnkcnt_zero_file
/send_doall
@@ -47,3 +48,4 @@
/edonr_test
/skein_test
/sha2_test
+/idmap_util
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
index c19c870cf698..066abb6ce3b5 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
@@ -112,20 +112,21 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/edonr_test %D%/skein_test \
%C%_edonr_test_LDADD = $(%C%_skein_test_LDADD)
%C%_blake3_test_LDADD = $(%C%_skein_test_LDADD)
-
if BUILD_LINUX
scripts_zfs_tests_bin_PROGRAMS += %D%/getversion
scripts_zfs_tests_bin_PROGRAMS += %D%/user_ns_exec
+scripts_zfs_tests_bin_PROGRAMS += %D%/renameat2
scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest
scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet
+scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util
+%C%_idmap_util_LDADD = libspl.la
dist_noinst_DATA += %D%/linux_dos_attributes/dos_attributes.h
scripts_zfs_tests_bin_PROGRAMS += %D%/read_dos_attributes %D%/write_dos_attributes
%C%_read_dos_attributes_SOURCES = %D%/linux_dos_attributes/read_dos_attributes.c
%C%_write_dos_attributes_SOURCES = %D%/linux_dos_attributes/write_dos_attributes.c
-
scripts_zfs_tests_bin_PROGRAMS += %D%/randfree_file
%C%_randfree_file_SOURCES = %D%/file/randfree_file.c
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/badsend.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/badsend.c
index 48d05bd3fd4c..7a54532fb28d 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/badsend.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/badsend.c
@@ -76,6 +76,10 @@ main(int argc, char const * const argv[])
tosnap = p + 1;
fsname = strndup(tofull, p - tofull);
+ if (fsname == NULL) {
+ perror("strndup");
+ exit(EXIT_FAILURE);
+ }
if (strncmp(fsname, fromfull, p - tofull) != 0)
usage(argv[0]);
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 4e2023003b0e..9a34bf559be0 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/btree_test.c
@@ -23,11 +23,11 @@
#define BUFSIZE 256
-int seed = 0;
-int stress_timeout = 180;
-int contents_frequency = 100;
-int tree_limit = 64 * 1024;
-boolean_t stress_only = B_FALSE;
+static int seed = 0;
+static int stress_timeout = 180;
+static int contents_frequency = 100;
+static int tree_limit = 64 * 1024;
+static boolean_t stress_only = B_FALSE;
static void
usage(int exit_value)
@@ -220,7 +220,6 @@ insert_find_remove(zfs_btree_t *bt, char *why)
static int
drain_tree(zfs_btree_t *bt, char *why)
{
- uint64_t *p;
avl_tree_t avl;
int i = 0;
int_node_t *node;
@@ -232,20 +231,20 @@ drain_tree(zfs_btree_t *bt, char *why)
/* Fill both trees with the same data */
for (i = 0; i < 64 * 1024; i++) {
- void *ret;
-
u_longlong_t randval = random();
- if ((p = (uint64_t *)zfs_btree_find(bt, &randval, &bt_idx)) !=
- NULL) {
+ if (zfs_btree_find(bt, &randval, &bt_idx) != NULL) {
continue;
}
zfs_btree_add_idx(bt, &randval, &bt_idx);
node = malloc(sizeof (int_node_t));
- ASSERT3P(node, !=, NULL);
+ if (node == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
node->data = randval;
- if ((ret = avl_find(&avl, node, &avl_idx)) != NULL) {
+ if (avl_find(&avl, node, &avl_idx) != NULL) {
(void) snprintf(why, BUFSIZE,
"Found in avl: %llu\n", randval);
return (1);
@@ -319,6 +318,10 @@ stress_tree(zfs_btree_t *bt, char *why)
uint64_t randval = random() % tree_limit;
node = malloc(sizeof (*node));
+ if (node == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
node->data = randval;
max = randval > max ? randval : max;
@@ -365,9 +368,7 @@ stress_tree(zfs_btree_t *bt, char *why)
if (stress_only) {
zfs_btree_index_t *idx = NULL;
- uint64_t *rv;
-
- while ((rv = zfs_btree_destroy_nodes(bt, &idx)) != NULL)
+ while (zfs_btree_destroy_nodes(bt, &idx) != NULL)
;
zfs_btree_verify(bt);
}
@@ -382,15 +383,15 @@ stress_tree(zfs_btree_t *bt, char *why)
static int
insert_duplicate(zfs_btree_t *bt)
{
- uint64_t *p, i = 23456;
+ uint64_t i = 23456;
zfs_btree_index_t bt_idx = {0};
- if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) {
+ if (zfs_btree_find(bt, &i, &bt_idx) != NULL) {
fprintf(stderr, "Found value in empty tree.\n");
return (0);
}
zfs_btree_add_idx(bt, &i, &bt_idx);
- if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) == NULL) {
+ if (zfs_btree_find(bt, &i, &bt_idx) == NULL) {
fprintf(stderr, "Did not find expected value.\n");
return (0);
}
@@ -408,10 +409,10 @@ insert_duplicate(zfs_btree_t *bt)
static int
remove_missing(zfs_btree_t *bt)
{
- uint64_t *p, i = 23456;
+ uint64_t i = 23456;
zfs_btree_index_t bt_idx = {0};
- if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) {
+ if (zfs_btree_find(bt, &i, &bt_idx) != NULL) {
fprintf(stderr, "Found value in empty tree.\n");
return (0);
}
@@ -492,10 +493,6 @@ main(int argc, char *argv[])
break;
}
}
- argc -= optind;
- argv += optind;
- optind = 1;
-
if (seed == 0) {
(void) gettimeofday(&tp, NULL);
@@ -529,7 +526,6 @@ main(int argc, char *argv[])
btree_test_t *test = &test_table[0];
while (test->name) {
int retval;
- uint64_t *rv;
char why[BUFSIZE] = {0};
zfs_btree_index_t *idx = NULL;
@@ -547,7 +543,7 @@ main(int argc, char *argv[])
}
/* Remove all the elements and re-verify the tree */
- while ((rv = zfs_btree_destroy_nodes(&bt, &idx)) != NULL)
+ while (zfs_btree_destroy_nodes(&bt, &idx) != NULL)
;
zfs_btree_verify(&bt);
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/edonr_test.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/edonr_test.c
index 3a0a48533c53..d010fbfcd4d6 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/edonr_test.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/edonr_test.c
@@ -40,16 +40,16 @@
* Test messages from:
* http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
*/
-const char *test_msg0 = "abc";
-const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn"
- "lmnomnopnopq";
-const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
- "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+static const char *test_msg0 = "abc";
+static const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
+ "nlmnomnopnopq";
+static const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfgh"
+ "ijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
/*
* Test digests computed by hand. There's no formal standard or spec for edonr.
*/
-const uint8_t edonr_224_test_digests[][28] = {
+static const uint8_t edonr_224_test_digests[][28] = {
{
/* for test_msg0 */
0x56, 0x63, 0xc4, 0x93, 0x95, 0x20, 0xfa, 0xf6,
@@ -67,7 +67,7 @@ const uint8_t edonr_224_test_digests[][28] = {
/* no test vector for test_msg2 */
};
-const uint8_t edonr_256_test_digests[][32] = {
+static const uint8_t edonr_256_test_digests[][32] = {
{
/* for test_msg0 */
0x54, 0xd7, 0x8b, 0x13, 0xc7, 0x4e, 0xda, 0x5a,
@@ -85,7 +85,7 @@ const uint8_t edonr_256_test_digests[][32] = {
/* no test vectorfor test_msg2 */
};
-const uint8_t edonr_384_test_digests[][48] = {
+static const uint8_t edonr_384_test_digests[][48] = {
{
/* for test_msg0 */
0x0e, 0x7c, 0xd7, 0x85, 0x78, 0x77, 0xe0, 0x89,
@@ -110,7 +110,7 @@ const uint8_t edonr_384_test_digests[][48] = {
}
};
-const uint8_t edonr_512_test_digests[][64] = {
+static const uint8_t edonr_512_test_digests[][64] = {
{
/* for test_msg0 */
0x1b, 0x14, 0xdb, 0x15, 0x5f, 0x1d, 0x40, 0x65,
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/sha2_test.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/sha2_test.c
index bb355311091e..d99e8757a24c 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/sha2_test.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/sha2_test.c
@@ -44,17 +44,17 @@
* http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
*/
-const char *test_msg0 = "abc";
-const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn"
- "lmnomnopnopq";
-const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
- "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+static const char *test_msg0 = "abc";
+static const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
+ "nlmnomnopnopq";
+static const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfgh"
+ "ijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
/*
* Test digests from:
* http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
*/
-const uint8_t sha256_test_digests[][32] = {
+static const uint8_t sha256_test_digests[][32] = {
{
/* for test_msg0 */
0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
@@ -72,7 +72,7 @@ const uint8_t sha256_test_digests[][32] = {
/* no test vector for test_msg2 */
};
-const uint8_t sha384_test_digests[][48] = {
+static const uint8_t sha384_test_digests[][48] = {
{
/* for test_msg0 */
0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
@@ -97,7 +97,7 @@ const uint8_t sha384_test_digests[][48] = {
}
};
-const uint8_t sha512_test_digests[][64] = {
+static const uint8_t sha512_test_digests[][64] = {
{
/* for test_msg0 */
0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
@@ -126,7 +126,7 @@ const uint8_t sha512_test_digests[][64] = {
}
};
-const uint8_t sha512_224_test_digests[][28] = {
+static const uint8_t sha512_224_test_digests[][28] = {
{
/* for test_msg0 */
0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54,
@@ -147,7 +147,7 @@ const uint8_t sha512_224_test_digests[][28] = {
}
};
-const uint8_t sha512_256_test_digests[][32] = {
+static const uint8_t sha512_256_test_digests[][32] = {
{
/* for test_msg0 */
0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9,
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/skein_test.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/skein_test.c
index 13611c860c42..20eb36d3e883 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/skein_test.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/skein_test.c
@@ -44,18 +44,18 @@
/*
* Test messages from the Skein spec, Appendix C.
*/
-const uint8_t test_msg0[] = {
+static const uint8_t test_msg0[] = {
0xFF
};
-const uint8_t test_msg1[] = {
+static const uint8_t test_msg1[] = {
0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0
};
-const uint8_t test_msg2[] = {
+static const uint8_t test_msg2[] = {
0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
@@ -66,7 +66,7 @@ const uint8_t test_msg2[] = {
0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0
};
-const uint8_t test_msg3[] = {
+static const uint8_t test_msg3[] = {
0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
@@ -85,7 +85,7 @@ const uint8_t test_msg3[] = {
0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80
};
-const uint8_t test_msg4[] = {
+static const uint8_t test_msg4[] = {
0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
@@ -123,7 +123,7 @@ const uint8_t test_msg4[] = {
/*
* Test digests from the Skein spec, Appendix C.
*/
-const uint8_t skein_256_test_digests[][32] = {
+static const uint8_t skein_256_test_digests[][32] = {
{
/* for test_msg0 */
0x0B, 0x98, 0xDC, 0xD1, 0x98, 0xEA, 0x0E, 0x50,
@@ -148,7 +148,7 @@ const uint8_t skein_256_test_digests[][32] = {
/* no test digests for test_msg3 and test_msg4 */
};
-const uint8_t skein_512_test_digests[][64] = {
+static const uint8_t skein_512_test_digests[][64] = {
{
/* for test_msg0 */
0x71, 0xB7, 0xBC, 0xE6, 0xFE, 0x64, 0x52, 0x22,
@@ -189,7 +189,7 @@ const uint8_t skein_512_test_digests[][64] = {
/* no test digests for test_msg4 */
};
-const uint8_t skein_1024_test_digests[][128] = {
+static const uint8_t skein_1024_test_digests[][128] = {
{
/* for test_msg0 */
0xE6, 0x2C, 0x05, 0x80, 0x2E, 0xA0, 0x15, 0x24,
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/ctime.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/ctime.c
index f0f3d526eb3e..0f5d81aea613 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/ctime.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/ctime.c
@@ -327,7 +327,6 @@ main(void)
if (access(tfile, F_OK) == 0) {
(void) unlink(tfile);
}
- ret = 0;
if ((fd = open(tfile, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE)) == -1) {
(void) fprintf(stderr, "open(%s) failed: %d\n", tfile, errno);
return (1);
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/draid.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/draid.c
index 46d7b4dcc69d..3e5ff59f7399 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/draid.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/draid.c
@@ -1285,12 +1285,11 @@ draid_merge_impl(nvlist_t *allcfgs, const char *srcfilename, int *mergedp)
if (nv_worst_ratio < allcfg_worst_ratio) {
fnvlist_remove(allcfgs, key);
- error = nvlist_add_nvlist(allcfgs,
- key, cfg);
+ fnvlist_add_nvlist(allcfgs, key, cfg);
merged++;
}
} else if (error == ENOENT) {
- error = nvlist_add_nvlist(allcfgs, key, cfg);
+ fnvlist_add_nvlist(allcfgs, key, cfg);
merged++;
} else {
return (error);
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/file/largest_file.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/file/largest_file.c
index 8545bb7eea42..d7252556b3cf 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/file/largest_file.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/file/largest_file.c
@@ -78,6 +78,8 @@ main(int argc, char **argv)
return (errno);
testfile = strdup(argv[1]);
+ if (testfile == NULL)
+ return (errno);
fd = open(testfile, O_CREAT | O_RDWR, mode);
if (fd < 0) {
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/idmap_util.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/idmap_util.c
new file mode 100644
index 000000000000..49483cbaa421
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/idmap_util.c
@@ -0,0 +1,808 @@
+/*
+ * 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
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <linux/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sched.h>
+#include <syscall.h>
+#include <sys/socket.h>
+
+#include <sys/list.h>
+
+#ifndef UINT_MAX
+#define UINT_MAX 4294967295U
+#endif
+
+#ifndef __NR_Linux
+#if defined __alpha__
+#define __NR_Linux 110
+#elif defined _MIPS_SIM
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+#define __NR_Linux 4000
+#endif
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+#define __NR_Linux 6000
+#endif
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+#define __NR_Linux 5000
+#endif
+#elif defined __ia64__
+#define __NR_Linux 1024
+#else
+#define __NR_Linux 0
+#endif
+#endif
+
+#ifndef __NR_mount_setattr
+#define __NR_mount_setattr (442 + __NR_Linux)
+#endif
+
+#ifndef __NR_open_tree
+#define __NR_open_tree (428 + __NR_Linux)
+#endif
+
+#ifndef __NR_move_mount
+#define __NR_move_mount (429 + __NR_Linux)
+#endif
+
+#ifndef MNT_DETACH
+#define MNT_DETACH 2
+#endif
+
+#ifndef MOVE_MOUNT_F_EMPTY_PATH
+#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004
+#endif
+
+#ifndef MOUNT_ATTR_IDMAP
+#define MOUNT_ATTR_IDMAP 0x00100000
+#endif
+
+#ifndef OPEN_TREE_CLONE
+#define OPEN_TREE_CLONE 1
+#endif
+
+#ifndef OPEN_TREE_CLOEXEC
+#define OPEN_TREE_CLOEXEC O_CLOEXEC
+#endif
+
+#ifndef AT_RECURSIVE
+#define AT_RECURSIVE 0x8000
+#endif
+
+typedef struct {
+ __u64 attr_set;
+ __u64 attr_clr;
+ __u64 propagation;
+ __u64 userns_fd;
+} mount_attr_t;
+
+static inline int
+sys_mount_setattr(int dfd, const char *path, unsigned int flags,
+ mount_attr_t *attr, size_t size)
+{
+ return (syscall(__NR_mount_setattr, dfd, path, flags, attr, size));
+}
+
+static inline int
+sys_open_tree(int dfd, const char *filename, unsigned int flags)
+{
+ return (syscall(__NR_open_tree, dfd, filename, flags));
+}
+
+static inline int sys_move_mount(int from_dfd, const char *from_pathname,
+ int to_dfd, const char *to_pathname, unsigned int flags)
+{
+ return (syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
+ to_pathname, flags));
+}
+
+typedef enum idmap_type_t {
+ TYPE_UID,
+ TYPE_GID,
+ TYPE_BOTH
+} idmap_type_t;
+
+struct idmap_entry {
+ __u32 first;
+ __u32 lower_first;
+ __u32 count;
+ idmap_type_t type;
+ list_node_t node;
+};
+
+static void
+log_msg(const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ fputc('\n', stderr);
+ va_end(ap);
+}
+
+#define log_errno(msg, args...) \
+ do { \
+ log_msg("%s:%d:%s: [%m] " msg, __FILE__, __LINE__,\
+ __FUNCTION__, ##args); \
+ } while (0)
+
+/*
+ * Parse the idmapping in the following format
+ * and add to the list:
+ *
+ * u:nsid_first:hostid_first:count
+ * g:nsid_first:hostid_first:count
+ * b:nsid_first:hostid_first:count
+ *
+ * The delimiter can be : or space character.
+ *
+ * Return:
+ * 0 if success
+ * ENOMEM if out of memory
+ * EINVAL if wrong arg or input
+ */
+static int
+parse_idmap_entry(list_t *head, char *input)
+{
+ char *token, *savedptr = NULL;
+ struct idmap_entry *entry;
+ unsigned long ul;
+ char *delimiter = (char *)": ";
+ char c;
+
+ if (!input || !head)
+ return (EINVAL);
+ entry = malloc(sizeof (*entry));
+ if (!entry)
+ return (ENOMEM);
+
+ token = strtok_r(input, delimiter, &savedptr);
+ if (token)
+ c = token[0];
+ if (!token || (c != 'b' && c != 'u' && c != 'g'))
+ goto errout;
+ entry->type = (c == 'b') ? TYPE_BOTH :
+ ((c == 'u') ? TYPE_UID : TYPE_GID);
+
+ token = strtok_r(NULL, delimiter, &savedptr);
+ if (!token)
+ goto errout;
+ ul = strtoul(token, NULL, 10);
+ if (ul > UINT_MAX || errno != 0)
+ goto errout;
+ entry->first = (__u32)ul;
+
+ token = strtok_r(NULL, delimiter, &savedptr);
+ if (!token)
+ goto errout;
+ ul = strtoul(token, NULL, 10);
+ if (ul > UINT_MAX || errno != 0)
+ goto errout;
+ entry->lower_first = (__u32)ul;
+
+ token = strtok_r(NULL, delimiter, &savedptr);
+ if (!token)
+ goto errout;
+ ul = strtoul(token, NULL, 10);
+ if (ul > UINT_MAX || errno != 0)
+ goto errout;
+ entry->count = (__u32)ul;
+
+ list_insert_tail(head, entry);
+
+ return (0);
+
+errout:
+ free(entry);
+ return (EINVAL);
+}
+
+/*
+ * Release all the entries in the list
+ */
+static void
+free_idmap(list_t *head)
+{
+ struct idmap_entry *entry;
+
+ while ((entry = list_remove_head(head)) != NULL)
+ free(entry);
+ /* list_destroy() to be done by the caller */
+}
+
+/*
+ * Write all bytes in the buffer to fd
+ */
+static ssize_t
+write_buf(int fd, const char *buf, size_t buf_size)
+{
+ ssize_t written, total_written = 0;
+ size_t remaining = buf_size;
+ char *position = (char *)buf;
+
+ for (;;) {
+ written = write(fd, position, remaining);
+ if (written < 0 && errno == EINTR)
+ continue;
+ if (written < 0) {
+ log_errno("write");
+ return (written);
+ }
+ total_written += written;
+ if (total_written == buf_size)
+ break;
+ remaining -= written;
+ position += written;
+ }
+
+ return (total_written);
+}
+
+/*
+ * Read data from file into buffer
+ */
+static ssize_t
+read_buf(int fd, char *buf, size_t buf_size)
+{
+ int ret;
+ for (;;) {
+ ret = read(fd, buf, buf_size);
+ if (ret < 0 && errno == EINTR)
+ continue;
+ break;
+ }
+ if (ret < 0)
+ log_errno("read");
+ return (ret);
+}
+
+/*
+ * Write idmap of the given type in the buffer to the
+ * process' uid_map or gid_map proc file.
+ *
+ * Return:
+ * 0 if success
+ * errno if there's any error
+ */
+static int
+write_idmap(pid_t pid, char *buf, size_t buf_size, idmap_type_t type)
+{
+ char path[PATH_MAX];
+ int fd = -EBADF;
+ int ret;
+
+ (void) snprintf(path, sizeof (path), "/proc/%d/%cid_map",
+ pid, type == TYPE_UID ? 'u' : 'g');
+ fd = open(path, O_WRONLY | O_CLOEXEC);
+ if (fd < 0) {
+ ret = errno;
+ log_errno("open(%s)", path);
+ goto out;
+ }
+ ret = write_buf(fd, buf, buf_size);
+ if (ret < 0)
+ ret = errno;
+ else
+ ret = 0;
+out:
+ if (fd >= 0)
+ close(fd);
+ return (ret);
+}
+
+/*
+ * Write idmap info in the list to the process
+ * user namespace, i.e. its /proc/<pid>/uid_map
+ * and /proc/<pid>/gid_map file.
+ *
+ * Return:
+ * 0 if success
+ * errno if it fails
+ */
+static int
+write_pid_idmaps(pid_t pid, list_t *head)
+{
+ char *buf_uids, *buf_gids;
+ char *curr_bufu, *curr_bufg;
+ /* max 4k to be allowed for each map */
+ int size_buf_uids = 4096, size_buf_gids = 4096;
+ struct idmap_entry *entry;
+ int uid_filled, gid_filled;
+ int ret = 0;
+ int has_uids = 0, has_gids = 0;
+ size_t buf_size;
+
+ buf_uids = malloc(size_buf_uids);
+ if (!buf_uids)
+ return (ENOMEM);
+ buf_gids = malloc(size_buf_gids);
+ if (!buf_gids) {
+ free(buf_uids);
+ return (ENOMEM);
+ }
+ curr_bufu = buf_uids;
+ curr_bufg = buf_gids;
+
+ for (entry = list_head(head); entry; entry = list_next(head, entry)) {
+ if (entry->type == TYPE_UID || entry->type == TYPE_BOTH) {
+ uid_filled = snprintf(curr_bufu, size_buf_uids,
+ "%u %u %u\n", entry->first, entry->lower_first,
+ entry->count);
+ if (uid_filled <= 0 || uid_filled >= size_buf_uids) {
+ ret = E2BIG;
+ goto out;
+ }
+ curr_bufu += uid_filled;
+ size_buf_uids -= uid_filled;
+ has_uids = 1;
+ }
+ if (entry->type == TYPE_GID || entry->type == TYPE_BOTH) {
+ gid_filled = snprintf(curr_bufg, size_buf_gids,
+ "%u %u %u\n", entry->first, entry->lower_first,
+ entry->count);
+ if (gid_filled <= 0 || gid_filled >= size_buf_gids) {
+ ret = E2BIG;
+ goto out;
+ }
+ curr_bufg += gid_filled;
+ size_buf_gids -= gid_filled;
+ has_gids = 1;
+ }
+ }
+ if (has_uids) {
+ buf_size = curr_bufu - buf_uids;
+ ret = write_idmap(pid, buf_uids, buf_size, TYPE_UID);
+ if (ret)
+ goto out;
+ }
+ if (has_gids) {
+ buf_size = curr_bufg - buf_gids;
+ ret = write_idmap(pid, buf_gids, buf_size, TYPE_GID);
+ }
+
+out:
+ free(buf_uids);
+ free(buf_gids);
+ return (ret);
+}
+
+/*
+ * Wait for the child process to exit
+ * and reap it.
+ *
+ * Return:
+ * process exit code if available
+ */
+static int
+wait_for_pid(pid_t pid)
+{
+ int status;
+ int ret;
+
+ for (;;) {
+ ret = waitpid(pid, &status, 0);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return (EXIT_FAILURE);
+ }
+ break;
+ }
+ if (!WIFEXITED(status))
+ return (EXIT_FAILURE);
+ return (WEXITSTATUS(status));
+}
+
+/*
+ * Get the file descriptor of the process user namespace
+ * given its pid.
+ *
+ * Return:
+ * fd if success
+ * -1 if it fails
+ */
+static int
+userns_fd_from_pid(pid_t pid)
+{
+ int fd;
+ char path[PATH_MAX];
+
+ (void) snprintf(path, sizeof (path), "/proc/%d/ns/user", pid);
+ fd = open(path, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ log_errno("open(%s)", path);
+ return (fd);
+}
+
+/*
+ * Get the user namespace file descriptor given a list
+ * of idmap info.
+ *
+ * Return:
+ * fd if success
+ * -errno if it fails
+ */
+static int
+userns_fd_from_idmap(list_t *head)
+{
+ pid_t pid;
+ int ret, fd;
+ int fds[2];
+ char c;
+ int saved_errno = 0;
+
+ /* socketpair for bidirectional communication */
+ ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
+ if (ret) {
+ log_errno("socketpair");
+ return (-errno);
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ log_errno("fork");
+ fd = -errno;
+ goto out;
+ }
+
+ if (pid == 0) {
+ /* child process */
+ ret = unshare(CLONE_NEWUSER);
+ if (ret == 0) {
+ /* notify the parent of success */
+ ret = write_buf(fds[1], "1", 1);
+ if (ret < 0)
+ saved_errno = errno;
+ else {
+ /*
+ * Until the parent has written to idmap,
+ * we cannot exit, otherwise the defunct
+ * process is owned by the real root, writing
+ * to its idmap ends up with EPERM in the
+ * context of a user ns
+ */
+ ret = read_buf(fds[1], &c, 1);
+ if (ret < 0)
+ saved_errno = errno;
+ }
+ } else {
+ saved_errno = errno;
+ log_errno("unshare");
+ ret = write_buf(fds[1], "0", 1);
+ if (ret < 0)
+ saved_errno = errno;
+ }
+ exit(saved_errno);
+ }
+
+ /* parent process */
+ ret = read_buf(fds[0], &c, 1);
+ if (ret == 1 && c == '1') {
+ ret = write_pid_idmaps(pid, head);
+ if (!ret) {
+ fd = userns_fd_from_pid(pid);
+ if (fd < 0)
+ fd = -errno;
+ } else {
+ fd = -ret;
+ }
+ /* Let child know it can exit */
+ (void) write_buf(fds[0], "1", 1);
+ } else {
+ fd = -EBADF;
+ }
+ (void) wait_for_pid(pid);
+out:
+ close(fds[0]);
+ close(fds[1]);
+ return (fd);
+}
+
+/*
+ * Check if the operating system supports idmapped mount on the
+ * given path or not.
+ *
+ * Return:
+ * true if supported
+ * false if not supported
+ */
+static bool
+is_idmap_supported(char *path)
+{
+ list_t head;
+ int ret;
+ int tree_fd = -EBADF, path_fd = -EBADF;
+ mount_attr_t attr = {
+ .attr_set = MOUNT_ATTR_IDMAP,
+ .userns_fd = -EBADF,
+ };
+
+ /* strtok_r() won't be happy with a const string */
+ /* To check if idmapped mount can be done in a user ns, map 0 to 0 */
+ char *input = strdup("b:0:0:1");
+
+ if (!input) {
+ errno = ENOMEM;
+ log_errno("strdup");
+ return (false);
+ }
+
+ list_create(&head, sizeof (struct idmap_entry),
+ offsetof(struct idmap_entry, node));
+ ret = parse_idmap_entry(&head, input);
+ if (ret) {
+ errno = ret;
+ log_errno("parse_idmap_entry(%s)", input);
+ goto out1;
+ }
+ ret = userns_fd_from_idmap(&head);
+ if (ret < 0)
+ goto out1;
+ attr.userns_fd = ret;
+ ret = openat(-EBADF, path, O_DIRECTORY | O_CLOEXEC);
+ if (ret < 0) {
+ log_errno("openat(%s)", path);
+ goto out;
+ }
+ path_fd = ret;
+ ret = sys_open_tree(path_fd, "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT |
+ AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE);
+ if (ret < 0) {
+ log_errno("sys_open_tree");
+ goto out;
+ }
+ tree_fd = ret;
+ ret = sys_mount_setattr(tree_fd, "", AT_EMPTY_PATH, &attr,
+ sizeof (attr));
+ if (ret < 0) {
+ log_errno("sys_mount_setattr");
+ }
+out:
+ close(attr.userns_fd);
+out1:
+ free_idmap(&head);
+ list_destroy(&head);
+ if (tree_fd >= 0)
+ close(tree_fd);
+ if (path_fd >= 0)
+ close(path_fd);
+ free(input);
+ return (ret == 0);
+}
+
+/*
+ * Check if the given path is a mount point or not.
+ *
+ * Return:
+ * true if it is
+ * false otherwise
+ */
+static bool
+is_mountpoint(char *path)
+{
+ char *parent;
+ struct stat st_me, st_parent;
+ bool ret;
+
+ parent = malloc(strlen(path)+4);
+ if (!parent) {
+ errno = ENOMEM;
+ log_errno("malloc");
+ return (false);
+ }
+ strcat(strcpy(parent, path), "/..");
+ if (lstat(path, &st_me) != 0 ||
+ lstat(parent, &st_parent) != 0)
+ ret = false;
+ else
+ if (st_me.st_dev != st_parent.st_dev ||
+ st_me.st_ino == st_parent.st_ino)
+ ret = true;
+ else
+ ret = false;
+ free(parent);
+ return (ret);
+}
+
+/*
+ * Remount the source on the new target folder with the given
+ * list of idmap info. If target is NULL, the source will be
+ * unmounted and then remounted if it is a mountpoint, otherwise
+ * no unmount is done, the source is simply idmap remounted.
+ *
+ * Return:
+ * 0 if success
+ * -errno otherwise
+ */
+static int
+do_idmap_mount(list_t *idmap, char *source, char *target, int flags)
+{
+ int ret;
+ int tree_fd = -EBADF, source_fd = -EBADF;
+ mount_attr_t attr = {
+ .attr_set = MOUNT_ATTR_IDMAP,
+ .userns_fd = -EBADF,
+ };
+
+ ret = userns_fd_from_idmap(idmap);
+ if (ret < 0)
+ goto out1;
+ attr.userns_fd = ret;
+ ret = openat(-EBADF, source, O_DIRECTORY | O_CLOEXEC);
+ if (ret < 0) {
+ ret = -errno;
+ log_errno("openat(%s)", source);
+ goto out;
+ }
+ source_fd = ret;
+ ret = sys_open_tree(source_fd, "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT |
+ AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE | flags);
+ if (ret < 0) {
+ ret = -errno;
+ log_errno("sys_open_tree");
+ goto out;
+ }
+ tree_fd = ret;
+ ret = sys_mount_setattr(tree_fd, "", AT_EMPTY_PATH | flags, &attr,
+ sizeof (attr));
+ if (ret < 0) {
+ ret = -errno;
+ log_errno("sys_mount_setattr");
+ goto out;
+ }
+ if (target == NULL && is_mountpoint(source)) {
+ ret = umount2(source, MNT_DETACH);
+ if (ret < 0) {
+ ret = -errno;
+ log_errno("umount2(%s)", source);
+ goto out;
+ }
+ }
+ ret = sys_move_mount(tree_fd, "", -EBADF, target == NULL ?
+ source : target, MOVE_MOUNT_F_EMPTY_PATH);
+ if (ret < 0) {
+ ret = -errno;
+ log_errno("sys_move_mount(%s)", target == NULL ?
+ source : target);
+ }
+out:
+ close(attr.userns_fd);
+out1:
+ if (tree_fd >= 0)
+ close(tree_fd);
+ if (source_fd >= 0)
+ close(source_fd);
+ return (ret);
+}
+
+static void
+print_usage(char *argv[])
+{
+ fprintf(stderr, "Usage: %s [-r] [-c] [-m <idmap1>] [-m <idmap2>]" \
+ " ... [<source>] [<target>]\n", argv[0]);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -r Recursively do idmapped mount.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -c Checks if idmapped mount is supported " \
+ "on the <source> by the operating system or not.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -m <idmap> to specify the idmap info, " \
+ "in the following format:\n");
+ fprintf(stderr, " <id_type>:<nsid_first>:<hostid_first>:<count>\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " <id_type> can be either of 'b', 'u', and 'g'.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "The <source> folder will be mounted at <target> " \
+ "with the provided idmap information.\nIf no <target> is " \
+ "specified, and <source> is a mount point, " \
+ "then <source> will be unmounted and then remounted.\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int opt;
+ list_t idmap_head;
+ int check_supported = 0;
+ int ret = EXIT_SUCCESS;
+ char *source = NULL, *target = NULL;
+ int flags = 0;
+
+ list_create(&idmap_head, sizeof (struct idmap_entry),
+ offsetof(struct idmap_entry, node));
+
+ while ((opt = getopt(argc, argv, "rcm:")) != -1) {
+ switch (opt) {
+ case 'r':
+ flags |= AT_RECURSIVE;
+ break;
+ case 'c':
+ check_supported = 1;
+ break;
+ case 'm':
+ ret = parse_idmap_entry(&idmap_head, optarg);
+ if (ret) {
+ errno = ret;
+ log_errno("parse_idmap_entry(%s)", optarg);
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+ break;
+ default:
+ print_usage(argv);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (check_supported == 0 && list_is_empty(&idmap_head)) {
+ print_usage(argv);
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ if (optind >= argc) {
+ fprintf(stderr, "Expected to have <source>, <target>.\n");
+ print_usage(argv);
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ source = argv[optind];
+ if (optind < (argc - 1)) {
+ target = argv[optind + 1];
+ }
+
+ if (check_supported) {
+ free_idmap(&idmap_head);
+ list_destroy(&idmap_head);
+ if (is_idmap_supported(source)) {
+ printf("idmapped mount is supported on [%s].\n",
+ source);
+ return (EXIT_SUCCESS);
+ } else {
+ printf("idmapped mount is NOT supported.\n");
+ return (EXIT_FAILURE);
+ }
+ }
+
+ ret = do_idmap_mount(&idmap_head, source, target, flags);
+ if (ret)
+ ret = EXIT_FAILURE;
+out:
+ free_idmap(&idmap_head);
+ list_destroy(&idmap_head);
+
+ exit(ret);
+}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/mkbusy.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/mkbusy.c
index cc4a6cfcb98c..78860381d880 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/mkbusy.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/mkbusy.c
@@ -148,14 +148,10 @@ main(int argc, char *argv[])
}
if (!isdir) {
- int fd;
-
- if ((fd = open(fpath, O_CREAT | O_RDWR, 0600)) < 0)
+ if (open(fpath, O_CREAT | O_RDWR, 0600) < 0)
fail("open");
} else {
- DIR *dp;
-
- if ((dp = opendir(fpath)) == NULL)
+ if (opendir(fpath) == NULL)
fail("opendir");
}
free(fpath);
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_libaio.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_libaio.c
index 7d76c9b4eb2f..5ee1f600a737 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_libaio.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_libaio.c
@@ -33,7 +33,7 @@
#include <libaio.h>
#include <err.h>
-io_context_t io_ctx;
+static io_context_t io_ctx;
static void
do_sync_io(struct iocb *iocb)
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmapwrite.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmapwrite.c
index ca55d730fd34..a18609898485 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/mmapwrite.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/mmapwrite.c
@@ -88,29 +88,21 @@ map_writer(void *filename)
int ret = 0;
char *buf = NULL;
int page_size = getpagesize();
- int op_errno = 0;
char *file_path = filename;
while (1) {
- ret = access(file_path, F_OK);
- if (ret) {
- op_errno = errno;
- if (op_errno == ENOENT) {
+ fd = open(file_path, O_RDWR);
+ if (fd == -1) {
+ if (errno == ENOENT) {
fd = open(file_path, O_RDWR | O_CREAT, 0777);
if (fd == -1) {
err(1, "open file failed");
}
-
ret = ftruncate(fd, page_size);
if (ret == -1) {
err(1, "truncate file failed");
}
} else {
- err(1, "access file failed!");
- }
- } else {
- fd = open(file_path, O_RDWR, 0777);
- if (fd == -1) {
err(1, "open file failed");
}
}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/nvlist_to_lua.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/nvlist_to_lua.c
index b65b3fd269d9..3da69397a993 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/nvlist_to_lua.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/nvlist_to_lua.c
@@ -129,6 +129,11 @@ run_tests(void)
/* Note: maximum nvlist key length is 32KB */
int len = 1024 * 31;
char *bigstring = malloc(len);
+ if (bigstring == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
for (int i = 0; i < len; i++)
bigstring[i] = 'a' + i % 26;
bigstring[len - 1] = '\0';
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/renameat2.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/renameat2.c
new file mode 100644
index 000000000000..a9d0a8b20adf
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/renameat2.c
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: CDDL-1.0 OR MPL-2.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 http://www.opensolaris.org/os/licensing.
+ * 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) 2019 Aleksa Sarai <cyphar@cyphar.com>
+ * Copyright (C) 2019 SUSE LLC
+ */
+
+/*
+ * mv(1) doesn't currently support RENAME_{EXCHANGE,WHITEOUT} so this is a very
+ * simple renameat2(2) wrapper for the OpenZFS self-tests.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+#ifndef SYS_renameat2
+#ifdef __NR_renameat2
+#define SYS_renameat2 __NR_renameat2
+#elif defined(__x86_64__)
+#define SYS_renameat2 316
+#elif defined(__i386__)
+#define SYS_renameat2 353
+#elif defined(__arm__) || defined(__aarch64__)
+#define SYS_renameat2 382
+#else
+#error "SYS_renameat2 not known for this architecture."
+#endif
+#endif
+
+#ifndef RENAME_NOREPLACE
+#define RENAME_NOREPLACE (1 << 0) /* Don't overwrite target */
+#endif
+#ifndef RENAME_EXCHANGE
+#define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */
+#endif
+#ifndef RENAME_WHITEOUT
+#define RENAME_WHITEOUT (1 << 2) /* Whiteout source */
+#endif
+
+/* glibc doesn't provide renameat2 wrapper, let's use our own */
+static int
+sys_renameat2(int olddirfd, const char *oldpath,
+ int newdirfd, const char *newpath, unsigned int flags)
+{
+ int ret = syscall(SYS_renameat2, olddirfd, oldpath, newdirfd, newpath,
+ flags);
+ return ((ret < 0) ? -errno : ret);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: renameat2 [-Cnwx] src dst\n");
+ exit(1);
+}
+
+static void
+check(void)
+{
+ int err = sys_renameat2(AT_FDCWD, ".", AT_FDCWD, ".", RENAME_EXCHANGE);
+ exit(err == -ENOSYS);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *src, *dst;
+ int ch, err;
+ unsigned int flags = 0;
+
+ while ((ch = getopt(argc, argv, "Cnwx")) >= 0) {
+ switch (ch) {
+ case 'C':
+ check();
+ break;
+ case 'n':
+ flags |= RENAME_NOREPLACE;
+ break;
+ case 'w':
+ flags |= RENAME_WHITEOUT;
+ break;
+ case 'x':
+ flags |= RENAME_EXCHANGE;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ usage();
+ src = argv[0];
+ dst = argv[1];
+
+ err = sys_renameat2(AT_FDCWD, src, AT_FDCWD, dst, flags);
+ if (err < 0)
+ fprintf(stderr, "renameat2: %s", strerror(-err));
+ return (err != 0);
+}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/stride_dd.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/stride_dd.c
index 732ac9f47268..a20b26131650 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/stride_dd.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/stride_dd.c
@@ -25,8 +25,8 @@ static int bsize = 0;
static int count = 0;
static char *ifile = NULL;
static char *ofile = NULL;
-static int stride = 0;
-static int seek = 0;
+static off_t stride = 0;
+static off_t seek = 0;
static const char *execname = "stride_dd";
static void usage(void);
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/user_ns_exec.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/user_ns_exec.c
index 86593622399e..d781301473a9 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/user_ns_exec.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/user_ns_exec.c
@@ -97,7 +97,6 @@ set_idmap(pid_t pid, const char *file)
mapfd = open(path, O_WRONLY);
if (mapfd < 0) {
- result = errno;
perror("open");
return (errno);
}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
index c05b918325b7..b3cfe149ffa7 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
+++ b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
@@ -156,7 +156,8 @@ export SYSTEM_FILES_LINUX='attr
useradd
userdel
usermod
-
+ setpriv
+ mountpoint
flock
logger'
@@ -207,6 +208,7 @@ export ZFSTEST_FILES='badsend
randwritecomp
readmmap
read_dos_attributes
+ renameat2
rename_dir
rm_lnkcnt_zero_file
send_doall
@@ -226,4 +228,5 @@ export ZFSTEST_FILES='badsend
truncate_test
ereports
zfs_diff-socket
- dosmode_readonly_write'
+ dosmode_readonly_write
+ idmap_util'
diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/properties.shlib b/sys/contrib/openzfs/tests/zfs-tests/include/properties.shlib
index 14b3f4415b7d..3dfb295a40df 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/include/properties.shlib
+++ b/sys/contrib/openzfs/tests/zfs-tests/include/properties.shlib
@@ -11,6 +11,7 @@
#
# Copyright (c) 2012, 2016, Delphix. All rights reserved.
+# Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
#
. $STF_SUITE/include/libtest.shlib
@@ -27,7 +28,7 @@ typeset -a canmount_prop_vals=('on' 'off' 'noauto')
typeset -a copies_prop_vals=('1' '2' '3')
typeset -a logbias_prop_vals=('latency' 'throughput')
typeset -a primarycache_prop_vals=('all' 'none' 'metadata')
-typeset -a redundant_metadata_prop_vals=('all' 'most')
+typeset -a redundant_metadata_prop_vals=('all' 'most' 'some' 'none')
typeset -a secondarycache_prop_vals=('all' 'none' 'metadata')
typeset -a snapdir_prop_vals=('hidden' 'visible')
typeset -a sync_prop_vals=('standard' 'always' 'disabled')
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
index 6aeb862fbb85..39eb44f73171 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
@@ -368,6 +368,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/upgrade/upgrade_common.kshlib \
functional/user_namespace/user_namespace.cfg \
functional/user_namespace/user_namespace_common.kshlib \
+ functional/userquota/13709_reproducer.bz2 \
functional/userquota/userquota.cfg \
functional/userquota/userquota_common.kshlib \
functional/vdev_zaps/vdev_zaps.kshlib \
@@ -378,7 +379,9 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
functional/zvol/zvol_common.shlib \
functional/zvol/zvol_ENOSPC/zvol_ENOSPC.cfg \
functional/zvol/zvol_misc/zvol_misc_common.kshlib \
- functional/zvol/zvol_swap/zvol_swap.cfg
+ functional/zvol/zvol_swap/zvol_swap.cfg \
+ functional/idmap_mount/idmap_mount.cfg \
+ functional/idmap_mount/idmap_mount_common.kshlib
nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/acl/off/cleanup.ksh \
@@ -1933,6 +1936,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/userquota/userspace_003_pos.ksh \
functional/userquota/userspace_encrypted.ksh \
functional/userquota/userspace_send_encrypted.ksh \
+ functional/userquota/userspace_encrypted_13709.ksh \
functional/vdev_zaps/cleanup.ksh \
functional/vdev_zaps/setup.ksh \
functional/vdev_zaps/vdev_zaps_001_pos.ksh \
@@ -1998,4 +2002,11 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/zvol/zvol_swap/zvol_swap_003_pos.ksh \
functional/zvol/zvol_swap/zvol_swap_004_pos.ksh \
functional/zvol/zvol_swap/zvol_swap_005_pos.ksh \
- functional/zvol/zvol_swap/zvol_swap_006_pos.ksh
+ functional/zvol/zvol_swap/zvol_swap_006_pos.ksh \
+ functional/idmap_mount/cleanup.ksh \
+ functional/idmap_mount/setup.ksh \
+ functional/idmap_mount/idmap_mount_001.ksh \
+ functional/idmap_mount/idmap_mount_002.ksh \
+ functional/idmap_mount/idmap_mount_003.ksh \
+ functional/idmap_mount/idmap_mount_004.ksh \
+ functional/idmap_mount/idmap_mount_005.ksh
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
index 5d76c220fc45..8bd9a6854950 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
@@ -25,13 +25,16 @@
# ZFS should receive to an encrypted child dataset.
#
# STRATEGY:
-# 1. Snapshot the default dataset
-# 2. Create an encrypted dataset
-# 3. Attempt to receive a stream to an encrypted child
-# 4. Attempt to receive a stream with properties to an encrypted child
-# 5. Attempt to receive a replication stream to an encrypted child
-# 6. Unmount and unload the encrypted dataset keys
-# 7. Attempt to receive a snapshot stream to an encrypted child
+# 1. Snapshot the default dataset
+# 2. Create an encrypted dataset
+# 3. Attempt to receive a stream to an encrypted child
+# 4. Unload the key
+# 5. Attempt to receive an incremental stream to an encrypted child (must fail)
+# 6. Attempt to receive a stream with properties to an unencrypted child
+# 7. Attempt to receive an incremental stream to an unencrypted child
+# 8. Attempt to receive with -o encryption=off to an unencrypted child
+# 9. Attempt to receive a replication stream to an unencrypted child
+# 10. Attempt to receive a snapshot stream to an encrypted child (must fail)
#
verify_runnable "both"
@@ -39,6 +42,7 @@ verify_runnable "both"
function cleanup
{
snapexists $snap && destroy_dataset $snap -f
+ snapexists $snap2 && destroy_dataset $snap2 -f
datasetexists $TESTPOOL/$TESTFS1 && \
destroy_dataset $TESTPOOL/$TESTFS1 -r
@@ -50,15 +54,17 @@ log_assert "ZFS should receive encrypted filesystems into child dataset"
typeset passphrase="password"
typeset snap="$TESTPOOL/$TESTFS@snap"
+typeset snap2="$TESTPOOL/$TESTFS@snap2"
typeset testfile="testfile"
log_must zfs snapshot $snap
+log_must zfs snapshot $snap2
log_must eval "echo $passphrase | zfs create -o encryption=on" \
"-o keyformat=passphrase $TESTPOOL/$TESTFS1"
log_note "Verifying ZFS will receive to an encrypted child"
-log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
+log_must eval "zfs send $snap | zfs receive -u $TESTPOOL/$TESTFS1/c1"
log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c1)" != "off"
# Unload the key, the following tests won't require it and we will test
@@ -66,10 +72,17 @@ log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c1)" != "off"
log_must zfs unmount $TESTPOOL/$TESTFS1
log_must zfs unload-key $TESTPOOL/$TESTFS1
+log_note "Verifying ZFS will not receive an incremental into an encrypted" \
+ "dataset when the key is unloaded"
+log_mustnot eval "zfs send -i $snap $snap2 | zfs receive $TESTPOOL/$TESTFS1/c1"
+
log_note "Verifying 'send -p' will receive to an unencrypted child"
-log_must eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2"
+log_must eval "zfs send -p $snap | zfs receive -u $TESTPOOL/$TESTFS1/c2"
log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c2)" == "off"
+log_note "Verifying 'send -i' will receive to an unencrypted child"
+log_must eval "zfs send -i $snap $snap2 | zfs receive $TESTPOOL/$TESTFS1/c2"
+
# For completeness add the property override case.
log_note "Verifying recv -o encyption=off' will receive to an unencrypted child"
log_must eval "zfs send $snap | \
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh
index 0166e84baa18..7ecaf849e44b 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh
@@ -44,7 +44,7 @@ verify_runnable "global"
function cleanup
{
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
poolexists $TESTPOOL && destroy_pool $TESTPOOL
rm -f $disk1 $disk2
}
@@ -77,13 +77,13 @@ do
# Make sure we can also set the ashift using the tunable.
#
log_must zpool create $TESTPOOL $disk1
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $ashift
log_must zpool add $TESTPOOL $disk2
exp=$(( (ashift <= max_auto_ashift) ? ashift : logical_ashift ))
log_must verify_ashift $disk2 $exp
# clean things for the next run
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
log_must zpool destroy $TESTPOOL
log_must zpool labelclear $disk1
log_must zpool labelclear $disk2
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh
index 964cfaa525e0..228f62232aae 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh
@@ -44,7 +44,7 @@ verify_runnable "global"
function cleanup
{
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
poolexists $TESTPOOL && destroy_pool $TESTPOOL
log_must rm -f $disk1 $disk2
}
@@ -63,7 +63,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT)
# the ashift using the -o ashift property should still
# be honored.
#
-log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16
+log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16
typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16")
for ashift in ${ashifts[@]}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_004_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_004_pos.ksh
index fbaed2af13c5..646edc1a4557 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_004_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_004_pos.ksh
@@ -74,4 +74,8 @@ log_must zpool add $TESTPOOL $ZVOL_DEVDIR/$TESTPOOL1/$TESTVOL
log_must vdevs_in_pool "$TESTPOOL" "$ZVOL_DEVDIR/$TESTPOOL1/$TESTVOL"
+# Give zed a chance to finish processing the event, otherwise
+# a race condition can lead to stuck "zpool destroy $TESTPOOL"
+sleep 1
+
log_pass "'zpool add <pool> <vdev> ...' adds zfs volume to the pool successfully"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh
index a96bc16761f7..6ccec6abd66f 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh
@@ -42,7 +42,7 @@ verify_runnable "global"
function cleanup
{
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1
rm -f $disk1 $disk2
}
@@ -61,7 +61,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT)
# the ashift using the -o ashift property should still
# be honored.
#
-log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16
+log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16
typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16")
for ashift in ${ashifts[@]}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh
index 7610f2855c03..37ed0062e61c 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh
@@ -42,7 +42,7 @@ verify_runnable "global"
function cleanup
{
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1
rm -f $disk1 $disk2
}
@@ -61,7 +61,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT)
# the ashift using the -o ashift property should still
# be honored.
#
-log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16
+log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16
typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16")
for ashift in ${ashifts[@]}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh
index 313b388b2ba4..ffdaf91a2841 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh
@@ -44,7 +44,7 @@ verify_runnable "global"
function cleanup
{
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1
rm -f $disk1 $disk2
}
@@ -63,7 +63,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT)
# the ashift using the -o ashift property should still
# be honored.
#
-log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16
+log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16
typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16")
for ashift in ${ashifts[@]}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh
index 58119e37cc67..41fef8f7cdb4 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh
@@ -42,7 +42,7 @@ verify_runnable "global"
function cleanup
{
- log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
+ log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift
destroy_pool $TESTPOOL1
rm -f $disk
}
@@ -60,7 +60,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT)
# the ashift using the -o ashift property should still
# be honored.
#
-log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16
+log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16
disk=$TEST_BASE_DIR/disk
log_must mkfile $SIZE $disk
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh
index 0ab9317c0a06..c0387e1d3235 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh
@@ -121,6 +121,11 @@ done
# the removed data device
for conf in "${poolconfs[@]}"
do
+ # special vdev can not be replaced by a hot spare
+ if [[ $conf = *"special mirror"* ]]; then
+ continue
+ fi
+
# 1. Create a pool with a spare
log_must zpool create -f $TESTPOOL $conf
block_device_wait ${DEV_DSKDIR}/${removedev}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh
new file mode 100755
index 000000000000..4895aa23ee4a
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh
@@ -0,0 +1,25 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg
new file mode 100644
index 000000000000..51998945d0d1
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg
@@ -0,0 +1,25 @@
+#
+# 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
+#
+
+export UID1=1000000
+export GID1=1000000
+export UID2=2000000
+export GID2=2000000
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh
new file mode 100755
index 000000000000..e7187935e532
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh
@@ -0,0 +1,76 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib
+
+#
+#
+# DESCRIPTION:
+# Test uid and gid of files in idmapped folder are mapped correctly
+#
+#
+# STRATEGY:
+# 1. Create files/folder owned by $UID1 and $GID1 under "idmap_test"
+# 2. Idmap the folder to "idmap_dest"
+# 3. Verify the owner of files/folder under "idmap_dest"
+#
+
+verify_runnable "global"
+
+export WORKDIR=$TESTDIR/idmap_test
+export IDMAPDIR=$TESTDIR/idmap_dest
+
+function cleanup
+{
+ log_must rm -rf $WORKDIR
+ if mountpoint $IDMAPDIR; then
+ log_must umount $IDMAPDIR
+ fi
+ log_must rm -rf $IDMAPDIR
+}
+
+log_onexit cleanup
+
+if ! idmap_util -c $TESTDIR; then
+ log_unsupported "Idmap mount not supported."
+fi
+
+log_must mkdir -p $WORKDIR
+log_must mkdir -p $IDMAPDIR
+log_must touch $WORKDIR/file1
+log_must mkdir $WORKDIR/subdir
+log_must ln -s $WORKDIR/file1 $WORKDIR/file1_sym
+log_must ln $WORKDIR/file1 $WORKDIR/subdir/file1_hard
+log_must touch $WORKDIR/subdir/file2
+log_must chown -R $UID1:$GID1 $WORKDIR
+log_must chown $UID2:$GID2 $WORKDIR/subdir/file2
+
+log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR
+
+log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/file1)"
+log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/file1_sym)"
+log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/subdir)"
+log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/subdir/file1_hard)"
+log_mustnot test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/subdir/file2)"
+
+log_pass "Owner verification of entries under idmapped folder is successful."
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh
new file mode 100755
index 000000000000..8cba90ea58b7
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh
@@ -0,0 +1,97 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib
+
+#
+#
+# DESCRIPTION:
+# Perform file operations in idmapped folder, check owner in its base.
+#
+#
+# STRATEGY:
+# 1. Create folder "idmap_test"
+# 2. Idmap the folder to "idmap_dest"
+# 3. Do basic file operations in "idmap_dest" folder, verify the owner in
+# the base folder "idmap_test"
+#
+
+verify_runnable "global"
+
+export WORKDIR=$TESTDIR/idmap_test
+export IDMAPDIR=$TESTDIR/idmap_dest
+
+function cleanup
+{
+ log_must rm -rf $IDMAPDIR/*
+ if mountpoint $IDMAPDIR; then
+ log_must umount $IDMAPDIR
+ fi
+ log_must rm -rf $IDMAPDIR $WORKDIR
+}
+
+log_onexit cleanup
+
+if ! idmap_util -c $TESTDIR; then
+ log_unsupported "Idmap mount not supported."
+fi
+
+log_must mkdir -p $WORKDIR
+log_must mkdir -p $IDMAPDIR
+
+log_must chown $UID1:$GID1 $WORKDIR
+log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR
+
+SETPRIV="setpriv --reuid $UID2 --regid $GID2 --clear-groups"
+
+log_must $SETPRIV touch $IDMAPDIR/file1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)"
+
+log_must $SETPRIV mv $IDMAPDIR/file1 $IDMAPDIR/file1_renamed
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_renamed)"
+
+log_must $SETPRIV mv $IDMAPDIR/file1_renamed $IDMAPDIR/file1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)"
+
+log_must $SETPRIV mkdir $IDMAPDIR/subdir
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir)"
+
+log_must $SETPRIV ln -s $IDMAPDIR/file1 $IDMAPDIR/file1_sym
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_sym)"
+
+log_must $SETPRIV ln $IDMAPDIR/file1 $IDMAPDIR/subdir/file1_hard
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir/file1_hard)"
+
+log_must $SETPRIV touch $IDMAPDIR/subdir/file2
+log_must $SETPRIV chown $UID2:$GID2 $IDMAPDIR/subdir/file2
+log_mustnot $SETPRIV chown $UID1 $IDMAPDIR/subdir/file2
+
+log_must $SETPRIV cp -r $IDMAPDIR/subdir $IDMAPDIR/subdir1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file2)"
+log_must $SETPRIV rm -rf $IDMAPDIR/subdir1
+
+log_must $SETPRIV cp -rp $IDMAPDIR/subdir $IDMAPDIR/subdir1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file1_hard)"
+log_must $SETPRIV rm -rf $IDMAPDIR/subdir1
+
+log_pass "Owner verification of entries under base folder is successful."
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh
new file mode 100755
index 000000000000..1f1a2aec655e
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh
@@ -0,0 +1,121 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib
+
+#
+#
+# DESCRIPTION:
+# Perform file operations in idmapped folder in user namespace,
+# then check the owner in its base.
+#
+#
+# STRATEGY:
+# 1. Create folder "idmap_test"
+# 2. Idmap the folder to "idmap_dest"
+# 3. Perform file operations in the idmapped folder in the user
+# namespace having the same idmap info as the idmapped mount
+# 4. Verify the owner of entries under the base folder "idmap_test"
+#
+
+verify_runnable "global"
+
+export WORKDIR=$TESTDIR/idmap_test
+export IDMAPDIR=$TESTDIR/idmap_dest
+
+function cleanup
+{
+ kill -TERM ${unshared_pid}
+ log_must rm -rf $IDMAPDIR/*
+ if mountpoint $IDMAPDIR; then
+ log_must umount $IDMAPDIR
+ fi
+ log_must rm -rf $IDMAPDIR $WORKDIR
+}
+
+log_onexit cleanup
+
+if ! idmap_util -c $TESTDIR; then
+ log_unsupported "Idmap mount not supported."
+fi
+
+log_must mkdir -p $WORKDIR
+log_must mkdir -p $IDMAPDIR
+
+log_must chown $UID1:$GID1 $WORKDIR
+log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR
+
+# Create a user namespace with the same idmapping
+unshare -Urm echo test
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to create user namespace"
+fi
+unshare -Um /usr/bin/sleep 2h &
+unshared_pid=$!
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to create user namespace"
+fi
+# wait for userns to be ready
+sleep 1
+echo "${UID1} ${UID2} 1" > /proc/$unshared_pid/uid_map
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to write to uid_map"
+fi
+echo "${GID1} ${GID2} 1" > /proc/$unshared_pid/gid_map
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to write to gid_map"
+fi
+
+NSENTER="nsenter -t $unshared_pid --all -S ${UID1} -G ${GID1}"
+
+log_must $NSENTER touch $IDMAPDIR/file1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)"
+
+log_must $NSENTER mv $IDMAPDIR/file1 $IDMAPDIR/file1_renamed
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_renamed)"
+
+log_must $NSENTER mv $IDMAPDIR/file1_renamed $IDMAPDIR/file1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)"
+
+log_must $NSENTER mkdir $IDMAPDIR/subdir
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir)"
+
+log_must $NSENTER ln -s $IDMAPDIR/file1 $IDMAPDIR/file1_sym
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_sym)"
+
+log_must $NSENTER ln $IDMAPDIR/file1 $IDMAPDIR/subdir/file1_hard
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir/file1_hard)"
+
+log_must $NSENTER touch $IDMAPDIR/subdir/file2
+log_must $NSENTER chown $UID1:$GID1 $IDMAPDIR/subdir/file2
+log_mustnot $NSENTER chown $UID2 $IDMAPDIR/subdir/file2
+
+log_must $NSENTER cp -r $IDMAPDIR/subdir $IDMAPDIR/subdir1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file2)"
+log_must $NSENTER rm -rf $IDMAPDIR/subdir1
+
+log_must $NSENTER cp -rp $IDMAPDIR/subdir $IDMAPDIR/subdir1
+log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file1_hard)"
+log_must $NSENTER rm -rf $IDMAPDIR/subdir1
+
+log_pass "Owner verification of entries under the base folder is successful."
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh
new file mode 100755
index 000000000000..89f2f750d23c
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh
@@ -0,0 +1,106 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib
+
+#
+#
+# DESCRIPTION:
+# Test setgid bit is set properly on the idmapped mount
+# in a user namespace.
+#
+# STRATEGY:
+# 1. Create folder "idmap_test", set gid bit on it
+# 2. Idmap the folder to "idmap_dest"
+# 3. Create file and folder in the idmapped folder in the user
+# namespace having the same idmap info
+# 4. Verify the gid bit of the file and folder is set
+#
+
+verify_runnable "global"
+
+export WORKDIR=$TESTDIR/idmap_test
+export IDMAPDIR=$TESTDIR/idmap_dest
+
+function cleanup
+{
+ kill -TERM ${unshared_pid}
+ log_must rm -rf $IDMAPDIR/*
+ if mountpoint $IDMAPDIR; then
+ log_must umount $IDMAPDIR
+ fi
+ log_must rm -rf $IDMAPDIR $WORKDIR
+}
+
+log_onexit cleanup
+
+if ! idmap_util -c $TESTDIR; then
+ log_unsupported "Idmap mount not supported."
+fi
+
+log_must mkdir -p $WORKDIR
+log_must mkdir -p $IDMAPDIR
+
+log_must chown $UID1:$GID1 $WORKDIR
+# set gid bit
+log_must chmod 2755 $WORKDIR
+log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR
+log_must test -g $IDMAPDIR
+
+# Create a user namespace with the same idmapping
+unshare -Urm echo test
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to create user namespace"
+fi
+unshare -Um /usr/bin/sleep 2h &
+unshared_pid=$!
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to create user namespace"
+fi
+# wait for userns to be ready
+sleep 1
+echo "${UID1} ${UID2} 1" > /proc/$unshared_pid/uid_map
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to write to uid_map"
+fi
+echo "${GID1} ${GID2} 1" > /proc/$unshared_pid/gid_map
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to write to gid_map"
+fi
+
+NSENTER="nsenter -t $unshared_pid --all -S ${UID1} -G ${GID1}"
+
+# gid bit can be set on the file
+log_must $NSENTER touch $IDMAPDIR/file1
+log_must $NSENTER chmod 2654 $IDMAPDIR/file1
+log_must test -g $WORKDIR/file1
+log_must test -g $IDMAPDIR/file1
+log_must test "$UID1 $GID1" = "$($NSENTER stat -c '%u %g' $IDMAPDIR/file1)"
+
+# gid bit is carried over to new folder
+log_must $NSENTER mkdir $IDMAPDIR/subdir
+log_must test -g $WORKDIR/subdir
+log_must test -g $IDMAPDIR/subdir
+log_must test "$UID1 $GID1" = "$($NSENTER stat -c '%u %g' $IDMAPDIR/subdir)"
+
+log_pass "Verification of setting gid bit in userns is successful."
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_005.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_005.ksh
new file mode 100755
index 000000000000..a4ecea92c127
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_005.ksh
@@ -0,0 +1,138 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib
+
+#
+#
+# DESCRIPTION:
+# Test idmapped mount in a user namespace
+#
+# STRATEGY:
+# 1. Create a zoned dataset
+# 2. Create a user namespace and designate the dataset to the zone
+# 3. In the zone, mount the dataset to "idmap_test"
+# 4. In the zone, idmap mount the dataset mountpoint to "idmap_dest"
+# 5. Do some file operations in the idmapped mountpoint "idmap_dest"
+# 6. Check the owner of files/folder in the mount point "idmap_test"
+# 7. unmount the mountpoints in the zone
+# 8. Remount the dataset in global zone to "idmap_test"
+# 9. Check the owenr of filers/folder in the mountpoint "idmap_test"
+#
+
+verify_runnable "global"
+
+export WORKDIR=$TESTDIR/idmap_test
+export IDMAPDIR=$TESTDIR/idmap_dest
+
+function cleanup
+{
+ if [[ -v unshared_pid ]]; then
+ zfs unzone /proc/$unshared_pid/ns/user "$TESTPOOL/userns"
+ kill -TERM ${unshared_pid}
+ fi
+ if mountpoint $WORKDIR; then
+ log_must umount $WORKDIR
+ fi
+ log_must rm -rf $WORKDIR
+}
+
+log_onexit cleanup
+
+if ! idmap_util -c $TESTDIR; then
+ log_unsupported "Idmap mount not supported."
+fi
+
+unshare -Urm echo test
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to create user namespace"
+fi
+
+log_must zfs create -o zoned=off -o mountpoint=$WORKDIR "$TESTPOOL/userns"
+
+# "root" user and group in the user ns
+log_must chown 1000000:1000000 $WORKDIR
+log_must zfs set zoned=on "$TESTPOOL/userns"
+
+log_must mkdir -p $IDMAPDIR
+
+unshare -Um /usr/bin/sleep 2h &
+unshared_pid=$!
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to create user namespace"
+fi
+# wait for userns to be ready
+sleep 1
+echo "0 1000000 1000000" > /proc/$unshared_pid/uid_map
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to write to uid_map"
+fi
+echo "0 1000000 1000000" > /proc/$unshared_pid/gid_map
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Failed to write to gid_map"
+fi
+
+NSENTER="nsenter -t $unshared_pid --all -S 0 -G 0"
+
+log_must zfs zone /proc/$unshared_pid/ns/user "$TESTPOOL/userns"
+log_must $NSENTER zfs mount "$TESTPOOL/userns"
+log_must $NSENTER chmod 777 $WORKDIR
+
+$NSENTER idmap_util -c $WORKDIR
+if [ "$?" -ne "0" ]; then
+ log_unsupported "Idmapped mount not supported in a user namespace"
+fi
+
+log_must $NSENTER idmap_util -m b:0:10000:100000 $WORKDIR $IDMAPDIR
+log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups touch $IDMAPDIR/file
+log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups mkdir $IDMAPDIR/folder
+log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups ln -s file $IDMAPDIR/file-soft
+log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups ln $IDMAPDIR/file $IDMAPDIR/file-hard
+
+log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups cp -p $IDMAPDIR/file $IDMAPDIR/folder/file-p
+log_must $NSENTER setpriv --reuid 11000 --regid 11000 --clear-groups cp $IDMAPDIR/file $IDMAPDIR/folder/file
+
+log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/file)"
+log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/folder)"
+log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/file-soft)"
+log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/file-hard)"
+log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/folder/file-p)"
+log_must test "1000 1000" = "$($NSENTER stat -c '%u %g' $WORKDIR/folder/file)"
+
+log_must $NSENTER umount $IDMAPDIR
+log_must $NSENTER umount $WORKDIR
+
+log_must zfs unzone /proc/$unshared_pid/ns/user "$TESTPOOL/userns"
+log_must kill -TERM $unshared_pid
+unset unshared_pid
+log_must zfs set zoned=off "$TESTPOOL/userns"
+log_must zfs mount "$TESTPOOL/userns"
+
+log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/file)"
+log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/folder)"
+log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/file-soft)"
+log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/file-hard)"
+log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/folder/file-p)"
+log_must test "1001000 1001000" = "$(stat -c '%u %g' $WORKDIR/folder/file)"
+
+log_pass "Testing idmapped mount in a user ns is successful."
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib
new file mode 100644
index 000000000000..980845ca209c
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib
@@ -0,0 +1,23 @@
+#
+# 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
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/idmap_mount/idmap_mount.cfg
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh
new file mode 100755
index 000000000000..90a14f12058f
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# 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
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+# unable to do idmapped mount in a local zone
+verify_runnable "global"
+
+DISK=${DISKS%% *}
+default_setup $DISK
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh
index e525c51344ad..1f203e1dc551 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh
@@ -26,6 +26,7 @@
#
# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
+# Copyright (c) 2022 Hewlett Packard Enterprise Development LP.
#
. $STF_SUITE/include/libtest.shlib
@@ -376,7 +377,8 @@ set -A prop "checksum" "" \
"sharenfs" "" \
"recordsize" "recsize" \
"snapdir" "" \
- "readonly" ""
+ "readonly" "" \
+ "redundant_metadata" ""
#
# Note except for the mountpoint default value (which is handled in
@@ -387,12 +389,14 @@ set -A prop "checksum" "" \
set -A def_val "on" "on" "on" \
"off" "" \
"hidden" \
- "off"
+ "off" \
+ "all"
set -A local_val "off" "off" "off" \
"on" "" \
"visible" \
- "off"
+ "off" \
+ "none"
#
# Add system specific values
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/Makefile.am
new file mode 100644
index 000000000000..bd8d6c9d68bf
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/Makefile.am
@@ -0,0 +1,7 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/renameat2
+dist_pkgdata_SCRIPTS = \
+ setup.ksh \
+ cleanup.ksh \
+ renameat2_noreplace.ksh \
+ renameat2_exchange.ksh \
+ renameat2_whiteout.ksh
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/cleanup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/cleanup.ksh
new file mode 100755
index 000000000000..3166bd6ec16e
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/cleanup.ksh
@@ -0,0 +1,34 @@
+#!/bin/ksh -p
+#
+# 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 http://www.opensolaris.org/os/licensing.
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2013 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+default_cleanup
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_exchange.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_exchange.ksh
new file mode 100755
index 000000000000..94e56231feb1
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_exchange.ksh
@@ -0,0 +1,61 @@
+#!/bin/ksh -p
+#
+# 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 http://www.opensolaris.org/os/licensing.
+# 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) 2019 Aleksa Sarai <cyphar@cyphar.com>
+# Copyright (C) 2019 SUSE LLC
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "both"
+
+function cleanup
+{
+ log_must rm -rf $TESTDIR/*
+}
+
+log_assert "ZFS supports RENAME_EXCHANGE."
+log_onexit cleanup
+
+cd $TESTDIR
+echo "foo" > foo
+echo "bar" > bar
+
+# Self-exchange is a no-op.
+log_must renameat2 -x foo foo
+log_must grep '^foo$' foo
+
+# Basic exchange.
+log_must renameat2 -x foo bar
+log_must grep '^bar$' foo
+log_must grep '^foo$' bar
+
+# And exchange back.
+log_must renameat2 -x foo bar
+log_must grep '^foo$' foo
+log_must grep '^bar$' bar
+
+# Exchange with a bad path should fail.
+log_mustnot renameat2 -x bar baz
+
+log_pass "ZFS supports RENAME_EXCHANGE as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_noreplace.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_noreplace.ksh
new file mode 100755
index 000000000000..d75b94fab465
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_noreplace.ksh
@@ -0,0 +1,51 @@
+#!/bin/ksh -p
+#
+# 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 http://www.opensolaris.org/os/licensing.
+# 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) 2019 Aleksa Sarai <cyphar@cyphar.com>
+# Copyright (C) 2019 SUSE LLC
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "both"
+
+function cleanup
+{
+ log_must rm -rf $TESTDIR/*
+}
+
+log_assert "ZFS supports RENAME_NOREPLACE."
+log_onexit cleanup
+
+cd $TESTDIR
+touch foo bar
+
+# Clobbers should always fail.
+log_mustnot renameat2 -n foo foo
+log_mustnot renameat2 -n foo bar
+log_mustnot renameat2 -n bar foo
+
+# Regular renames should succeed.
+log_must renameat2 -n bar baz
+
+log_pass "ZFS supports RENAME_NOREPLACE as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_whiteout.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_whiteout.ksh
new file mode 100755
index 000000000000..8ecb074dbbdb
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/renameat2_whiteout.ksh
@@ -0,0 +1,50 @@
+#!/bin/ksh -p
+#
+# 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 http://www.opensolaris.org/os/licensing.
+# 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) 2019 Aleksa Sarai <cyphar@cyphar.com>
+# Copyright (C) 2019 SUSE LLC
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "both"
+
+function cleanup
+{
+ log_must rm -rf $TESTDIR/*
+}
+
+log_assert "ZFS supports RENAME_WHITEOUT."
+log_onexit cleanup
+
+cd $TESTDIR
+echo "whiteout" > whiteout
+
+# Straight-forward rename-with-whiteout.
+log_must renameat2 -w whiteout new
+# Check new file.
+log_must grep '^whiteout$' new
+# Check that the whiteout is actually a {0,0} char device.
+log_must grep '^character special file:0:0$' <<<"$(stat -c '%F:%t:%T' whiteout)"
+
+log_pass "ZFS supports RENAME_WHITEOUT as expected."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/setup.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/setup.ksh
new file mode 100755
index 000000000000..b8c26d5ba062
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/renameat2/setup.ksh
@@ -0,0 +1,37 @@
+#!/bin/ksh -p
+#
+# 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 http://www.opensolaris.org/os/licensing.
+# 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) 2019 Aleksa Sarai <cyphar@cyphar.com>
+# Copyright (C) 2019 SUSE LLC
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+if ! is_linux ; then
+ log_unsupported "renameat2 is linux-only"
+elif ! renameat2 -C ; then
+ log_unsupported "renameat2 not supported on this (pre-3.15) linux kernel"
+fi
+
+DISK=${DISKS%% *}
+default_setup $DISK
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/rsend_009_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/rsend_009_pos.ksh
index ba60afe9acd3..fc5a582f881e 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/rsend_009_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/rsend_009_pos.ksh
@@ -45,13 +45,16 @@
verify_runnable "global"
+BPOOL=bpool_test
+SPOOL=spool_test
+
function cleanup
{
- if datasetexists bpool ; then
- log_must_busy zpool destroy -f bpool
+ if datasetexists $BPOOL ; then
+ log_must_busy zpool destroy -f $BPOOL
fi
- if datasetexists spool ; then
- log_must_busy zpool destroy -f spool
+ if datasetexists $SPOOL ; then
+ log_must_busy zpool destroy -f $SPOOL
fi
}
@@ -60,33 +63,33 @@ log_onexit cleanup
log_must mkfile $MINVDEVSIZE $TESTDIR/bfile
log_must mkfile $SPA_MINDEVSIZE $TESTDIR/sfile
-log_must zpool create -O compression=off bpool $TESTDIR/bfile
-log_must zpool create -O compression=off spool $TESTDIR/sfile
+log_must zpool create -O compression=off $BPOOL $TESTDIR/bfile
+log_must zpool create -O compression=off $SPOOL $TESTDIR/sfile
#
# Test out of space on sub-filesystem
#
-log_must zfs create bpool/fs
-log_must mkfile 30M /bpool/fs/file
+log_must zfs create $BPOOL/fs
+log_must mkfile 30M /$BPOOL/fs/file
-log_must zfs snapshot bpool/fs@snap
-log_must eval "zfs send -R bpool/fs@snap > $BACKDIR/fs-R"
-log_mustnot eval "zfs receive -d -F spool < $BACKDIR/fs-R"
+log_must zfs snapshot $BPOOL/fs@snap
+log_must eval "zfs send -R $BPOOL/fs@snap > $BACKDIR/fs-R"
+log_mustnot eval "zfs receive -d -F $SPOOL < $BACKDIR/fs-R"
-log_must datasetnonexists spool/fs
-log_must ismounted spool
+log_must datasetnonexists $SPOOL/fs
+log_must ismounted $SPOOL
#
# Test out of space on top filesystem
#
-log_must mv /bpool/fs/file /bpool
-log_must_busy zfs destroy -rf bpool/fs
+log_must mv /$BPOOL/fs/file /$BPOOL
+log_must_busy zfs destroy -rf $BPOOL/fs
-log_must zfs snapshot bpool@snap
-log_must eval "zfs send -R bpool@snap > $BACKDIR/bpool-R"
-log_mustnot eval "zfs receive -d -F spool < $BACKDIR/bpool-R"
+log_must zfs snapshot $BPOOL@snap
+log_must eval "zfs send -R $BPOOL@snap > $BACKDIR/bpool-R"
+log_mustnot eval "zfs receive -d -F $SPOOL < $BACKDIR/bpool-R"
-log_must datasetnonexists spool/fs
-log_must ismounted spool
+log_must datasetnonexists $SPOOL/fs
+log_must ismounted $SPOOL
log_pass "zfs receive can handle out of space correctly."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send-c_zstream_recompress.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send-c_zstream_recompress.ksh
new file mode 100755
index 000000000000..dd2a7d02a261
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send-c_zstream_recompress.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2022 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+. $STF_SUITE/include/math.shlib
+
+#
+# Description:
+# Verify compression features show up in zstream dump
+#
+# Strategy:
+# 1. Create a compressed send stream
+# 2. Recompress the stream with a different algorithm
+# 3. Verify it can be received correctly
+# 4. Verify the contents match the original filesystem
+# 5. Create an uncompressed send stream
+# 6. Compress the send stream
+# 7. Verify that the stream is smaller when compressed
+#
+
+verify_runnable "both"
+
+log_assert "Verify zstream recompress correctly modifies send streams."
+log_onexit cleanup_pool $POOL2
+
+typeset sendfs=$POOL2/fs
+typeset recvfs=$POOL2/fs2
+
+log_must zfs create -o compress=lz4 $sendfs
+typeset dir=$(get_prop mountpoint $sendfs)
+write_compressible $dir 16m
+log_must zfs snapshot $sendfs@snap
+
+log_must eval "zfs send -c $sendfs@snap | zstream recompress gzip-1 | zfs recv $recvfs"
+typeset recvdir=$(get_prop mountpoint $recvfs)
+log_must diff -r $dir $recvdir
+
+log_must eval "zfs send $sendfs@snap >$BACKDIR/uncompressed"
+log_must zstream recompress gzip-1 <$BACKDIR/uncompressed >$BACKDIR/compressed
+typeset uncomp_size=$(wc -c $BACKDIR/uncompressed | awk '{print $1}')
+typeset comp_size=$(wc -c $BACKDIR/compressed | awk '{print $1}')
+[[ "$uncomp_size" -gt "$comp_size" ]] || log_fail "recompressed stream was not smaller"
+
+log_pass "zstream recompress correctly modifies send streams."
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/slog_replay_fs_001.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/slog_replay_fs_001.ksh
index eddecbc2db7e..8f3585a5997f 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/slog_replay_fs_001.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/slog/slog_replay_fs_001.ksh
@@ -175,6 +175,29 @@ log_must ln /$TESTPOOL/$TESTFS/link_and_unlink \
/$TESTPOOL/$TESTFS/link_and_unlink.link
log_must rm /$TESTPOOL/$TESTFS/link_and_unlink.link
+# We can't test RENAME_* flags without renameat2(2) support.
+if ! is_linux ; then
+ log_note "renameat2 is linux-only"
+elif ! renameat2 -C ; then
+ log_note "renameat2 not supported on this (pre-3.15) linux kernel"
+else
+ # TX_RENAME_EXCHANGE
+ log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/xchg-a bs=1k count=1
+ log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/xchg-b bs=1k count=1
+ log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/xchg-c bs=1k count=1
+ log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/xchg-d bs=1k count=1
+ # rotate the files around
+ log_must renameat2 -x /$TESTPOOL/$TESTFS/xchg-{a,b}
+ log_must renameat2 -x /$TESTPOOL/$TESTFS/xchg-{b,c}
+ log_must renameat2 -x /$TESTPOOL/$TESTFS/xchg-{c,a}
+ # exchange same path
+ log_must renameat2 -x /$TESTPOOL/$TESTFS/xchg-{d,d}
+
+ # TX_RENAME_WHITEOUT
+ log_must mkfile 1k /$TESTPOOL/$TESTFS/whiteout
+ log_must renameat2 -w /$TESTPOOL/$TESTFS/whiteout{,-moved}
+fi
+
#
# 4. Copy TESTFS to temporary location (TESTDIR/copy)
#
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_002_pos.c b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_002_pos.c
index 424231d112b2..906b81b4d9b3 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_002_pos.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_002_pos.c
@@ -46,7 +46,6 @@ main(void)
int i, fd;
char spath[1024], dpath[1024];
const char *penv[] = {"TESTDIR", "TESTFILE0"};
- struct stat sbuf;
(void) fprintf(stdout, "Verify O_TMPFILE file can be linked.\n");
@@ -73,12 +72,10 @@ main(void)
run("export");
run("import");
- if (stat(dpath, &sbuf) < 0) {
- perror("stat");
- unlink(dpath);
+ if (unlink(dpath) == -1) {
+ perror("unlink");
exit(5);
}
- unlink(dpath);
return (0);
}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c
index 4c34aec8bdb4..8f936d36de1f 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/tmpfile/tmpfile_stat_mode.c
@@ -37,18 +37,18 @@
/*
* DESCRIPTION:
- * Verify stat(2) for O_TMPFILE file considers umask.
+ * Verify fstat(2) for O_TMPFILE file considers umask.
*
* STRATEGY:
* 1. open(2) with O_TMPFILE.
* 2. linkat(2).
- * 3. fstat(2)/stat(2) and verify .st_mode value.
+ * 3. fstat(2) and verify .st_mode value.
*/
static void
test_stat_mode(mode_t mask)
{
- struct stat st, fst;
+ struct stat fst;
int i, fd;
char spath[1024], dpath[1024];
const char *penv[] = {"TESTDIR", "TESTFILE0"};
@@ -68,7 +68,7 @@ test_stat_mode(mode_t mask)
err(2, "open(%s)", penv[0]);
if (fstat(fd, &fst) == -1)
- err(3, "open");
+ err(3, "fstat(%s)", penv[0]);
snprintf(spath, sizeof (spath), "/proc/self/fd/%d", fd);
snprintf(dpath, sizeof (dpath), "%s/%s", penv[0], penv[1]);
@@ -78,19 +78,23 @@ test_stat_mode(mode_t mask)
err(4, "linkat");
close(fd);
- if (stat(dpath, &st) == -1)
- err(5, "stat");
- unlink(dpath);
-
- /* Verify fstat(2) result */
+ /* Verify fstat(2) result at old path */
mode = fst.st_mode & 0777;
if (mode != masked)
- errx(6, "fstat(2) %o != %o\n", mode, masked);
+ errx(5, "fstat(2) %o != %o\n", mode, masked);
+
+ fd = open(dpath, O_RDWR);
+ if (fd == -1)
+ err(6, "open(%s)", dpath);
- /* Verify stat(2) result */
- mode = st.st_mode & 0777;
+ if (fstat(fd, &fst) == -1)
+ err(7, "fstat(%s)", dpath);
+
+ /* Verify fstat(2) result at new path */
+ mode = fst.st_mode & 0777;
if (mode != masked)
- errx(7, "stat(2) %o != %o\n", mode, masked);
+ errx(8, "fstat(2) %o != %o\n", mode, masked);
+ close(fd);
}
int
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/13709_reproducer.bz2 b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/13709_reproducer.bz2
new file mode 100644
index 000000000000..9c3168279461
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/13709_reproducer.bz2
Binary files differ
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_encrypted_13709.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_encrypted_13709.ksh
new file mode 100755
index 000000000000..9c1d847756d1
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/userquota/userspace_encrypted_13709.ksh
@@ -0,0 +1,45 @@
+#!/bin/ksh -p
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/userquota/userquota_common.kshlib
+
+#
+# DESCRIPTION:
+# Avoid allowing #11294/#13709 to recur a third time.
+#
+# So we hardcode a copy of a pool with this bug, try unlocking it,
+# and fail on error. Simple.
+
+function cleanup
+{
+ destroy_pool $POOLNAME
+ rm -f $FILEDEV
+}
+
+log_onexit cleanup
+
+FILEDEV="$TEST_BASE_DIR/userspace_13709"
+POOLNAME="testpool_13709"
+
+log_assert "ZFS should be able to unlock pools with #13709's failure mode"
+
+log_must bzcat $STF_SUITE/tests/functional/userquota/13709_reproducer.bz2 > $FILEDEV
+
+log_must zpool import -d $FILEDEV $POOLNAME
+
+echo -e 'password\npassword\n' | log_must zfs mount -al
+
+# Cleanup
+cleanup
+
+log_pass "#13709 not happening here"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/perf/regression/random_readwrite.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/perf/regression/random_readwrite.ksh
index 3a358774f565..e0626c0b42f3 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/perf/regression/random_readwrite.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/perf/regression/random_readwrite.ksh
@@ -60,7 +60,7 @@ export TOTAL_SIZE=$(($(get_prop avail $PERFPOOL) * 3 / 2))
# Variables specific to this test for use by fio.
export PERF_NTHREADS=${PERF_NTHREADS:-'32 64'}
export PERF_NTHREADS_PER_FS=${PERF_NTHREADS_PER_FS:-'0'}
-export PERF_IOSIZES='' # bssplit used instead
+export PERF_IOSIZES='bssplit' # bssplit used instead of fixed sizes
export PERF_SYNC_TYPES=${PERF_SYNC_TYPES:-'1'}
# Layout the files to be used by the readwrite tests. Create as many files