From 2acbac8ef9d314b73fbbd68c2e70580988c063a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 26 Feb 2024 09:59:08 +0100 Subject: New upstream version 4.23 --- src/io.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'src/io.c') diff --git a/src/io.c b/src/io.c index ee48dee..9199d03 100644 --- a/src/io.c +++ b/src/io.c @@ -7,6 +7,7 @@ * General Public License as published by the Free Software Foundation; * either version 2.1 or (at your option) any later version. */ +#define _GNU_SOURCE 1 #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -630,15 +631,37 @@ EXPORT_SYMBOL ssize_t HXio_fullwrite(int fd, const void *vbuf, size_t size) } #if __linux__ -static ssize_t HX_sendfile_linux(int dst, int src, size_t count) +#ifdef HAVE_COPY_FILE_RANGE +static ssize_t HX_cfr_linux(int dst, int src, size_t count) { - long pagesize = sysconf(_SC_PAGE_SIZE); - size_t xfersize; ssize_t ret, xferd = 0; + /* + * Use INT(32)_MAX rather than SSIZE_MAX, as there is an issue with + * overflow detection pending. + * https://lore.kernel.org/linux-man/38nr2286-1o9q-0004-2323-799587773o15@vanv.qr/ + */ + size_t xfersize = INT_MAX; + if (count > xfersize) + count = xfersize; + while ((ret = copy_file_range(src, nullptr, dst, nullptr, count, 0)) > 0) + xferd += ret; + if (xferd > 0) + return xferd; + if (ret < 0) + return -errno; + return 0; +} +#endif - if (pagesize < 0) - pagesize = 4096; - xfersize = SSIZE_MAX - pagesize; +static ssize_t HX_sendfile_linux(int dst, int src, size_t count) +{ + ssize_t ret, xferd = 0; + /* + * Use INT(32)_MAX rather than SSIZE_MAX, as there is an issue with + * overflow detection pending. + * https://lore.kernel.org/linux-man/38nr2286-1o9q-0004-2323-799587773o15@vanv.qr/ + */ + size_t xfersize = INT_MAX; if (count > xfersize) count = xfersize; while ((ret = sendfile(dst, src, nullptr, count)) > 0) @@ -686,7 +709,13 @@ static ssize_t HX_sendfile_rw(int dst, int src, size_t count) EXPORT_SYMBOL ssize_t HX_sendfile(int dst, int src, size_t count) { #if __linux__ - ssize_t ret = HX_sendfile_linux(dst, src, count); + ssize_t ret; +#ifdef HAVE_COPY_FILE_RANGE + ret = HX_cfr_linux(dst, src, count); + if (ret != -ENOSYS && ret != -EXDEV) + return ret; +#endif + ret = HX_sendfile_linux(dst, src, count); if (ret != -ENOSYS) return ret; #endif -- cgit v1.2.3