Andreas Schwab wrote: > Jim Meyering <j...@meyering.net> 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 <gscriv...@gnu.org> 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 _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils