From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:39274) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S76ze-0001OT-2j for qemu-devel@nongnu.org; Mon, 12 Mar 2012 11:17:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S76zG-0005QA-Lr for qemu-devel@nongnu.org; Mon, 12 Mar 2012 11:17:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48248) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S76zG-0005Pp-Ef for qemu-devel@nongnu.org; Mon, 12 Mar 2012 11:16:38 -0400 From: Kevin Wolf Date: Mon, 12 Mar 2012 16:19:46 +0100 Message-Id: <1331565591-8414-16-git-send-email-kwolf@redhat.com> In-Reply-To: <1331565591-8414-1-git-send-email-kwolf@redhat.com> References: <1331565591-8414-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 15/20] qcow2: Add qcow2_alloc_clusters_at() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org This function allows to allocate clusters at a given offset in the image file. This is useful if you want to allocate the second part of an area that must be contiguous. Signed-off-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi --- block/qcow2-refcount.c | 28 ++++++++++++++++++++++++++++ block/qcow2.h | 2 ++ 2 files changed, 30 insertions(+), 0 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 2db2ede..f39928a 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -582,6 +582,34 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size) return offset; } +int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, + int nb_clusters) +{ + BDRVQcowState *s = bs->opaque; + uint64_t cluster_index; + int i, refcount, ret; + + /* Check how many clusters there are free */ + cluster_index = offset >> s->cluster_bits; + for(i = 0; i < nb_clusters; i++) { + refcount = get_refcount(bs, cluster_index++); + + if (refcount < 0) { + return refcount; + } else if (refcount != 0) { + break; + } + } + + /* And then allocate them */ + ret = update_refcount(bs, offset, i << s->cluster_bits, 1); + if (ret < 0) { + return ret; + } + + return i; +} + /* only used to allocate compressed sectors. We try to allocate contiguous sectors. size must be <= cluster_size */ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size) diff --git a/block/qcow2.h b/block/qcow2.h index fc35838..5129e3e 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -193,6 +193,8 @@ int qcow2_refcount_init(BlockDriverState *bs); void qcow2_refcount_close(BlockDriverState *bs); int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size); +int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, + int nb_clusters); int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size); void qcow2_free_clusters(BlockDriverState *bs, int64_t offset, int64_t size); -- 1.7.6.5