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 #
19dnl # 6.8: generic_copy_file_range() removed, replaced by
20dnl #      splice_copy_file_range()
21dnl #
22AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE], [
23	ZFS_LINUX_TEST_SRC([vfs_copy_file_range], [
24		#include <linux/fs.h>
25
26		static ssize_t test_copy_file_range(struct file *src_file,
27		    loff_t src_off, struct file *dst_file, loff_t dst_off,
28		    size_t len, unsigned int flags) {
29			(void) src_file; (void) src_off;
30			(void) dst_file; (void) dst_off;
31			(void) len; (void) flags;
32			return (0);
33		}
34
35		static const struct file_operations
36		    fops __attribute__ ((unused)) = {
37			.copy_file_range	= test_copy_file_range,
38		};
39	],[])
40])
41AC_DEFUN([ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE], [
42	AC_MSG_CHECKING([whether fops->copy_file_range() is available])
43	ZFS_LINUX_TEST_RESULT([vfs_copy_file_range], [
44		AC_MSG_RESULT([yes])
45		AC_DEFINE(HAVE_VFS_COPY_FILE_RANGE, 1,
46		    [fops->copy_file_range() is available])
47	],[
48		AC_MSG_RESULT([no])
49	])
50])
51
52AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE], [
53	ZFS_LINUX_TEST_SRC([generic_copy_file_range], [
54		#include <linux/fs.h>
55	], [
56		struct file *src_file __attribute__ ((unused)) = NULL;
57		loff_t src_off __attribute__ ((unused)) = 0;
58		struct file *dst_file __attribute__ ((unused)) = NULL;
59		loff_t dst_off __attribute__ ((unused)) = 0;
60		size_t len __attribute__ ((unused)) = 0;
61		unsigned int flags __attribute__ ((unused)) = 0;
62		generic_copy_file_range(src_file, src_off, dst_file, dst_off,
63		    len, flags);
64	])
65])
66AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE], [
67	AC_MSG_CHECKING([whether generic_copy_file_range() is available])
68	ZFS_LINUX_TEST_RESULT_SYMBOL([generic_copy_file_range],
69	[generic_copy_file_range], [fs/read_write.c], [
70		AC_MSG_RESULT(yes)
71		AC_DEFINE(HAVE_VFS_GENERIC_COPY_FILE_RANGE, 1,
72		    [generic_copy_file_range() is available])
73	],[
74		AC_MSG_RESULT(no)
75	])
76])
77
78AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_SPLICE_COPY_FILE_RANGE], [
79	ZFS_LINUX_TEST_SRC([splice_copy_file_range], [
80		#include <linux/splice.h>
81	], [
82		struct file *src_file __attribute__ ((unused)) = NULL;
83		loff_t src_off __attribute__ ((unused)) = 0;
84		struct file *dst_file __attribute__ ((unused)) = NULL;
85		loff_t dst_off __attribute__ ((unused)) = 0;
86		size_t len __attribute__ ((unused)) = 0;
87		splice_copy_file_range(src_file, src_off, dst_file, dst_off,
88		    len);
89	])
90])
91AC_DEFUN([ZFS_AC_KERNEL_VFS_SPLICE_COPY_FILE_RANGE], [
92	AC_MSG_CHECKING([whether splice_copy_file_range() is available])
93	ZFS_LINUX_TEST_RESULT([splice_copy_file_range], [
94		AC_MSG_RESULT(yes)
95		AC_DEFINE(HAVE_VFS_SPLICE_COPY_FILE_RANGE, 1,
96		    [splice_copy_file_range() is available])
97	],[
98		AC_MSG_RESULT(no)
99	])
100])
101
102AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE], [
103	ZFS_LINUX_TEST_SRC([vfs_clone_file_range], [
104		#include <linux/fs.h>
105
106		static int test_clone_file_range(struct file *src_file,
107		    loff_t src_off, struct file *dst_file, loff_t dst_off,
108		    u64 len) {
109			(void) src_file; (void) src_off;
110			(void) dst_file; (void) dst_off;
111			(void) len;
112			return (0);
113		}
114
115		static const struct file_operations
116		    fops __attribute__ ((unused)) = {
117			.clone_file_range	= test_clone_file_range,
118		};
119	],[])
120])
121AC_DEFUN([ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE], [
122	AC_MSG_CHECKING([whether fops->clone_file_range() is available])
123	ZFS_LINUX_TEST_RESULT([vfs_clone_file_range], [
124		AC_MSG_RESULT([yes])
125		AC_DEFINE(HAVE_VFS_CLONE_FILE_RANGE, 1,
126		    [fops->clone_file_range() is available])
127	],[
128		AC_MSG_RESULT([no])
129	])
130])
131
132AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE], [
133	ZFS_LINUX_TEST_SRC([vfs_dedupe_file_range], [
134		#include <linux/fs.h>
135
136		static int test_dedupe_file_range(struct file *src_file,
137		    loff_t src_off, struct file *dst_file, loff_t dst_off,
138		    u64 len) {
139			(void) src_file; (void) src_off;
140			(void) dst_file; (void) dst_off;
141			(void) len;
142			return (0);
143		}
144
145		static const struct file_operations
146		    fops __attribute__ ((unused)) = {
147                .dedupe_file_range	= test_dedupe_file_range,
148		};
149	],[])
150])
151AC_DEFUN([ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE], [
152	AC_MSG_CHECKING([whether fops->dedupe_file_range() is available])
153	ZFS_LINUX_TEST_RESULT([vfs_dedupe_file_range], [
154		AC_MSG_RESULT([yes])
155		AC_DEFINE(HAVE_VFS_DEDUPE_FILE_RANGE, 1,
156		    [fops->dedupe_file_range() is available])
157	],[
158		AC_MSG_RESULT([no])
159	])
160])
161
162AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE], [
163	ZFS_LINUX_TEST_SRC([vfs_remap_file_range], [
164		#include <linux/fs.h>
165
166		static loff_t test_remap_file_range(struct file *src_file,
167		    loff_t src_off, struct file *dst_file, loff_t dst_off,
168		    loff_t len, unsigned int flags) {
169			(void) src_file; (void) src_off;
170			(void) dst_file; (void) dst_off;
171			(void) len; (void) flags;
172			return (0);
173		}
174
175		static const struct file_operations
176		    fops __attribute__ ((unused)) = {
177			.remap_file_range	= test_remap_file_range,
178		};
179	],[])
180])
181
182AC_DEFUN([ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE], [
183	AC_MSG_CHECKING([whether fops->remap_file_range() is available])
184	ZFS_LINUX_TEST_RESULT([vfs_remap_file_range], [
185		AC_MSG_RESULT([yes])
186		AC_DEFINE(HAVE_VFS_REMAP_FILE_RANGE, 1,
187		    [fops->remap_file_range() is available])
188	],[
189		AC_MSG_RESULT([no])
190	])
191])
192