coreutils: 9.8 -> 9.9 (#460517)
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
From 231cc20195294c9774ab68f523dd06059f4b0a5c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
|
||||
Date: Wed, 29 Oct 2025 23:41:55 +0000
|
||||
Subject: [PATCH] copy: avoid posix_fadvise bypassing copy offload behavior
|
||||
|
||||
* src/copy-file-data.c (): pass 0 to posix_fadvise to indicate to EOF.
|
||||
coreutils 9.8 used OFF_T_MAX instead, which triggered OpenZFS 2.2.2
|
||||
at least to synchronously (decompress and) populate the page cache.
|
||||
Addresses https://github.com/coreutils/coreutils/issues/122
|
||||
---
|
||||
src/copy-file-data.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/copy-file-data.c b/src/copy-file-data.c
|
||||
index 1eefd3071f58a54f725c96dfcd2fd352012398c5..9eb6f47244f0a62c2f4934c7663794fd4dcf21bf 100644
|
||||
--- a/src/copy-file-data.c
|
||||
+++ b/src/copy-file-data.c
|
||||
@@ -536,9 +536,12 @@ copy_file_data (int ifd, struct stat const *ist, off_t ipos, char const *iname,
|
||||
&& scantype != PLAIN_SCANTYPE)));
|
||||
|
||||
/* Don't bother calling fadvise for small copies, as it is not
|
||||
- likely to help performance and might even hurt it. */
|
||||
+ likely to help performance and might even hurt it.
|
||||
+ Note it's important to use a 0 length to indicate the whole file
|
||||
+ as OpenZFS 2.2.2 at least will otherwise synchronously
|
||||
+ (decompress and) populate the cache when given a specific length. */
|
||||
if (IO_BUFSIZE < ibytes)
|
||||
- fdadvise (ifd, ipos, ibytes <= OFF_T_MAX - ipos ? ibytes : 0,
|
||||
+ fdadvise (ifd, ipos, ibytes < OFF_T_MAX - ipos ? ibytes : 0,
|
||||
FADVISE_SEQUENTIAL);
|
||||
|
||||
/* If not making a sparse file, try to use a more-efficient
|
||||
@@ -1,68 +0,0 @@
|
||||
(NB: we drop the NEWS change to avoid conflicts)
|
||||
|
||||
From 64b8fdb5b4767e0f833486507c3eae46ed1b40f8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
|
||||
Date: Thu, 30 Oct 2025 13:02:48 +0000
|
||||
Subject: [PATCH] copy: don't avoid copy-offload upon SEEK_HOLE indicating
|
||||
non-sparse
|
||||
|
||||
* src/copy-file-data.c (infer_scantype): Fall back to a plain copy
|
||||
if SEEK_HOLE indicates non-sparse, as zero copy avoids copy offload.
|
||||
This was seen with transparently compressed files on OpenZFS.
|
||||
* tests/cp/sparse-perf.sh: Add a test case even though it might
|
||||
only trigger on compressed file systems that don't support reflink.
|
||||
* NEWS: Mention the bug fix.
|
||||
Addresses https://github.com/coreutils/coreutils/issues/122
|
||||
---
|
||||
NEWS | 8 ++++++++
|
||||
src/copy-file-data.c | 11 +++++++++--
|
||||
tests/cp/sparse-perf.sh | 10 ++++++++++
|
||||
3 files changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/copy-file-data.c b/src/copy-file-data.c
|
||||
index 9eb6f47244f0a62c2f4934c7663794fd4dcf21bf..8fd25fee9201eda7bd0a8caf01f02821a3390448 100644
|
||||
--- a/src/copy-file-data.c
|
||||
+++ b/src/copy-file-data.c
|
||||
@@ -481,12 +481,19 @@ infer_scantype (int fd, struct stat const *sb, off_t pos,
|
||||
if (scan_inference->hole_start < sb->st_size)
|
||||
return LSEEK_SCANTYPE;
|
||||
|
||||
- /* Though the file likely has holes, SEEK_DATA and SEEK_HOLE
|
||||
+ /* Though the file may have holes, SEEK_DATA and SEEK_HOLE
|
||||
didn't find any. This can happen with file systems like
|
||||
circa-2025 squashfs that support SEEK_HOLE only trivially.
|
||||
- Fall back on ZERO_SCANTYPE. */
|
||||
+ This can also happen due to transparent file compression,
|
||||
+ which can also indicate fewer than the usual number of blocks. */
|
||||
+
|
||||
if (lseek (fd, pos, SEEK_SET) < 0)
|
||||
return ERROR_SCANTYPE;
|
||||
+
|
||||
+ /* we prefer to return PLAIN_SCANTYPE here so that copy offload
|
||||
+ continues to be used. Falling through to ZERO_SCANTYPE would be
|
||||
+ less performant in the compressed file case. */
|
||||
+ return PLAIN_SCANTYPE;
|
||||
}
|
||||
}
|
||||
else if (pos < scan_inference->ext_start || errno == ENXIO)
|
||||
diff --git a/tests/cp/sparse-perf.sh b/tests/cp/sparse-perf.sh
|
||||
index 5a283c1fe65816a36342d9f583c1ed787947bf10..5ee984c527d7d8b6395d4193fcf81804b1135b8a 100755
|
||||
--- a/tests/cp/sparse-perf.sh
|
||||
+++ b/tests/cp/sparse-perf.sh
|
||||
@@ -35,6 +35,16 @@ cmp $other_partition_sparse k2 || fail=1
|
||||
grep ': avoided' cp.out && { cat cp.out; fail=1; }
|
||||
|
||||
|
||||
+# Create a large-non-sparse-but-compressible file
|
||||
+# Ensure we don't avoid copy offload which we saw with
|
||||
+# transparent compression on OpenZFS at least
|
||||
+# (as that triggers our sparse heuristic).
|
||||
+mls='might-look-sparse'
|
||||
+yes | head -n1M > "$mls" || framework_failure_
|
||||
+cp --debug "$mls" "$mls.cp" >cp.out || fail=1
|
||||
+cmp "$mls" "$mls.cp" || fail=1
|
||||
+grep ': avoided' cp.out && { cat cp.out; fail=1; }
|
||||
+
|
||||
|
||||
# Create a large-but-sparse file on the current partition.
|
||||
# We disable relinking below, thus verifying SEEK_HOLE support
|
||||
@@ -1,52 +0,0 @@
|
||||
From 2c5754649e08a664f3d43f7bc1df08f498bc1554 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
|
||||
Date: Fri, 31 Oct 2025 15:37:55 +0000
|
||||
Subject: [PATCH] copy: be more defensive/restrictive with posix_fadvise
|
||||
|
||||
* src/copy-file-data.c (copy_file_data): Only give the
|
||||
POSIX_FADV_SEQUENTIAL hint when we _know_ we'll definitely
|
||||
use a read/write loop to copy the data. Also only apply
|
||||
the hint to the whole file, as we've seen OpenZFS at least
|
||||
special case that.
|
||||
(sparse_copy): Update stale comment.
|
||||
---
|
||||
src/copy-file-data.c | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/copy-file-data.c b/src/copy-file-data.c
|
||||
index 8fd25fee9201eda7bd0a8caf01f02821a3390448..c46b7edc5228f5f1e9c398d8ad7ff20b6fa60fb6 100644
|
||||
--- a/src/copy-file-data.c
|
||||
+++ b/src/copy-file-data.c
|
||||
@@ -105,8 +105,6 @@ is_CLONENOTSUP (int err)
|
||||
If HOLE_SIZE, look for holes in the input; *HOLE_SIZE contains
|
||||
the size of the current hole so far, and update *HOLE_SIZE
|
||||
at end to be the size of the hole at the end of the copy.
|
||||
- Set *TOTAL_N_READ to the number of bytes read; this counts
|
||||
- the trailing hole, which has not yet been output.
|
||||
Read and update *DEBUG as needed.
|
||||
If successful, return the number of bytes copied,
|
||||
otherwise diagnose the failure and return -1. */
|
||||
@@ -542,14 +540,17 @@ copy_file_data (int ifd, struct stat const *ist, off_t ipos, char const *iname,
|
||||
|| (x->sparse_mode == SPARSE_AUTO
|
||||
&& scantype != PLAIN_SCANTYPE)));
|
||||
|
||||
- /* Don't bother calling fadvise for small copies, as it is not
|
||||
- likely to help performance and might even hurt it.
|
||||
- Note it's important to use a 0 length to indicate the whole file
|
||||
+ /* If we _know_ we're going to read data sequentially into the process,
|
||||
+ i.e., --reflink or --sparse are not in auto mode,
|
||||
+ give that hint to the kernel so it can tune caching behavior.
|
||||
+ Also we don't bother calling fadvise for small copies,
|
||||
+ as it is not likely to help performance and might even hurt it.
|
||||
+ Also we only apply this hint for the whole file (0 length)
|
||||
as OpenZFS 2.2.2 at least will otherwise synchronously
|
||||
(decompress and) populate the cache when given a specific length. */
|
||||
- if (IO_BUFSIZE < ibytes)
|
||||
- fdadvise (ifd, ipos, ibytes < OFF_T_MAX - ipos ? ibytes : 0,
|
||||
- FADVISE_SEQUENTIAL);
|
||||
+ if (ipos == 0 && ibytes == COUNT_MAX
|
||||
+ && (x->reflink_mode != REFLINK_AUTO || x->sparse_mode != SPARSE_AUTO))
|
||||
+ fdadvise (ifd, 0, 0, FADVISE_SEQUENTIAL);
|
||||
|
||||
/* If not making a sparse file, try to use a more-efficient
|
||||
buffer size. */
|
||||
@@ -48,26 +48,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "coreutils" + (optionalString (!minimal) "-full");
|
||||
version = "9.8";
|
||||
version = "9.9";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnu/coreutils/coreutils-${version}.tar.xz";
|
||||
hash = "sha256-5tT9LYUskUGhwqGKE9FGoM1+RRlfcik6TkwETsbMyhU=";
|
||||
hash = "sha256-Gby2yoZxg8V9dxVerpRsXs7YgYMUO0XKUa19JsYoynU=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Extremely bad bug where `tail` prints fewer lines than it should.
|
||||
# https://github.com/coreutils/coreutils/commit/914972e80dbf82aac9ffe3ff1f67f1028e1a788b
|
||||
./tail.patch
|
||||
# Fix performance regression in cp.
|
||||
# https://github.com/coreutils/coreutils/commit/231cc20195294c9774ab68f523dd06059f4b0a5c
|
||||
# https://github.com/coreutils/coreutils/commit/64b8fdb5b4767e0f833486507c3eae46ed1b40f8
|
||||
# https://github.com/coreutils/coreutils/commit/2c5754649e08a664f3d43f7bc1df08f498bc1554
|
||||
./cp-1.patch
|
||||
./cp-2.patch
|
||||
./cp-3.patch
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# The test tends to fail on btrfs, f2fs and maybe other unusual filesystems.
|
||||
sed '2i echo Skipping dd sparse test && exit 77' -i ./tests/dd/sparse.sh
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
(NB: we omit the new test, in order to avoid rerunning autoconf.)
|
||||
|
||||
From 914972e80dbf82aac9ffe3ff1f67f1028e1a788b Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Braun <hannes@hannesbraun.net>
|
||||
Date: Wed, 24 Sep 2025 21:20:49 +0200
|
||||
Subject: [PATCH] tail: fix tailing larger number of lines in regular files
|
||||
|
||||
* src/tail.c (file_lines): Seek to the previous block instead of the
|
||||
beginning (or a little before) of the block that was just scanned.
|
||||
Otherwise, the same block is read and scanned (at least partially)
|
||||
again. This bug was introduced by commit v9.7-219-g976f8abc1.
|
||||
* tests/tail/basic-seek.sh: Add a new test.
|
||||
* tests/local.mk: Reference the new test.
|
||||
* NEWS: mention the bug fix.
|
||||
---
|
||||
NEWS | 4 ++++
|
||||
src/tail.c | 2 +-
|
||||
tests/local.mk | 1 +
|
||||
tests/tail/basic-seek.sh | 28 ++++++++++++++++++++++++++++
|
||||
4 files changed, 34 insertions(+), 1 deletion(-)
|
||||
create mode 100755 tests/tail/basic-seek.sh
|
||||
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 7a1a73113e839f010aa6c734e6f07da68827b953..dc1d26879327761d35499815776477771758edd4 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -7,6 +7,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
`basenc --base58` would not operate correctly with input > 15561475 bytes.
|
||||
[bug introduced with --base58 in coreutils-9.8]
|
||||
|
||||
+ 'tail' outputs the correct number of lines again for non-small -n values.
|
||||
+ Previously it may have output too few lines.
|
||||
+ [bug introduced in coreutils-9.8]
|
||||
+
|
||||
|
||||
* Noteworthy changes in release 9.8 (2025-09-22) [stable]
|
||||
|
||||
diff --git a/src/tail.c b/src/tail.c
|
||||
index b8bef1d91cdb6cde2b666b6c1575376e075eaeb8..c7779c77dfe4cf5a672a265b6e796c7153590170 100644
|
||||
--- a/src/tail.c
|
||||
+++ b/src/tail.c
|
||||
@@ -596,7 +596,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb,
|
||||
goto free_buffer;
|
||||
}
|
||||
|
||||
- pos = xlseek (fd, -bufsize, SEEK_CUR, prettyname);
|
||||
+ pos = xlseek (fd, -(bufsize + bytes_read), SEEK_CUR, prettyname);
|
||||
bytes_read = read (fd, buffer, bufsize);
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
Reference in New Issue
Block a user