[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 20/29] qemu-img: Special post-backing convert handlin
From: |
Max Reitz |
Subject: |
[Qemu-devel] [PULL 20/29] qemu-img: Special post-backing convert handling |
Date: |
Mon, 11 Jun 2018 16:26:02 +0200 |
Currently, qemu-img convert writes zeroes when it reads zeroes.
Sometimes it does not because the target is initialized to zeroes
anyway, so we do not need to overwrite (and thus potentially allocate)
it. This is never the case for targets with backing files, though. But
even they may have an area that is initialized to zeroes, and that is
the area past the end of the backing file (if that is shorter than the
overlay).
So if the target format's unallocated blocks are zero and there is a gap
between the target's backing file's end and the target's end, we do not
have to explicitly write zeroes there.
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1527898
Signed-off-by: Max Reitz <address@hidden>
Message-id: address@hidden
Reviewed-by: Eric Blake <address@hidden>
Signed-off-by: Max Reitz <address@hidden>
---
qemu-img.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/qemu-img.c b/qemu-img.c
index ebe1b866da..ae4acb655b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1556,7 +1556,9 @@ typedef struct ImgConvertState {
BlockBackend *target;
bool has_zero_init;
bool compressed;
+ bool unallocated_blocks_are_zero;
bool target_has_backing;
+ int64_t target_backing_sectors; /* negative if unknown */
bool wr_in_order;
bool copy_range;
int min_sparse;
@@ -1586,12 +1588,23 @@ static int convert_iteration_sectors(ImgConvertState
*s, int64_t sector_num)
{
int64_t src_cur_offset;
int ret, n, src_cur;
+ bool post_backing_zero = false;
convert_select_part(s, sector_num, &src_cur, &src_cur_offset);
assert(s->total_sectors > sector_num);
n = MIN(s->total_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS);
+ if (s->target_backing_sectors >= 0) {
+ if (sector_num >= s->target_backing_sectors) {
+ post_backing_zero = s->unallocated_blocks_are_zero;
+ } else if (sector_num + n > s->target_backing_sectors) {
+ /* Split requests around target_backing_sectors (because
+ * starting from there, zeros are handled differently) */
+ n = s->target_backing_sectors - sector_num;
+ }
+ }
+
if (s->sector_next_status <= sector_num) {
int64_t count = n * BDRV_SECTOR_SIZE;
@@ -1613,7 +1626,7 @@ static int convert_iteration_sectors(ImgConvertState *s,
int64_t sector_num)
n = DIV_ROUND_UP(count, BDRV_SECTOR_SIZE);
if (ret & BDRV_BLOCK_ZERO) {
- s->status = BLK_ZERO;
+ s->status = post_backing_zero ? BLK_BACKING_FILE : BLK_ZERO;
} else if (ret & BDRV_BLOCK_DATA) {
s->status = BLK_DATA;
} else {
@@ -2379,6 +2392,16 @@ static int img_convert(int argc, char **argv)
}
}
+ if (s.target_has_backing) {
+ /* Errors are treated as "backing length unknown" (which means
+ * s.target_backing_sectors has to be negative, which it will
+ * be automatically). The backing file length is used only
+ * for optimizations, so such a case is not fatal. */
+ s.target_backing_sectors = bdrv_nb_sectors(out_bs->backing->bs);
+ } else {
+ s.target_backing_sectors = -1;
+ }
+
ret = bdrv_get_info(out_bs, &bdi);
if (ret < 0) {
if (s.compressed) {
@@ -2388,6 +2411,7 @@ static int img_convert(int argc, char **argv)
} else {
s.compressed = s.compressed || bdi.needs_compressed_writes;
s.cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
+ s.unallocated_blocks_are_zero = bdi.unallocated_blocks_are_zero;
}
ret = convert_do_copy(&s);
--
2.17.1
- [Qemu-devel] [PULL 11/29] qcow2: Repair OFLAG_COPIED when fixing leaks, (continued)
- [Qemu-devel] [PULL 11/29] qcow2: Repair OFLAG_COPIED when fixing leaks, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 10/29] iotests: Rework 113, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 12/29] iotests: Repairing error during snapshot deletion, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 15/29] qemu-io: Exit with error when a command failed, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 08/29] qemu-img: Recognize no creation support in -o help, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 16/29] iotests.py: Add qemu_io_silent, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 18/29] qemu-img: Resolve relative backing paths in rebase, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 17/29] iotests: Let 216 make use of qemu-io's exit code, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 19/29] iotests: Add test for rebasing with relative paths, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 14/29] qemu-io: Let command functions return error code, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 20/29] qemu-img: Special post-backing convert handling,
Max Reitz <=
- [Qemu-devel] [PULL 22/29] iotests: improve pause_job, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 13/29] qemu-io: Drop command functions' return values, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 21/29] iotests: Test post-backing convert target behavior, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 26/29] throttle: Fix crash on reopen, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 23/29] iotests: Fix 219's timing, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 25/29] block/qcow2-bitmap: fix free_bitmap_clusters, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 27/29] block: Make bdrv_is_writable() public, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 24/29] qemu-img: Remove deprecated -s snapshot_id_or_name option, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 28/29] qcow2: Do not mark inactive images corrupt, Max Reitz, 2018/06/11
- [Qemu-devel] [PULL 29/29] iotests: Add case for a corrupted inactive image, Max Reitz, 2018/06/11