[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]