[libvirt] [PATCH RFC] storage: perform btrfs clone if possible

Chen Hanxiao chenhanxiao at cn.fujitsu.com
Mon Nov 24 06:11:47 UTC 2014


We already had nocow flags in virStorageSource.
But when creating RAW file, we don't take advantage
of clone of btrfs.
This file introduce btrfs_clone_file function,
and try to use it when !nocow.

Signed-off-by: Chen Hanxiao <chenhanxiao at cn.fujitsu.com>
---
 src/storage/storage_backend.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 98720f6..f5ea34c 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -156,6 +156,27 @@ 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.
+ */
+static inline int
+btrfs_clone_file(int dest_fd, int src_fd)
+{
+#ifdef __linux__
+# undef BTRFS_IOCTL_MAGICi
+# 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
+    (void) dest_fd;
+    (void) src_fd;
+    errno = ENOTSUP;
+    return -1;
+#endif
+}
+
 static int ATTRIBUTE_NONNULL(2)
 virStorageBackendCopyToFD(virStorageVolDefPtr vol,
                           virStorageVolDefPtr inputvol,
@@ -200,6 +221,16 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
         goto cleanup;
     }
 
+    if (!vol->target.nocow) {
+        if (btrfs_clone_file(fd, inputfd) == -1) {
+            if (errno == ENOTSUP)
+                VIR_DEBUG("btrfs clone not supported, try another way.");
+        } else {
+            VIR_DEBUG("btrfs clone findished.");
+            goto cleanup;
+        }
+    }
+
     while (amtread != 0) {
         int amtleft;
 
-- 
1.9.3




More information about the libvir-list mailing list