qcow2: Switch to .bdrv_co_block_status()
We are gradually moving away from sector-based interfaces, towards byte-based. Update the qcow2 driver accordingly. For now, we are ignoring the 'want_zero' hint. However, it should be relatively straightforward to honor the hint as a way to return larger *pnum values when we have consecutive clusters with the same data/zero status but which differ only in having non-consecutive mappings. Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
d63b4c93e3
commit
a320fb04b6
@ -1670,32 +1670,34 @@ static void qcow2_join_options(QDict *options, QDict *old_options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
|
static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
||||||
int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
|
bool want_zero,
|
||||||
|
int64_t offset, int64_t count,
|
||||||
|
int64_t *pnum, int64_t *map,
|
||||||
|
BlockDriverState **file)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
int index_in_cluster, ret;
|
int index_in_cluster, ret;
|
||||||
unsigned int bytes;
|
unsigned int bytes;
|
||||||
int64_t status = 0;
|
int status = 0;
|
||||||
|
|
||||||
bytes = MIN(INT_MAX, nb_sectors * BDRV_SECTOR_SIZE);
|
bytes = MIN(INT_MAX, count);
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
ret = qcow2_get_cluster_offset(bs, sector_num << BDRV_SECTOR_BITS, &bytes,
|
ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
|
||||||
&cluster_offset);
|
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pnum = bytes >> BDRV_SECTOR_BITS;
|
*pnum = bytes;
|
||||||
|
|
||||||
if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
|
if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
|
||||||
!s->crypto) {
|
!s->crypto) {
|
||||||
index_in_cluster = sector_num & (s->cluster_sectors - 1);
|
index_in_cluster = offset & (s->cluster_size - 1);
|
||||||
cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
|
*map = cluster_offset | index_in_cluster;
|
||||||
*file = bs->file->bs;
|
*file = bs->file->bs;
|
||||||
status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset;
|
status |= BDRV_BLOCK_OFFSET_VALID;
|
||||||
}
|
}
|
||||||
if (ret == QCOW2_CLUSTER_ZERO_PLAIN || ret == QCOW2_CLUSTER_ZERO_ALLOC) {
|
if (ret == QCOW2_CLUSTER_ZERO_PLAIN || ret == QCOW2_CLUSTER_ZERO_ALLOC) {
|
||||||
status |= BDRV_BLOCK_ZERO;
|
status |= BDRV_BLOCK_ZERO;
|
||||||
@ -4352,7 +4354,7 @@ BlockDriver bdrv_qcow2 = {
|
|||||||
.bdrv_child_perm = bdrv_format_default_perms,
|
.bdrv_child_perm = bdrv_format_default_perms,
|
||||||
.bdrv_create = qcow2_create,
|
.bdrv_create = qcow2_create,
|
||||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||||
.bdrv_co_get_block_status = qcow2_co_get_block_status,
|
.bdrv_co_block_status = qcow2_co_block_status,
|
||||||
|
|
||||||
.bdrv_co_preadv = qcow2_co_preadv,
|
.bdrv_co_preadv = qcow2_co_preadv,
|
||||||
.bdrv_co_pwritev = qcow2_co_pwritev,
|
.bdrv_co_pwritev = qcow2_co_pwritev,
|
||||||
|
Loading…
Reference in New Issue
Block a user