]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
copy: attempt copy offload with sparse files by default
authorPádraig Brady <P@draigBrady.com>
Fri, 30 Dec 2022 19:34:27 +0000 (19:34 +0000)
committerPádraig Brady <P@draigBrady.com>
Sat, 31 Dec 2022 00:20:45 +0000 (00:20 +0000)
This was seen to vastly improve performance
on NFS 4.2 systems by allowing server side copies,
with partially sparse files (avidemux generated mp4 files).

* src/copy.c (lseek_copy): Also set hole_size to 0,
i.e. enable copy_file_range(), with --sparse=auto (the default),
to enable copy offload in this case, as we've strong signal
from SEEK_DATA that we're operating on actual data and not holes here.
* NEWS: Mention the improvement.
Fixes https://bugs.gnu.org/60416

NEWS
src/copy.c

diff --git a/NEWS b/NEWS
index 7fb8c5363f49cf9e7ceb832db8abc2d3fcaf1bff..0beaef506607a3a71627d0d58ce0f2e8cc58a894 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -69,6 +69,12 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** Improvements
 
+  cp --sparse=auto (the default), mv, and install,
+  will use the copy_file_range syscall now also with sparse files.
+  This may be more efficient, by avoiding user space copies,
+  and possibly employing copy offloading or reflinking,
+  for the non sparse portion of such sparse files.
+
   date --debug now diagnoses if multiple --date or --set options are
   specified, as only the last specified is significant in that case.
 
index e465271efac43d9d51486b874c3f6f4d7cb55330..7407517f164c8bd12ead16dcd8e2095edefa77f9 100644 (file)
@@ -526,12 +526,12 @@ lseek_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size,
       last_ext_len = ext_len;
 
       /* Copy this extent, looking for further opportunities to not
-         bother to write zeros unless --sparse=never, since SEEK_HOLE
+         bother to write zeros if --sparse=always, since SEEK_HOLE
          is conservative and may miss some holes.  */
       off_t n_read;
       bool read_hole;
       if ( ! sparse_copy (src_fd, dest_fd, abuf, buf_size,
-                          sparse_mode == SPARSE_NEVER ? 0 : hole_size,
+                          sparse_mode != SPARSE_ALWAYS ? 0 : hole_size,
                           true, allow_reflink, src_name, dst_name,
                           ext_len, &n_read, &read_hole))
         return false;