When using copy_file_range() on ZFS, blksize was 512 bytespathconf(..., as this is_PC_MIN_HOLE_SIZE)
the granularity of holes as returned by pathconf.returns 512 bytes, It was being roundedas this is the smallest possible granularity of
up to 4096 bytesholes in ZFS due to dynamic record sizes, but this resulted in much worse performanceand the expectation thant
copying using the recordall hole locations will be aligned to this size.
Instead, always copy in maxphyscopy_file_range() enforced a minimum block sized chunks of 4096 bytes, unless one of thebut
filesystems involved does not support FIOSEEKDATA or FIOSEEKHOLE orthis resulted in much worse performance than copying using a more
otherwise returned an error.reasonable block size, In tsuch as the recordsize.
This case fall back to copying inwas reported as up to a 70% performance regression in cp(1)
the blksize chunks with zero detection for holescompared to 12.x which did not have copy_file_range() and used
a userspace buffer of MAXPHYS * 8 (1 MB in most cases).
If the minimum hole size is less than or equal to 512 bytes, we
instead opt to use the block size reported by the filesystem, which
in the ZFS case will be the recordsize of the dataset.
While here, replace the static upper bound on the copy_file_range()
block size of 1 MB with maxphys, so it can be larger when the system
is configured for such.
Sponsored by: Klara, Inc.