From 613db35596e37c16063d531de6d635f0bd3b2f52 Mon Sep 17 00:00:00 2001 From: LongPing Wei Date: Wed, 16 Mar 2022 10:38:55 +0800 Subject: [PATCH] Enable copy_file_range when it is available. Fallback to read+write when copy_file_range failed, as both fd_in and fd_out must refer to regular files. Signed-off-by: LongPing Wei --- lib/portability.c | 17 +++++++++++------ scripts/genconfig.sh | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/portability.c b/lib/portability.c index 5f98138c..d7648a8f 100644 --- a/lib/portability.c +++ b/lib/portability.c @@ -629,20 +629,25 @@ int get_block_device_size(int fd, unsigned long long* size) long long sendfile_len(int in, int out, long long bytes, long long *consumed) { long long total = 0, len, ww; + int copy_file_range = CFG_TOYBOX_COPYFILERANGE; if (consumed) *consumed = 0; if (in<0) return 0; while (bytes != total) { ww = 0; len = bytes-total; - if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf); errno = 0; -#if CFG_TOYBOX_COPYFILERANGE - len = copy_file_range(in, 0, out, 0, bytes, 0); -#else - ww = len = read(in, libbuf, len); -#endif + if (copy_file_range) { + if (bytes<0) len = INT_MAX; + len = syscall(__NR_copy_file_range, in, 0, out, 0, len, 0); + if (len < 0 && errno == EINVAL) + copy_file_range = 0; + } + if (!copy_file_range) { + if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf); + ww = len = read(in, libbuf, len); + } if (len<1 && errno==EAGAIN) continue; if (len<1) break; if (consumed) *consumed += len; diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh index 01b2eaaf..38af2b36 100755 --- a/scripts/genconfig.sh +++ b/scripts/genconfig.sh @@ -104,7 +104,7 @@ EOF probesymbol TOYBOX_COPYFILERANGE << EOF #include #include - int main(void) { copyfilerange(0, 0, 1, 0, 123, 0); } + int main(void) { syscall(__NR_copy_file_range, 0, 0, 1, 0, 123, 0); } EOF probesymbol TOYBOX_HASTIMERS << EOF #include -- 2.39.2