From: Lennart Poettering Date: Sat, 17 Jan 2015 17:11:45 +0000 (+0100) Subject: qcow2: when dissecting qcow2, use btrfs clone ioctls for reflinking blocks to target X-Git-Tag: v219~435 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=1c7dd82563ff2e71a067aea20d2acb2d0553644b;hp=1e20b41187ff7d27477b5322690e447753c66ace qcow2: when dissecting qcow2, use btrfs clone ioctls for reflinking blocks to target --- diff --git a/Makefile.am b/Makefile.am index ce5ebf7c4..37ea845ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5285,6 +5285,7 @@ test_qcow2_CFLAGS = \ test_qcow2_LDADD = \ libsystemd-internal.la \ + libsystemd-label.la \ libsystemd-shared.la \ $(ZLIB_LIBS) endif diff --git a/src/import/qcow2-util.c b/src/import/qcow2-util.c index c84c6aa0d..9b0c23bb1 100644 --- a/src/import/qcow2-util.c +++ b/src/import/qcow2-util.c @@ -24,6 +24,7 @@ #include "util.h" #include "sparse-endian.h" #include "qcow2-util.h" +#include "btrfs-util.h" #define QCOW2_MAGIC 0x514649fb @@ -85,6 +86,11 @@ static int copy_cluster( void *buffer) { ssize_t l; + int r; + + r = btrfs_clone_range(sfd, soffset, dfd, doffset, cluster_size); + if (r >= 0) + return r; l = pread(sfd, buffer, cluster_size, soffset); if (l < 0) diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index bd100eef0..254483c31 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -275,6 +275,26 @@ int btrfs_reflink(int infd, int outfd) { return 0; } +int btrfs_clone_range(int infd, uint64_t in_offset, int outfd, uint64_t out_offset, uint64_t sz) { + struct btrfs_ioctl_clone_range_args args = { + .src_fd = infd, + .src_offset = in_offset, + .src_length = sz, + .dest_offset = out_offset, + }; + int r; + + assert(infd >= 0); + assert(outfd >= 0); + assert(sz > 0); + + r = ioctl(outfd, BTRFS_IOC_CLONE_RANGE, &args); + if (r < 0) + return -errno; + + return 0; +} + int btrfs_get_block_device(const char *path, dev_t *dev) { struct btrfs_ioctl_fs_info_args fsi = {}; _cleanup_close_ int fd = -1; diff --git a/src/shared/btrfs-util.h b/src/shared/btrfs-util.h index 1bff9171d..28946c60c 100644 --- a/src/shared/btrfs-util.h +++ b/src/shared/btrfs-util.h @@ -55,6 +55,7 @@ int btrfs_subvol_get_info_fd(int fd, BtrfsSubvolInfo *info); int btrfs_subvol_get_quota_fd(int fd, BtrfsQuotaInfo *quota); int btrfs_reflink(int infd, int outfd); +int btrfs_clone_range(int infd, uint64_t in_offset, int ofd, uint64_t out_offset, uint64_t sz); int btrfs_get_block_device(const char *path, dev_t *dev);