Signed-off-by: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
---
configure.ac | 12 ++++++++++++
src/storage/storage_backend.c | 24 ++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/configure.ac b/configure.ac
index f370475..2498389 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2175,6 +2175,18 @@ fi
AM_CONDITIONAL([WITH_HYPERV], [test "$with_hyperv" = "yes"])
+dnl
+dnl check for kernel headers required by btrfs ioctl
+dnl
+if test "$with_linux" = "yes"; then
+ have_btrfs=no
+ AC_CHECK_HEADER([linux/btrfs.h],[have_btrfs=yes])
+ if test "${have_btrfs}" = yes; then
+ AC_DEFINE([HAVE_BTRFS_IOC_CLONE], 1,
+ [whether have btrfs CoW clone ioctl])
+ fi
+fi
+
dnl Allow perl/python overrides
AC_PATH_PROGS([PYTHON], [python2 python])
AC_PATH_PROG([PERL], [perl])
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index b990a82..d2a664b 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -46,6 +46,10 @@
# include <selinux/selinux.h>
#endif
+#if HAVE_BTRFS_IOC_CLONE
+# include <linux/btrfs.h>
+#endif
+
#include "datatypes.h"
#include "virerror.h"
#include "viralloc.h"
@@ -156,6 +160,26 @@ enum {
#define READ_BLOCK_SIZE_DEFAULT (1024 * 1024)
#define WRITE_BLOCK_SIZE_DEFAULT (4 * 1024)
+/*
+ * Perform the O(1) btrfs clone operation, if possible.
+ * Upon success, return 0. Otherwise, return -1 and set errno.
+ */
+#if defined(HAVE_BTRFS_IOC_CLONE)
+static inline int
+btrfsCloneFile(int dest_fd, int src_fd)
+{
+ return ioctl(dest_fd, BTRFS_IOC_CLONE, src_fd);
+}
+#else
+static inline int
+btrfsCloneFile(int dest_fd ATTRIBUTE_UNUSED,
+ int src_fd ATTRIBUTE_UNUSED)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+#endif
+
static int ATTRIBUTE_NONNULL(2)
virStorageBackendCopyToFD(virStorageVolDefPtr vol,
virStorageVolDefPtr inputvol,
--
2.1.0