The branch releng/14.0 has been updated by mm:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4afaeab99e9e4e8e4d8306aff51f9557d8d14cdf

commit 4afaeab99e9e4e8e4d8306aff51f9557d8d14cdf
Author:     Martin Matuska <[email protected]>
AuthorDate: 2023-09-21 09:29:21 +0000
Commit:     Martin Matuska <[email protected]>
CommitDate: 2023-09-24 17:30:02 +0000

    zfs: merge openzfs/zfs@62677576a (zfs-2.2-release) into stable/14
    
    Notable upstream pull request merges:
     #15274 f7a07d76e Retire z_nr_znodes
     #15278 62677576a ZIL: Fix potential race on flush deferring
     #15279 11943656f Update the MOS directory on spa_upgrade_errlog()
     #15281 54c6fbd37 zed: Allow autoreplace and fault LEDs for removed vdevs
    
    Obtained from:  OpenZFS
    Approved by:    re (gjb)
    OpenZFS commit: 62677576a75e94396e945c4ecd9372f5d34e50cb
    
    (cherry picked from commit 35e5fd1b286c18371ec6f66addf678cd4429302c)
    (cherry picked from commit 646c82e08a433b61b97073051fd558e42c64603c)
---
 sys/contrib/openzfs/META                           |  2 +-
 sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c       |  1 +
 .../openzfs/cmd/zed/zed.d/statechange-led.sh       |  2 +-
 sys/contrib/openzfs/config/kernel-blkdev.m4        | 84 +++++++++++++++++++++-
 .../config/kernel-block-device-operations.m4       | 35 ++++++++-
 .../openzfs/config/kernel-filemap-splice-read.m4   | 25 +++++++
 .../openzfs/config/kernel-register_sysctl_table.m4 | 27 +++++++
 sys/contrib/openzfs/config/kernel-vfs-iov_iter.m4  | 26 ++++++-
 sys/contrib/openzfs/config/kernel.m4               |  4 ++
 .../include/os/freebsd/zfs/sys/zfs_vfsops_os.h     |  1 -
 .../include/os/linux/kernel/linux/blkdev_compat.h  |  7 ++
 sys/contrib/openzfs/include/os/linux/spl/sys/uio.h | 12 ++++
 .../include/os/linux/zfs/sys/zfs_vfsops_os.h       |  1 -
 sys/contrib/openzfs/man/man7/zpoolconcepts.7       |  8 +--
 sys/contrib/openzfs/module/Makefile.in             |  2 +-
 .../openzfs/module/os/freebsd/zfs/zfs_vfsops.c     |  8 +--
 .../openzfs/module/os/freebsd/zfs/zfs_znode.c      |  2 -
 sys/contrib/openzfs/module/os/linux/spl/spl-proc.c | 77 ++++++++++++++------
 .../openzfs/module/os/linux/zfs/vdev_disk.c        | 65 ++++++++++++++---
 .../openzfs/module/os/linux/zfs/zfs_ctldir.c       |  1 -
 .../openzfs/module/os/linux/zfs/zfs_vfsops.c       |  7 +-
 .../openzfs/module/os/linux/zfs/zfs_vnops_os.c     |  2 +-
 .../openzfs/module/os/linux/zfs/zfs_znode.c        |  2 -
 .../openzfs/module/os/linux/zfs/zpl_ctldir.c       |  2 +-
 sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c | 15 ++--
 sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c  | 28 ++++++--
 sys/contrib/openzfs/module/zfs/spa_errlog.c        |  9 +++
 sys/contrib/openzfs/module/zfs/zil.c               |  9 +++
 .../cli_root/zdb/zdb_block_size_histogram.ksh      |  8 +--
 sys/modules/zfs/zfs_config.h                       | 27 ++++++-
 sys/modules/zfs/zfs_gitrev.h                       |  2 +-
 31 files changed, 419 insertions(+), 82 deletions(-)

diff --git a/sys/contrib/openzfs/META b/sys/contrib/openzfs/META
index 0953cc51922f..9ffe90458dbd 100644
--- a/sys/contrib/openzfs/META
+++ b/sys/contrib/openzfs/META
@@ -6,5 +6,5 @@ Release:       rc4
 Release-Tags:  relext
 License:       CDDL
 Author:        OpenZFS
-Linux-Maximum: 6.4
+Linux-Maximum: 6.5
 Linux-Minimum: 3.10
diff --git a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c 
b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
index a8d084bb4bd3..2f040ff7582c 100644
--- a/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
+++ b/sys/contrib/openzfs/cmd/zed/agents/zfs_mod.c
@@ -372,6 +372,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, 
boolean_t labeled)
        /* Only autoreplace bad disks */
        if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
            (vs->vs_state != VDEV_STATE_FAULTED) &&
+           (vs->vs_state != VDEV_STATE_REMOVED) &&
            (vs->vs_state != VDEV_STATE_CANT_OPEN)) {
                zed_log_msg(LOG_INFO, "  not autoreplacing since disk isn't in "
                    "a bad state (currently %llu)", vs->vs_state);
diff --git a/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh 
b/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh
index 46bfc1b866f1..40cb61f17307 100755
--- a/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh
+++ b/sys/contrib/openzfs/cmd/zed/zed.d/statechange-led.sh
@@ -121,7 +121,7 @@ state_to_val()
 {
        state="$1"
        case "$state" in
-               FAULTED|DEGRADED|UNAVAIL)
+               FAULTED|DEGRADED|UNAVAIL|REMOVED)
                        echo 1
                        ;;
                ONLINE)
diff --git a/sys/contrib/openzfs/config/kernel-blkdev.m4 
b/sys/contrib/openzfs/config/kernel-blkdev.m4
index 887acee670ba..e04a2bd2c3b6 100644
--- a/sys/contrib/openzfs/config/kernel-blkdev.m4
+++ b/sys/contrib/openzfs/config/kernel-blkdev.m4
@@ -16,12 +16,63 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [
        ])
 ])
 
+dnl #
+dnl # 6.5.x API change,
+dnl # blkdev_get_by_path() takes 4 args
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG], [
+       ZFS_LINUX_TEST_SRC([blkdev_get_by_path_4arg], [
+               #include <linux/fs.h>
+               #include <linux/blkdev.h>
+       ], [
+               struct block_device *bdev __attribute__ ((unused)) = NULL;
+               const char *path = "path";
+               fmode_t mode = 0;
+               void *holder = NULL;
+               struct blk_holder_ops h;
+
+               bdev = blkdev_get_by_path(path, mode, holder, &h);
+       ])
+])
+
 AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
-       AC_MSG_CHECKING([whether blkdev_get_by_path() exists])
+       AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args])
        ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
                AC_MSG_RESULT(yes)
        ], [
-               ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
+               AC_MSG_RESULT(no)
+               AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 
4 args])
+               ZFS_LINUX_TEST_RESULT([blkdev_get_by_path_4arg], [
+                       AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH_4ARG, 1,
+                               [blkdev_get_by_path() exists and takes 4 args])
+                       AC_MSG_RESULT(yes)
+               ], [
+                       ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
+               ])
+       ])
+])
+
+dnl #
+dnl # 6.5.x API change
+dnl # blk_mode_t was added as a type to supercede some places where fmode_t
+dnl # is used
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T], [
+       ZFS_LINUX_TEST_SRC([blk_mode_t], [
+               #include <linux/fs.h>
+               #include <linux/blkdev.h>
+       ], [
+               blk_mode_t m __attribute((unused)) = (blk_mode_t)0;
+       ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T], [
+       AC_MSG_CHECKING([whether blk_mode_t is defined])
+       ZFS_LINUX_TEST_RESULT([blk_mode_t], [
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_BLK_MODE_T, 1, [blk_mode_t is defined])
+       ], [
+               AC_MSG_RESULT(no)
        ])
 ])
 
@@ -41,12 +92,35 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [
        ])
 ])
 
+dnl #
+dnl # 6.5.x API change.
+dnl # blkdev_put() takes (void* holder) as arg 2
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER], [
+       ZFS_LINUX_TEST_SRC([blkdev_put_holder], [
+               #include <linux/fs.h>
+               #include <linux/blkdev.h>
+       ], [
+               struct block_device *bdev = NULL;
+               void *holder = NULL;
+
+               blkdev_put(bdev, holder);
+       ])
+])
+
 AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
        AC_MSG_CHECKING([whether blkdev_put() exists])
        ZFS_LINUX_TEST_RESULT([blkdev_put], [
                AC_MSG_RESULT(yes)
        ], [
-               ZFS_LINUX_TEST_ERROR([blkdev_put()])
+               AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2])
+               ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [
+                       AC_MSG_RESULT(yes)
+                       AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1,
+                               [blkdev_put() accepts void* as arg 2])
+               ], [
+                       ZFS_LINUX_TEST_ERROR([blkdev_put()])
+               ])
        ])
 ])
 
@@ -495,7 +569,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [
 
 AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
        ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
+       ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG
        ZFS_AC_KERNEL_SRC_BLKDEV_PUT
+       ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER
        ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
        ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
        ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV
@@ -510,6 +586,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
        ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV
        ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE
        ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT
+       ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T
 ])
 
 AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
@@ -530,4 +607,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
        ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV
        ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE
        ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT
+       ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T
 ])
diff --git a/sys/contrib/openzfs/config/kernel-block-device-operations.m4 
b/sys/contrib/openzfs/config/kernel-block-device-operations.m4
index 84e39dc8a2f6..d13c1337b1fb 100644
--- a/sys/contrib/openzfs/config/kernel-block-device-operations.m4
+++ b/sys/contrib/openzfs/config/kernel-block-device-operations.m4
@@ -49,12 +49,42 @@ 
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
        ], [], [])
 ])
 
+dnl #
+dnl # 5.9.x API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [
+       ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [
+               #include <linux/blkdev.h>
+
+               void blk_release(struct gendisk *g) {
+                       (void) g;
+                       return;
+               }
+
+               static const struct block_device_operations
+                   bops __attribute__ ((unused)) = {
+                       .open           = NULL,
+                       .release        = blk_release,
+                       .ioctl          = NULL,
+                       .compat_ioctl   = NULL,
+               };
+       ], [], [])
+])
+
 AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
-       AC_MSG_CHECKING([whether bops->release() is void])
+       AC_MSG_CHECKING([whether bops->release() is void and takes 2 args])
        ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [
                AC_MSG_RESULT(yes)
        ],[
-               ZFS_LINUX_TEST_ERROR([bops->release()])
+               AC_MSG_RESULT(no)
+               AC_MSG_CHECKING([whether bops->release() is void and takes 1 
arg])
+               
ZFS_LINUX_TEST_RESULT([block_device_operations_release_void_1arg], [
+                       AC_MSG_RESULT(yes)
+                       AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], 
[1],
+                               [Define if release() in block_device_operations 
takes 1 arg])
+               ],[
+                       ZFS_LINUX_TEST_ERROR([bops->release()])
+               ])
        ])
 ])
 
@@ -92,6 +122,7 @@ 
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
 AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
        ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
        ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
+       ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG
        ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
 ])
 
diff --git a/sys/contrib/openzfs/config/kernel-filemap-splice-read.m4 
b/sys/contrib/openzfs/config/kernel-filemap-splice-read.m4
new file mode 100644
index 000000000000..4c83b31d738a
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-filemap-splice-read.m4
@@ -0,0 +1,25 @@
+AC_DEFUN([ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ], [
+       dnl #
+       dnl # Kernel 6.5 - generic_file_splice_read was removed in favor
+       dnl # of copy_splice_read for the .splice_read member of the
+       dnl # file_operations struct.
+       dnl #
+       ZFS_LINUX_TEST_SRC([has_copy_splice_read], [
+               #include <linux/fs.h>
+
+               struct file_operations fops __attribute__((unused)) = {
+                       .splice_read = copy_splice_read,
+               };
+       ],[])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_COPY_SPLICE_READ], [
+       AC_MSG_CHECKING([whether copy_splice_read() exists])
+       ZFS_LINUX_TEST_RESULT([has_copy_splice_read], [
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_COPY_SPLICE_READ, 1,
+                   [copy_splice_read exists])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+])
diff --git a/sys/contrib/openzfs/config/kernel-register_sysctl_table.m4 
b/sys/contrib/openzfs/config/kernel-register_sysctl_table.m4
new file mode 100644
index 000000000000..a5e934f56d29
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-register_sysctl_table.m4
@@ -0,0 +1,27 @@
+dnl #
+dnl # Linux 6.5 removes register_sysctl_table
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE], [
+       ZFS_LINUX_TEST_SRC([has_register_sysctl_table], [
+               #include <linux/sysctl.h>
+
+               static struct ctl_table dummy_table[] = {
+                       {}
+               };
+
+    ],[
+               struct ctl_table_header *h
+                       __attribute((unused)) = 
register_sysctl_table(dummy_table);
+    ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE], [
+       AC_MSG_CHECKING([whether register_sysctl_table exists])
+       ZFS_LINUX_TEST_RESULT([has_register_sysctl_table], [
+               AC_MSG_RESULT([yes])
+               AC_DEFINE(HAVE_REGISTER_SYSCTL_TABLE, 1,
+                       [register_sysctl_table exists])
+       ],[
+               AC_MSG_RESULT([no])
+       ])
+])
diff --git a/sys/contrib/openzfs/config/kernel-vfs-iov_iter.m4 
b/sys/contrib/openzfs/config/kernel-vfs-iov_iter.m4
index e0617faab02c..ff560ff3eef0 100644
--- a/sys/contrib/openzfs/config/kernel-vfs-iov_iter.m4
+++ b/sys/contrib/openzfs/config/kernel-vfs-iov_iter.m4
@@ -6,8 +6,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
                #include <linux/fs.h>
                #include <linux/uio.h>
        ],[
-               int type __attribute__ ((unused)) =
-                   ITER_IOVEC | ITER_KVEC | ITER_BVEC | ITER_PIPE;
+               int type __attribute__ ((unused)) = ITER_KVEC;
        ])
 
        ZFS_LINUX_TEST_SRC([iov_iter_advance], [
@@ -93,6 +92,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
                struct iov_iter iter = { 0 };
                __attribute__((unused)) enum iter_type i = iov_iter_type(&iter);
        ])
+
+       ZFS_LINUX_TEST_SRC([iter_iov], [
+               #include <linux/fs.h>
+               #include <linux/uio.h>
+       ],[
+               struct iov_iter iter = { 0 };
+               __attribute__((unused)) const struct iovec *iov = 
iter_iov(&iter);
+       ])
 ])
 
 AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
@@ -201,4 +208,19 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [
                AC_DEFINE(HAVE_VFS_IOV_ITER, 1,
                    [All required iov_iter interfaces are available])
        ])
+
+       dnl #
+       dnl # Kernel 6.5 introduces the iter_iov() function that returns the
+       dnl # __iov member of an iov_iter*. The iov member was renamed to this
+       dnl # __iov member, and is intended to be accessed via the helper
+       dnl # function now.
+       dnl #
+       AC_MSG_CHECKING([whether iter_iov() is available])
+       ZFS_LINUX_TEST_RESULT([iter_iov], [
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_ITER_IOV, 1,
+                   [iter_iov() is available])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
 ])
diff --git a/sys/contrib/openzfs/config/kernel.m4 
b/sys/contrib/openzfs/config/kernel.m4
index 1487fa2e7793..df194ec72207 100644
--- a/sys/contrib/openzfs/config/kernel.m4
+++ b/sys/contrib/openzfs/config/kernel.m4
@@ -160,6 +160,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
        ZFS_AC_KERNEL_SRC_FILEMAP
        ZFS_AC_KERNEL_SRC_WRITEPAGE_T
        ZFS_AC_KERNEL_SRC_RECLAIMED
+       ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE
+       ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ
        case "$host_cpu" in
                powerpc*)
                        ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE
@@ -299,6 +301,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
        ZFS_AC_KERNEL_FILEMAP
        ZFS_AC_KERNEL_WRITEPAGE_T
        ZFS_AC_KERNEL_RECLAIMED
+       ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE
+       ZFS_AC_KERNEL_COPY_SPLICE_READ
        case "$host_cpu" in
                powerpc*)
                        ZFS_AC_KERNEL_CPU_HAS_FEATURE
diff --git a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h 
b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
index 5948e44daab1..56a0ac96ac19 100644
--- a/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
+++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
@@ -93,7 +93,6 @@ struct zfsvfs {
        zfs_teardown_lock_t z_teardown_lock;
        zfs_teardown_inactive_lock_t z_teardown_inactive_lock;
        list_t          z_all_znodes;   /* all vnodes in the fs */
-       uint64_t        z_nr_znodes;    /* number of znodes in the fs */
        kmutex_t        z_znodes_lock;  /* lock for z_all_znodes */
        struct zfsctl_root      *z_ctldir;      /* .zfs directory pointer */
        boolean_t       z_show_ctldir;  /* expose .zfs in the root dir */
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 e0f20ba32008..f111e648ccf7 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
@@ -347,6 +347,7 @@ zfs_check_media_change(struct block_device *bdev)
 #define        vdev_bdev_reread_part(bdev)     zfs_check_media_change(bdev)
 #elif defined(HAVE_DISK_CHECK_MEDIA_CHANGE)
 #define        vdev_bdev_reread_part(bdev)     
disk_check_media_change(bdev->bd_disk)
+#define        zfs_check_media_change(bdev)    
disk_check_media_change(bdev->bd_disk)
 #else
 /*
  * This is encountered if check_disk_change() and bdev_check_media_change()
@@ -397,6 +398,12 @@ vdev_lookup_bdev(const char *path, dev_t *dev)
 #endif
 }
 
+#if defined(HAVE_BLK_MODE_T)
+#define        blk_mode_is_open_write(flag)    ((flag) & BLK_OPEN_WRITE)
+#else
+#define        blk_mode_is_open_write(flag)    ((flag) & FMODE_WRITE)
+#endif
+
 /*
  * Kernels without bio_set_op_attrs use bi_rw for the bio flags.
  */
diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/uio.h 
b/sys/contrib/openzfs/include/os/linux/spl/sys/uio.h
index fe2b5c07a018..cce097e16fbc 100644
--- a/sys/contrib/openzfs/include/os/linux/spl/sys/uio.h
+++ b/sys/contrib/openzfs/include/os/linux/spl/sys/uio.h
@@ -173,4 +173,16 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter 
*iter, offset_t offset,
 }
 #endif
 
+#if defined(HAVE_ITER_IOV)
+#define        zfs_uio_iter_iov(iter)  iter_iov((iter))
+#else
+#define        zfs_uio_iter_iov(iter)  (iter)->iov
+#endif
+
+#if defined(HAVE_IOV_ITER_TYPE)
+#define        zfs_uio_iov_iter_type(iter)     iov_iter_type((iter))
+#else
+#define        zfs_uio_iov_iter_type(iter)     (iter)->type
+#endif
+
 #endif /* SPL_UIO_H */
diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h 
b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h
index e320b8de4222..b4d5db21f5e5 100644
--- a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h
+++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_vfsops_os.h
@@ -105,7 +105,6 @@ struct zfsvfs {
        rrmlock_t       z_teardown_lock;
        krwlock_t       z_teardown_inactive_lock;
        list_t          z_all_znodes;   /* all znodes in the fs */
-       uint64_t        z_nr_znodes;    /* number of znodes in the fs */
        unsigned long   z_rollback_time; /* last online rollback time */
        unsigned long   z_snap_defer_time; /* last snapshot unmount deferral */
        kmutex_t        z_znodes_lock;  /* lock for z_all_znodes */
diff --git a/sys/contrib/openzfs/man/man7/zpoolconcepts.7 
b/sys/contrib/openzfs/man/man7/zpoolconcepts.7
index db3fd4926236..98f3ee7cd660 100644
--- a/sys/contrib/openzfs/man/man7/zpoolconcepts.7
+++ b/sys/contrib/openzfs/man/man7/zpoolconcepts.7
@@ -203,11 +203,9 @@ For more information, see the
 section.
 .El
 .Pp
-Virtual devices cannot be nested, so a mirror or raidz virtual device can only
-contain files or disks.
-Mirrors of mirrors
-.Pq or other combinations
-are not allowed.
+Virtual devices cannot be nested arbitrarily.
+A mirror, raidz or draid virtual device can only be created with files or 
disks.
+Mirrors of mirrors or other such combinations are not allowed.
 .Pp
 A pool can have any number of virtual devices at the top of the configuration
 .Po known as
diff --git a/sys/contrib/openzfs/module/Makefile.in 
b/sys/contrib/openzfs/module/Makefile.in
index 5b71e1abf79e..9b34b3dfaec7 100644
--- a/sys/contrib/openzfs/module/Makefile.in
+++ b/sys/contrib/openzfs/module/Makefile.in
@@ -168,4 +168,4 @@ gen-zstd-symbols:
        for obj in $(addprefix zstd/,$(ZSTD_UPSTREAM_OBJS)); do echo; echo "/* 
$${obj#zstd/}: */"; @OBJDUMP@ -t $$obj | awk '$$2 == "g" && !/ zfs_/ {print 
"#define\t" $$6 " zfs_" $$6}' | sort; done >> zstd/include/zstd_compat_wrapper.h
 
 check-zstd-symbols:
-       @OBJDUMP@ -t $(addprefix zstd/,$(ZSTD_UPSTREAM_OBJS)) | awk '/file 
format/ {print}  $$2 == "g" && !/ zfs_/ {++ret; print}  END {exit ret}'
+       @OBJDUMP@ -t $(addprefix zstd/,$(ZSTD_UPSTREAM_OBJS)) | awk '/file 
format/ {print}  $$2 == "g" && (!/ zfs_/ && !/ __pfx_zfs_/) {++ret; print}  END 
{exit ret}'
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 49b97ae8f590..8969fd6a54bd 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c
@@ -1158,7 +1158,6 @@ zfsvfs_free(zfsvfs_t *zfsvfs)
 
        mutex_destroy(&zfsvfs->z_znodes_lock);
        mutex_destroy(&zfsvfs->z_lock);
-       ASSERT3U(zfsvfs->z_nr_znodes, ==, 0);
        list_destroy(&zfsvfs->z_all_znodes);
        ZFS_TEARDOWN_DESTROY(zfsvfs);
        ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs);
@@ -1562,12 +1561,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
                 * may add the parents of dir-based xattrs to the taskq
                 * so we want to wait for these.
                 *
-                * We can safely read z_nr_znodes without locking because the
-                * VFS has already blocked operations which add to the
-                * z_all_znodes list and thus increment z_nr_znodes.
+                * We can safely check z_all_znodes for being empty because the
+                * VFS has already blocked operations which add to it.
                 */
                int round = 0;
-               while (zfsvfs->z_nr_znodes > 0) {
+               while (!list_is_empty(&zfsvfs->z_all_znodes)) {
                        taskq_wait_outstanding(dsl_pool_zrele_taskq(
                            dmu_objset_pool(zfsvfs->z_os)), 0);
                        if (++round > 1 && !unmounting)
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 c4f2b722ef4e..0d4c94555c6b 100644
--- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
+++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
@@ -537,7 +537,6 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
 
        mutex_enter(&zfsvfs->z_znodes_lock);
        list_insert_tail(&zfsvfs->z_all_znodes, zp);
-       zfsvfs->z_nr_znodes++;
        zp->z_zfsvfs = zfsvfs;
        mutex_exit(&zfsvfs->z_znodes_lock);
 
@@ -1286,7 +1285,6 @@ zfs_znode_free(znode_t *zp)
        mutex_enter(&zfsvfs->z_znodes_lock);
        POINTER_INVALIDATE(&zp->z_zfsvfs);
        list_remove(&zfsvfs->z_all_znodes, zp);
-       zfsvfs->z_nr_znodes--;
        mutex_exit(&zfsvfs->z_znodes_lock);
 
 #if __FreeBSD_version >= 1300139
diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c 
b/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c
index 01f5619e1893..f0f929d3ce90 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c
@@ -47,6 +47,10 @@ static unsigned long table_min = 0;
 static unsigned long table_max = ~0;
 
 static struct ctl_table_header *spl_header = NULL;
+#ifndef HAVE_REGISTER_SYSCTL_TABLE
+static struct ctl_table_header *spl_kmem = NULL;
+static struct ctl_table_header *spl_kstat = NULL;
+#endif
 static struct proc_dir_entry *proc_spl = NULL;
 static struct proc_dir_entry *proc_spl_kmem = NULL;
 static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
@@ -624,6 +628,7 @@ static struct ctl_table spl_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dohostid,
        },
+#ifdef HAVE_REGISTER_SYSCTL_TABLE
        {
                .procname       = "kmem",
                .mode           = 0555,
@@ -634,9 +639,11 @@ static struct ctl_table spl_table[] = {
                .mode           = 0555,
                .child          = spl_kstat_table,
        },
+#endif
        {},
 };
 
+#ifdef HAVE_REGISTER_SYSCTL_TABLE
 static struct ctl_table spl_dir[] = {
        {
                .procname       = "spl",
@@ -648,21 +655,64 @@ static struct ctl_table spl_dir[] = {
 
 static struct ctl_table spl_root[] = {
        {
-       .procname = "kernel",
-       .mode = 0555,
-       .child = spl_dir,
+               .procname       = "kernel",
+               .mode           = 0555,
+               .child          = spl_dir,
        },
        {}
 };
+#endif
+
+static void spl_proc_cleanup(void)
+{
+       remove_proc_entry("kstat", proc_spl);
+       remove_proc_entry("slab", proc_spl_kmem);
+       remove_proc_entry("kmem", proc_spl);
+       remove_proc_entry("taskq-all", proc_spl);
+       remove_proc_entry("taskq", proc_spl);
+       remove_proc_entry("spl", NULL);
+
+#ifndef HAVE_REGISTER_SYSCTL_TABLE
+       if (spl_kstat) {
+               unregister_sysctl_table(spl_kstat);
+               spl_kstat = NULL;
+       }
+       if (spl_kmem) {
+               unregister_sysctl_table(spl_kmem);
+               spl_kmem = NULL;
+       }
+#endif
+       if (spl_header) {
+               unregister_sysctl_table(spl_header);
+               spl_header = NULL;
+       }
+}
 
 int
 spl_proc_init(void)
 {
        int rc = 0;
 
+#ifdef HAVE_REGISTER_SYSCTL_TABLE
        spl_header = register_sysctl_table(spl_root);
        if (spl_header == NULL)
                return (-EUNATCH);
+#else
+       spl_header = register_sysctl("kernel/spl", spl_table);
+       if (spl_header == NULL)
+               return (-EUNATCH);
+
+       spl_kmem = register_sysctl("kernel/spl/kmem", spl_kmem_table);
+       if (spl_kmem == NULL) {
+               rc = -EUNATCH;
+               goto out;
+       }
+       spl_kstat = register_sysctl("kernel/spl/kstat", spl_kstat_table);
+       if (spl_kstat == NULL) {
+               rc = -EUNATCH;
+               goto out;
+       }
+#endif
 
        proc_spl = proc_mkdir("spl", NULL);
        if (proc_spl == NULL) {
@@ -703,15 +753,8 @@ spl_proc_init(void)
                goto out;
        }
 out:
-       if (rc) {
-               remove_proc_entry("kstat", proc_spl);
-               remove_proc_entry("slab", proc_spl_kmem);
-               remove_proc_entry("kmem", proc_spl);
-               remove_proc_entry("taskq-all", proc_spl);
-               remove_proc_entry("taskq", proc_spl);
-               remove_proc_entry("spl", NULL);
-               unregister_sysctl_table(spl_header);
-       }
+       if (rc)
+               spl_proc_cleanup();
 
        return (rc);
 }
@@ -719,13 +762,5 @@ out:
 void
 spl_proc_fini(void)
 {
-       remove_proc_entry("kstat", proc_spl);
-       remove_proc_entry("slab", proc_spl_kmem);
-       remove_proc_entry("kmem", proc_spl);
-       remove_proc_entry("taskq-all", proc_spl);
-       remove_proc_entry("taskq", proc_spl);
-       remove_proc_entry("spl", NULL);
-
-       ASSERT(spl_header != NULL);
-       unregister_sysctl_table(spl_header);
+       spl_proc_cleanup();
 }
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 925ee9d9fe9c..48ac55f07034 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
@@ -80,9 +80,22 @@ typedef struct dio_request {
 
 static unsigned int zfs_vdev_failfast_mask = 1;
 
+#ifdef HAVE_BLK_MODE_T
+static blk_mode_t
+#else
 static fmode_t
+#endif
 vdev_bdev_mode(spa_mode_t spa_mode)
 {
+#ifdef HAVE_BLK_MODE_T
+       blk_mode_t mode = 0;
+
+       if (spa_mode & SPA_MODE_READ)
+               mode |= BLK_OPEN_READ;
+
+       if (spa_mode & SPA_MODE_WRITE)
+               mode |= BLK_OPEN_WRITE;
+#else
        fmode_t mode = 0;
 
        if (spa_mode & SPA_MODE_READ)
@@ -90,6 +103,7 @@ vdev_bdev_mode(spa_mode_t spa_mode)
 
        if (spa_mode & SPA_MODE_WRITE)
                mode |= FMODE_WRITE;
+#endif
 
        return (mode);
 }
@@ -197,12 +211,47 @@ vdev_disk_kobj_evt_post(vdev_t *v)
        }
 }
 
+#if !defined(HAVE_BLKDEV_GET_BY_PATH_4ARG)
+/*
+ * Define a dummy struct blk_holder_ops for kernel versions
+ * prior to 6.5.
+ */
+struct blk_holder_ops {};
+#endif
+
+static struct block_device *
+vdev_blkdev_get_by_path(const char *path, spa_mode_t mode, void *holder,
+    const struct blk_holder_ops *hops)
+{
+#ifdef HAVE_BLKDEV_GET_BY_PATH_4ARG
+       return (blkdev_get_by_path(path,
+           vdev_bdev_mode(mode) | BLK_OPEN_EXCL, holder, hops));
+#else
+       return (blkdev_get_by_path(path,
+           vdev_bdev_mode(mode) | FMODE_EXCL, holder));
+#endif
+}
+
+static void
+vdev_blkdev_put(struct block_device *bdev, spa_mode_t mode, void *holder)
+{
+#ifdef HAVE_BLKDEV_PUT_HOLDER
+       return (blkdev_put(bdev, holder));
+#else
+       return (blkdev_put(bdev, vdev_bdev_mode(mode) | FMODE_EXCL));
+#endif
+}
+
 static int
 vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
     uint64_t *logical_ashift, uint64_t *physical_ashift)
 {
        struct block_device *bdev;
+#ifdef HAVE_BLK_MODE_T
+       blk_mode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa));
+#else
        fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa));
+#endif
        hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms);
        vdev_disk_t *vd;
 
@@ -252,15 +301,15 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t 
*max_psize,
                                        reread_part = B_TRUE;
                        }
 
-                       blkdev_put(bdev, mode | FMODE_EXCL);
+                       vdev_blkdev_put(bdev, mode, zfs_vdev_holder);
                }
 
                if (reread_part) {
-                       bdev = blkdev_get_by_path(disk_name, mode | FMODE_EXCL,
-                           zfs_vdev_holder);
+                       bdev = vdev_blkdev_get_by_path(disk_name, mode,
+                           zfs_vdev_holder, NULL);
                        if (!IS_ERR(bdev)) {
                                int error = vdev_bdev_reread_part(bdev);
-                               blkdev_put(bdev, mode | FMODE_EXCL);
+                               vdev_blkdev_put(bdev, mode, zfs_vdev_holder);
                                if (error == 0) {
                                        timeout = MSEC2NSEC(
                                            zfs_vdev_open_timeout_ms * 2);
@@ -305,8 +354,8 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t 
*max_psize,
        hrtime_t start = gethrtime();
        bdev = ERR_PTR(-ENXIO);
        while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) {
-               bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL,
-                   zfs_vdev_holder);
+               bdev = vdev_blkdev_get_by_path(v->vdev_path, mode,
+                   zfs_vdev_holder, NULL);
                if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
                        /*
                         * There is no point of waiting since device is removed
@@ -382,8 +431,8 @@ vdev_disk_close(vdev_t *v)
                return;
 
        if (vd->vd_bdev != NULL) {
-               blkdev_put(vd->vd_bdev,
-                   vdev_bdev_mode(spa_mode(v->vdev_spa)) | FMODE_EXCL);
+               vdev_blkdev_put(vd->vd_bdev, spa_mode(v->vdev_spa),
+                   zfs_vdev_holder);
        }
 
        rw_destroy(&vd->vd_lock);
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 c45a3eb5a4eb..02cb379ea840 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ctldir.c
@@ -537,7 +537,6 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
 
        mutex_enter(&zfsvfs->z_znodes_lock);
        list_insert_tail(&zfsvfs->z_all_znodes, zp);
-       zfsvfs->z_nr_znodes++;
        membar_producer();
        mutex_exit(&zfsvfs->z_znodes_lock);
 
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 464c12e1108d..a1db5c57c18b 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vfsops.c
@@ -1330,12 +1330,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
                 * may add the parents of dir-based xattrs to the taskq
                 * so we want to wait for these.
                 *
-                * We can safely read z_nr_znodes without locking because the
-                * VFS has already blocked operations which add to the
-                * z_all_znodes list and thus increment z_nr_znodes.
+                * We can safely check z_all_znodes for being empty because the
+                * VFS has already blocked operations which add to it.
                 */
                int round = 0;
-               while (zfsvfs->z_nr_znodes > 0) {
+               while (!list_is_empty(&zfsvfs->z_all_znodes)) {
                        taskq_wait_outstanding(dsl_pool_zrele_taskq(
                            dmu_objset_pool(zfsvfs->z_os)), 0);
                        if (++round > 1 && !unmounting)
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 234c4d5ef0e0..33baac9db06b 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
@@ -186,7 +186,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr)
                return (error);
 
        /* Honor ZFS_APPENDONLY file attribute */
-       if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) &&
+       if (blk_mode_is_open_write(mode) && (zp->z_pflags & ZFS_APPENDONLY) &&
            ((flag & O_APPEND) == 0)) {
                zfs_exit(zfsvfs, FTAG);
                return (SET_ERROR(EPERM));
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 335ae3460c58..52c8e51df659 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_znode.c
@@ -390,7 +390,6 @@ zfs_inode_destroy(struct inode *ip)
        mutex_enter(&zfsvfs->z_znodes_lock);
        if (list_link_active(&zp->z_link_node)) {
                list_remove(&zfsvfs->z_all_znodes, zp);
-               zfsvfs->z_nr_znodes--;
        }
        mutex_exit(&zfsvfs->z_znodes_lock);
 
@@ -641,7 +640,6 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
 
        mutex_enter(&zfsvfs->z_znodes_lock);
        list_insert_tail(&zfsvfs->z_all_znodes, zp);
-       zfsvfs->z_nr_znodes++;
        mutex_exit(&zfsvfs->z_znodes_lock);
 
        if (links > 0)
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 68a7de78f471..7786444fea35 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_ctldir.c
@@ -42,7 +42,7 @@
 static int
 zpl_common_open(struct inode *ip, struct file *filp)
 {
-       if (filp->f_mode & FMODE_WRITE)
+       if (blk_mode_is_open_write(filp->f_mode))
                return (-EACCES);
 
        return (generic_file_open(ip, filp));
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 73526db731c4..3caa0fc6c214 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c
@@ -301,15 +301,10 @@ zpl_uio_init(zfs_uio_t *uio, struct kiocb *kiocb, struct 
iov_iter *to,
 #if defined(HAVE_VFS_IOV_ITER)
        zfs_uio_iov_iter_init(uio, to, pos, count, skip);
 #else
-#ifdef HAVE_IOV_ITER_TYPE
-       zfs_uio_iovec_init(uio, to->iov, to->nr_segs, pos,
-           iov_iter_type(to) & ITER_KVEC ? UIO_SYSSPACE : UIO_USERSPACE,
+       zfs_uio_iovec_init(uio, zfs_uio_iter_iov(to), to->nr_segs, pos,
+           zfs_uio_iov_iter_type(to) & ITER_KVEC ?
+           UIO_SYSSPACE : UIO_USERSPACE,
            count, skip);
-#else
-       zfs_uio_iovec_init(uio, to->iov, to->nr_segs, pos,
-           to->type & ITER_KVEC ? UIO_SYSSPACE : UIO_USERSPACE,
-           count, skip);
-#endif
 #endif
 }
 
@@ -1328,7 +1323,11 @@ const struct file_operations zpl_file_operations = {
        .read_iter      = zpl_iter_read,
        .write_iter     = zpl_iter_write,
 #ifdef HAVE_VFS_IOV_ITER
+#ifdef HAVE_COPY_SPLICE_READ
+       .splice_read    = copy_splice_read,
+#else
        .splice_read    = generic_file_splice_read,
+#endif
        .splice_write   = iter_file_splice_write,
 #endif
 #else
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 38bc8e2c4eeb..7a95b54bdf0d 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -671,7 +671,11 @@ zvol_request(struct request_queue *q, struct bio *bio)
 }
 
 static int
+#ifdef HAVE_BLK_MODE_T
+zvol_open(struct gendisk *disk, blk_mode_t flag)
+#else
 zvol_open(struct block_device *bdev, fmode_t flag)
+#endif
 {
        zvol_state_t *zv;
        int error = 0;
@@ -686,10 +690,14 @@ retry:
        /*
         * Obtain a copy of private_data under the zvol_state_lock to make
         * sure that either the result of zvol free code path setting
-        * bdev->bd_disk->private_data to NULL is observed, or zvol_os_free()
+        * disk->private_data to NULL is observed, or zvol_os_free()
         * is not called on this zv because of the positive zv_open_count.
         */
+#ifdef HAVE_BLK_MODE_T
+       zv = disk->private_data;
+#else
        zv = bdev->bd_disk->private_data;
+#endif
        if (zv == NULL) {
                rw_exit(&zvol_state_lock);
                return (SET_ERROR(-ENXIO));
@@ -769,14 +777,15 @@ retry:
                        }
                }
 
-               error = -zvol_first_open(zv, !(flag & FMODE_WRITE));
+               error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag)));
 
                if (drop_namespace)
                        mutex_exit(&spa_namespace_lock);
        }
 
        if (error == 0) {
-               if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
+               if ((blk_mode_is_open_write(flag)) &&
+                   (zv->zv_flags & ZVOL_RDONLY)) {
                        if (zv->zv_open_count == 0)
*** 204 LINES SKIPPED ***

Reply via email to