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

From: Paul Eggert <[email-masked]>
Date: Fri, 29 Oct 2021 19:04:04 -0700

On 10/28/21 13:59, Pádraig Brady wrote:

> I wonder after getting a SEEK_DATA ENXIO, might we correlate
> we really are at end of file by checking SEEK_HOLE also returns ENXIO?

Wouldn't SEEK_HOLE return the current offset, instead of ENXIO? That is, 
if the underlying data structure is wrong and claims that the rest of 
the file is a hole, wouldn't SEEK_HOLE merely repeat that information?

> Perhaps zfs is updating st_blocks async, or perhaps there are
> runs of zeros in these files that a linker or whatever is sparsifying?

Even if st_blocks was out-of-date, that's just a heuristic and the later 
lseeks should still work. I don't think the files contain actual holes.

I don't see an easy workaround for the ZFS bug, unless we want to slow 
down 'cp' for everybody. This really needs to be fixed on the ZFS side.

The attached patch to OpenZFS might work around the bug (I haven't 
tested it; perhaps someone who uses ZFS could give it a try).

diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index 9bd75c011..1d1bef079 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -100,7 +100,13 @@ zfs_holey_common(znode_t *zp, ulong_t cmd, loff_t *off)
 	else
 		hole = B_FALSE;
 
+	/* Work around OpenZFS bug 11900
+	   <https://github.com/openzfs/zfs/issues/11900>.  */
+# if 0
 	error = dmu_offset_next(ZTOZSB(zp)->z_os, zp->z_id, hole, &noff);
+# else
+	error = EBUSY;
+# fi
 
 	if (error == ESRCH)
 		return (SET_ERROR(ENXIO));