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.
Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #15930
Closes #15931
(cherry picked from commit ef08a4d406
)
This commit is contained in:
parent
c883088df8
commit
58211157bf
|
@ -16,6 +16,9 @@ dnl #
|
||||||
dnl # 5.3: VFS copy_file_range() expected to do its own fallback,
|
dnl # 5.3: VFS copy_file_range() expected to do its own fallback,
|
||||||
dnl # generic_copy_file_range() added to support it
|
dnl # generic_copy_file_range() added to support it
|
||||||
dnl #
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE], [
|
||||||
ZFS_LINUX_TEST_SRC([vfs_copy_file_range], [
|
ZFS_LINUX_TEST_SRC([vfs_copy_file_range], [
|
||||||
#include <linux/fs.h>
|
#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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE], [
|
||||||
ZFS_LINUX_TEST_SRC([vfs_clone_file_range], [
|
ZFS_LINUX_TEST_SRC([vfs_clone_file_range], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
|
@ -118,6 +118,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||||
ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
|
ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
|
||||||
ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE
|
ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE
|
||||||
ZFS_AC_KERNEL_SRC_VFS_GENERIC_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_REMAP_FILE_RANGE
|
||||||
ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE
|
ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE
|
||||||
ZFS_AC_KERNEL_SRC_VFS_DEDUPE_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_IOV_ITER
|
||||||
ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE
|
ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE
|
||||||
ZFS_AC_KERNEL_VFS_GENERIC_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_REMAP_FILE_RANGE
|
||||||
ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE
|
ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE
|
||||||
ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE
|
ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#endif
|
#endif
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#ifdef HAVE_VFS_SPLICE_COPY_FILE_RANGE
|
||||||
|
#include <linux/splice.h>
|
||||||
|
#endif
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/zfs_znode.h>
|
#include <sys/zfs_znode.h>
|
||||||
#include <sys/zfs_vnops.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,
|
ret = zpl_clone_file_range_impl(src_file, src_off,
|
||||||
dst_file, dst_off, len);
|
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
|
* Since Linux 5.3 the filesystem driver is responsible for executing
|
||||||
* an appropriate fallback, and a generic fallback function is provided.
|
* 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 == -EAGAIN)
|
||||||
ret = generic_copy_file_range(src_file, src_off, dst_file,
|
ret = generic_copy_file_range(src_file, src_off, dst_file,
|
||||||
dst_off, len, flags);
|
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
|
#else
|
||||||
/*
|
/*
|
||||||
* Before Linux 5.3 the filesystem has to return -EOPNOTSUPP to signal
|
* 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)
|
if (ret == -EINVAL || ret == -EXDEV || ret == -EAGAIN)
|
||||||
ret = -EOPNOTSUPP;
|
ret = -EOPNOTSUPP;
|
||||||
#endif /* HAVE_VFS_GENERIC_COPY_FILE_RANGE */
|
#endif /* HAVE_VFS_GENERIC_COPY_FILE_RANGE || HAVE_VFS_SPLICE_COPY_FILE_RANGE */
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue