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

Reply via email to