forked from openzfs/zfs
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
linux: implement filesystem-side copy/clone functions
This implements the Linux VFS ops required to service the file copy/clone APIs: .copy_file_range (4.5+) .clone_file_range (4.5-4.19) .dedupe_file_range (4.5-4.19) .remap_file_range (4.20+) Note that dedupe_file_range() and remap_file_range(REMAP_FILE_DEDUP) are hooked up here, but are not implemented yet. Signed-off-by: Rob Norris <[email protected]> Sponsored-By: OpenDrives Inc. Sponsored-By: Klara Inc.
- Loading branch information
1 parent
95a528d
commit 5067565
Showing
6 changed files
with
384 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
dnl # | ||
dnl # The *_file_range APIs have a long history: | ||
dnl # | ||
dnl # 2.6.29: BTRFS_IOC_CLONE and BTRFS_IOC_CLONE_RANGE ioctl introduced | ||
dnl # 3.12: BTRFS_IOC_FILE_EXTENT_SAME ioctl introduced | ||
dnl # | ||
dnl # 4.5: copy_file_range() syscall introduced, added to VFS | ||
dnl # 4.5: BTRFS_IOC_CLONE and BTRFS_IOC_CLONE_RANGE renamed to FICLONE ands | ||
dnl # FICLONERANGE, added to VFS as clone_file_range() | ||
dnl # 4.5: BTRFS_IOC_FILE_EXTENT_SAME renamed to FIDEDUPERANGE, added to VFS | ||
dnl # as dedupe_file_range() | ||
dnl # | ||
dnl # 4.20: VFS clone_file_range() and dedupe_file_range() replaced by | ||
dnl # remap_file_range() | ||
dnl # | ||
dnl # 5.3: VFS copy_file_range() expected to do its own fallback, | ||
dnl # generic_copy_file_range() added to support it | ||
dnl # | ||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE], [ | ||
ZFS_LINUX_TEST_SRC([vfs_copy_file_range], [ | ||
#include <linux/fs.h> | ||
static ssize_t test_copy_file_range(struct file *src_file, | ||
loff_t src_off, struct file *dst_file, loff_t dst_off, | ||
size_t len, unsigned int flags) { | ||
(void) src_file; (void) src_off; | ||
(void) dst_file; (void) dst_off; | ||
(void) len; (void) flags; | ||
return (0); | ||
} | ||
static const struct file_operations | ||
fops __attribute__ ((unused)) = { | ||
.copy_file_range = test_copy_file_range, | ||
}; | ||
],[]) | ||
]) | ||
AC_DEFUN([ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE], [ | ||
AC_MSG_CHECKING([whether fops->copy_file_range() is available]) | ||
ZFS_LINUX_TEST_RESULT([vfs_copy_file_range], [ | ||
AC_MSG_RESULT([yes]) | ||
AC_DEFINE(HAVE_VFS_COPY_FILE_RANGE, 1, | ||
[fops->copy_file_range() is available]) | ||
],[ | ||
AC_MSG_RESULT([no]) | ||
]) | ||
]) | ||
|
||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE], [ | ||
ZFS_LINUX_TEST_SRC([generic_copy_file_range], [ | ||
#include <linux/fs.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; | ||
unsigned int flags __attribute__ ((unused)) = 0; | ||
generic_copy_file_range(src_file, src_off, dst_file, dst_off, | ||
len, flags); | ||
]) | ||
]) | ||
AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE], [ | ||
AC_MSG_CHECKING([whether generic_copy_file_range() is available]) | ||
ZFS_LINUX_TEST_RESULT_SYMBOL([generic_copy_file_range], | ||
[generic_copy_file_range], [fs/read_write.c], [ | ||
AC_MSG_RESULT(yes) | ||
AC_DEFINE(HAVE_VFS_GENERIC_COPY_FILE_RANGE, 1, | ||
[generic_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> | ||
static int test_clone_file_range(struct file *src_file, | ||
loff_t src_off, struct file *dst_file, loff_t dst_off, | ||
u64 len) { | ||
(void) src_file; (void) src_off; | ||
(void) dst_file; (void) dst_off; | ||
(void) len; | ||
return (0); | ||
} | ||
static const struct file_operations | ||
fops __attribute__ ((unused)) = { | ||
.clone_file_range = test_clone_file_range, | ||
}; | ||
],[]) | ||
]) | ||
AC_DEFUN([ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE], [ | ||
AC_MSG_CHECKING([whether fops->clone_file_range() is available]) | ||
ZFS_LINUX_TEST_RESULT([vfs_clone_file_range], [ | ||
AC_MSG_RESULT([yes]) | ||
AC_DEFINE(HAVE_VFS_CLONE_FILE_RANGE, 1, | ||
[fops->clone_file_range() is available]) | ||
],[ | ||
AC_MSG_RESULT([no]) | ||
]) | ||
]) | ||
|
||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE], [ | ||
ZFS_LINUX_TEST_SRC([vfs_dedupe_file_range], [ | ||
#include <linux/fs.h> | ||
static int test_dedupe_file_range(struct file *src_file, | ||
loff_t src_off, struct file *dst_file, loff_t dst_off, | ||
u64 len) { | ||
(void) src_file; (void) src_off; | ||
(void) dst_file; (void) dst_off; | ||
(void) len; | ||
return (0); | ||
} | ||
static const struct file_operations | ||
fops __attribute__ ((unused)) = { | ||
.dedupe_file_range = test_dedupe_file_range, | ||
}; | ||
],[]) | ||
]) | ||
AC_DEFUN([ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE], [ | ||
AC_MSG_CHECKING([whether fops->dedupe_file_range() is available]) | ||
ZFS_LINUX_TEST_RESULT([vfs_dedupe_file_range], [ | ||
AC_MSG_RESULT([yes]) | ||
AC_DEFINE(HAVE_VFS_DEDUPE_FILE_RANGE, 1, | ||
[fops->dedupe_file_range() is available]) | ||
],[ | ||
AC_MSG_RESULT([no]) | ||
]) | ||
]) | ||
|
||
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE], [ | ||
ZFS_LINUX_TEST_SRC([vfs_remap_file_range], [ | ||
#include <linux/fs.h> | ||
static loff_t test_remap_file_range(struct file *src_file, | ||
loff_t src_off, struct file *dst_file, loff_t dst_off, | ||
loff_t len, unsigned int flags) { | ||
(void) src_file; (void) src_off; | ||
(void) dst_file; (void) dst_off; | ||
(void) len; (void) flags; | ||
return (0); | ||
} | ||
static const struct file_operations | ||
fops __attribute__ ((unused)) = { | ||
.remap_file_range = test_remap_file_range, | ||
}; | ||
],[]) | ||
]) | ||
|
||
AC_DEFUN([ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE], [ | ||
AC_MSG_CHECKING([whether fops->remap_file_range() is available]) | ||
ZFS_LINUX_TEST_RESULT([vfs_remap_file_range], [ | ||
AC_MSG_RESULT([yes]) | ||
AC_DEFINE(HAVE_VFS_REMAP_FILE_RANGE, 1, | ||
[fops->remap_file_range() is available]) | ||
],[ | ||
AC_MSG_RESULT([no]) | ||
]) | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.