aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qemu-img.c26
-rw-r--r--tests/qemu-iotests/122.out6
2 files changed, 17 insertions, 15 deletions
diff --git a/qemu-img.c b/qemu-img.c
index 55f76e7b00..06264d9128 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1514,10 +1514,6 @@ static int convert_read(ImgConvertState *s, int64_t sector_num, int nb_sectors,
int n;
int ret;
- if (s->status == BLK_ZERO || s->status == BLK_BACKING_FILE) {
- return 0;
- }
-
assert(nb_sectors <= s->buf_sectors);
while (nb_sectors > 0) {
BlockBackend *blk;
@@ -1655,7 +1651,8 @@ static int convert_do_copy(ImgConvertState *s)
ret = n;
goto fail;
}
- if (s->status == BLK_DATA) {
+ if (s->status == BLK_DATA || (!s->min_sparse && s->status == BLK_ZERO))
+ {
s->allocated_sectors += n;
}
sector_num += n;
@@ -1675,17 +1672,24 @@ static int convert_do_copy(ImgConvertState *s)
ret = n;
goto fail;
}
- if (s->status == BLK_DATA) {
+ if (s->status == BLK_DATA || (!s->min_sparse && s->status == BLK_ZERO))
+ {
allocated_done += n;
qemu_progress_print(100.0 * allocated_done / s->allocated_sectors,
0);
}
- ret = convert_read(s, sector_num, n, buf);
- if (ret < 0) {
- error_report("error while reading sector %" PRId64
- ": %s", sector_num, strerror(-ret));
- goto fail;
+ if (s->status == BLK_DATA) {
+ ret = convert_read(s, sector_num, n, buf);
+ if (ret < 0) {
+ error_report("error while reading sector %" PRId64
+ ": %s", sector_num, strerror(-ret));
+ goto fail;
+ }
+ } else if (!s->min_sparse && s->status == BLK_ZERO) {
+ n = MIN(n, s->buf_sectors);
+ memset(buf, 0, n * BDRV_SECTOR_SIZE);
+ s->status = BLK_DATA;
}
ret = convert_write(s, sector_num, n, buf);
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
index 0068e96741..98814de5d6 100644
--- a/tests/qemu-iotests/122.out
+++ b/tests/qemu-iotests/122.out
@@ -112,16 +112,14 @@ read 3145728/3145728 bytes at offset 0
3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 63963136/63963136 bytes at offset 3145728
61 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 6291456, "depth": 0, "zero": false, "data": true, "offset": 327680},
-{ "start": 6291456, "length": 60817408, "depth": 0, "zero": true, "data": false}]
+[{ "start": 0, "length": 67108864, "depth": 0, "zero": false, "data": true, "offset": 327680}]
convert -c -S 0:
read 3145728/3145728 bytes at offset 0
3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 63963136/63963136 bytes at offset 3145728
61 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 6291456, "depth": 0, "zero": false, "data": true},
-{ "start": 6291456, "length": 60817408, "depth": 0, "zero": true, "data": false}]
+[{ "start": 0, "length": 67108864, "depth": 0, "zero": false, "data": true}]
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
wrote 33554432/33554432 bytes at offset 0
32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)