summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2009-11-26 14:03:42 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-12-03 11:45:49 -0600
commite1c7f0e3f998866bedc9bdb53d247859b7beb5ce (patch)
treeb283a6bbc755d9e20be49635b48f440f919130d4
parentf35d68f0e79ed82d1c9a8a78a688d0ead8bf05f2 (diff)
downloadqemu-e1c7f0e3f998866bedc9bdb53d247859b7beb5ce.tar.gz
qcow2: Store exact backing format length
Currently qcow2 unnecessarily rounds up the length of the backing format string to the next multiple of 8. At the same time, the array in BlockDriverState can only hold 15 characters, so in effect backing formats with 9 characters or more don't work (e.g. host_device). Save the real string length and things start to work for all valid image format names. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--block/qcow2.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index 3954cf1398..984264b3ea 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -124,12 +124,12 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
#ifdef DEBUG_EXT
printf("Qcow2: Got format extension %s\n", bs->backing_format);
#endif
- offset += ((ext.len + 7) & ~7);
+ offset = ((offset + ext.len + 7) & ~7);
break;
default:
/* unknown magic -- just skip it */
- offset += ((ext.len + 7) & ~7);
+ offset = ((offset + ext.len + 7) & ~7);
break;
}
}
@@ -738,6 +738,7 @@ static int qcow_create2(const char *filename, int64_t total_size,
int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
int ref_clusters, backing_format_len = 0;
+ int rounded_ext_bf_len = 0;
QCowHeader header;
uint64_t tmp, offset;
QCowCreateState s1, *s = &s1;
@@ -759,8 +760,9 @@ static int qcow_create2(const char *filename, int64_t total_size,
if (backing_format) {
ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT;
backing_format_len = strlen(backing_format);
- ext_bf.len = (backing_format_len + 7) & ~7;
- header_size += ((sizeof(ext_bf) + ext_bf.len + 7) & ~7);
+ ext_bf.len = backing_format_len;
+ rounded_ext_bf_len = (sizeof(ext_bf) + ext_bf.len + 7) & ~7;
+ header_size += rounded_ext_bf_len;
}
header.backing_file_offset = cpu_to_be64(header_size);
backing_filename_len = strlen(backing_file);
@@ -828,15 +830,15 @@ static int qcow_create2(const char *filename, int64_t total_size,
if (backing_file) {
if (backing_format_len) {
char zero[16];
- int d = ext_bf.len - backing_format_len;
+ int padding = rounded_ext_bf_len - (ext_bf.len + sizeof(ext_bf));
memset(zero, 0, sizeof(zero));
cpu_to_be32s(&ext_bf.magic);
cpu_to_be32s(&ext_bf.len);
write(fd, &ext_bf, sizeof(ext_bf));
write(fd, backing_format, backing_format_len);
- if (d>0) {
- write(fd, zero, d);
+ if (padding > 0) {
+ write(fd, zero, padding);
}
}
write(fd, backing_file, backing_filename_len);