From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33086) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z1q2x-0007vd-EV for qemu-devel@nongnu.org; Mon, 08 Jun 2015 01:56:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z1q2w-00006m-Bn for qemu-devel@nongnu.org; Mon, 08 Jun 2015 01:56:31 -0400 From: Fam Zheng Date: Mon, 8 Jun 2015 13:56:07 +0800 Message-Id: <1433742974-20128-2-git-send-email-famz@redhat.com> In-Reply-To: <1433742974-20128-1-git-send-email-famz@redhat.com> References: <1433742974-20128-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [PATCH v7 1/8] block: Add bdrv_get_block_status_above List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, Jeff Cody , qemu-stable@nongnu.org, Stefan Hajnoczi , pbonzini@redhat.com, jsnow@redhat.com, wangxiaolong@ucloud.cn Like bdrv_is_allocated_above, this function follows the backing chain until seeing BDRV_BLOCK_ALLOCATED. Base is not included. Reimplement bdrv_is_allocated on top. Signed-off-by: Fam Zheng --- block/io.c | 56 +++++++++++++++++++++++++++++++++++++++++---------- include/block/block.h | 4 ++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/block/io.c b/block/io.c index e394d92..41463a6 100644 --- a/block/io.c +++ b/block/io.c @@ -1560,28 +1560,54 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, return ret; } -/* Coroutine wrapper for bdrv_get_block_status() */ -static void coroutine_fn bdrv_get_block_status_co_entry(void *opaque) +static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs, + BlockDriverState *base, + int64_t sector_num, + int nb_sectors, + int *pnum) +{ + BlockDriverState *p; + int64_t ret; + + assert(bs != base); + for (p = bs; p != base; p = p->backing_hd) { + ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum); + if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) { + break; + } + /* [sector_num, pnum] unallocated on this layer, which could be only + * the first part of [sector_num, nb_sectors]. */ + nb_sectors = MIN(nb_sectors, *pnum); + } + return ret; +} + +/* Coroutine wrapper for bdrv_get_block_status_above() */ +static void coroutine_fn bdrv_get_block_status_above_co_entry(void *opaque) { BdrvCoGetBlockStatusData *data = opaque; - BlockDriverState *bs = data->bs; - data->ret = bdrv_co_get_block_status(bs, data->sector_num, data->nb_sectors, - data->pnum); + data->ret = bdrv_co_get_block_status_above(data->bs, data->base, + data->sector_num, + data->nb_sectors, + data->pnum); data->done = true; } /* - * Synchronous wrapper around bdrv_co_get_block_status(). + * Synchronous wrapper around bdrv_co_get_block_status_above(). * - * See bdrv_co_get_block_status() for details. + * See bdrv_co_get_block_status_above() for details. */ -int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) +int64_t bdrv_get_block_status_above(BlockDriverState *bs, + BlockDriverState *base, + int64_t sector_num, + int nb_sectors, int *pnum) { Coroutine *co; BdrvCoGetBlockStatusData data = { .bs = bs, + .base = base, .sector_num = sector_num, .nb_sectors = nb_sectors, .pnum = pnum, @@ -1590,11 +1616,11 @@ int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, if (qemu_in_coroutine()) { /* Fast-path if already in coroutine context */ - bdrv_get_block_status_co_entry(&data); + bdrv_get_block_status_above_co_entry(&data); } else { AioContext *aio_context = bdrv_get_aio_context(bs); - co = qemu_coroutine_create(bdrv_get_block_status_co_entry); + co = qemu_coroutine_create(bdrv_get_block_status_above_co_entry); qemu_coroutine_enter(co, &data); while (!data.done) { aio_poll(aio_context, true); @@ -1603,6 +1629,14 @@ int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, return data.ret; } +int64_t bdrv_get_block_status(BlockDriverState *bs, + int64_t sector_num, + int nb_sectors, int *pnum) +{ + return bdrv_get_block_status_above(bs, bs->backing_hd, + sector_num, nb_sectors, pnum); +} + int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { diff --git a/include/block/block.h b/include/block/block.h index f7680b6..4d9b555 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -361,6 +361,10 @@ bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs); bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); +int64_t bdrv_get_block_status_above(BlockDriverState *bs, + BlockDriverState *base, + int64_t sector_num, + int nb_sectors, int *pnum); int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, -- 2.4.2