summaryrefslogtreecommitdiff
path: root/block/qcow2-refcount.c
diff options
context:
space:
mode:
authorMax Reitz <mreitz@redhat.com>2015-09-14 16:39:47 +0200
committerKevin Wolf <kwolf@redhat.com>2015-09-14 16:51:37 +0200
commitb6d36def6d9e9fd187327182d0abafc9b7085d8f (patch)
tree475f42def1a1636491174996483a98ba323276b2 /block/qcow2-refcount.c
parent231f66d2a3401473778c70a75d5f670765ab6d91 (diff)
downloadqemu-b6d36def6d9e9fd187327182d0abafc9b7085d8f.tar.gz
qcow2: Make size_to_clusters() return uint64_t
Sadly, some images may have more clusters than what can be represented using a plain int. We should be prepared for that case (in qcow2_check_refcounts() we actually were trying to catch that case, but since size_to_clusters() truncated the returned value, that check never did anything useful). Cc: qemu-stable <qemu-stable@nongnu.org> Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/qcow2-refcount.c')
-rw-r--r--block/qcow2-refcount.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index b780bb92c6..a49d59e71e 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -875,8 +875,8 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size)
return offset;
}
-int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
- int nb_clusters)
+int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
+ int64_t nb_clusters)
{
BDRVQcow2State *s = bs->opaque;
uint64_t cluster_index, refcount;
@@ -1259,7 +1259,7 @@ static size_t refcount_array_byte_size(BDRVQcow2State *s, uint64_t entries)
static int realloc_refcount_array(BDRVQcow2State *s, void **array,
int64_t *size, int64_t new_size)
{
- size_t old_byte_size, new_byte_size;
+ int64_t old_byte_size, new_byte_size;
void *new_ptr;
/* Round to clusters so the array can be directly written to disk */
@@ -1275,13 +1275,17 @@ static int realloc_refcount_array(BDRVQcow2State *s, void **array,
assert(new_byte_size > 0);
+ if (new_byte_size > SIZE_MAX) {
+ return -ENOMEM;
+ }
+
new_ptr = g_try_realloc(*array, new_byte_size);
if (!new_ptr) {
return -ENOMEM;
}
if (new_byte_size > old_byte_size) {
- memset((void *)((uintptr_t)new_ptr + old_byte_size), 0,
+ memset((char *)new_ptr + old_byte_size, 0,
new_byte_size - old_byte_size);
}