Subject: bug#56392: closed (Re: bug#56391: `cp --reflink=always` creates empty file on failure)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 05 Jul 2022 15:05:03 +0000

Your bug report

#56391: `cp --reflink=always` creates empty file on failure

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
56391: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=56391
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#56391: `cp --reflink=always` creates empty file on failure
From: Paul Eggert <[email-masked]>
To: Benjamin Gilbert <[email-masked]>
Cc: [email-masked]
Date: Tue, 5 Jul 2022 10:04:48 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

Thanks for reporting that. I installed the attached patch.

From 08f14d9492e35188b7ed85eb59b7e605285d8b09 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 5 Jul 2022 09:34:17 -0500
Subject: [PATCH] =?UTF-8?q?cp:=20don=E2=80=99t=20create=20empty=20file=20i?=
 =?UTF-8?q?f=20cannot=20clone?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* src/copy.c (copy_reg): With --reflink=always, if FICLONE fails
on a file we just created, clean up by removing the file (Bug#56391).
---
 src/copy.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/copy.c b/src/copy.c
index 0c368d0e4..eaed148b4 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1279,6 +1279,9 @@ copy_reg (char const *src_name, char const *dst_name,
         {
           error (0, errno, _("failed to clone %s from %s"),
                  quoteaf_n (0, dst_name), quoteaf_n (1, src_name));
+          if (*new_dst && unlinkat (dst_dirfd, dst_relname, 0) != 0
+              && errno != ENOENT)
+            error (0, errno, _("cannot remove %s"), quoteaf (dst_name));
           return_val = false;
           goto close_src_and_dst_desc;
         }
-- 
2.36.1

Subject: `cp --reflink=always` creates empty file on failure
From: Benjamin Gilbert <[email-masked]>
To: [email-masked]
Date: Tue, 5 Jul 2022 03:41:29 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

When `cp --reflink=always` fails because the filesystem does not
support reflinks, I'd expect it not to leave anything at the
destination path.  However, it appears to leave an empty file instead:

$ ls -l
total 0
$ echo "some data" > src
$ cp --reflink=always src dest
cp: failed to clone 'dest' from 'src': Operation not supported
$ ls -l
total 4
-rw-rw-r--. 1 bgilbert bgilbert  0 Jul  5 01:27 dest
-rw-rw-r--. 1 bgilbert bgilbert 10 Jul  5 01:27 src

I'm seeing this on both coreutils 9.0 (Fedora 36) and 9.1.31-fa332
built from Git.

Best,
--Benjamin Gilbert