mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 18:55:40 +03:00
qcow2: when dissecting qcow2, use btrfs clone ioctls for reflinking blocks to target
This commit is contained in:
parent
1e20b41187
commit
1c7dd82563
@ -5285,6 +5285,7 @@ test_qcow2_CFLAGS = \
|
||||
|
||||
test_qcow2_LDADD = \
|
||||
libsystemd-internal.la \
|
||||
libsystemd-label.la \
|
||||
libsystemd-shared.la \
|
||||
$(ZLIB_LIBS)
|
||||
endif
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user