Jim Meyering wrote: > 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
Giuseppe is going to write a root-only test to exercise this code, so I've made one final adjustment to his patch (move decl of "copied" down to definition) and have pushed this change: >From 45330176690b079ed47ac7c58f29a1b028f97b07 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 | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/src/copy.c b/src/copy.c index 4c8c432..bbed336 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 @@ -589,6 +610,13 @@ 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. */ + bool copied = (x->sparse_mode == SPARSE_AUTO + && clone_file (dest_desc, source_desc) == 0); + + if (!copied) { typedef uintptr_t word; off_t n_read_total = 0; -- 1.6.4.rc3.201.gd9d59 _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils