aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2024-09-09 20:40:58 +0000
committerMartin Matuska <mm@FreeBSD.org>2024-09-09 20:41:36 +0000
commit755e773877e9f3abab3bed2d46d9d87978e303d9 (patch)
tree5f07bd5f47715d8c5e67886938f7177530284718
parent65c70eb58bbe81b1b191cf82d0a36b9ba280b5e7 (diff)
parentbaa50314567afd986a00838f0fa65fdacbd12daf (diff)
zfs: merge openzfs/zfs@33174af15 (zfs-2.2-release) into stable/14
OpenZFS release 2.2.6 Notable upstream pull request merges: #15557 bce36e21c module/icp/asm-arm/sha2: auto detect __ARM_ARCH #15623 2ca151537 module/icp/asm-arm/sha2: enable non-SIMD asm kernels on armv5/6 #16308 ac6500389 zfs: add bounds checking to zil_parse #16316 859f906a4 Fix null ptr deref when renaming a zvol with snaps and snapdev=visible #16343 cd42e992b Enable L2 cache of all (MRU+MFU) metadata but MFU data only #16382 3a36797ad FreeBSD: Fix RLIMIT_FSIZE handling for block cloning Obtained from: OpenZFS OpenZFS commit: 33174af15112ed5c53299da2d28e763b0163f428 OpenZFS tag: zfs-2.2.6
-rw-r--r--sys/contrib/openzfs/META4
-rw-r--r--sys/contrib/openzfs/config/kernel-blk-queue.m428
-rw-r--r--sys/contrib/openzfs/config/kernel-make-request-fn.m421
-rw-r--r--sys/contrib/openzfs/config/kernel-mm-page-size.m417
-rw-r--r--sys/contrib/openzfs/config/kernel-mm-pagemap.m436
-rw-r--r--sys/contrib/openzfs/config/kernel-register_sysctl_table.m459
-rw-r--r--sys/contrib/openzfs/config/kernel.m46
-rw-r--r--sys/contrib/openzfs/contrib/bash_completion.d/.gitignore1
-rw-r--r--sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am12
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h35
-rw-r--r--sys/contrib/openzfs/include/os/linux/kernel/linux/mm_compat.h7
-rw-r--r--sys/contrib/openzfs/man/man4/zfs.414
-rw-r--r--sys/contrib/openzfs/module/Kbuild.in4
-rw-r--r--sys/contrib/openzfs/module/icp/algs/sha2/sha256_impl.c22
-rw-r--r--sys/contrib/openzfs/module/icp/algs/sha2/sha512_impl.c19
-rw-r--r--sys/contrib/openzfs/module/icp/asm-arm/sha2/sha256-armv7.S11
-rw-r--r--sys/contrib/openzfs/module/icp/asm-arm/sha2/sha512-armv7.S11
-rw-r--r--sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c7
-rw-r--r--sys/contrib/openzfs/module/os/linux/spl/spl-proc.c53
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c1
-rw-r--r--sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c99
-rw-r--r--sys/contrib/openzfs/module/zfs/arc.c11
-rw-r--r--sys/contrib/openzfs/module/zfs/dataset_kstats.c3
-rw-r--r--sys/contrib/openzfs/module/zfs/zil.c21
-rw-r--r--sys/contrib/openzfs/rpm/generic/zfs-kmod.spec.in18
-rw-r--r--sys/contrib/openzfs/rpm/generic/zfs.spec.in1
-rw-r--r--sys/contrib/openzfs/tests/runfiles/common.run3
-rwxr-xr-xsys/contrib/openzfs/tests/test-runner/bin/zts-report.py.in2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am1
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/alloc_class/alloc_class.kshlib2
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/block_cloning/block_cloning_rlimit_fsize.ksh64
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_copies/zfs_copies.kshlib2
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_resume_single.ksh2
-rw-r--r--sys/contrib/openzfs/tests/zfs-tests/tests/functional/history/history.cfg6
-rwxr-xr-xsys/contrib/openzfs/tests/zfs-tests/tests/functional/io/io_uring.ksh6
-rw-r--r--sys/modules/zfs/zfs_config.h16
-rw-r--r--sys/modules/zfs/zfs_gitrev.h2
37 files changed, 499 insertions, 128 deletions
diff --git a/sys/contrib/openzfs/META b/sys/contrib/openzfs/META
index 14cfc5f00a41..40376428ba95 100644
--- a/sys/contrib/openzfs/META
+++ b/sys/contrib/openzfs/META
@@ -1,10 +1,10 @@
Meta: 1
Name: zfs
Branch: 1.0
-Version: 2.2.5
+Version: 2.2.6
Release: 1
Release-Tags: relext
License: CDDL
Author: OpenZFS
-Linux-Maximum: 6.9
+Linux-Maximum: 6.10
Linux-Minimum: 3.10
diff --git a/sys/contrib/openzfs/config/kernel-blk-queue.m4 b/sys/contrib/openzfs/config/kernel-blk-queue.m4
index 2f0b386e6637..a064140f337a 100644
--- a/sys/contrib/openzfs/config/kernel-blk-queue.m4
+++ b/sys/contrib/openzfs/config/kernel-blk-queue.m4
@@ -25,6 +25,8 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [
dnl #
dnl # 2.6.32 - 4.11: statically allocated bdi in request_queue
dnl # 4.12: dynamically allocated bdi in request_queue
+dnl # 6.11: bdi no longer available through request_queue, so get it from
+dnl # the gendisk attached to the queue
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [
ZFS_LINUX_TEST_SRC([blk_queue_bdi], [
@@ -47,6 +49,30 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [
])
])
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISK_BDI], [
+ ZFS_LINUX_TEST_SRC([blk_queue_disk_bdi], [
+ #include <linux/blkdev.h>
+ #include <linux/backing-dev.h>
+ ], [
+ struct request_queue q;
+ struct gendisk disk;
+ struct backing_dev_info bdi __attribute__ ((unused));
+ q.disk = &disk;
+ q.disk->bdi = &bdi;
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISK_BDI], [
+ AC_MSG_CHECKING([whether backing_dev_info is available through queue gendisk])
+ ZFS_LINUX_TEST_RESULT([blk_queue_disk_bdi], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_DISK_BDI, 1,
+ [backing_dev_info is available through queue gendisk])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
dnl #
dnl # 5.9: added blk_queue_update_readahead(),
dnl # 5.15: renamed to disk_update_readahead()
@@ -407,6 +433,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_MQ], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG
ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
+ ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISK_BDI
ZFS_AC_KERNEL_SRC_BLK_QUEUE_UPDATE_READAHEAD
ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
@@ -421,6 +448,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [
ZFS_AC_KERNEL_BLK_QUEUE_PLUG
ZFS_AC_KERNEL_BLK_QUEUE_BDI
+ ZFS_AC_KERNEL_BLK_QUEUE_DISK_BDI
ZFS_AC_KERNEL_BLK_QUEUE_UPDATE_READAHEAD
ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
diff --git a/sys/contrib/openzfs/config/kernel-make-request-fn.m4 b/sys/contrib/openzfs/config/kernel-make-request-fn.m4
index 9813ad2fb3f3..4c54bdd6d4a2 100644
--- a/sys/contrib/openzfs/config/kernel-make-request-fn.m4
+++ b/sys/contrib/openzfs/config/kernel-make-request-fn.m4
@@ -58,6 +58,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
disk = blk_alloc_disk(lim, NUMA_NO_NODE);
])
+ ZFS_LINUX_TEST_SRC([blkdev_queue_limits_features], [
+ #include <linux/blkdev.h>
+ ],[
+ struct queue_limits *lim = NULL;
+ lim->features = 0;
+ ])
+
ZFS_LINUX_TEST_SRC([blk_cleanup_disk], [
#include <linux/blkdev.h>
],[
@@ -115,6 +122,20 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
AC_DEFINE([HAVE_BLK_ALLOC_DISK_2ARG], 1, [blk_alloc_disk() exists and takes 2 args])
dnl #
+ dnl # Linux 6.11 API change:
+ dnl # struct queue_limits gains a 'features' field,
+ dnl # used to set flushing options
+ dnl #
+ AC_MSG_CHECKING([whether struct queue_limits has a features field])
+ ZFS_LINUX_TEST_RESULT([blkdev_queue_limits_features], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([HAVE_BLKDEV_QUEUE_LIMITS_FEATURES], 1,
+ [struct queue_limits has a features field])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+
+ dnl #
dnl # 5.20 API change,
dnl # Removed blk_cleanup_disk(), put_disk() should be used.
dnl #
diff --git a/sys/contrib/openzfs/config/kernel-mm-page-size.m4 b/sys/contrib/openzfs/config/kernel-mm-page-size.m4
deleted file mode 100644
index d5ebd926986a..000000000000
--- a/sys/contrib/openzfs/config/kernel-mm-page-size.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE], [
- ZFS_LINUX_TEST_SRC([page_size], [
- #include <linux/mm.h>
- ],[
- unsigned long s;
- s = page_size(NULL);
- ])
-])
-AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_SIZE], [
- AC_MSG_CHECKING([whether page_size() is available])
- ZFS_LINUX_TEST_RESULT([page_size], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_MM_PAGE_SIZE, 1, [page_size() is available])
- ],[
- AC_MSG_RESULT(no)
- ])
-])
diff --git a/sys/contrib/openzfs/config/kernel-mm-pagemap.m4 b/sys/contrib/openzfs/config/kernel-mm-pagemap.m4
new file mode 100644
index 000000000000..466b6fa07d9a
--- /dev/null
+++ b/sys/contrib/openzfs/config/kernel-mm-pagemap.m4
@@ -0,0 +1,36 @@
+AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE], [
+ ZFS_LINUX_TEST_SRC([page_size], [
+ #include <linux/mm.h>
+ ],[
+ unsigned long s;
+ s = page_size(NULL);
+ ])
+])
+AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_SIZE], [
+ AC_MSG_CHECKING([whether page_size() is available])
+ ZFS_LINUX_TEST_RESULT([page_size], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_MM_PAGE_SIZE, 1, [page_size() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
+
+AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING], [
+ ZFS_LINUX_TEST_SRC([page_mapping], [
+ #include <linux/pagemap.h>
+ ],[
+ struct page *p = NULL;
+ struct address_space *m = page_mapping(NULL);
+ ])
+])
+AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_MAPPING], [
+ AC_MSG_CHECKING([whether page_mapping() is available])
+ ZFS_LINUX_TEST_RESULT([page_mapping], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_MM_PAGE_MAPPING, 1, [page_mapping() is available])
+ ],[
+ 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
index a5e934f56d29..12ffe9d95142 100644
--- a/sys/contrib/openzfs/config/kernel-register_sysctl_table.m4
+++ b/sys/contrib/openzfs/config/kernel-register_sysctl_table.m4
@@ -25,3 +25,62 @@ AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE], [
AC_MSG_RESULT([no])
])
])
+
+dnl #
+dnl # Linux 6.11 register_sysctl() enforces that sysctl tables no longer
+dnl # supply a sentinel end-of-table element. 6.6 introduces
+dnl # register_sysctl_sz() to enable callers to choose, so we use it if
+dnl # available for backward compatibility.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ], [
+ ZFS_LINUX_TEST_SRC([has_register_sysctl_sz], [
+ #include <linux/sysctl.h>
+ ],[
+ struct ctl_table test_table[] __attribute__((unused)) = {0};
+ register_sysctl_sz("", test_table, 0);
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_SZ], [
+ AC_MSG_CHECKING([whether register_sysctl_sz exists])
+ ZFS_LINUX_TEST_RESULT([has_register_sysctl_sz], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_REGISTER_SYSCTL_SZ, 1,
+ [register_sysctl_sz exists])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+])
+
+dnl #
+dnl # Linux 6.11 makes const the ctl_table arg of proc_handler
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_PROC_HANDLER_CTL_TABLE_CONST], [
+ ZFS_LINUX_TEST_SRC([has_proc_handler_ctl_table_const], [
+ #include <linux/sysctl.h>
+
+ static int test_handler(
+ const struct ctl_table *ctl __attribute((unused)),
+ int write __attribute((unused)),
+ void *buffer __attribute((unused)),
+ size_t *lenp __attribute((unused)),
+ loff_t *ppos __attribute((unused)))
+ {
+ return (0);
+ }
+ ], [
+ proc_handler *ph __attribute((unused)) =
+ &test_handler;
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_PROC_HANDLER_CTL_TABLE_CONST], [
+ AC_MSG_CHECKING([whether proc_handler ctl_table arg is const])
+ ZFS_LINUX_TEST_RESULT([has_proc_handler_ctl_table_const], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_PROC_HANDLER_CTL_TABLE_CONST, 1,
+ [proc_handler ctl_table arg is const])
+ ], [
+ AC_MSG_RESULT([no])
+ ])
+])
diff --git a/sys/contrib/openzfs/config/kernel.m4 b/sys/contrib/openzfs/config/kernel.m4
index b51477b6a951..f0cd76fd7325 100644
--- a/sys/contrib/openzfs/config/kernel.m4
+++ b/sys/contrib/openzfs/config/kernel.m4
@@ -166,9 +166,12 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_WRITEPAGE_T
ZFS_AC_KERNEL_SRC_RECLAIMED
ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE
+ ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ
+ ZFS_AC_KERNEL_SRC_PROC_HANDLER_CTL_TABLE_CONST
ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ
ZFS_AC_KERNEL_SRC_SYNC_BDEV
ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE
+ ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING
case "$host_cpu" in
powerpc*)
ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE
@@ -317,9 +320,12 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_WRITEPAGE_T
ZFS_AC_KERNEL_RECLAIMED
ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE
+ ZFS_AC_KERNEL_REGISTER_SYSCTL_SZ
+ ZFS_AC_KERNEL_PROC_HANDLER_CTL_TABLE_CONST
ZFS_AC_KERNEL_COPY_SPLICE_READ
ZFS_AC_KERNEL_SYNC_BDEV
ZFS_AC_KERNEL_MM_PAGE_SIZE
+ ZFS_AC_KERNEL_MM_PAGE_MAPPING
case "$host_cpu" in
powerpc*)
ZFS_AC_KERNEL_CPU_HAS_FEATURE
diff --git a/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore b/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore
index 0fd9cc63af2a..217893a6bd89 100644
--- a/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore
+++ b/sys/contrib/openzfs/contrib/bash_completion.d/.gitignore
@@ -1 +1,2 @@
/zfs
+/zpool
diff --git a/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am b/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am
index 1ec05ed73d2d..d3e6c0e79071 100644
--- a/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am
+++ b/sys/contrib/openzfs/contrib/bash_completion.d/Makefile.am
@@ -1,5 +1,9 @@
-nodist_bashcompletion_DATA = %D%/zfs
-SUBSTFILES += $(nodist_bashcompletion_DATA)
+nodist_bashcompletion_DATA = %D%/zfs %D%/zpool
+COMPLETION_FILES = %D%/zfs
+SUBSTFILES += $(COMPLETION_FILES)
-SHELLCHECKSCRIPTS += $(nodist_bashcompletion_DATA)
-$(call SHELLCHECK_OPTS,$(nodist_bashcompletion_DATA)): SHELLCHECK_SHELL = bash
+SHELLCHECKSCRIPTS += $(COMPLETION_FILES)
+$(call SHELLCHECK_OPTS,$(COMPLETION_FILES)): SHELLCHECK_SHELL = bash
+
+%D%/zpool: %D%/zfs
+ $(LN_S) zfs $@
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 b0f398354e4f..6154c4a86331 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
@@ -57,6 +57,11 @@ blk_queue_flag_clear(unsigned int flag, struct request_queue *q)
#endif
/*
+ * 6.11 API
+ * Setting the flush flags directly is no longer possible; flush flags are set
+ * on the queue_limits structure and passed to blk_disk_alloc(). In this case
+ * we remove this function entirely.
+ *
* 4.7 API,
* The blk_queue_write_cache() interface has replaced blk_queue_flush()
* interface. However, the new interface is GPL-only thus we implement
@@ -68,39 +73,43 @@ blk_queue_flag_clear(unsigned int flag, struct request_queue *q)
* new one is GPL-only. Thus if the GPL-only version is detected we
* implement our own trivial helper.
*/
+#if !defined(HAVE_BLK_ALLOC_DISK_2ARG) || \
+ !defined(HAVE_BLKDEV_QUEUE_LIMITS_FEATURES)
static inline void
-blk_queue_set_write_cache(struct request_queue *q, bool wc, bool fua)
+blk_queue_set_write_cache(struct request_queue *q, bool on)
{
#if defined(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY)
- if (wc)
+ if (on) {
blk_queue_flag_set(QUEUE_FLAG_WC, q);
- else
- blk_queue_flag_clear(QUEUE_FLAG_WC, q);
- if (fua)
blk_queue_flag_set(QUEUE_FLAG_FUA, q);
- else
+ } else {
+ blk_queue_flag_clear(QUEUE_FLAG_WC, q);
blk_queue_flag_clear(QUEUE_FLAG_FUA, q);
+ }
#elif defined(HAVE_BLK_QUEUE_WRITE_CACHE)
- blk_queue_write_cache(q, wc, fua);
+ blk_queue_write_cache(q, on, on);
#elif defined(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY)
- if (wc)
- q->flush_flags |= REQ_FLUSH;
- if (fua)
- q->flush_flags |= REQ_FUA;
+ if (on)
+ q->flush_flags |= REQ_FLUSH | REQ_FUA;
+ else
+ q->flush_flags &= ~(REQ_FLUSH | REQ_FUA);
#elif defined(HAVE_BLK_QUEUE_FLUSH)
- blk_queue_flush(q, (wc ? REQ_FLUSH : 0) | (fua ? REQ_FUA : 0));
+ blk_queue_flush(q, on ? (REQ_FLUSH | REQ_FUA) : 0);
#else
#error "Unsupported kernel"
#endif
}
+#endif /* !HAVE_BLK_ALLOC_DISK_2ARG || !HAVE_BLKDEV_QUEUE_LIMITS_FEATURES */
static inline void
blk_queue_set_read_ahead(struct request_queue *q, unsigned long ra_pages)
{
#if !defined(HAVE_BLK_QUEUE_UPDATE_READAHEAD) && \
!defined(HAVE_DISK_UPDATE_READAHEAD)
-#ifdef HAVE_BLK_QUEUE_BDI_DYNAMIC
+#if defined(HAVE_BLK_QUEUE_BDI_DYNAMIC)
q->backing_dev_info->ra_pages = ra_pages;
+#elif defined(HAVE_BLK_QUEUE_DISK_BDI)
+ q->disk->bdi->ra_pages = ra_pages;
#else
q->backing_dev_info.ra_pages = ra_pages;
#endif
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/mm_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/mm_compat.h
index 40056c68d6dd..817f6df422de 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/mm_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/mm_compat.h
@@ -21,16 +21,23 @@
/*
* Copyright (c) 2023, 2024, Klara Inc.
+ * Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
*/
#ifndef _ZFS_MM_COMPAT_H
#define _ZFS_MM_COMPAT_H
#include <linux/mm.h>
+#include <linux/pagemap.h>
/* 5.4 introduced page_size(). Older kernels can use a trivial macro instead */
#ifndef HAVE_MM_PAGE_SIZE
#define page_size(p) ((unsigned long)(PAGE_SIZE << compound_order(p)))
#endif
+/* 6.11 removed page_mapping(). A simple wrapper around folio_mapping() works */
+#ifndef HAVE_MM_PAGE_MAPPING
+#define page_mapping(p) folio_mapping(page_folio(p))
+#endif
+
#endif /* _ZFS_MM_COMPAT_H */
diff --git a/sys/contrib/openzfs/man/man4/zfs.4 b/sys/contrib/openzfs/man/man4/zfs.4
index 717cf8e6eae8..c17bfb80bf09 100644
--- a/sys/contrib/openzfs/man/man4/zfs.4
+++ b/sys/contrib/openzfs/man/man4/zfs.4
@@ -121,20 +121,26 @@ Controls whether buffers present on special vdevs are eligible for caching
into L2ARC.
If set to 1, exclude dbufs on special vdevs from being cached to L2ARC.
.
-.It Sy l2arc_mfuonly Ns = Ns Sy 0 Ns | Ns 1 Pq int
+.It Sy l2arc_mfuonly Ns = Ns Sy 0 Ns | Ns 1 Ns | Ns 2 Pq int
Controls whether only MFU metadata and data are cached from ARC into L2ARC.
This may be desired to avoid wasting space on L2ARC when reading/writing large
amounts of data that are not expected to be accessed more than once.
.Pp
-The default is off,
+The default is 0,
meaning both MRU and MFU data and metadata are cached.
-When turning off this feature, some MRU buffers will still be present
-in ARC and eventually cached on L2ARC.
+When turning off this feature (setting it to 0), some MRU buffers will
+still be present in ARC and eventually cached on L2ARC.
.No If Sy l2arc_noprefetch Ns = Ns Sy 0 ,
some prefetched buffers will be cached to L2ARC, and those might later
transition to MRU, in which case the
.Sy l2arc_mru_asize No arcstat will not be Sy 0 .
.Pp
+Setting it to 1 means to L2 cache only MFU data and metadata.
+.Pp
+Setting it to 2 means to L2 cache all metadata (MRU+MFU) but
+only MFU data (ie: MRU data are not cached). This can be the right setting
+to cache as much metadata as possible even when having high data turnover.
+.Pp
Regardless of
.Sy l2arc_noprefetch ,
some MFU buffers might be evicted from ARC,
diff --git a/sys/contrib/openzfs/module/Kbuild.in b/sys/contrib/openzfs/module/Kbuild.in
index 87bd17cf5a6d..3d980819291c 100644
--- a/sys/contrib/openzfs/module/Kbuild.in
+++ b/sys/contrib/openzfs/module/Kbuild.in
@@ -16,8 +16,8 @@ src = @abs_srcdir@
obj = @abs_builddir@
else
zfs_include = $(srctree)/include/zfs
-icp_include = $(srctree)/$(src)/icp/include
-zstd_include = $(srctree)/$(src)/zstd/include
+icp_include = $(src)/icp/include
+zstd_include = $(src)/zstd/include
ZFS_MODULE_CFLAGS += -include $(zfs_include)/zfs_config.h
endif
diff --git a/sys/contrib/openzfs/module/icp/algs/sha2/sha256_impl.c b/sys/contrib/openzfs/module/icp/algs/sha2/sha256_impl.c
index 01ce5cbd814c..0f24319511d7 100644
--- a/sys/contrib/openzfs/module/icp/algs/sha2/sha256_impl.c
+++ b/sys/contrib/openzfs/module/icp/algs/sha2/sha256_impl.c
@@ -118,7 +118,15 @@ const sha256_ops_t sha256_shani_impl = {
};
#endif
-#elif defined(__aarch64__) || (defined(__arm__) && __ARM_ARCH > 6)
+#elif defined(__aarch64__) || defined(__arm__)
+extern void zfs_sha256_block_armv7(uint32_t s[8], const void *, size_t);
+const sha256_ops_t sha256_armv7_impl = {
+ .is_supported = sha2_is_supported,
+ .transform = zfs_sha256_block_armv7,
+ .name = "armv7"
+};
+
+#if __ARM_ARCH > 6
static boolean_t sha256_have_neon(void)
{
return (kfpu_allowed() && zfs_neon_available());
@@ -129,13 +137,6 @@ static boolean_t sha256_have_armv8ce(void)
return (kfpu_allowed() && zfs_sha256_available());
}
-extern void zfs_sha256_block_armv7(uint32_t s[8], const void *, size_t);
-const sha256_ops_t sha256_armv7_impl = {
- .is_supported = sha2_is_supported,
- .transform = zfs_sha256_block_armv7,
- .name = "armv7"
-};
-
TF(zfs_sha256_block_neon, tf_sha256_neon);
const sha256_ops_t sha256_neon_impl = {
.is_supported = sha256_have_neon,
@@ -149,6 +150,7 @@ const sha256_ops_t sha256_armv8_impl = {
.transform = tf_sha256_armv8ce,
.name = "armv8-ce"
};
+#endif
#elif defined(__PPC64__)
static boolean_t sha256_have_isa207(void)
@@ -192,11 +194,13 @@ static const sha256_ops_t *const sha256_impls[] = {
#if defined(__x86_64) && defined(HAVE_SSE4_1)
&sha256_shani_impl,
#endif
-#if defined(__aarch64__) || (defined(__arm__) && __ARM_ARCH > 6)
+#if defined(__aarch64__) || defined(__arm__)
&sha256_armv7_impl,
+#if __ARM_ARCH > 6
&sha256_neon_impl,
&sha256_armv8_impl,
#endif
+#endif
#if defined(__PPC64__)
&sha256_ppc_impl,
&sha256_power8_impl,
diff --git a/sys/contrib/openzfs/module/icp/algs/sha2/sha512_impl.c b/sys/contrib/openzfs/module/icp/algs/sha2/sha512_impl.c
index 27b35a639a54..6291fbd77e36 100644
--- a/sys/contrib/openzfs/module/icp/algs/sha2/sha512_impl.c
+++ b/sys/contrib/openzfs/module/icp/algs/sha2/sha512_impl.c
@@ -88,7 +88,7 @@ const sha512_ops_t sha512_avx2_impl = {
};
#endif
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) || defined(__arm__)
extern void zfs_sha512_block_armv7(uint64_t s[8], const void *, size_t);
const sha512_ops_t sha512_armv7_impl = {
.is_supported = sha2_is_supported,
@@ -96,6 +96,7 @@ const sha512_ops_t sha512_armv7_impl = {
.name = "armv7"
};
+#if defined(__aarch64__)
static boolean_t sha512_have_armv8ce(void)
{
return (kfpu_allowed() && zfs_sha512_available());
@@ -107,15 +108,9 @@ const sha512_ops_t sha512_armv8_impl = {
.transform = tf_sha512_armv8ce,
.name = "armv8-ce"
};
+#endif
-#elif defined(__arm__) && __ARM_ARCH > 6
-extern void zfs_sha512_block_armv7(uint64_t s[8], const void *, size_t);
-const sha512_ops_t sha512_armv7_impl = {
- .is_supported = sha2_is_supported,
- .transform = zfs_sha512_block_armv7,
- .name = "armv7"
-};
-
+#if defined(__arm__) && __ARM_ARCH > 6
static boolean_t sha512_have_neon(void)
{
return (kfpu_allowed() && zfs_neon_available());
@@ -127,6 +122,7 @@ const sha512_ops_t sha512_neon_impl = {
.transform = tf_sha512_neon,
.name = "neon"
};
+#endif
#elif defined(__PPC64__)
TF(zfs_sha512_ppc, tf_sha512_ppc);
@@ -164,14 +160,15 @@ static const sha512_ops_t *const sha512_impls[] = {
#if defined(__x86_64) && defined(HAVE_AVX2)
&sha512_avx2_impl,
#endif
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__arm__)
&sha512_armv7_impl,
+#if defined(__aarch64__)
&sha512_armv8_impl,
#endif
#if defined(__arm__) && __ARM_ARCH > 6
- &sha512_armv7_impl,
&sha512_neon_impl,
#endif
+#endif
#if defined(__PPC64__)
&sha512_ppc_impl,
&sha512_power8_impl,
diff --git a/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha256-armv7.S b/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha256-armv7.S
index 0001e4d69055..3ae66626df31 100644
--- a/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha256-armv7.S
+++ b/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha256-armv7.S
@@ -21,8 +21,11 @@
#if defined(__arm__)
-#define __ARM_ARCH__ 7
-#define __ARM_MAX_ARCH__ 7
+#ifndef __ARM_ARCH
+# define __ARM_ARCH__ 7
+#else
+# define __ARM_ARCH__ __ARM_ARCH
+#endif
#if defined(__thumb2__)
.syntax unified
@@ -1834,6 +1837,7 @@ zfs_sha256_block_armv7:
#endif
.size zfs_sha256_block_armv7,.-zfs_sha256_block_armv7
+#if __ARM_ARCH__ >= 7
.arch armv7-a
.fpu neon
@@ -2766,4 +2770,5 @@ zfs_sha256_block_armv8:
bx lr @ bx lr
.size zfs_sha256_block_armv8,.-zfs_sha256_block_armv8
-#endif
+#endif // #if __ARM_ARCH__ >= 7
+#endif // #if defined(__arm__)
diff --git a/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha512-armv7.S b/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha512-armv7.S
index a4c804033b92..66d7dd3cf0f7 100644
--- a/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha512-armv7.S
+++ b/sys/contrib/openzfs/module/icp/asm-arm/sha2/sha512-armv7.S
@@ -21,8 +21,11 @@
#if defined(__arm__)
-#define __ARM_ARCH__ 7
-#define __ARM_MAX_ARCH__ 7
+#ifndef __ARM_ARCH
+# define __ARM_ARCH__ 7
+#else
+# define __ARM_ARCH__ __ARM_ARCH
+#endif
#ifndef __KERNEL__
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
@@ -490,6 +493,7 @@ zfs_sha512_block_armv7:
#endif
.size zfs_sha512_block_armv7,.-zfs_sha512_block_armv7
+#if __ARM_ARCH__ >= 7
.arch armv7-a
.fpu neon
@@ -1819,4 +1823,5 @@ zfs_sha512_block_neon:
VFP_ABI_POP
bx lr @ .word 0xe12fff1e
.size zfs_sha512_block_neon,.-zfs_sha512_block_neon
-#endif
+#endif // #if __ARM_ARCH__ >= 7
+#endif // #if defined(__arm__)
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 0655142dcea3..715b0ee6419c 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
@@ -6270,7 +6270,6 @@ zfs_freebsd_copy_file_range(struct vop_copy_file_range_args *ap)
struct vnode *invp = ap->a_invp;
struct vnode *outvp = ap->a_outvp;
struct mount *mp;
- struct uio io;
int error;
uint64_t len = *ap->a_lenp;
@@ -6318,12 +6317,6 @@ zfs_freebsd_copy_file_range(struct vop_copy_file_range_args *ap)
goto out_locked;
#endif
- io.uio_offset = *ap->a_outoffp;
- io.uio_resid = *ap->a_lenp;
- error = vn_rlimit_fsize(outvp, &io, ap->a_fsizetd);
- if (error != 0)
- goto out_locked;
-
error = zfs_clone_range(VTOZ(invp), ap->a_inoffp, VTOZ(outvp),
ap->a_outoffp, &len, ap->a_outcred);
if (error == EXDEV || error == EAGAIN || error == EINVAL ||
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 f0f929d3ce90..2c0cdd9febf5 100644
--- a/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c
+++ b/sys/contrib/openzfs/module/os/linux/spl/spl-proc.c
@@ -22,6 +22,9 @@
*
* Solaris Porting Layer (SPL) Proc Implementation.
*/
+/*
+ * Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
+ */
#include <sys/systeminfo.h>
#include <sys/kstat.h>
@@ -43,6 +46,12 @@ typedef struct ctl_table __no_const spl_ctl_table;
typedef struct ctl_table spl_ctl_table;
#endif
+#ifdef HAVE_PROC_HANDLER_CTL_TABLE_CONST
+#define CONST_CTL_TABLE const struct ctl_table
+#else
+#define CONST_CTL_TABLE struct ctl_table
+#endif
+
static unsigned long table_min = 0;
static unsigned long table_max = ~0;
@@ -60,7 +69,7 @@ struct proc_dir_entry *proc_spl_kstat = NULL;
#ifdef DEBUG_KMEM
static int
-proc_domemused(struct ctl_table *table, int write,
+proc_domemused(CONST_CTL_TABLE *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc = 0;
@@ -88,7 +97,7 @@ proc_domemused(struct ctl_table *table, int write,
#endif /* DEBUG_KMEM */
static int
-proc_doslab(struct ctl_table *table, int write,
+proc_doslab(CONST_CTL_TABLE *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc = 0;
@@ -135,7 +144,7 @@ proc_doslab(struct ctl_table *table, int write,
}
static int
-proc_dohostid(struct ctl_table *table, int write,
+proc_dohostid(CONST_CTL_TABLE *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
char *end, str[32];
@@ -688,6 +697,37 @@ static void spl_proc_cleanup(void)
}
}
+#ifndef HAVE_REGISTER_SYSCTL_TABLE
+
+/*
+ * Traditionally, struct ctl_table arrays have been terminated by an "empty"
+ * sentinel element (specifically, one with .procname == NULL).
+ *
+ * Linux 6.6 began migrating away from this, adding register_sysctl_sz() so
+ * that callers could provide the size directly, and redefining
+ * register_sysctl() to just call register_sysctl_sz() with the array size. It
+ * retained support for the terminating element so that existing callers would
+ * continue to work.
+ *
+ * Linux 6.11 removed support for the terminating element, instead interpreting
+ * it as a real malformed element, and rejecting it.
+ *
+ * In order to continue support older kernels, we retain the terminating
+ * sentinel element for our sysctl tables, but instead detect availability of
+ * register_sysctl_sz(). If it exists, we pass it the array size -1, stopping
+ * the kernel from trying to process the terminator. For pre-6.6 kernels that
+ * don't have register_sysctl_sz(), we just use register_sysctl(), which can
+ * handle the terminating element as it always has.
+ */
+#ifdef HAVE_REGISTER_SYSCTL_SZ
+#define spl_proc_register_sysctl(p, t) \
+ register_sysctl_sz(p, t, ARRAY_SIZE(t)-1)
+#else
+#define spl_proc_register_sysctl(p, t) \
+ register_sysctl(p, t)
+#endif
+#endif
+
int
spl_proc_init(void)
{
@@ -698,16 +738,17 @@ spl_proc_init(void)
if (spl_header == NULL)
return (-EUNATCH);
#else
- spl_header = register_sysctl("kernel/spl", spl_table);
+ spl_header = spl_proc_register_sysctl("kernel/spl", spl_table);
if (spl_header == NULL)
return (-EUNATCH);
- spl_kmem = register_sysctl("kernel/spl/kmem", spl_kmem_table);
+ spl_kmem = spl_proc_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);
+ spl_kstat = spl_proc_register_sysctl("kernel/spl/kstat",
+ spl_kstat_table);
if (spl_kstat == NULL) {
rc = -EUNATCH;
goto out;
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 be528f6e8176..fb871ed8cef6 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
@@ -69,6 +69,7 @@
#include <sys/zpl.h>
#include <sys/zil.h>
#include <sys/sa_impl.h>
+#include <linux/mm_compat.h>
/*
* Programming rules.
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 129e3606bb8d..928a222f1505 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2012, 2020 by Delphix. All rights reserved.
+ * Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
*/
#include <sys/dataset_kstats.h>
@@ -730,7 +731,7 @@ retry:
#endif
if (zv == NULL) {
rw_exit(&zvol_state_lock);
- return (SET_ERROR(-ENXIO));
+ return (-SET_ERROR(ENXIO));
}
mutex_enter(&zv->zv_state_lock);
@@ -794,10 +795,10 @@ retry:
#ifdef HAVE_BLKDEV_GET_ERESTARTSYS
schedule();
- return (SET_ERROR(-ERESTARTSYS));
+ return (-SET_ERROR(ERESTARTSYS));
#else
if ((gethrtime() - start) > timeout)
- return (SET_ERROR(-ERESTARTSYS));
+ return (-SET_ERROR(ERESTARTSYS));
schedule_timeout(MSEC_TO_TICK(10));
goto retry;
@@ -819,7 +820,7 @@ retry:
if (zv->zv_open_count == 0)
zvol_last_close(zv);
- error = SET_ERROR(-EROFS);
+ error = -SET_ERROR(EROFS);
} else {
zv->zv_open_count++;
}
@@ -1074,11 +1075,42 @@ static const struct block_device_operations zvol_ops = {
#endif
};
+/*
+ * Since 6.9, Linux has been removing queue limit setters in favour of an
+ * initial queue_limits struct applied when the device is open. Since 6.11,
+ * queue_limits is being extended to allow more things to be applied when the
+ * device is open. Setters are also being removed for this.
+ *
+ * For OpenZFS, this means that depending on kernel version, some options may
+ * be set up before the device is open, and some applied to an open device
+ * (queue) after the fact.
+ *
+ * We manage this complexity by having our own limits struct,
+ * zvol_queue_limits_t, in which we carry any queue config that we're
+ * interested in setting. This structure is the same on all kernels.
+ *
+ * These limits are then applied to the queue at device open time by the most
+ * appropriate method for the kernel.
+ *
+ * zvol_queue_limits_convert() is used on 6.9+ (where the two-arg form of
+ * blk_alloc_disk() exists). This converts our limits struct to a proper Linux
+ * struct queue_limits, and passes it in. Any fields added in later kernels are
+ * (obviously) not set up here.
+ *
+ * zvol_queue_limits_apply() is called on all kernel versions after the queue
+ * is created, and applies any remaining config. Before 6.9 that will be
+ * everything, via setter methods. After 6.9 that will be whatever couldn't be
+ * put into struct queue_limits. (This implies that zvol_queue_limits_apply()
+ * will always be a no-op on the latest kernel we support).
+ */
typedef struct zvol_queue_limits {
unsigned int zql_max_hw_sectors;
unsigned short zql_max_segments;
unsigned int zql_max_segment_size;
unsigned int zql_io_opt;
+ unsigned int zql_physical_block_size;
+ unsigned int zql_max_discard_sectors;
+ unsigned int zql_discard_granularity;
} zvol_queue_limits_t;
static void
@@ -1147,6 +1179,11 @@ zvol_queue_limits_init(zvol_queue_limits_t *limits, zvol_state_t *zv,
}
limits->zql_io_opt = zv->zv_volblocksize;
+
+ limits->zql_physical_block_size = zv->zv_volblocksize;
+ limits->zql_max_discard_sectors =
+ (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9;
+ limits->zql_discard_granularity = zv->zv_volblocksize;
}
#ifdef HAVE_BLK_ALLOC_DISK_2ARG
@@ -1159,18 +1196,35 @@ zvol_queue_limits_convert(zvol_queue_limits_t *limits,
qlimits->max_segments = limits->zql_max_segments;
qlimits->max_segment_size = limits->zql_max_segment_size;
qlimits->io_opt = limits->zql_io_opt;
+ qlimits->physical_block_size = limits->zql_physical_block_size;
+ qlimits->max_discard_sectors = limits->zql_max_discard_sectors;
+ qlimits->max_hw_discard_sectors = limits->zql_max_discard_sectors;
+ qlimits->discard_granularity = limits->zql_discard_granularity;
+#ifdef HAVE_BLKDEV_QUEUE_LIMITS_FEATURES
+ qlimits->features =
+ BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA | BLK_FEAT_IO_STAT;
+#endif
}
-#else
+#endif
+
static void
zvol_queue_limits_apply(zvol_queue_limits_t *limits,
struct request_queue *queue)
{
+#ifndef HAVE_BLK_ALLOC_DISK_2ARG
blk_queue_max_hw_sectors(queue, limits->zql_max_hw_sectors);
blk_queue_max_segments(queue, limits->zql_max_segments);
blk_queue_max_segment_size(queue, limits->zql_max_segment_size);
blk_queue_io_opt(queue, limits->zql_io_opt);
-}
+ blk_queue_physical_block_size(queue, limits->zql_physical_block_size);
+ blk_queue_max_discard_sectors(queue, limits->zql_max_discard_sectors);
+ blk_queue_discard_granularity(queue, limits->zql_discard_granularity);
+#endif
+#ifndef HAVE_BLKDEV_QUEUE_LIMITS_FEATURES
+ blk_queue_set_write_cache(queue, B_TRUE);
+ blk_queue_flag_set(QUEUE_FLAG_IO_STAT, queue);
#endif
+}
static int
zvol_alloc_non_blk_mq(struct zvol_state_os *zso, zvol_queue_limits_t *limits)
@@ -1183,7 +1237,6 @@ zvol_alloc_non_blk_mq(struct zvol_state_os *zso, zvol_queue_limits_t *limits)
zso->zvo_disk->minors = ZVOL_MINORS;
zso->zvo_queue = zso->zvo_disk->queue;
- zvol_queue_limits_apply(limits, zso->zvo_queue);
#elif defined(HAVE_BLK_ALLOC_DISK_2ARG)
struct queue_limits qlimits;
zvol_queue_limits_convert(limits, &qlimits);
@@ -1196,6 +1249,7 @@ zvol_alloc_non_blk_mq(struct zvol_state_os *zso, zvol_queue_limits_t *limits)
zso->zvo_disk = disk;
zso->zvo_disk->minors = ZVOL_MINORS;
zso->zvo_queue = zso->zvo_disk->queue;
+
#else
zso->zvo_queue = blk_alloc_queue(NUMA_NO_NODE);
if (zso->zvo_queue == NULL)
@@ -1208,7 +1262,6 @@ zvol_alloc_non_blk_mq(struct zvol_state_os *zso, zvol_queue_limits_t *limits)
}
zso->zvo_disk->queue = zso->zvo_queue;
- zvol_queue_limits_apply(limits, zso->zvo_queue);
#endif /* HAVE_BLK_ALLOC_DISK */
#else
zso->zvo_queue = blk_generic_alloc_queue(zvol_request, NUMA_NO_NODE);
@@ -1222,8 +1275,10 @@ zvol_alloc_non_blk_mq(struct zvol_state_os *zso, zvol_queue_limits_t *limits)
}
zso->zvo_disk->queue = zso->zvo_queue;
- zvol_queue_limits_apply(limits, zso->zvo_queue);
#endif /* HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS */
+
+ zvol_queue_limits_apply(limits, zso->zvo_queue);
+
return (0);
}
@@ -1245,7 +1300,6 @@ zvol_alloc_blk_mq(zvol_state_t *zv, zvol_queue_limits_t *limits)
return (1);
}
zso->zvo_queue = zso->zvo_disk->queue;
- zvol_queue_limits_apply(limits, zso->zvo_queue);
zso->zvo_disk->minors = ZVOL_MINORS;
#elif defined(HAVE_BLK_ALLOC_DISK_2ARG)
struct queue_limits qlimits;
@@ -1276,10 +1330,11 @@ zvol_alloc_blk_mq(zvol_state_t *zv, zvol_queue_limits_t *limits)
/* Our queue is now created, assign it to our disk */
zso->zvo_disk->queue = zso->zvo_queue;
- zvol_queue_limits_apply(limits, zso->zvo_queue);
-
#endif
+
+ zvol_queue_limits_apply(limits, zso->zvo_queue);
#endif
+
return (0);
}
@@ -1288,7 +1343,7 @@ zvol_alloc_blk_mq(zvol_state_t *zv, zvol_queue_limits_t *limits)
* request queue and generic disk structures for the block device.
*/
static zvol_state_t *
-zvol_alloc(dev_t dev, const char *name)
+zvol_alloc(dev_t dev, const char *name, uint64_t volblocksize)
{
zvol_state_t *zv;
struct zvol_state_os *zso;
@@ -1308,6 +1363,7 @@ zvol_alloc(dev_t dev, const char *name)
zso = kmem_zalloc(sizeof (struct zvol_state_os), KM_SLEEP);
zv->zv_zso = zso;
zv->zv_volmode = volmode;
+ zv->zv_volblocksize = volblocksize;
list_link_init(&zv->zv_next);
mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL);
@@ -1344,8 +1400,6 @@ zvol_alloc(dev_t dev, const char *name)
if (ret != 0)
goto out_kmem;
- blk_queue_set_write_cache(zso->zvo_queue, B_TRUE, B_TRUE);
-
/* Limit read-ahead to a single page to prevent over-prefetching. */
blk_queue_set_read_ahead(zso->zvo_queue, 1);
@@ -1354,9 +1408,6 @@ zvol_alloc(dev_t dev, const char *name)
blk_queue_flag_set(QUEUE_FLAG_NOMERGES, zso->zvo_queue);
}
- /* Enable /proc/diskstats */
- blk_queue_flag_set(QUEUE_FLAG_IO_STAT, zso->zvo_queue);
-
zso->zvo_queue->queuedata = zv;
zso->zvo_dev = dev;
zv->zv_open_count = 0;
@@ -1599,7 +1650,8 @@ zvol_os_create_minor(const char *name)
if (error)
goto out_dmu_objset_disown;
- zv = zvol_alloc(MKDEV(zvol_major, minor), name);
+ zv = zvol_alloc(MKDEV(zvol_major, minor), name,
+ doi->doi_data_block_size);
if (zv == NULL) {
error = SET_ERROR(EAGAIN);
goto out_dmu_objset_disown;
@@ -1609,20 +1661,11 @@ zvol_os_create_minor(const char *name)
if (dmu_objset_is_snapshot(os))
zv->zv_flags |= ZVOL_RDONLY;
- zv->zv_volblocksize = doi->doi_data_block_size;
zv->zv_volsize = volsize;
zv->zv_objset = os;
set_capacity(zv->zv_zso->zvo_disk, zv->zv_volsize >> 9);
-
-
- blk_queue_physical_block_size(zv->zv_zso->zvo_queue,
- zv->zv_volblocksize);
- blk_queue_max_discard_sectors(zv->zv_zso->zvo_queue,
- (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);
- blk_queue_discard_granularity(zv->zv_zso->zvo_queue,
- zv->zv_volblocksize);
#ifdef QUEUE_FLAG_DISCARD
blk_queue_flag_set(QUEUE_FLAG_DISCARD, zv->zv_zso->zvo_queue);
#endif
diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c
index f25afa312cb4..d7ee9d32a75b 100644
--- a/sys/contrib/openzfs/module/zfs/arc.c
+++ b/sys/contrib/openzfs/module/zfs/arc.c
@@ -9055,12 +9055,17 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
*/
for (int pass = 0; pass < L2ARC_FEED_TYPES; pass++) {
/*
- * If pass == 1 or 3, we cache MRU metadata and data
- * respectively.
+ * pass == 0: MFU meta
+ * pass == 1: MRU meta
+ * pass == 2: MFU data
+ * pass == 3: MRU data
*/
- if (l2arc_mfuonly) {
+ if (l2arc_mfuonly == 1) {
if (pass == 1 || pass == 3)
continue;
+ } else if (l2arc_mfuonly > 1) {
+ if (pass == 3)
+ continue;
}
uint64_t passed_sz = 0;
diff --git a/sys/contrib/openzfs/module/zfs/dataset_kstats.c b/sys/contrib/openzfs/module/zfs/dataset_kstats.c
index 2ac058fd2c93..5abee12434e9 100644
--- a/sys/contrib/openzfs/module/zfs/dataset_kstats.c
+++ b/sys/contrib/openzfs/module/zfs/dataset_kstats.c
@@ -201,6 +201,9 @@ dataset_kstats_destroy(dataset_kstats_t *dk)
void
dataset_kstats_rename(dataset_kstats_t *dk, const char *name)
{
+ if (dk->dk_kstats == NULL)
+ return;
+
dataset_kstat_values_t *dkv = dk->dk_kstats->ks_data;
char *ds_name;
diff --git a/sys/contrib/openzfs/module/zfs/zil.c b/sys/contrib/openzfs/module/zfs/zil.c
index 9b5d866a8c22..9293429e43c7 100644
--- a/sys/contrib/openzfs/module/zfs/zil.c
+++ b/sys/contrib/openzfs/module/zfs/zil.c
@@ -513,9 +513,26 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
for (; lrp < end; lrp += reclen) {
lr_t *lr = (lr_t *)lrp;
+
+ /*
+ * Are the remaining bytes large enough to hold an
+ * log record?
+ */
+ if ((char *)(lr + 1) > end) {
+ cmn_err(CE_WARN, "zil_parse: lr_t overrun");
+ error = SET_ERROR(ECKSUM);
+ arc_buf_destroy(abuf, &abuf);
+ goto done;
+ }
reclen = lr->lrc_reclen;
- ASSERT3U(reclen, >=, sizeof (lr_t));
- ASSERT3U(reclen, <=, end - lrp);
+ if (reclen < sizeof (lr_t) || reclen > end - lrp) {
+ cmn_err(CE_WARN,
+ "zil_parse: lr_t has an invalid reclen");
+ error = SET_ERROR(ECKSUM);
+ arc_buf_destroy(abuf, &abuf);
+ goto done;
+ }
+
if (lr->lrc_seq > claim_lr_seq) {
arc_buf_destroy(abuf, &abuf);
goto done;
diff --git a/sys/contrib/openzfs/rpm/generic/zfs-kmod.spec.in b/sys/contrib/openzfs/rpm/generic/zfs-kmod.spec.in
index 4cc075585d4b..30524474d1ac 100644
--- a/sys/contrib/openzfs/rpm/generic/zfs-kmod.spec.in
+++ b/sys/contrib/openzfs/rpm/generic/zfs-kmod.spec.in
@@ -145,6 +145,24 @@ for kernel_version in %{?kernel_versions}; do
%{?kernel_cc} \
%{?kernel_ld} \
%{?kernel_llvm}
+
+ # Pre-6.10 kernel builds didn't need to copy over the source files to the
+ # build directory. However we do need to do it though post-6.10 due to
+ # these commits:
+ #
+ # b1992c3772e6 kbuild: use $(src) instead of $(srctree)/$(src) for source
+ # directory
+ #
+ # 9a0ebe5011f4 kbuild: use $(obj)/ instead of $(src)/ for common pattern
+ # rules
+ #
+ # Note that kmodtool actually copies over the source into the build
+ # directory, so what we're doing here is normal. For efficiency reasons
+ # though we just use hardlinks instead of copying.
+ #
+ # See https://github.com/openzfs/zfs/issues/16439 for more info.
+ cp -lR ../%{module}-%{version}/module/* module/
+
make %{?_smp_mflags}
cd ..
done
diff --git a/sys/contrib/openzfs/rpm/generic/zfs.spec.in b/sys/contrib/openzfs/rpm/generic/zfs.spec.in
index 2e89abd0edfd..c7a00c61f6bb 100644
--- a/sys/contrib/openzfs/rpm/generic/zfs.spec.in
+++ b/sys/contrib/openzfs/rpm/generic/zfs.spec.in
@@ -532,6 +532,7 @@ systemctl --system daemon-reload >/dev/null || true
%attr(440, root, root) %config(noreplace) %{_sysconfdir}/sudoers.d/*
%config(noreplace) %{_bashcompletiondir}/zfs
+%config(noreplace) %{_bashcompletiondir}/zpool
%files -n libzpool5
%{_libdir}/libzpool.so.*
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index 3e1a3aeb6cbe..f302df81b919 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -81,7 +81,8 @@ tests = ['block_cloning_clone_mmap_cached',
'block_cloning_cross_enc_dataset',
'block_cloning_copyfilerange_fallback_same_txg',
'block_cloning_replay', 'block_cloning_replay_encrypted',
- 'block_cloning_lwb_buffer_overflow', 'block_cloning_clone_mmap_write']
+ 'block_cloning_lwb_buffer_overflow', 'block_cloning_clone_mmap_write',
+ 'block_cloning_rlimit_fsize']
tags = ['functional', 'block_cloning']
[tests/functional/bootfs]
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 de06c7c6e2c1..3370f9b4e350 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
@@ -330,6 +330,8 @@ elif sys.platform.startswith('linux'):
['SKIP', cfr_reason],
'block_cloning/block_cloning_replay_encrypted':
['SKIP', cfr_reason],
+ 'block_cloning/block_cloning_rlimit_fsize':
+ ['SKIP', cfr_reason],
'cli_root/zfs_rename/zfs_rename_002_pos': ['FAIL', known_reason],
'cli_root/zpool_reopen/zpool_reopen_003_pos': ['FAIL', known_reason],
'cp_files/cp_files_002_pos': ['SKIP', cfr_reason],
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
index b8eed952b90e..a896a21093ca 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am
@@ -478,6 +478,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/block_cloning/block_cloning_replay.ksh \
functional/block_cloning/block_cloning_replay_encrypted.ksh \
functional/block_cloning/block_cloning_lwb_buffer_overflow.ksh \
+ functional/block_cloning/block_cloning_rlimit_fsize.ksh \
functional/bootfs/bootfs_001_pos.ksh \
functional/bootfs/bootfs_002_neg.ksh \
functional/bootfs/bootfs_003_pos.ksh \
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/alloc_class/alloc_class.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/alloc_class/alloc_class.kshlib
index e204f43b3bcd..795e71b26b5a 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/alloc_class/alloc_class.kshlib
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/alloc_class/alloc_class.kshlib
@@ -55,7 +55,7 @@ function display_status
((ret |= $?))
typeset mntpnt=$(get_prop mountpoint $pool)
- dd if=/dev/random of=$mntpnt/testfile.$$ &
+ dd if=/dev/urandom of=$mntpnt/testfile.$$ &
typeset pid=$!
zpool iostat -v 1 3 > /dev/null
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/block_cloning/block_cloning_rlimit_fsize.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/block_cloning/block_cloning_rlimit_fsize.ksh
new file mode 100755
index 000000000000..3632fc9a4df0
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/block_cloning/block_cloning_rlimit_fsize.ksh
@@ -0,0 +1,64 @@
+#!/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
+. $STF_SUITE/tests/functional/block_cloning/block_cloning.kshlib
+
+#
+# DESCRIPTION:
+# When block cloning is used to implement copy_file_range(2), the
+# RLIMIT_FSIZE limit must be respected.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. ???
+#
+
+verify_runnable "global"
+
+VDIR=$TEST_BASE_DIR/disk-bclone
+VDEV="$VDIR/a"
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ rm -rf $VDIR
+}
+
+log_onexit cleanup
+
+log_assert "Test for RLIMIT_FSIZE handling with block cloning enabled"
+
+log_must rm -rf $VDIR
+log_must mkdir -p $VDIR
+log_must truncate -s 1G $VDEV
+
+log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $VDEV
+
+log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=1 count=1000
+
+ulimit -f 2
+log_must clonefile -f /$TESTPOOL/file1 /$TESTPOOL/file2 0 0 all
+ulimit -f 1
+log_mustnot clonefile -f /$TESTPOOL/file1 /$TESTPOOL/file3 0 0 all
+
+log_pass "copy_file_range(2) respects RLIMIT_FSIZE"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_copies/zfs_copies.kshlib b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_copies/zfs_copies.kshlib
index 9911ccdf536d..a7a93a3046d2 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_copies/zfs_copies.kshlib
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_copies/zfs_copies.kshlib
@@ -153,5 +153,7 @@ function do_vol_test
log_must umount $mntp
fi
+ # Ubuntu 20.04 wants a sync here
+ log_must sync
log_must zfs destroy $vol
}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_resume_single.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_resume_single.ksh
index 041dadb1eadb..05f3ac708477 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_resume_single.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/fault/suspend_resume_single.ksh
@@ -42,7 +42,7 @@ log_onexit cleanup
log_assert "ensure single-disk pool resumes properly after suspend and clear"
# create a file, and take a checksum, so we can compare later
-log_must dd if=/dev/random of=$DATAFILE bs=128K count=1
+log_must dd if=/dev/urandom of=$DATAFILE bs=128K count=1
typeset sum1=$(cat $DATAFILE | md5sum)
# make a debug device that we can "unplug"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/history/history.cfg b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/history/history.cfg
index a508a7935684..6020443bcdb0 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/history/history.cfg
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/history/history.cfg
@@ -37,11 +37,7 @@ export TMP_HISTORY=$TEST_BASE_DIR/tmp_history.$$
export NEW_HISTORY=$TEST_BASE_DIR/new_history.$$
export MIGRATEDPOOLNAME=${MIGRATEDPOOLNAME:-history_pool}
-if is_freebsd; then
- export TIMEZONE=${TIMEZONE:-America/Denver}
-else
- export TIMEZONE=${TIMEZONE:-US/Mountain}
-fi
+export TIMEZONE=${TIMEZONE:-America/Denver}
export HIST_USER="huser"
export HIST_GROUP="hgroup"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/io/io_uring.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/io/io_uring.ksh
index 2fa146556358..f14b9f450826 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/io/io_uring.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/io/io_uring.ksh
@@ -41,13 +41,13 @@ verify_runnable "global"
if ! $(grep -q "CONFIG_IO_URING=y" /boot/config-$(uname -r)); then
- log_unsupported "Requires io_uring support"
+ log_unsupported "Requires io_uring support within Kernel"
fi
if [ -e /etc/os-release ] ; then
source /etc/os-release
- if [ -n "$REDHAT_SUPPORT_PRODUCT_VERSION" ] && ((floor($REDHAT_SUPPORT_PRODUCT_VERSION) == 9)) ; then
- log_unsupported "Disabled on CentOS 9, fails with 'Operation not permitted'"
+ if [ $PLATFORM_ID = "platform:el9" ]; then
+ log_unsupported "Disabled on RHEL 9 variants: fails with 'Operation not permitted'"
fi
fi
diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h
index af6633ec205e..6f1ec6dd8d83 100644
--- a/sys/modules/zfs/zfs_config.h
+++ b/sys/modules/zfs/zfs_config.h
@@ -228,6 +228,9 @@
/* blk_queue_discard() is available */
/* #undef HAVE_BLK_QUEUE_DISCARD */
+/* backing_dev_info is available through queue gendisk */
+/* #undef HAVE_BLK_QUEUE_DISK_BDI */
+
/* blk_queue_flag_clear() exists */
/* #undef HAVE_BLK_QUEUE_FLAG_CLEAR */
@@ -700,6 +703,9 @@
/* Define to 1 if you have the 'mlockall' function. */
#define HAVE_MLOCKALL 1
+/* page_mapping() is available */
+/* #undef HAVE_MM_PAGE_MAPPING */
+
/* page_size() is available */
/* #undef HAVE_MM_PAGE_SIZE */
@@ -745,6 +751,9 @@
/* posix_acl_valid() wants user namespace */
/* #undef HAVE_POSIX_ACL_VALID_WITH_NS */
+/* proc_handler ctl_table arg is const */
+/* #undef HAVE_PROC_HANDLER_CTL_TABLE_CONST */
+
/* proc_ops structure exists */
/* #undef HAVE_PROC_OPS_STRUCT */
@@ -769,6 +778,9 @@
/* register_shrinker is vararg */
/* #undef HAVE_REGISTER_SHRINKER_VARARG */
+/* register_sysctl_sz exists */
+/* #undef HAVE_REGISTER_SYSCTL_SZ */
+
/* register_sysctl_table exists */
/* #undef HAVE_REGISTER_SYSCTL_TABLE */
@@ -1197,7 +1209,7 @@
/* #undef ZFS_IS_GPL_COMPATIBLE */
/* Define the project alias string. */
-#define ZFS_META_ALIAS "zfs-2.2.5-FreeBSD_g33174af15"
+#define ZFS_META_ALIAS "zfs-2.2.6-FreeBSD_g33174af15"
/* Define the project author. */
#define ZFS_META_AUTHOR "OpenZFS"
@@ -1230,7 +1242,7 @@
#define ZFS_META_RELEASE "FreeBSD_g33174af15"
/* Define the project version. */
-#define ZFS_META_VERSION "2.2.5"
+#define ZFS_META_VERSION "2.2.6"
/* count is located in percpu_ref.data */
/* #undef ZFS_PERCPU_REF_COUNT_IN_DATA */
diff --git a/sys/modules/zfs/zfs_gitrev.h b/sys/modules/zfs/zfs_gitrev.h
index dd06a2d01985..ba3f91705173 100644
--- a/sys/modules/zfs/zfs_gitrev.h
+++ b/sys/modules/zfs/zfs_gitrev.h
@@ -1 +1 @@
-#define ZFS_META_GITREV "zfs-2.2.5-0-g33174af15"
+#define ZFS_META_GITREV "zfs-2.2.6-0-gbaa503145"