aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/qcow2.c')
-rw-r--r--block/qcow2.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index edbf9fbd0a..070f89c700 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2043,6 +2043,7 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
BDRVQcow2State *s = bs->opaque;
uint64_t host_offset;
unsigned int bytes;
+ QCow2ClusterType type;
int ret, status = 0;
qemu_co_mutex_lock(&s->lock);
@@ -2054,7 +2055,7 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
}
bytes = MIN(INT_MAX, count);
- ret = qcow2_get_host_offset(bs, offset, &bytes, &host_offset);
+ ret = qcow2_get_host_offset(bs, offset, &bytes, &host_offset, &type);
qemu_co_mutex_unlock(&s->lock);
if (ret < 0) {
return ret;
@@ -2062,15 +2063,15 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
*pnum = bytes;
- if ((ret == QCOW2_CLUSTER_NORMAL || ret == QCOW2_CLUSTER_ZERO_ALLOC) &&
+ if ((type == QCOW2_CLUSTER_NORMAL || type == QCOW2_CLUSTER_ZERO_ALLOC) &&
!s->crypto) {
*map = host_offset;
*file = s->data_file->bs;
status |= BDRV_BLOCK_OFFSET_VALID;
}
- if (ret == QCOW2_CLUSTER_ZERO_PLAIN || ret == QCOW2_CLUSTER_ZERO_ALLOC) {
+ if (type == QCOW2_CLUSTER_ZERO_PLAIN || type == QCOW2_CLUSTER_ZERO_ALLOC) {
status |= BDRV_BLOCK_ZERO;
- } else if (ret != QCOW2_CLUSTER_UNALLOCATED) {
+ } else if (type != QCOW2_CLUSTER_UNALLOCATED) {
status |= BDRV_BLOCK_DATA;
}
if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) &&
@@ -2279,6 +2280,7 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
int ret = 0;
unsigned int cur_bytes; /* number of bytes in current iteration */
uint64_t host_offset = 0;
+ QCow2ClusterType type;
AioTaskPool *aio = NULL;
while (bytes != 0 && aio_task_pool_status(aio) == 0) {
@@ -2290,22 +2292,23 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
}
qemu_co_mutex_lock(&s->lock);
- ret = qcow2_get_host_offset(bs, offset, &cur_bytes, &host_offset);
+ ret = qcow2_get_host_offset(bs, offset, &cur_bytes,
+ &host_offset, &type);
qemu_co_mutex_unlock(&s->lock);
if (ret < 0) {
goto out;
}
- if (ret == QCOW2_CLUSTER_ZERO_PLAIN ||
- ret == QCOW2_CLUSTER_ZERO_ALLOC ||
- (ret == QCOW2_CLUSTER_UNALLOCATED && !bs->backing))
+ if (type == QCOW2_CLUSTER_ZERO_PLAIN ||
+ type == QCOW2_CLUSTER_ZERO_ALLOC ||
+ (type == QCOW2_CLUSTER_UNALLOCATED && !bs->backing))
{
qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes);
} else {
if (!aio && cur_bytes != bytes) {
aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
}
- ret = qcow2_add_task(bs, aio, qcow2_co_preadv_task_entry, ret,
+ ret = qcow2_add_task(bs, aio, qcow2_co_preadv_task_entry, type,
host_offset, offset, cur_bytes,
qiov, qiov_offset, NULL);
if (ret < 0) {
@@ -3834,6 +3837,7 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
if (head || tail) {
uint64_t off;
unsigned int nr;
+ QCow2ClusterType type;
assert(head + bytes <= s->cluster_size);
@@ -3849,10 +3853,11 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
offset = QEMU_ALIGN_DOWN(offset, s->cluster_size);
bytes = s->cluster_size;
nr = s->cluster_size;
- ret = qcow2_get_host_offset(bs, offset, &nr, &off);
- if (ret != QCOW2_CLUSTER_UNALLOCATED &&
- ret != QCOW2_CLUSTER_ZERO_PLAIN &&
- ret != QCOW2_CLUSTER_ZERO_ALLOC) {
+ ret = qcow2_get_host_offset(bs, offset, &nr, &off, &type);
+ if (ret < 0 ||
+ (type != QCOW2_CLUSTER_UNALLOCATED &&
+ type != QCOW2_CLUSTER_ZERO_PLAIN &&
+ type != QCOW2_CLUSTER_ZERO_ALLOC)) {
qemu_co_mutex_unlock(&s->lock);
return -ENOTSUP;
}
@@ -3916,16 +3921,18 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
while (bytes != 0) {
uint64_t copy_offset = 0;
+ QCow2ClusterType type;
/* prepare next request */
cur_bytes = MIN(bytes, INT_MAX);
cur_write_flags = write_flags;
- ret = qcow2_get_host_offset(bs, src_offset, &cur_bytes, &copy_offset);
+ ret = qcow2_get_host_offset(bs, src_offset, &cur_bytes,
+ &copy_offset, &type);
if (ret < 0) {
goto out;
}
- switch (ret) {
+ switch (type) {
case QCOW2_CLUSTER_UNALLOCATED:
if (bs->backing && bs->backing->bs) {
int64_t backing_length = bdrv_getlength(bs->backing->bs);