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@xxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list