aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2010-02-25 23:20:30 -0300
committerMarcelo Tosatti <mtosatti@redhat.com>2010-02-25 23:20:30 -0300
commit25de3b156c5e35b1a46acccd8293212d5d9cf231 (patch)
treeb4d7d29e8cbf87896dad45d6afd435556a94106a /block
parentMerge commit 'c502715a74675b3554cf7bcd684b82c9733ecfae' into stable-0.12-merge (diff)
parentcirrus: Properly re-register cirrus_linear_io_addr on vram unmap (diff)
downloadqemu-kvm-25de3b156c5e35b1a46acccd8293212d5d9cf231.tar.gz
qemu-kvm-25de3b156c5e35b1a46acccd8293212d5d9cf231.tar.bz2
qemu-kvm-25de3b156c5e35b1a46acccd8293212d5d9cf231.zip
Merge commit '299e0bc52a5d56ff89ad8d7d09c82233cd8ccb6a' into stable-0.12-merge
* commit '299e0bc52a5d56ff89ad8d7d09c82233cd8ccb6a': cirrus: Properly re-register cirrus_linear_io_addr on vram unmap qcow2: Don't ignore qcow2_alloc_clusters return value qcow2: Don't ignore update_refcount return value qcow2: Allow updating no refcounts qcow2: Improve error handling in update_refcount qcow2: Fix error handling in grow_refcount_table block: Return original error codes in bdrv_pread/write qcow2: Return 0/-errno in qcow2_alloc_cluster_offset qcow2: Return 0/-errno in get_cluster_table qcow2: Fix error handling in qcow_save_vmstate qcow2: Fix error handling in qcow2_grow_l1_table win32/sdl: Fix toggle full screen win32: pair qemu_memalign() with qemu_vfree() vnc_refresh: calling vnc_update_client might free vs Musicpal: Fix descriptor walk in eth_send Musicpal: Fix wm8750 I2C address fix savevm command without id or tag reduce number of reinjects on ACK QMP: Fix asynchronous events delivery Conflicts: hw/cirrus_vga.c Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/qcow2-cluster.c87
-rw-r--r--block/qcow2-refcount.c84
-rw-r--r--block/qcow2-snapshot.c11
-rw-r--r--block/qcow2.c41
-rw-r--r--block/qcow2.h4
-rw-r--r--block/raw-posix.c2
6 files changed, 159 insertions, 70 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f88118cdc..4e30d161a 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -33,7 +33,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
BDRVQcowState *s = bs->opaque;
int new_l1_size, new_l1_size2, ret, i;
uint64_t *new_l1_table;
- uint64_t new_l1_table_offset;
+ int64_t new_l1_table_offset;
uint8_t data[12];
new_l1_size = s->l1_size;
@@ -55,6 +55,10 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
/* write new table (align to cluster) */
new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
+ if (new_l1_table_offset < 0) {
+ qemu_free(new_l1_table);
+ return new_l1_table_offset;
+ }
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
@@ -67,9 +71,10 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
/* set new table */
cpu_to_be32w((uint32_t*)data, new_l1_size);
cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,
- sizeof(data)) != sizeof(data))
+ ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,sizeof(data));
+ if (ret != sizeof(data)) {
goto fail;
+ }
qemu_free(s->l1_table);
qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
s->l1_table_offset = new_l1_table_offset;
@@ -77,8 +82,9 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
s->l1_size = new_l1_size;
return 0;
fail:
- qemu_free(s->l1_table);
- return -EIO;
+ qemu_free(new_l1_table);
+ qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
+ return ret < 0 ? ret : -EIO;
}
void qcow2_l2_cache_reset(BlockDriverState *bs)
@@ -220,6 +226,9 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)
/* allocate a new l2 entry */
l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
+ if (l2_offset < 0) {
+ return NULL;
+ }
/* update the L1 entry */
@@ -479,8 +488,8 @@ out:
* the l2 table offset in the qcow2 file and the cluster index
* in the l2 table are given to the caller.
*
+ * Returns 0 on success, -errno in failure case
*/
-
static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
uint64_t **new_l2_table,
uint64_t *new_l2_offset,
@@ -496,8 +505,9 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
l1_index = offset >> (s->l2_bits + s->cluster_bits);
if (l1_index >= s->l1_size) {
ret = qcow2_grow_l1_table(bs, l1_index + 1);
- if (ret < 0)
- return 0;
+ if (ret < 0) {
+ return ret;
+ }
}
l2_offset = s->l1_table[l1_index];
@@ -507,14 +517,16 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
/* load the l2 table in memory */
l2_offset &= ~QCOW_OFLAG_COPIED;
l2_table = l2_load(bs, l2_offset);
- if (l2_table == NULL)
- return 0;
+ if (l2_table == NULL) {
+ return -EIO;
+ }
} else {
if (l2_offset)
qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
l2_table = l2_allocate(bs, l1_index);
- if (l2_table == NULL)
- return 0;
+ if (l2_table == NULL) {
+ return -EIO;
+ }
l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
}
@@ -526,7 +538,7 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
*new_l2_offset = l2_offset;
*new_l2_index = l2_index;
- return 1;
+ return 0;
}
/*
@@ -552,8 +564,9 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
int nb_csectors;
ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
- if (ret == 0)
+ if (ret < 0) {
return 0;
+ }
cluster_offset = be64_to_cpu(l2_table[l2_index]);
if (cluster_offset & QCOW_OFLAG_COPIED)
@@ -563,6 +576,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
qcow2_free_any_clusters(bs, cluster_offset, 1);
cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
+ if (cluster_offset < 0) {
+ return 0;
+ }
+
nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
(cluster_offset >> 9);
@@ -605,12 +622,12 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,
return 0;
}
-int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
- QCowL2Meta *m)
+int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
{
BDRVQcowState *s = bs->opaque;
int i, j = 0, l2_index, ret;
uint64_t *old_cluster, start_sect, l2_offset, *l2_table;
+ uint64_t cluster_offset = m->cluster_offset;
if (m->nb_clusters == 0)
return 0;
@@ -633,10 +650,11 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
goto err;
}
- ret = -EIO;
/* update L2 table */
- if (!get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index))
+ ret = get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index);
+ if (ret < 0) {
goto err;
+ }
for (i = 0; i < m->nb_clusters; i++) {
/* if two concurrent writes happen to the same unallocated cluster
@@ -670,16 +688,22 @@ err:
/*
* alloc_cluster_offset
*
- * For a given offset of the disk image, return cluster offset in
- * qcow2 file.
- *
+ * For a given offset of the disk image, return cluster offset in qcow2 file.
* If the offset is not found, allocate a new cluster.
*
- * Return the cluster offset if successful,
- * Return 0, otherwise.
+ * If the cluster was already allocated, m->nb_clusters is set to 0,
+ * m->depends_on is set to NULL and the other fields in m are meaningless.
+ *
+ * If the cluster is newly allocated, m->nb_clusters is set to the number of
+ * contiguous clusters that have been allocated. This may be 0 if the request
+ * conflict with another write request in flight; in this case, m->depends_on
+ * is set and the remaining fields of m are meaningless.
*
+ * If m->nb_clusters is non-zero, the other fields of m are valid and contain
+ * information about the first allocated cluster.
+ *
+ * Return 0 on success and -errno in error cases
*/
-
uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int n_start, int n_end,
@@ -687,13 +711,15 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
{
BDRVQcowState *s = bs->opaque;
int l2_index, ret;
- uint64_t l2_offset, *l2_table, cluster_offset;
+ uint64_t l2_offset, *l2_table;
+ int64_t cluster_offset;
unsigned int nb_clusters, i = 0;
QCowL2Meta *old_alloc;
ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
- if (ret == 0)
- return 0;
+ if (ret < 0) {
+ return ret;
+ }
nb_clusters = size_to_clusters(s, n_end << 9);
@@ -709,6 +735,7 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
cluster_offset &= ~QCOW_OFLAG_COPIED;
m->nb_clusters = 0;
+ m->depends_on = NULL;
goto out;
}
@@ -779,6 +806,9 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
/* allocate a new cluster */
cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);
+ if (cluster_offset < 0) {
+ return cluster_offset;
+ }
/* save info needed for meta data update */
m->offset = offset;
@@ -787,10 +817,11 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
out:
m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end);
+ m->cluster_offset = cluster_offset;
*num = m->nb_available - n_start;
- return cluster_offset;
+ return 0;
}
static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 54b19f86d..c2a5c0471 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -168,9 +168,12 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size)
cpu_to_be64w((uint64_t*)data, table_offset);
cpu_to_be32w((uint32_t*)(data + 8), refcount_table_clusters);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
- data, sizeof(data)) != sizeof(data))
+ ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
+ data, sizeof(data));
+ if (ret != sizeof(data)) {
goto fail;
+ }
+
qemu_free(s->refcount_table);
old_table_offset = s->refcount_table_offset;
old_table_size = s->refcount_table_size;
@@ -183,7 +186,7 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size)
return 0;
fail:
qemu_free(new_table);
- return -EIO;
+ return ret < 0 ? ret : -EIO;
}
@@ -266,22 +269,26 @@ static int write_refcount_block_entries(BDRVQcowState *s,
}
/* XXX: cache several refcount block clusters ? */
-static int update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
- int addend)
+static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
+ int64_t offset, int64_t length, int addend)
{
BDRVQcowState *s = bs->opaque;
int64_t start, last, cluster_offset;
int64_t refcount_block_offset = 0;
int64_t table_index = -1, old_table_index;
int first_index = -1, last_index = -1;
+ int ret;
#ifdef DEBUG_ALLOC2
printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
offset, length, addend);
#endif
- if (length <= 0)
+ if (length < 0) {
return -EINVAL;
+ } else if (length == 0) {
+ return 0;
+ }
+
start = offset & ~(s->cluster_size - 1);
last = (offset + length - 1) & ~(s->cluster_size - 1);
for(cluster_offset = start; cluster_offset <= last;
@@ -289,6 +296,7 @@ static int update_refcount(BlockDriverState *bs,
{
int block_index, refcount;
int64_t cluster_index = cluster_offset >> s->cluster_bits;
+ int64_t new_block;
/* Only write refcount block to disk when we are done with it */
old_table_index = table_index;
@@ -306,10 +314,12 @@ static int update_refcount(BlockDriverState *bs,
}
/* Load the refcount block and allocate it if needed */
- refcount_block_offset = alloc_refcount_block(bs, cluster_index);
- if (refcount_block_offset < 0) {
- return refcount_block_offset;
+ new_block = alloc_refcount_block(bs, cluster_index);
+ if (new_block < 0) {
+ ret = new_block;
+ goto fail;
}
+ refcount_block_offset = new_block;
/* we can update the count and save it */
block_index = cluster_index &
@@ -323,24 +333,38 @@ static int update_refcount(BlockDriverState *bs,
refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
refcount += addend;
- if (refcount < 0 || refcount > 0xffff)
- return -EINVAL;
+ if (refcount < 0 || refcount > 0xffff) {
+ ret = -EINVAL;
+ goto fail;
+ }
if (refcount == 0 && cluster_index < s->free_cluster_index) {
s->free_cluster_index = cluster_index;
}
s->refcount_block_cache[block_index] = cpu_to_be16(refcount);
}
+ ret = 0;
+fail:
+
/* Write last changed block to disk */
if (refcount_block_offset != 0) {
if (write_refcount_block_entries(s, refcount_block_offset,
first_index, last_index) < 0)
{
- return -EIO;
+ return ret < 0 ? ret : -EIO;
}
}
- return 0;
+ /*
+ * Try do undo any updates if an error is returned (This may succeed in
+ * some cases like ENOSPC for allocating a new refcount block)
+ */
+ if (ret < 0) {
+ int dummy;
+ dummy = update_refcount(bs, offset, cluster_offset - offset, -addend);
+ }
+
+ return ret;
}
/* addend must be 1 or -1 */
@@ -390,9 +414,13 @@ retry:
int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
{
int64_t offset;
+ int ret;
offset = alloc_clusters_noref(bs, size);
- update_refcount(bs, offset, size, 1);
+ ret = update_refcount(bs, offset, size, 1);
+ if (ret < 0) {
+ return ret;
+ }
return offset;
}
@@ -407,6 +435,9 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
assert(size > 0 && size <= s->cluster_size);
if (s->free_byte_offset == 0) {
s->free_byte_offset = qcow2_alloc_clusters(bs, s->cluster_size);
+ if (s->free_byte_offset < 0) {
+ return s->free_byte_offset;
+ }
}
redo:
free_in_cluster = s->cluster_size -
@@ -422,6 +453,9 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
update_cluster_refcount(bs, offset >> s->cluster_bits, 1);
} else {
offset = qcow2_alloc_clusters(bs, s->cluster_size);
+ if (offset < 0) {
+ return offset;
+ }
cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1);
if ((cluster_offset + s->cluster_size) == offset) {
/* we are lucky: contiguous data */
@@ -439,7 +473,13 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
void qcow2_free_clusters(BlockDriverState *bs,
int64_t offset, int64_t size)
{
- update_refcount(bs, offset, size, -1);
+ int ret;
+
+ ret = update_refcount(bs, offset, size, -1);
+ if (ret < 0) {
+ fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret));
+ abort();
+ }
}
/*
@@ -549,9 +589,15 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (offset & QCOW_OFLAG_COMPRESSED) {
nb_csectors = ((offset >> s->csize_shift) &
s->csize_mask) + 1;
- if (addend != 0)
- update_refcount(bs, (offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512, addend);
+ if (addend != 0) {
+ int ret;
+ ret = update_refcount(bs,
+ (offset & s->cluster_offset_mask) & ~511,
+ nb_csectors * 512, addend);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
/* compressed clusters are never modified */
refcount = 2;
} else {
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index d63c7e17d..8ddaea23b 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -139,6 +139,9 @@ static int qcow_write_snapshots(BlockDriverState *bs)
snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
offset = snapshots_offset;
+ if (offset < 0) {
+ return offset;
+ }
for(i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
@@ -235,6 +238,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
QCowSnapshot *snapshots1, sn1, *sn = &sn1;
int i, ret;
uint64_t *l1_table = NULL;
+ int64_t l1_table_offset;
memset(sn, 0, sizeof(*sn));
@@ -263,7 +267,12 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto fail;
/* create the L1 table of the snapshot */
- sn->l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
+ l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
+ if (l1_table_offset < 0) {
+ goto fail;
+ }
+
+ sn->l1_table_offset = l1_table_offset;
sn->l1_size = s->l1_size;
if (s->l1_size != 0) {
diff --git a/block/qcow2.c b/block/qcow2.c
index 984264b3e..4ae8f193d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -561,7 +561,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
acb->hd_aiocb = NULL;
if (ret >= 0) {
- ret = qcow2_alloc_cluster_link_l2(bs, acb->cluster_offset, &acb->l2meta);
+ ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta);
}
run_dependent_requests(&acb->l2meta);
@@ -585,21 +585,23 @@ static void qcow_aio_write_cb(void *opaque, int ret)
n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
- acb->cluster_offset = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
- index_in_cluster,
- n_end, &acb->n, &acb->l2meta);
+ ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
+ index_in_cluster, n_end, &acb->n, &acb->l2meta);
+ if (ret < 0) {
+ goto done;
+ }
+
+ acb->cluster_offset = acb->l2meta.cluster_offset;
/* Need to wait for another request? If so, we are done for now. */
- if (!acb->cluster_offset && acb->l2meta.depends_on != NULL) {
+ if (acb->l2meta.nb_clusters == 0 && acb->l2meta.depends_on != NULL) {
QLIST_INSERT_HEAD(&acb->l2meta.depends_on->dependent_requests,
acb, next_depend);
return;
}
- if (!acb->cluster_offset || (acb->cluster_offset & 511) != 0) {
- ret = -EIO;
- goto done;
- }
+ assert((acb->cluster_offset & 511) == 0);
+
if (s->crypt_method) {
if (!acb->cluster_data) {
acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
@@ -683,27 +685,27 @@ static int get_bits_from_size(size_t size)
static int preallocate(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
- uint64_t cluster_offset = 0;
uint64_t nb_sectors;
uint64_t offset;
int num;
+ int ret;
QCowL2Meta meta;
nb_sectors = bdrv_getlength(bs) >> 9;
offset = 0;
QLIST_INIT(&meta.dependent_requests);
+ meta.cluster_offset = 0;
while (nb_sectors) {
num = MIN(nb_sectors, INT_MAX >> 9);
- cluster_offset = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num,
- &meta);
+ ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, &meta);
- if (cluster_offset == 0) {
+ if (ret < 0) {
return -1;
}
- if (qcow2_alloc_cluster_link_l2(bs, cluster_offset, &meta) < 0) {
- qcow2_free_any_clusters(bs, cluster_offset, meta.nb_clusters);
+ if (qcow2_alloc_cluster_link_l2(bs, &meta) < 0) {
+ qcow2_free_any_clusters(bs, meta.cluster_offset, meta.nb_clusters);
return -1;
}
@@ -722,10 +724,10 @@ static int preallocate(BlockDriverState *bs)
* all of the allocated clusters (otherwise we get failing reads after
* EOF). Extend the image to the last allocated sector.
*/
- if (cluster_offset != 0) {
+ if (meta.cluster_offset != 0) {
uint8_t buf[512];
memset(buf, 0, 512);
- bdrv_write(s->hd, (cluster_offset >> 9) + num - 1, buf, 1);
+ bdrv_write(s->hd, (meta.cluster_offset >> 9) + num - 1, buf, 1);
}
return 0;
@@ -1056,12 +1058,13 @@ static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
{
BDRVQcowState *s = bs->opaque;
int growable = bs->growable;
+ int ret;
bs->growable = 1;
- bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
+ ret = bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
bs->growable = growable;
- return size;
+ return ret;
}
static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
diff --git a/block/qcow2.h b/block/qcow2.h
index 26ab5d952..d9ea6abc5 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -135,6 +135,7 @@ struct QCowAIOCB;
typedef struct QCowL2Meta
{
uint64_t offset;
+ uint64_t cluster_offset;
int n_start;
int nb_available;
int nb_clusters;
@@ -199,8 +200,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int compressed_size);
-int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
- QCowL2Meta *m);
+int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
/* qcow2-snapshot.c functions */
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 6dcc65189..c204cf94e 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -597,7 +597,7 @@ static void raw_close(BlockDriverState *bs)
close(s->fd);
s->fd = -1;
if (s->aligned_buf != NULL)
- qemu_free(s->aligned_buf);
+ qemu_vfree(s->aligned_buf);
}
}