On 02/09/2026 13:02, Peter Chaplin-Smith via GNU coreutils Bug Reports wrote:
Hello,We've been experiencing an interesting issue where, on a CentOS Stream 10 box running XFS with a 10GiB disk, `cp --reflink=auto` fails to fall back. We observed (via strace) that the ioctl for cloning fails with ENOSPC. It looks like XFS returns ENOSPC if the AG for reflink metadata is full [1] and we have confirmed this is the issue we're hitting. ENOSPC is one of the errors marked as terminal in `is_terminal_error` in `copy.c` so no fallback is attempted. Since it is only the AG for the reflink metadata which is full, using `cp --reflink=never` succeeds. Thank you, Peter Chaplin-Smith [1]: https://github.com/torvalds/linux/blob/89a312991dc6e638a36adc43ccb91dbc25504c04/fs/xfs/xfs_reflink.c#L1311-L1342
Interesting. AG = Allocation Group which is how XFS organizes/scales. So data could be copied to other AGs even if reflink fails with ENOSPC. This is probably a general issue for all CoW supporting file systems where the metadata is managed separately, so can exhaust independently. So I guess we should remove ENOSPC from being considered as a terminal error, as done in the attached. I'll push this shortly. Marking this as done. thanks, Padraig.
From e7379a52ff3ee4c55923f9f0f59cb6fcfa6cba0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]> Date: Wed, 2 Sep 2026 18:08:23 +0100 Subject: [PATCH] cp: fall back to standard copy if a clone fails with ENOSPC reflinking can fail due to failure to allocate metadata, while a standard copy may succeed. * src/copy.c (is_terminal_error): Remove ENOSPC from the list. Fixes https://bugs.gnu.org/81776 --- NEWS | 5 +++++ src/copy.c | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 40574ddac..c81d95eac 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,11 @@ GNU coreutils NEWS -*- outline -*- mistakenly exit with a nonzero status. [This bug was present in "the beginning".] + 'cp --reflink=auto` (the default) will fall back to a standard copy + in the case where the clone fails with ENOSPC. E.g. with XFS, an + allocation group can exhaust metadata space, while a standard copy works. + [bug introduced in coreutils-9.2] + 'cut -d' with multiple multi-byte delimiter options specified will correctly match the last delimiter specified. [bug introduced with multi-byte support in coreutils-9.11] diff --git a/src/copy.c b/src/copy.c index f3f7a407d..097d6af97 100644 --- a/src/copy.c +++ b/src/copy.c @@ -215,12 +215,17 @@ follow_fstatat (int dirfd, char const *filename, struct stat *st, int flags) /* Whether an errno value ERR, set by FICLONE or copy_file_range, indicates that the copying operation has terminally failed, even though it was invoked correctly (so that, e.g, EBADF cannot occur) - and even though !is_CLONENOTSUP (ERR). */ + and even though !is_CLONENOTSUP (ERR). + + Note ENOSPC is _not_ included as that can merely mean that + metadata space is exhausted, while a standard copy may proceed. + E.g. XFS has Allocation Groups where a clone may fail, but a + copy (to other groups) may succeed. */ static bool is_terminal_error (int err) { - return err == EIO || err == ENOMEM || err == ENOSPC || err == EDQUOT; + return err == EIO || err == ENOMEM || err == EDQUOT; } /* Perform the O(1) btrfs clone operation, if possible. -- 2.55.0
