1dnl #
2dnl # The *_file_range APIs have a long history:
3dnl #
4dnl # 2.6.29: BTRFS_IOC_CLONE and BTRFS_IOC_CLONE_RANGE ioctl introduced
5dnl # 3.12: BTRFS_IOC_FILE_EXTENT_SAME ioctl introduced
6dnl #
7dnl # 4.5: copy_file_range() syscall introduced, added to VFS
8dnl # 4.5: BTRFS_IOC_CLONE and BTRFS_IOC_CLONE_RANGE renamed to FICLONE ands
9dnl #      FICLONERANGE, added to VFS as clone_file_range()
10dnl # 4.5: BTRFS_IOC_FILE_EXTENT_SAME renamed to FIDEDUPERANGE, added to VFS
11dnl #      as dedupe_file_range()
12dnl #
13dnl # 4.20: VFS clone_file_range() and dedupe_file_range() replaced by
14dnl #       remap_file_range()
15dnl #
16dnl # 5.3: VFS copy_file_range() expected to do its own fallback,
17dnl #      generic_copy_file_range() added to support it
18dnl #
19AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE], [
20	ZFS_LINUX_TEST_SRC([vfs_copy_file_range], [
21		#include <linux/fs.h>
22
23		static ssize_t test_copy_file_range(struct file *src_file,
24		    loff_t src_off, struct file *dst_file, loff_t dst_off,
25		    size_t len, unsigned int flags) {
26			(void) src_file; (void) src_off;
27			(void) dst_file; (void) dst_off;
28			(void) len; (void) flags;
29			return (0);
30		}
31
32		static const struct file_operations
33		    fops __attribute__ ((unused)) = {
34			.copy_file_range	= test_copy_file_range,
35		};
36	],[])
37])
38AC_DEFUN([ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE], [
39	AC_MSG_CHECKING([whether fops->copy_file_range() is available])
40	ZFS_LINUX_TEST_RESULT([vfs_copy_file_range], [
41		AC_MSG_RESULT([yes])
42		AC_DEFINE(HAVE_VFS_COPY_FILE_RANGE, 1,
43		    [fops->copy_file_range() is available])
44	],[
45		AC_MSG_RESULT([no])
46	])
47])
48
49AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE], [
50	ZFS_LINUX_TEST_SRC([generic_copy_file_range], [
51		#include <linux/fs.h>
52	], [
53		struct file *src_file __attribute__ ((unused)) = NULL;
54		loff_t src_off __attribute__ ((unused)) = 0;
55		struct file *dst_file __attribute__ ((unused)) = NULL;
56		loff_t dst_off __attribute__ ((unused)) = 0;
57		size_t len __attribute__ ((unused)) = 0;
58		unsigned int flags __attribute__ ((unused)) = 0;
59		generic_copy_file_range(src_file, src_off, dst_file, dst_off,
60		    len, flags);
61	])
62])
63AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE], [
64	AC_MSG_CHECKING([whether generic_copy_file_range() is available])
65	ZFS_LINUX_TEST_RESULT_SYMBOL([generic_copy_file_range],
66	[generic_copy_file_range], [fs/read_write.c], [
67		AC_MSG_RESULT(yes)
68		AC_DEFINE(HAVE_VFS_GENERIC_COPY_FILE_RANGE, 1,
69		    [generic_copy_file_range() is available])
70	],[
71		AC_MSG_RESULT(no)
72	])
73])
74
75AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE], [
76	ZFS_LINUX_TEST_SRC([vfs_clone_file_range], [
77		#include <linux/fs.h>
78
79		static int test_clone_file_range(struct file *src_file,
80		    loff_t src_off, struct file *dst_file, loff_t dst_off,
81		    u64 len) {
82			(void) src_file; (void) src_off;
83			(void) dst_file; (void) dst_off;
84			(void) len;
85			return (0);
86		}
87
88		static const struct file_operations
89		    fops __attribute__ ((unused)) = {
90			.clone_file_range	= test_clone_file_range,
91		};
92	],[])
93])
94AC_DEFUN([ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE], [
95	AC_MSG_CHECKING([whether fops->clone_file_range() is available])
96	ZFS_LINUX_TEST_RESULT([vfs_clone_file_range], [
97		AC_MSG_RESULT([yes])
98		AC_DEFINE(HAVE_VFS_CLONE_FILE_RANGE, 1,
99		    [fops->clone_file_range() is available])
100	],[
101		AC_MSG_RESULT([no])
102	])
103])
104
105AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE], [
106	ZFS_LINUX_TEST_SRC([vfs_dedupe_file_range], [
107		#include <linux/fs.h>
108
109		static int test_dedupe_file_range(struct file *src_file,
110		    loff_t src_off, struct file *dst_file, loff_t dst_off,
111		    u64 len) {
112			(void) src_file; (void) src_off;
113			(void) dst_file; (void) dst_off;
114			(void) len;
115			return (0);
116		}
117
118		static const struct file_operations
119		    fops __attribute__ ((unused)) = {
120                .dedupe_file_range	= test_dedupe_file_range,
121		};
122	],[])
123])
124AC_DEFUN([ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE], [
125	AC_MSG_CHECKING([whether fops->dedupe_file_range() is available])
126	ZFS_LINUX_TEST_RESULT([vfs_dedupe_file_range], [
127		AC_MSG_RESULT([yes])
128		AC_DEFINE(HAVE_VFS_DEDUPE_FILE_RANGE, 1,
129		    [fops->dedupe_file_range() is available])
130	],[
131		AC_MSG_RESULT([no])
132	])
133])
134
135AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE], [
136	ZFS_LINUX_TEST_SRC([vfs_remap_file_range], [
137		#include <linux/fs.h>
138
139		static loff_t test_remap_file_range(struct file *src_file,
140		    loff_t src_off, struct file *dst_file, loff_t dst_off,
141		    loff_t len, unsigned int flags) {
142			(void) src_file; (void) src_off;
143			(void) dst_file; (void) dst_off;
144			(void) len; (void) flags;
145			return (0);
146		}
147
148		static const struct file_operations
149		    fops __attribute__ ((unused)) = {
150			.remap_file_range	= test_remap_file_range,
151		};
152	],[])
153])
154
155AC_DEFUN([ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE], [
156	AC_MSG_CHECKING([whether fops->remap_file_range() is available])
157	ZFS_LINUX_TEST_RESULT([vfs_remap_file_range], [
158		AC_MSG_RESULT([yes])
159		AC_DEFINE(HAVE_VFS_REMAP_FILE_RANGE, 1,
160		    [fops->remap_file_range() is available])
161	],[
162		AC_MSG_RESULT([no])
163	])
164])
165