Subject: Re: bug#79139: cp --reflink truncates sparse files on ZFS

From: Paul Eggert <[email-masked]>
Date: Sat, 2 Aug 2025 09:03:38 -0700

On 2025-08-02 01:32, Pádraig Brady wrote:

> it's worth mentioning run-time vs build-time checks. 

Yes, and this could be documented more. I installed the attached.

> For reference I made some notes on various version compat at:
> http://pixelbeat/programming/linux_binary_compatibility.html

I needed to use this URL:

https://www.pixelbeat.org/programming/linux_binary_compatibility.html

> the gnulib workaround isn't too onerous as SYS_BUFZISE_MAX is large,
> and I expect the glibc fix will be backported to glibc 2.41 systems 
> promptly anyway.

Yes, I went through similar thought processes. It didn't seem worth the 
hassle to do the extra glibc runtime checks. Gnulib has always used 
static checks for glibc versions, even in areas where this is serious 
business (e.g., malloc misbehavior). So far, nobody has reported an 
issue for this. Maybe people who build for older kernels (which is 
dubious if you ask me) aren't building for older glibcs (which is even 
more dubious).

From a44c85a227c84542cc5849b976eaccdd61d44354 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sat, 2 Aug 2025 08:52:29 -0700
Subject: [PATCH] More copy_file_range commentary

---
 doc/glibc-functions/copy_file_range.texi | 10 +++++++++-
 lib/copy-file-range.c                    |  5 +++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/doc/glibc-functions/copy_file_range.texi b/doc/glibc-functions/copy_file_range.texi
index 2b0ac85ee5..80469d0994 100644
--- a/doc/glibc-functions/copy_file_range.texi
+++ b/doc/glibc-functions/copy_file_range.texi
@@ -28,13 +28,16 @@ But the replacement function is only a stub: It always fails with error @code{EN
 
 @item
 This function has many problems on Linux kernel versions before 5.3.
+See @url{``Fixes for major copy_file_range() issues'',
+https://lwn.net/Articles/789527/}.
 On these kernel versions, the replacement function always fails with
 error @code{ENOSYS}.
 
 @item
-@c https://sourceware.org/bugzilla/show_bug.cgi?id=33245
 This function returns an incorrect value when the number of bytes copied
 exceeds @code{INT_MAX} on systems using glibc version 2.41 or 2.42.
+See @url{glibc bug 33245,
+https://sourceware.org/bugzilla/show_bug.cgi?id=33245}.
 
 @item
 This function is provided on GNU/Hurd but it is only a stub: It always
@@ -43,4 +46,9 @@ fails with error @code{ENOSYS}.
 
 Portability problems not fixed by Gnulib:
 @itemize
+@item
+If built with include files for Linux kernel 5.3 or later,
+the Gnulib substitute may misbehave when run on Linux kernel 5.2 or earlier.
+A similar problem exists if built with include files for glibc 2.43 or later,
+and run on glibc 2.41 or 2.42.
 @end itemize
diff --git a/lib/copy-file-range.c b/lib/copy-file-range.c
index 5c12f6f715..2465a55802 100644
--- a/lib/copy-file-range.c
+++ b/lib/copy-file-range.c
@@ -23,6 +23,11 @@
 #if defined __linux__ && HAVE_COPY_FILE_RANGE
 # include <linux/version.h>
 # include <sys/utsname.h>
+/* Although it can be dicey to use static checks for Linux kernel versions,
+   due to the dubious practice of building on newer kernels for older ones,
+   do it here anyway as the buggy kernels are rare (they are all EOLed)
+   and builders for them are unlikely to use the dubious practice.
+   Circa 2029 we should remove the old-kernel workarounds entirely.  */
 # if LINUX_VERSION_CODE < KERNEL_VERSION (5, 3, 0)
 #  define CHECK_LINUX_KERNEL_VERSION true
 # else
-- 
2.48.1