Giuseppe Scrivano wrote: > Jim Meyering <j...@meyering.net> writes: > >>>> Adding this optimization should not change the meaning of >>>> --sparse=always. >>> >>> So do you want to use it only when --sparse=auto is used? >> >> Precisely. > > I cleaned the patch a bit, the clone operation is done only when > --sparse=auto is used.
Thanks. Here's an adjusted version that moves the in-function #ifdefs into a helper function and includes sys/ioctl.h whenever HAVE_SYS_IOCTL_H is defined. I'll adjust indentation in a separate patch. >From 2be19afe6a06bdf4172ab10ff657a32121960217 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>. (clone_file): New function. (copy_reg): Use the btrfs clone operation if possible. --- src/copy.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/src/copy.c b/src/copy.c index 4c8c432..34af802 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,20 @@ 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__ +# define BTRFS_IOC_CLONE 1074041865 + 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 +462,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 +608,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.4.rc3.195.g2b05 _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils