coreutils
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]