[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 6/8] attempt copy_file_range if explicitly requested
From: |
David Disseldorp |
Subject: |
[PATCH 6/8] attempt copy_file_range if explicitly requested |
Date: |
Fri, 12 Mar 2021 02:30:17 +0100 |
This change sees --reflink behave similar to coreutils cp
--reflink=auto. The kernel may attempt a copy-on-write clone of the
range and may fallback to splice. cpio fallback to regular read/write
is needed in case the source and destination reside on separate
filesystems.
Signed-off-by: David Disseldorp <ddiss@suse.de>
---
src/copyin.c | 2 +-
src/copyout.c | 33 ++++++++++++++++++++++++++++++---
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/src/copyin.c b/src/copyin.c
index c8ea278..f6d7292 100644
--- a/src/copyin.c
+++ b/src/copyin.c
@@ -510,7 +510,7 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int
in_file_des)
}
copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr->c_filesize);
disk_empty_output_buffer (out_file_des, true);
-
+
if (to_stdout_option)
{
if (archive_format == arf_crcascii)
diff --git a/src/copyout.c b/src/copyout.c
index 5ca587f..076478e 100644
--- a/src/copyout.c
+++ b/src/copyout.c
@@ -718,9 +718,36 @@ process_copy_out ()
if (write_out_header (&file_hdr, out_file_des))
continue;
- copy_files_disk_to_tape (in_file_des,
- out_file_des, file_hdr.c_filesize,
- orig_file_name);
+#ifdef HAVE_CPIO_REFLINK
+ /*
+ * copy_file_range(2) should only be used if:
+ * - it has explicitly been requested via --reflink
+ * - crc calculations for aren't needed
+ * - output is a regular seekable file
+ */
+ if (reflink_flag && !crc_i_flag && output_is_seekable)
+ {
+ ssize_t ret;
+ /* flush output buffer before copy_file_range I/O */
+ tape_empty_output_buffer (out_file_des);
+ ret = copy_files_range (in_file_des,
+ out_file_des,
+ file_hdr.c_filesize);
+ /* -EXDEV: can't use copy_file_range, fallback to read/write
*/
+ if (ret == -EXDEV)
+ copy_files_disk_to_tape (in_file_des,
+ out_file_des, file_hdr.c_filesize,
+ orig_file_name);
+ else if (ret < 0)
+ error (PAXEXIT_FAILURE, -ret, _("copy_file_range failed."));
+ }
+ else
+#endif /* HAVE_CPIO_REFLINK */
+ {
+ copy_files_disk_to_tape (in_file_des,
+ out_file_des, file_hdr.c_filesize,
+ orig_file_name);
+ }
warn_if_file_changed(orig_file_name, file_hdr.c_filesize,
file_hdr.c_mtime);
--
2.26.2
- cpio copy-out reflink and chain support, David Disseldorp, 2021/03/11
- [PATCH 1/8] open device with O_NONBLOCK option, David Disseldorp, 2021/03/11
- [PATCH 5/8] add --reflink option, David Disseldorp, 2021/03/11
- [PATCH 7/8] ensure uniform post-trailer-zeros length, David Disseldorp, 2021/03/11
- [PATCH 3/8] add --chain test coverage, David Disseldorp, 2021/03/11
- [PATCH 6/8] attempt copy_file_range if explicitly requested,
David Disseldorp <=
- [PATCH 4/8] add copy_file_range syscall support, David Disseldorp, 2021/03/11
- [PATCH 2/8] add --chain option, David Disseldorp, 2021/03/11
- [PATCH 8/8] add --reflink test coverage, David Disseldorp, 2021/03/11
- Re: cpio copy-out reflink and chain support, Luis Henriques, 2021/03/18