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_GENERIC_COPY_FILE_RANGE], [ 23 ZFS_LINUX_TEST_SRC([generic_copy_file_range], [ 24 #include <linux/fs.h> 25 ], [ 26 struct file *src_file __attribute__ ((unused)) = NULL; 27 loff_t src_off __attribute__ ((unused)) = 0; 28 struct file *dst_file __attribute__ ((unused)) = NULL; 29 loff_t dst_off __attribute__ ((unused)) = 0; 30 size_t len __attribute__ ((unused)) = 0; 31 unsigned int flags __attribute__ ((unused)) = 0; 32 generic_copy_file_range(src_file, src_off, dst_file, dst_off, 33 len, flags); 34 ]) 35]) 36AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE], [ 37 AC_MSG_CHECKING([whether generic_copy_file_range() is available]) 38 ZFS_LINUX_TEST_RESULT_SYMBOL([generic_copy_file_range], 39 [generic_copy_file_range], [fs/read_write.c], [ 40 AC_MSG_RESULT(yes) 41 AC_DEFINE(HAVE_VFS_GENERIC_COPY_FILE_RANGE, 1, 42 [generic_copy_file_range() is available]) 43 ],[ 44 AC_MSG_RESULT(no) 45 ]) 46]) 47 48AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_SPLICE_COPY_FILE_RANGE], [ 49 ZFS_LINUX_TEST_SRC([splice_copy_file_range], [ 50 #include <linux/splice.h> 51 ], [ 52 struct file *src_file __attribute__ ((unused)) = NULL; 53 loff_t src_off __attribute__ ((unused)) = 0; 54 struct file *dst_file __attribute__ ((unused)) = NULL; 55 loff_t dst_off __attribute__ ((unused)) = 0; 56 size_t len __attribute__ ((unused)) = 0; 57 splice_copy_file_range(src_file, src_off, dst_file, dst_off, 58 len); 59 ]) 60]) 61AC_DEFUN([ZFS_AC_KERNEL_VFS_SPLICE_COPY_FILE_RANGE], [ 62 AC_MSG_CHECKING([whether splice_copy_file_range() is available]) 63 ZFS_LINUX_TEST_RESULT([splice_copy_file_range], [ 64 AC_MSG_RESULT(yes) 65 AC_DEFINE(HAVE_VFS_SPLICE_COPY_FILE_RANGE, 1, 66 [splice_copy_file_range() is available]) 67 ],[ 68 AC_MSG_RESULT(no) 69 ]) 70]) 71 72AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE], [ 73 ZFS_LINUX_TEST_SRC([vfs_clone_file_range], [ 74 #include <linux/fs.h> 75 76 static int test_clone_file_range(struct file *src_file, 77 loff_t src_off, struct file *dst_file, loff_t dst_off, 78 u64 len) { 79 (void) src_file; (void) src_off; 80 (void) dst_file; (void) dst_off; 81 (void) len; 82 return (0); 83 } 84 85 static const struct file_operations 86 fops __attribute__ ((unused)) = { 87 .clone_file_range = test_clone_file_range, 88 }; 89 ],[]) 90]) 91AC_DEFUN([ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE], [ 92 AC_MSG_CHECKING([whether fops->clone_file_range() is available]) 93 ZFS_LINUX_TEST_RESULT([vfs_clone_file_range], [ 94 AC_MSG_RESULT([yes]) 95 AC_DEFINE(HAVE_VFS_CLONE_FILE_RANGE, 1, 96 [fops->clone_file_range() is available]) 97 ],[ 98 AC_MSG_RESULT([no]) 99 ]) 100]) 101 102AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE], [ 103 ZFS_LINUX_TEST_SRC([vfs_dedupe_file_range], [ 104 #include <linux/fs.h> 105 106 static int test_dedupe_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 .dedupe_file_range = test_dedupe_file_range, 118 }; 119 ],[]) 120]) 121AC_DEFUN([ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE], [ 122 AC_MSG_CHECKING([whether fops->dedupe_file_range() is available]) 123 ZFS_LINUX_TEST_RESULT([vfs_dedupe_file_range], [ 124 AC_MSG_RESULT([yes]) 125 AC_DEFINE(HAVE_VFS_DEDUPE_FILE_RANGE, 1, 126 [fops->dedupe_file_range() is available]) 127 ],[ 128 AC_MSG_RESULT([no]) 129 ]) 130]) 131 132AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE], [ 133 ZFS_LINUX_TEST_SRC([vfs_remap_file_range], [ 134 #include <linux/fs.h> 135 136 static loff_t test_remap_file_range(struct file *src_file, 137 loff_t src_off, struct file *dst_file, loff_t dst_off, 138 loff_t len, unsigned int flags) { 139 (void) src_file; (void) src_off; 140 (void) dst_file; (void) dst_off; 141 (void) len; (void) flags; 142 return (0); 143 } 144 145 static const struct file_operations 146 fops __attribute__ ((unused)) = { 147 .remap_file_range = test_remap_file_range, 148 }; 149 ],[]) 150]) 151 152AC_DEFUN([ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE], [ 153 AC_MSG_CHECKING([whether fops->remap_file_range() is available]) 154 ZFS_LINUX_TEST_RESULT([vfs_remap_file_range], [ 155 AC_MSG_RESULT([yes]) 156 AC_DEFINE(HAVE_VFS_REMAP_FILE_RANGE, 1, 157 [fops->remap_file_range() is available]) 158 ],[ 159 AC_MSG_RESULT([no]) 160 ]) 161]) 162