[libvirt] [PATCH] storage: use btrfs file clone ioctl when possible

Oskari Saarenmaa os at ohmu.fi
Fri Sep 27 14:02:53 UTC 2013


Btrfs provides a copy-on-write clone ioctl so let's try to use it instead
of copying files block by block.  The ioctl is executed unconditionally if
it's available and we fall back to block copying if it fails, similarly to
cp --reflink=auto.

Signed-off-by: Oskari Saarenmaa <os at ohmu.fi>
---
 configure.ac                  |  5 +++++
 src/storage/storage_backend.c | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/configure.ac b/configure.ac
index 553015a..acae92e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1984,6 +1984,11 @@ fi
 AM_CONDITIONAL([WITH_STORAGE], [test "$with_storage" = "yes"])
 
 dnl
+dnl check for headers for filesystem specific operations
+dnl
+AC_CHECK_HEADERS([linux/btrfs.h])
+
+dnl
 dnl check for (ESX)
 dnl
 
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index b7edf85..40bfb73 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -38,6 +38,9 @@
 # include <sys/ioctl.h>
 # include <linux/fs.h>
 #endif
+#ifdef HAVE_LINUX_BTRFS_H
+# include <linux/btrfs.h>
+#endif
 
 #if WITH_SELINUX
 # include <selinux/selinux.h>
@@ -149,6 +152,13 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
         goto cleanup;
     }
 
+#ifdef HAVE_LINUX_BTRFS_H
+    /* try to perform a btrfs CoW clone */
+    if (ioctl(fd, BTRFS_IOC_CLONE, inputfd) == 0) {
+        goto done;
+    }
+#endif
+
 #ifdef __linux__
     if (ioctl(fd, BLKBSZGET, &wbytes) < 0) {
         wbytes = 0;
@@ -210,6 +220,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
         } while ((amtleft -= interval) > 0);
     }
 
+done:
     if (fdatasync(fd) < 0) {
         ret = -errno;
         virReportSystemError(errno, _("cannot sync data to file '%s'"),
-- 
1.8.3.1




More information about the libvir-list mailing list