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