diff options
author | Kevin Wolf <kwolf@redhat.com> | 2012-03-02 19:35:58 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2012-03-12 15:14:07 +0100 |
commit | 256900b16b0264af9e165bceabbf74dcece4ea38 (patch) | |
tree | 396c9278779d88bc4bb831b3b58780867a69d3ff | |
parent | bf319ece56bc07608bfdf46b8ef5c61b52be83f6 (diff) |
qcow2: Add qcow2_alloc_clusters_at()
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 <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
-rw-r--r-- | block/qcow2-refcount.c | 28 | ||||
-rw-r--r-- | block/qcow2.h | 2 |
2 files changed, 30 insertions, 0 deletions
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 2db2ede3d1..f39928a6bf 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 fc35838175..5129e3eab9 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); |