[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/3] copy: Use copy_file_range when possible
From: |
Goldwyn Rodrigues |
Subject: |
[PATCH 3/3] copy: Use copy_file_range when possible |
Date: |
Thu, 31 May 2018 15:42:43 -0500 |
From: Goldwyn Rodrigues <address@hidden>
copy_file_range() performs an internal copy and is faster than
bringing the data to userspace and writing it back.
If the copy_file_range() fails, it falls back to the older method
of reading and writing for data copy.
Signed-off-by: Goldwyn Rodrigues <address@hidden>
---
configure.ac | 1 +
src/copy.c | 24 +++++++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 669e9d1f2..f0bd3be23 100644
--- a/configure.ac
+++ b/configure.ac
@@ -261,6 +261,7 @@ AC_CHECK_FUNCS([gethostid],
gl_ADD_PROG([optional_bin_progs], [hostid]))
AC_CHECK_FUNCS([sigsuspend],
gl_ADD_PROG([optional_bin_progs], [timeout]))
+AC_CHECK_FUNCS(copy_file_range)
gl_WINSIZE_IN_PTEM
diff --git a/src/copy.c b/src/copy.c
index 3df635e81..7b5e79775 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -234,7 +234,29 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t
buf_size,
while (max_n_read)
{
- ssize_t n_read = read (src_fd, buf, MIN (max_n_read, buf_size));
+ ssize_t n_read = 0;
+
+#ifdef HAVE_COPY_FILE_RANGE
+ /*
+ * Since we don't have to create holes, we don't have to read the data
+ * Attempt a copy_file_range()
+ */
+ if (!punch_holes) {
+ n_read = copy_file_range(src_fd, NULL, dest_fd, NULL, max_n_read,
0);
+ if (n_read > 0) {
+ max_n_read -= n_read;
+ *total_n_read += n_read;
+ continue;
+ }
+ if (n_read == 0)
+ break;
+ /*
+ * FALLTHROUGH: Attempt the regular read/write cycle
+ * if copy_file_range() fails
+ */
+ }
+#endif
+ n_read = read (src_fd, buf, MIN (max_n_read, buf_size));
if (n_read < 0)
{
if (errno == EINTR)
--
2.16.3