qcow2: Allow alloc_clusters_noref to return errors
Currently it would consider blocks for which get_refcount fails used. However, it's unlikely that get_refcount would succeed for the next cluster, so it's not really helpful. Return an error instead. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
018faafdbd
commit
2eaa8f6338
@ -228,7 +228,10 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the refcount block itself and mark it as used */
|
/* Allocate the refcount block itself and mark it as used */
|
||||||
uint64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
|
int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
|
||||||
|
if (new_block < 0) {
|
||||||
|
return new_block;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ALLOC2
|
#ifdef DEBUG_ALLOC2
|
||||||
fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64
|
fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64
|
||||||
@ -579,14 +582,19 @@ static int update_cluster_refcount(BlockDriverState *bs,
|
|||||||
static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
|
static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int i, nb_clusters;
|
int i, nb_clusters, refcount;
|
||||||
|
|
||||||
nb_clusters = size_to_clusters(s, size);
|
nb_clusters = size_to_clusters(s, size);
|
||||||
retry:
|
retry:
|
||||||
for(i = 0; i < nb_clusters; i++) {
|
for(i = 0; i < nb_clusters; i++) {
|
||||||
int64_t next_cluster_index = s->free_cluster_index++;
|
int64_t next_cluster_index = s->free_cluster_index++;
|
||||||
if (get_refcount(bs, next_cluster_index) != 0)
|
refcount = get_refcount(bs, next_cluster_index);
|
||||||
|
|
||||||
|
if (refcount < 0) {
|
||||||
|
return refcount;
|
||||||
|
} else if (refcount != 0) {
|
||||||
goto retry;
|
goto retry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_ALLOC2
|
#ifdef DEBUG_ALLOC2
|
||||||
printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
|
printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
|
||||||
@ -603,6 +611,10 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
|
|||||||
|
|
||||||
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
|
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
|
||||||
offset = alloc_clusters_noref(bs, size);
|
offset = alloc_clusters_noref(bs, size);
|
||||||
|
if (offset < 0) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
ret = update_refcount(bs, offset, size, 1);
|
ret = update_refcount(bs, offset, size, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user