summarylogtreecommitdiffstats
path: root/linux-6.8-compat.patch
diff options
context:
space:
mode:
Diffstat (limited to 'linux-6.8-compat.patch')
-rw-r--r--linux-6.8-compat.patch130
1 files changed, 130 insertions, 0 deletions
diff --git a/linux-6.8-compat.patch b/linux-6.8-compat.patch
new file mode 100644
index 000000000000..0214c3b651a2
--- /dev/null
+++ b/linux-6.8-compat.patch
@@ -0,0 +1,130 @@
+From a24f6e17c8cf75b5f551eb43019d41747c08891f Mon Sep 17 00:00:00 2001
+From: Rob Norris <robn@despairlabs.com>
+Date: Sat, 24 Feb 2024 14:24:42 +1100
+Subject: [PATCH] Linux 6.8 compat: use splice_copy_file_range() for fallback
+
+Linux 6.8 removes generic_copy_file_range(), which had been reduced to a
+simple wrapper around splice_copy_file_range(). Detect that function
+directly and use it if generic_ is not available.
+
+Signed-off-by: Rob Norris <robn@despairlabs.com>
+Sponsored-by: https://despairlabs.com/sponsor/
+---
+ config/kernel-vfs-file_range.m4 | 27 +++++++++++++++++++++++++++
+ config/kernel.m4 | 2 ++
+ module/os/linux/zfs/zpl_file_range.c | 16 ++++++++++++++--
+ 3 files changed, 43 insertions(+), 2 deletions(-)
+
+diff --git a/config/kernel-vfs-file_range.m4 b/config/kernel-vfs-file_range.m4
+index cc96404d8bbe..8a5cbe2eeeed 100644
+--- a/config/kernel-vfs-file_range.m4
++++ b/config/kernel-vfs-file_range.m4
+@@ -16,6 +16,9 @@ dnl #
+ dnl # 5.3: VFS copy_file_range() expected to do its own fallback,
+ dnl # generic_copy_file_range() added to support it
+ dnl #
++dnl # 6.8: generic_copy_file_range() removed, replaced by
++dnl # splice_copy_file_range()
++dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE], [
+ ZFS_LINUX_TEST_SRC([vfs_copy_file_range], [
+ #include <linux/fs.h>
+@@ -72,6 +75,30 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE], [
+ ])
+ ])
+
++AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_SPLICE_COPY_FILE_RANGE], [
++ ZFS_LINUX_TEST_SRC([splice_copy_file_range], [
++ #include <linux/splice.h>
++ ], [
++ struct file *src_file __attribute__ ((unused)) = NULL;
++ loff_t src_off __attribute__ ((unused)) = 0;
++ struct file *dst_file __attribute__ ((unused)) = NULL;
++ loff_t dst_off __attribute__ ((unused)) = 0;
++ size_t len __attribute__ ((unused)) = 0;
++ splice_copy_file_range(src_file, src_off, dst_file, dst_off,
++ len);
++ ])
++])
++AC_DEFUN([ZFS_AC_KERNEL_VFS_SPLICE_COPY_FILE_RANGE], [
++ AC_MSG_CHECKING([whether splice_copy_file_range() is available])
++ ZFS_LINUX_TEST_RESULT([splice_copy_file_range], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_VFS_SPLICE_COPY_FILE_RANGE, 1,
++ [splice_copy_file_range() is available])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
++])
++
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE], [
+ ZFS_LINUX_TEST_SRC([vfs_clone_file_range], [
+ #include <linux/fs.h>
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index e3f8645774c5..1d0c5a27fc7f 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -118,6 +118,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
+ ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE
+ ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE
++ ZFS_AC_KERNEL_SRC_VFS_SPLICE_COPY_FILE_RANGE
+ ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE
+ ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE
+ ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE
+@@ -266,6 +267,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ ZFS_AC_KERNEL_VFS_IOV_ITER
+ ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE
+ ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE
++ ZFS_AC_KERNEL_VFS_SPLICE_COPY_FILE_RANGE
+ ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE
+ ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE
+ ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE
+diff --git a/module/os/linux/zfs/zpl_file_range.c b/module/os/linux/zfs/zpl_file_range.c
+index 3065d54fa9da..64728fdb1187 100644
+--- a/module/os/linux/zfs/zpl_file_range.c
++++ b/module/os/linux/zfs/zpl_file_range.c
+@@ -26,6 +26,9 @@
+ #include <linux/compat.h>
+ #endif
+ #include <linux/fs.h>
++#ifdef HAVE_VFS_SPLICE_COPY_FILE_RANGE
++#include <linux/splice.h>
++#endif
+ #include <sys/file.h>
+ #include <sys/zfs_znode.h>
+ #include <sys/zfs_vnops.h>
+@@ -102,7 +105,7 @@ zpl_copy_file_range(struct file *src_file, loff_t src_off,
+ ret = zpl_clone_file_range_impl(src_file, src_off,
+ dst_file, dst_off, len);
+
+-#ifdef HAVE_VFS_GENERIC_COPY_FILE_RANGE
++#if defined(HAVE_VFS_GENERIC_COPY_FILE_RANGE)
+ /*
+ * Since Linux 5.3 the filesystem driver is responsible for executing
+ * an appropriate fallback, and a generic fallback function is provided.
+@@ -111,6 +114,15 @@ zpl_copy_file_range(struct file *src_file, loff_t src_off,
+ ret == -EAGAIN)
+ ret = generic_copy_file_range(src_file, src_off, dst_file,
+ dst_off, len, flags);
++#elif defined(HAVE_VFS_SPLICE_COPY_FILE_RANGE)
++ /*
++ * Since 6.8 the fallback function is called splice_copy_file_range
++ * and has a slightly different signature.
++ */
++ if (ret == -EOPNOTSUPP || ret == -EINVAL || ret == -EXDEV ||
++ ret == -EAGAIN)
++ ret = splice_copy_file_range(src_file, src_off, dst_file,
++ dst_off, len);
+ #else
+ /*
+ * Before Linux 5.3 the filesystem has to return -EOPNOTSUPP to signal
+@@ -118,7 +130,7 @@ zpl_copy_file_range(struct file *src_file, loff_t src_off,
+ */
+ if (ret == -EINVAL || ret == -EXDEV || ret == -EAGAIN)
+ ret = -EOPNOTSUPP;
+-#endif /* HAVE_VFS_GENERIC_COPY_FILE_RANGE */
++#endif /* HAVE_VFS_GENERIC_COPY_FILE_RANGE || HAVE_VFS_SPLICE_COPY_FILE_RANGE */
+
+ return (ret);
+ } \ No newline at end of file