qcow2: Handle EAGAIN returned from update_refcount

Fixes a crash during image compression

Signed-off-by: Jindřich Makovička <makovick@gmail.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Jindřich Makovička 2015-06-24 07:05:25 +02:00 committed by Stefan Hajnoczi
parent 5dd7a535b7
commit 3e5feb6202

View file

@ -940,19 +940,21 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
} }
free_in_cluster = s->cluster_size - offset_into_cluster(s, offset); free_in_cluster = s->cluster_size - offset_into_cluster(s, offset);
if (!offset || free_in_cluster < size) { do {
int64_t new_cluster = alloc_clusters_noref(bs, s->cluster_size); if (!offset || free_in_cluster < size) {
if (new_cluster < 0) { int64_t new_cluster = alloc_clusters_noref(bs, s->cluster_size);
return new_cluster; if (new_cluster < 0) {
return new_cluster;
}
if (!offset || ROUND_UP(offset, s->cluster_size) != new_cluster) {
offset = new_cluster;
}
} }
if (!offset || ROUND_UP(offset, s->cluster_size) != new_cluster) { assert(offset);
offset = new_cluster; ret = update_refcount(bs, offset, size, 1, false, QCOW2_DISCARD_NEVER);
} } while (ret == -EAGAIN);
}
assert(offset);
ret = update_refcount(bs, offset, size, 1, false, QCOW2_DISCARD_NEVER);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }