[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 11/17] block: return get_block_status data and f
From: |
Fam Zheng |
Subject: |
Re: [Qemu-devel] [PATCH 11/17] block: return get_block_status data and flags for formats |
Date: |
Thu, 4 Jul 2013 11:22:25 +0800 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Wed, 07/03 16:34, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <address@hidden>
> ---
> block/cow.c | 8 +++++++-
> block/qcow.c | 9 ++++++++-
> block/qcow2.c | 16 ++++++++++++++--
> block/qed.c | 35 ++++++++++++++++++++++++++++-------
> block/sheepdog.c | 2 +-
> block/vdi.c | 13 ++++++++++++-
> block/vmdk.c | 16 +++++++++++++++-
> block/vvfat.c | 11 ++++++-----
> 8 files changed, 91 insertions(+), 19 deletions(-)
>
> diff --git a/block/cow.c b/block/cow.c
> index efe5ead..f6982d4 100644
> --- a/block/cow.c
> +++ b/block/cow.c
> @@ -194,7 +194,13 @@ static int coroutine_fn
> cow_co_is_allocated(BlockDriverState *bs,
> static int64_t coroutine_fn cow_co_get_block_status(BlockDriverState *bs,
> int64_t sector_num, int nb_sectors, int *num_same)
> {
> - return cow_co_is_allocated(bs, sector_num, nb_sectors, num_same);
> + BDRVCowState *s = bs->opaque;
> + int ret = cow_co_is_allocated(bs, sector_num, nb_sectors, num_same);
> + int64_t offset = s->cow_sectors_offset + (sector_num <<
> BDRV_SECTOR_BITS);
> + if (ret < 0) {
> + return ret;
> + }
> + return (ret ? BDRV_BLOCK_DATA : 0) | offset | BDRV_BLOCK_OFFSET_VALID;
> }
>
> static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
> diff --git a/block/qcow.c b/block/qcow.c
> index acd1aeb..9aebcc3 100644
> --- a/block/qcow.c
> +++ b/block/qcow.c
> @@ -410,7 +410,14 @@ static int64_t coroutine_fn
> qcow_co_get_block_status(BlockDriverState *bs,
> if (n > nb_sectors)
> n = nb_sectors;
> *pnum = n;
> - return (cluster_offset != 0);
> + if (!cluster_offset) {
> + return 0;
> + }
> + if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypt_method) {
> + return BDRV_BLOCK_DATA;
> + }
> + cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
> + return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | cluster_offset;
> }
>
> static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
> diff --git a/block/qcow2.c b/block/qcow2.c
> index d35a134..cac7ee8 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -645,7 +645,8 @@ static int64_t coroutine_fn
> qcow2_co_get_block_status(BlockDriverState *bs,
> {
> BDRVQcowState *s = bs->opaque;
> uint64_t cluster_offset;
> - int ret;
> + int index_in_cluster, ret;
> + int64_t status = 0;
>
> *pnum = nb_sectors;
> qemu_co_mutex_lock(&s->lock);
> @@ -655,7 +656,18 @@ static int64_t coroutine_fn
> qcow2_co_get_block_status(BlockDriverState *bs,
> return ret;
> }
>
> - return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
> + if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
> + !s->crypt_method) {
> + index_in_cluster = sector_num & (s->cluster_sectors - 1);
> + cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
> + status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset;
> + }
> + if (ret == QCOW2_CLUSTER_ZERO) {
> + status |= BDRV_BLOCK_ZERO;
> + } else if (ret != QCOW2_CLUSTER_UNALLOCATED) {
> + status |= BDRV_BLOCK_DATA;
> + }
> + return status;
> }
>
> /* handle reading after the end of the backing file */
> diff --git a/block/qed.c b/block/qed.c
> index b0978ba..cf4fbed 100644
> --- a/block/qed.c
> +++ b/block/qed.c
> @@ -652,16 +652,36 @@ static int bdrv_qed_create(const char *filename,
> QEMUOptionParameter *options)
> }
>
> typedef struct {
> + BlockDriverState *bs;
> Coroutine *co;
> - int is_allocated;
> + uint64_t pos;
> + int64_t status;
> int *pnum;
> } QEDIsAllocatedCB;
>
> static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset,
> size_t len)
> {
> QEDIsAllocatedCB *cb = opaque;
> + BDRVQEDState *s = cb->bs->opaque;
> *cb->pnum = len / BDRV_SECTOR_SIZE;
> - cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO);
> + switch (ret) {
> + case QED_CLUSTER_FOUND:
> + offset |= qed_offset_into_cluster(s, cb->pos);
> + cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
> + break;
> + case QED_CLUSTER_ZERO:
> + cb->status = BDRV_BLOCK_ZERO;
> + break;
> + case QED_CLUSTER_L2:
> + case QED_CLUSTER_L1:
> + cb->status = 0;
> + break;
> + default:
> + assert(ret < 0);
> + cb->status = ret;
> + break;
> + }
> +
> if (cb->co) {
> qemu_coroutine_enter(cb->co, NULL);
> }
> @@ -672,25 +692,26 @@ static int64_t coroutine_fn
> bdrv_qed_co_get_block_status(BlockDriverState *bs,
> int nb_sectors, int *pnum)
> {
> BDRVQEDState *s = bs->opaque;
> - uint64_t pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE;
> size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE;
> QEDIsAllocatedCB cb = {
> - .is_allocated = -1,
> + .bs = bs,
> + .pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE,
> + .status = BDRV_BLOCK_OFFSET_MASK,
> .pnum = pnum,
> };
> QEDRequest request = { .l2_table = NULL };
>
> - qed_find_cluster(s, &request, pos, len, qed_is_allocated_cb, &cb);
> + qed_find_cluster(s, &request, cb.pos, len, qed_is_allocated_cb, &cb);
>
> /* Now sleep if the callback wasn't invoked immediately */
> - while (cb.is_allocated == -1) {
> + while (cb.status == BDRV_BLOCK_OFFSET_MASK) {
> cb.co = qemu_coroutine_self();
> qemu_coroutine_yield();
> }
>
> qed_unref_l2_cache_entry(request.l2_table);
>
> - return cb.is_allocated;
> + return cb.status;
> }
>
> static int bdrv_qed_make_empty(BlockDriverState *bs)
> diff --git a/block/sheepdog.c b/block/sheepdog.c
> index e7b9c22..3dca26a 100644
> --- a/block/sheepdog.c
> +++ b/block/sheepdog.c
> @@ -2297,7 +2297,7 @@ sd_co_get_block_status(BlockDriverState *bs, int64_t
> sector_num, int nb_sectors,
> end = DIV_ROUND_UP((sector_num + nb_sectors) *
> BDRV_SECTOR_SIZE, SD_DATA_OBJ_SIZE);
> unsigned long idx;
> - int ret = 1;
> + int64_t ret = BDRV_BLOCK_DATA;
>
> for (idx = start; idx < end; idx++) {
> if (inode->data_vdi_id[idx] == 0) {
> diff --git a/block/vdi.c b/block/vdi.c
> index 7ab2567..e96b5b3 100644
> --- a/block/vdi.c
> +++ b/block/vdi.c
> @@ -479,12 +479,23 @@ static int64_t coroutine_fn
> vdi_co_get_block_status(BlockDriverState *bs,
> size_t sector_in_block = sector_num % s->block_sectors;
> int n_sectors = s->block_sectors - sector_in_block;
> uint32_t bmap_entry = le32_to_cpu(s->bmap[bmap_index]);
> + uint64_t offset;
> + int result;
> +
> logout("%p, %" PRId64 ", %d, %p\n", bs, sector_num, nb_sectors, pnum);
> if (n_sectors > nb_sectors) {
> n_sectors = nb_sectors;
> }
> *pnum = n_sectors;
> - return VDI_IS_ALLOCATED(bmap_entry);
> + result = VDI_IS_ALLOCATED(bmap_entry);
> + if (!result) {
> + return 0;
> + }
> +
> + offset = s->header.offset_data +
> + (uint64_t)bmap_entry * s->block_size +
> + sector_in_block * SECTOR_SIZE;
> + return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
> }
>
> static int vdi_co_read(BlockDriverState *bs,
> diff --git a/block/vmdk.c b/block/vmdk.c
> index e24f6c7..f829620 100644
> --- a/block/vmdk.c
> +++ b/block/vmdk.c
> @@ -1015,7 +1015,21 @@ static int64_t coroutine_fn
> vmdk_co_get_block_status(BlockDriverState *bs,
> sector_num * 512, 0, &offset);
> qemu_co_mutex_unlock(&s->lock);
>
> - ret = (ret == VMDK_OK || ret == VMDK_ZEROED);
> + switch (ret) {
> + case VMDK_ERROR:
> + ret = -EIO;
> + break;
> + case VMDK_UNALLOC:
> + ret = 0;
> + break;
> + case VMDK_ZEROED:
> + ret = BDRV_BLOCK_ZERO;
> + break;
> + case VMDK_OK:
> + /* TODO: might return offset if the extents are in bs->file. */
> + ret = BDRV_BLOCK_DATA;
if (extent->file == bs->file) {
ret |= BDRV_BLOCK_OFFSET_VALID | offset;
}
> + break;
> + }
>
> index_in_cluster = sector_num % extent->cluster_sectors;
> n = extent->cluster_sectors - index_in_cluster;
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 510a559..415fba3 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -2879,11 +2879,12 @@ static int64_t coroutine_fn
> vvfat_co_get_block_status(BlockDriverState *bs,
> {
> BDRVVVFATState* s = bs->opaque;
> *n = s->sector_count - sector_num;
> - if (*n > nb_sectors)
> - *n = nb_sectors;
> - else if (*n < 0)
> - return 0;
> - return 1;
> + if (*n > nb_sectors) {
> + *n = nb_sectors;
> + } else if (*n < 0) {
> + return 0;
> + }
> + return BDRV_BLOCK_DATA;
> }
>
> static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
> --
> 1.8.2.1
>
>
>
--
Fam
- [Qemu-devel] [PATCH 12/17] qemu-img: add a "map" subcommand, (continued)
[Qemu-devel] [PATCH 11/17] block: return get_block_status data and flags for formats, Paolo Bonzini, 2013/07/03
- Re: [Qemu-devel] [PATCH 11/17] block: return get_block_status data and flags for formats,
Fam Zheng <=
[Qemu-devel] [PATCH 14/17] raw-posix: return get_block_status data and flags, Paolo Bonzini, 2013/07/03
[Qemu-devel] [PATCH 13/17] block: use bdrv_has_zero_init to return BDRV_BLOCK_ZERO, Paolo Bonzini, 2013/07/03
[Qemu-devel] [PATCH 15/17] raw-posix: detect XFS unwritten extents, Paolo Bonzini, 2013/07/03
[Qemu-devel] [PATCH 16/17] block: add default get_block_status implementation for protocols, Paolo Bonzini, 2013/07/03