bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: BTRFS file clone support for cp


From: Jim Meyering
Subject: Re: BTRFS file clone support for cp
Date: Tue, 28 Jul 2009 11:26:03 +0200

Andreas Schwab wrote:

> Jim Meyering <address@hidden> writes:
>
>> +#ifdef __linux__
>> +# define BTRFS_IOC_CLONE 1074041865
>
> This is wrong, the actual value is architecture dependent.  You should
> use the _IOW macro instead.

Good point.  Thanks!
I've adjusted it.
Here's the patch I'm considering now:

>From 6ae1f09da25f6600f32dc540551a9479dd2e618e Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <address@hidden>
Date: Sat, 25 Jul 2009 16:35:27 +0200
Subject: [PATCH] cp: support btrfs' copy-on-write file clone operation

* src/copy.c [HAVE_SYS_IOCTL_H]: Include <sys/ioctl.h>.
(BTRFS_IOCTL_MAGIC, BTRFS_IOC_CLONE): Define.
(clone_file): New function.
(copy_reg): Use the btrfs clone operation if possible.
---
 src/copy.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/src/copy.c b/src/copy.c
index 4c8c432..ce4c67a 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -61,6 +61,10 @@
 # include "verror.h"
 #endif

+#if HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
 #ifndef HAVE_FCHOWN
 # define HAVE_FCHOWN false
 # define fchown(fd, uid, gid) (-1)
@@ -114,6 +118,23 @@ static bool owner_failure_ok (struct cp_options const *x);
 static char const *top_level_src_name;
 static char const *top_level_dst_name;

+/* Perform the O(1) btrfs clone operation, if possible.
+   Upon success, return 0.  Otherwise, return -1 and set errno.  */
+static inline int
+clone_file (int dest_fd, int src_fd)
+{
+#ifdef __linux__
+# undef BTRFS_IOCTL_MAGIC
+# define BTRFS_IOCTL_MAGIC 0x94
+# undef BTRFS_IOC_CLONE
+# define BTRFS_IOC_CLONE _IOW (BTRFS_IOCTL_MAGIC, 9, int)
+  return ioctl (dest_fd, BTRFS_IOC_CLONE, src_fd);
+#else
+  errno = ENOTSUP;
+  return -1;
+#endif
+}
+
 /* FIXME: describe */
 /* FIXME: rewrite this to use a hash table so we avoid the quadratic
    performance hit that's probably noticeable only on trees deeper
@@ -444,6 +465,7 @@ copy_reg (char const *src_name, char const *dst_name,
   struct stat sb;
   struct stat src_open_sb;
   bool return_val = true;
+  bool copied = false;

   source_desc = open (src_name,
                      (O_RDONLY | O_BINARY
@@ -589,6 +611,14 @@ copy_reg (char const *src_name, char const *dst_name,
       goto close_src_and_dst_desc;
     }

+  /* If --sparse=auto is in effect, attempt a btrfs clone operation.
+     If the operation is not supported or it fails then copy the file
+     in the usual way.  */
+  if (x->sparse_mode == SPARSE_AUTO
+      && clone_file (dest_desc, source_desc) == 0)
+    copied = true;
+
+  if (!copied)
   {
     typedef uintptr_t word;
     off_t n_read_total = 0;
--
1.6.2.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]