From 45330176690b079ed47ac7c58f29a1b028f97b07 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano 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 . (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 file changed, 28 insertions(+) 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 +#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; -- 2.7.4