Commit v9.8-95-g4c0cf3864 intended to initialize ext_start to src_pos, as was described at: https://lists.gnu.org/r/coreutils/2025-11/msg00035.html However ipos was inadvertently used, which is only valid the first time through the loop.
* src/copy-file-data.c (lseek_copy): Use scan_inference->hole_start only with the initial offset passed to lseek_copy(). * NEWS: Mention the bug fix. Reported at https://github.com/coreutils/coreutils/issues/159 --- NEWS | 5 +++++ src/copy-file-data.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e3858a855..af8667aeb 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,11 @@ GNU coreutils NEWS -*- outline -*- ** Bug fixes + 'cp' no longer enters an infinite loop copying sparse files with SEEK_HOLE. + E.g., this was seen copying files with certain extent patterns, + from ext4 to another file system. + [bug introduced in coreutils-9.9] + 'date' no longer fails with format directives that return an empty string. [bug introduced in coreutils-9.9] diff --git a/src/copy-file-data.c b/src/copy-file-data.c index 927a6e048..56b669fe7 100644 --- a/src/copy-file-data.c +++ b/src/copy-file-data.c @@ -338,7 +338,7 @@ lseek_copy (int src_fd, int dest_fd, char **abuf, idx_t buf_size, for (off_t ext_start = scan_inference->ext_start; 0 <= ext_start && ext_start < max_ipos; ) { - off_t ext_end = (ext_start == ipos + off_t ext_end = (ext_start == src_pos ? scan_inference->hole_start : lseek (src_fd, ext_start, SEEK_HOLE)); if (0 <= ext_end) -- 2.52.0
