From: Oleg Sidorkin Date: Sat, 31 Jan 2026 09:46:13 +0000 (+0300) Subject: perf: Use copy_file_range to copy files if available (#1680) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=464aaab4dbbdfaed0b66fb495ff47b75f87c296f;p=thirdparty%2Fccache.git perf: Use copy_file_range to copy files if available (#1680) --- diff --git a/cmake/GenerateConfigurationFile.cmake b/cmake/GenerateConfigurationFile.cmake index 01522ad9..ad8cce6a 100644 --- a/cmake/GenerateConfigurationFile.cmake +++ b/cmake/GenerateConfigurationFile.cmake @@ -25,6 +25,7 @@ endforeach() include(CheckFunctionExists) set(functions + copy_file_range getopt_long getpwuid localtime_r diff --git a/cmake/config.h.in b/cmake/config.h.in index dfd8e4e3..87dd0322 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -113,6 +113,9 @@ // === Functions === +// Define if you have the "copy_file_range" function. +#cmakedefine HAVE_COPY_FILE_RANGE + // Define if you have the "getopt_long" function. #cmakedefine HAVE_GETOPT_LONG diff --git a/src/ccache/util/file.cpp b/src/ccache/util/file.cpp index 4631eb33..4653e247 100644 --- a/src/ccache/util/file.cpp +++ b/src/ccache/util/file.cpp @@ -161,17 +161,23 @@ copy_file_impl(const fs::path& src, FMT("Failed to copy {} to {}: {}", src, dest, strerror(errno))); } return {}; -# elif defined(HAVE_SYS_SENDFILE_H) +# elif defined(HAVE_COPY_FILE_RANGE) || defined(HAVE_SYS_SENDFILE_H) DirEntry dir_entry(src, *src_fd); if (!dir_entry) { return tl::unexpected(FMT("Failed to stat {}: {}", src, strerror(errno))); } ssize_t bytes_left = dir_entry.size(); while (bytes_left > 0) { +# if defined(HAVE_SYS_SENDFILE_H) ssize_t n = sendfile(*dst_fd, *src_fd, nullptr, bytes_left); +# elif defined(HAVE_COPY_FILE_RANGE) + ssize_t n = + copy_file_range(*src_fd, nullptr, *dst_fd, nullptr, bytes_left, 0); +# endif if (n < 0) { switch (errno) { case EINVAL: + case EXDEV: case ENOSYS: return copy_fd(*src_fd, *dst_fd); default: