Skip to content

Commit

Permalink
qcow2: Make qcow2_alloc_bytes() more explicit
Browse files Browse the repository at this point in the history
In case of -EAGAIN returned by update_refcount(), we should discard the
cluster offset we were trying to allocate and request a new one, because
in theory that old offset might now be taken by a refcount block.

In practice, this was not the case due to update_refcount() generally
returning strictly monotonic increasing cluster offsets. However, this
behavior is not set in stone, and it is also not obvious when looking at
qcow2_alloc_bytes() alone, so we should not rely on it.

Reported-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
XanClic authored and kevmw committed Sep 14, 2015
1 parent 3efffc3 commit 2ac0152
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions block/qcow2-refcount.c
Expand Up @@ -949,11 +949,17 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)

if (!offset || ROUND_UP(offset, s->cluster_size) != new_cluster) {
offset = new_cluster;
free_in_cluster = s->cluster_size;
} else {
free_in_cluster += s->cluster_size;
}
}

assert(offset);
ret = update_refcount(bs, offset, size, 1, false, QCOW2_DISCARD_NEVER);
if (ret < 0) {
offset = 0;
}
} while (ret == -EAGAIN);
if (ret < 0) {
return ret;
Expand Down

0 comments on commit 2ac0152

Please sign in to comment.