Hi,

I am proposing two patches to solve an issue when copying reflink on
a non-btrfs file system. This issue was already previously discussed [1, 2].

The first one cleans only on a reflink creation failure. The second one was
based on the previously refused patch [2] and it is more general solution.

I am not sure if this behavior is considered to be a bug. There is no
specification what to do in situations like this and whether the empty file
should be left or unlinked [3]. Nevertheless it would be nice to handle this
issue.

Have a nice day!
Fridolin Pokorny

[1] https://bugzilla.redhat.com/show_bug.cgi?id=921708
[2] http://lists.gnu.org/archive/html/coreutils/2013-03/msg00056.html
[3] http://pubs.opengroup.org/onlinepubs/007904875/utilities/cp.html
diff --git a/src/copy.c b/src/copy.c
index 26d5bdd..97dacac 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1281,6 +1281,18 @@ close_src_and_dst_desc:
       error (0, errno, _("failed to close %s"), quote (dst_name));
       return_val = false;
     }
+
+  if (! return_val && *new_dst)
+    {
+      if (errno == EXDEV || errno == ENOTTY || errno == ENOTSUP)
+        {
+          if (unlink (dst_name) != 0)
+            error (0, errno, _("cannot remove %s"), quote (dst_name));
+          else if (x->verbose)
+            printf (_("removed %s\n"), quote (dst_name));
+        }
+    }
+
 close_src_desc:
   if (close (source_desc) < 0)
     {
diff --git a/src/copy.c b/src/copy.c
index 26d5bdd..ee0d919 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1088,6 +1088,13 @@ copy_reg (char const *src_name, char const *dst_name,
         {
           if (!clone_ok)
             {
+              if (errno == ENOTSUP || errno == ENOTTY || errno == EXDEV)
+                {
+                  if (unlink (dst_name) != 0)
+                    error (0, errno, _("cannot remove %s"), quote (dst_name));
+                  else if (x->verbose)
+                    printf (_("removed %s\n"), quote (dst_name));
+                }
               error (0, errno, _("failed to clone %s from %s"),
                      quote_n (0, dst_name), quote_n (1, src_name));
               return_val = false;

Reply via email to