1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-04-28 06:33:36 +00:00

copy-file-range: tune for more-modern kernels

* lib/copy-file-range.c [__linux__ && HAVE_COPY_FILE_RANGE]:
Include <linux/version.h>.  Include <sys/utsname.h>
only for kernel 5.2 and earlier.
(CHECK_LINUX_KERNEL_VERSION): New macro.
(copy_file_range) [__linux__ && HAVE_COPY_FILE_RANGE]:
Call utsname only when built for kernel 5.2 and earlier.
(copy_file_range) [!__linux__ && HAVE_COPY_FILE_RANGE]:
Use underlying copy_file_range.  This doesn’t change
behavior since the code is not compiled in this case,
but it makes the code a bit cleaner.
* modules/copy-file-range (Depends-on): Add bool.
This commit is contained in:
Paul Eggert
2025-08-01 14:46:51 -07:00
parent c184b2cd50
commit 626f229915
4 changed files with 47 additions and 20 deletions

View File

@@ -1,3 +1,18 @@
2025-08-01 Paul Eggert <eggert@cs.ucla.edu>
copy-file-range: tune for more-modern kernels
* lib/copy-file-range.c [__linux__ && HAVE_COPY_FILE_RANGE]:
Include <linux/version.h>. Include <sys/utsname.h>
only for kernel 5.2 and earlier.
(CHECK_LINUX_KERNEL_VERSION): New macro.
(copy_file_range) [__linux__ && HAVE_COPY_FILE_RANGE]:
Call utsname only when built for kernel 5.2 and earlier.
(copy_file_range) [!__linux__ && HAVE_COPY_FILE_RANGE]:
Use underlying copy_file_range. This doesnt change
behavior since the code is not compiled in this case,
but it makes the code a bit cleaner.
* modules/copy-file-range (Depends-on): Add bool.
2025-08-01 Bruno Haible <bruno@clisp.org>
sigsegv: Use new ioctl available in Linux >= 6.11.

View File

@@ -21,7 +21,13 @@
#include <errno.h>
#if defined __linux__ && HAVE_COPY_FILE_RANGE
# include <linux/version.h>
# include <sys/utsname.h>
# if LINUX_VERSION_CODE < KERNEL_VERSION (5, 3, 0)
# define CHECK_LINUX_KERNEL_VERSION true
# else
# define CHECK_LINUX_KERNEL_VERSION false
# endif
#endif
ssize_t
@@ -31,32 +37,38 @@ copy_file_range (int infd, off_t *pinoff,
{
#undef copy_file_range
#if defined __linux__ && HAVE_COPY_FILE_RANGE
#if HAVE_COPY_FILE_RANGE
bool ok = true;
# if CHECK_LINUX_KERNEL_VERSION
/* The implementation of copy_file_range (which first appeared in
Linux kernel release 4.5) had many issues before release 5.3
<https://lwn.net/Articles/789527/>, so fail with ENOSYS for Linux
kernels 5.2 and earlier.
This workaround, and the configure-time check for Linux, can be
removed when such kernels (released March 2016 through September
2019) are no longer a consideration. As of January 2021, the
furthest-future planned kernel EOL is December 2024 for kernel
release 4.19. */
This workaround can be removed when such kernels (released March
2016 through September 2019) are no longer a consideration.
Although all such kernels have reached EOL, some distros use
older kernels. For example, RHEL 8 uses kernel 4.18 and has an
EOL of 2029. */
static signed char ok;
static signed char kernel_ok;
if (! kernel_ok)
{
struct utsname name;
uname (&name);
char *p = name.release;
kernel_ok = ((p[1] != '.' || '5' < p[0]
|| (p[0] == '5' && (p[3] != '.' || '2' < p[2])))
? 1 : -1);
}
if (! ok)
{
struct utsname name;
uname (&name);
char *p = name.release;
ok = ((p[1] != '.' || '5' < p[0]
|| (p[0] == '5' && (p[3] != '.' || '2' < p[2])))
? 1 : -1);
}
if (kernel_ok < 0)
ok = false;
# endif
if (0 < ok)
return copy_file_range (infd, pinoff, outfd, poutoff, length, flags);
if (ok)
return copy_file_range (infd, pinoff, outfd, poutoff, length, flags);
#endif
/* There is little need to emulate copy_file_range with read+write,

View File

@@ -52,8 +52,7 @@ AC_DEFUN([gl_FUNC_COPY_FILE_RANGE],
case $host_os in
linux*)
# See copy-file-range.c comment re pre-5.3 Linux kernel bugs.
# We should be able to remove this hack in 2025.
# See copy-file-range.c comment re Linux kernel bugs.
REPLACE_COPY_FILE_RANGE=1;;
esac
fi

View File

@@ -6,6 +6,7 @@ lib/copy-file-range.c
m4/copy-file-range.m4
Depends-on:
bool
largefile
unistd-h