From patchwork Mon Jun 4 11:13:22 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 162769 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AB163B6FB6 for ; Mon, 4 Jun 2012 21:52:21 +1000 (EST) Received: from localhost ([::1]:33132 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SbVEu-0006Eh-GW for incoming@patchwork.ozlabs.org; Mon, 04 Jun 2012 07:14:24 -0400 Received: from eggs.gnu.org ([208.118.235.92]:56073) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SbVEE-0004HT-QW for qemu-devel@nongnu.org; Mon, 04 Jun 2012 07:13:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SbVEB-0005zC-G4 for qemu-devel@nongnu.org; Mon, 04 Jun 2012 07:13:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37494) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SbVEB-0005ym-7M for qemu-devel@nongnu.org; Mon, 04 Jun 2012 07:13:39 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q54BDblG006238 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 4 Jun 2012 07:13:37 -0400 Received: from dhcp-5-188.str.redhat.com (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q54BDUCq004265; Mon, 4 Jun 2012 07:13:36 -0400 From: Kevin Wolf To: anthony@codemonkey.ws Date: Mon, 4 Jun 2012 13:13:22 +0200 Message-Id: <1338808409-19501-6-git-send-email-kwolf@redhat.com> In-Reply-To: <1338808409-19501-1-git-send-email-kwolf@redhat.com> References: <1338808409-19501-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 05/12] stream: move is_allocated_above to block.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Paolo Bonzini Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf --- block.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 4 ++++ block/stream.c | 53 ++--------------------------------------------------- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/block.c b/block.c index 7547051..c07ff39 100644 --- a/block.c +++ b/block.c @@ -2569,6 +2569,55 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, return data.ret; } +/* + * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] + * + * Return true if the given sector is allocated in any image between + * BASE and TOP (inclusive). BASE can be NULL to check if the given + * sector is allocated in any image of the chain. Return false otherwise. + * + * 'pnum' is set to the number of sectors (including and immediately following + * the specified sector) that are known to be in the same + * allocated/unallocated state. + * + */ +int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, + BlockDriverState *base, + int64_t sector_num, + int nb_sectors, int *pnum) +{ + BlockDriverState *intermediate; + int ret, n = nb_sectors; + + intermediate = top; + while (intermediate && intermediate != base) { + int pnum_inter; + ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors, + &pnum_inter); + if (ret < 0) { + return ret; + } else if (ret) { + *pnum = pnum_inter; + return 1; + } + + /* + * [sector_num, nb_sectors] is unallocated on top but intermediate + * might have + * + * [sector_num+x, nr_sectors] allocated. + */ + if (n > pnum_inter) { + n = pnum_inter; + } + + intermediate = intermediate->backing_hd; + } + + *pnum = n; + return 0; +} + BlockInfoList *qmp_query_block(Error **errp) { BlockInfoList *head = NULL, *cur_item = NULL; diff --git a/block.h b/block.h index 7408acc..799cf48 100644 --- a/block.h +++ b/block.h @@ -165,6 +165,10 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); +int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top, + BlockDriverState *base, + int64_t sector_num, + int nb_sectors, int *pnum); BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_truncate(BlockDriverState *bs, int64_t offset); diff --git a/block/stream.c b/block/stream.c index 4490a25..811388a 100644 --- a/block/stream.c +++ b/block/stream.c @@ -98,55 +98,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, top->backing_hd = base; } -/* - * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP] - * - * Return true if the given sector is allocated in any image between - * BASE and TOP (inclusive). BASE can be NULL to check if the given - * sector is allocated in any image of the chain. Return false otherwise. - * - * 'pnum' is set to the number of sectors (including and immediately following - * the specified sector) that are known to be in the same - * allocated/unallocated state. - * - */ -static int coroutine_fn is_allocated_above(BlockDriverState *top, - BlockDriverState *base, - int64_t sector_num, - int nb_sectors, int *pnum) -{ - BlockDriverState *intermediate; - int ret, n = nb_sectors; - - intermediate = top; - while (intermediate != base) { - int pnum_inter; - ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors, - &pnum_inter); - if (ret < 0) { - return ret; - } else if (ret) { - *pnum = pnum_inter; - return 1; - } - - /* - * [sector_num, nb_sectors] is unallocated on top but intermediate - * might have - * - * [sector_num+x, nr_sectors] allocated. - */ - if (n > pnum_inter) { - n = pnum_inter; - } - - intermediate = intermediate->backing_hd; - } - - *pnum = n; - return 0; -} - static void coroutine_fn stream_run(void *opaque) { StreamBlockJob *s = opaque; @@ -196,10 +147,10 @@ wait: } else { /* Copy if allocated in the intermediate images. Limit to the * known-unallocated area [sector_num, sector_num+n). */ - ret = is_allocated_above(bs->backing_hd, base, sector_num, n, &n); + ret = bdrv_co_is_allocated_above(bs->backing_hd, base, + sector_num, n, &n); copy = (ret == 1); } - trace_stream_one_iteration(s, sector_num, n, ret); if (ret >= 0 && copy) { if (s->common.speed) {