Subject: bug#51433: cp 9.0 sometimes fails with SEEK_DATA/SEEK_HOLE

From: Paul Eggert <[email-masked]>
Date: Sat, 30 Oct 2021 10:07:53 -0700

On 10/30/21 03:22, Pádraig Brady wrote:

> Given this patch doesn't change any operation,
> it may be best to revert to avoid the complexity?

Yes, and thanks for checking. I installed the attached.

The main bug of course remains unfixed, as it's a ZFS bug that needs 
fixing in ZFS.

From b41425fbf7dc6d25a1a4d2fe322863fab597d65a Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sat, 30 Oct 2021 10:00:10 -0700
Subject: [PATCH] cp: revert unnecessary FreeBSD workaround
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

That was a false alarm due to a bug in FreeBSD 9.1 truss;
see Pádraig Brady’s report (Bug#51433#29).
* src/copy.c (lseek_copy, infer_scantype): Don’t bother checking
whether lseek returned -1.  This doesn’t entirely revert the
previous change, as it keeps the code simplification of the
previous change while reverting the check for -1.
---
 src/copy.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/copy.c b/src/copy.c
index 1cbc9480c..a6523ed97 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -530,7 +530,7 @@ lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
       off_t ext_end = lseek (src_fd, ext_start, SEEK_HOLE);
       if (ext_end < 0)
         {
-          if (! (ext_end == -1 && errno == ENXIO))
+          if (errno != ENXIO)
             goto cannot_lseek;
           ext_end = src_total_size;
           if (ext_end <= ext_start)
@@ -607,7 +607,7 @@ lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
         }
 
       ext_start = lseek (src_fd, dest_pos, SEEK_DATA);
-      if (ext_start < 0 && ! (ext_start == -1 && errno == ENXIO))
+      if (ext_start < 0 && errno != ENXIO)
         goto cannot_lseek;
     }
 
@@ -1093,8 +1093,7 @@ infer_scantype (int fd, struct stat const *sb,
 
 #ifdef SEEK_HOLE
   scan_inference->ext_start = lseek (fd, 0, SEEK_DATA);
-  if (0 <= scan_inference->ext_start
-      || (scan_inference->ext_start == -1 && errno == ENXIO))
+  if (0 <= scan_inference->ext_start || errno == ENXIO)
     return LSEEK_SCANTYPE;
   else if (errno != EINVAL && !is_ENOTSUP (errno))
     return ERROR_SCANTYPE;
-- 
2.32.0