summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2013-12-04 11:06:36 +0100
committerMichael Roth <mdroth@linux.vnet.ibm.com>2013-12-09 11:40:30 -0600
commit982c8c5e209d0331f06c0d6bd9a440aa67a5e721 (patch)
tree24fe60e9a53c5b56b67e0952033bd2ee6985424b
parentd90ff19d0a664400232ae062163790937068a0f8 (diff)
downloadqemu-982c8c5e209d0331f06c0d6bd9a440aa67a5e721.tar.gz
qcow2: Zero-initialise first cluster for new images
Strictly speaking, this is only required for has_zero_init() == false, but it's easy enough to just do a cluster-aligned write that is padded with zeros after the header. This fixes that after 'qemu-img create' header extensions are attempted to be parsed that are really just random leftover data. Cc: qemu-stable@nongnu.org Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> (cherry picked from commit f8413b3c23b08a547ce18609acc6fae5fd04ed5c) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r--block/qcow2.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index 7f7282e0c4..3bf932b06e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1285,7 +1285,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* size for any qcow2 image.
*/
BlockDriverState* bs;
- QCowHeader header;
+ QCowHeader *header;
uint8_t* refcount_table;
int ret;
@@ -1300,30 +1300,34 @@ static int qcow2_create2(const char *filename, int64_t total_size,
}
/* Write the header */
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(version);
- header.cluster_bits = cpu_to_be32(cluster_bits);
- header.size = cpu_to_be64(0);
- header.l1_table_offset = cpu_to_be64(0);
- header.l1_size = cpu_to_be32(0);
- header.refcount_table_offset = cpu_to_be64(cluster_size);
- header.refcount_table_clusters = cpu_to_be32(1);
- header.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT);
- header.header_length = cpu_to_be32(sizeof(header));
+ QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
+ header = g_malloc0(cluster_size);
+ *header = (QCowHeader) {
+ .magic = cpu_to_be32(QCOW_MAGIC),
+ .version = cpu_to_be32(version),
+ .cluster_bits = cpu_to_be32(cluster_bits),
+ .size = cpu_to_be64(0),
+ .l1_table_offset = cpu_to_be64(0),
+ .l1_size = cpu_to_be32(0),
+ .refcount_table_offset = cpu_to_be64(cluster_size),
+ .refcount_table_clusters = cpu_to_be32(1),
+ .refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT),
+ .header_length = cpu_to_be32(sizeof(*header)),
+ };
if (flags & BLOCK_FLAG_ENCRYPT) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
+ header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
} else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
+ header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
}
if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) {
- header.compatible_features |=
+ header->compatible_features |=
cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
}
- ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
+ ret = bdrv_pwrite(bs, 0, header, cluster_size);
+ g_free(header);
if (ret < 0) {
goto out;
}