summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorFam Zheng <famcool@gmail.com>2011-08-12 23:19:34 +0800
committerKevin Wolf <kwolf@redhat.com>2011-09-06 12:33:29 +0200
commitbb45ded93115ad4303471c9a492579dc36716547 (patch)
tree1ddc2be55e6113c63ab807a07dcb1822c9573d5d /block
parentf16f509d17de295300404f94598b558ac5b8cfdd (diff)
downloadqemu-bb45ded93115ad4303471c9a492579dc36716547.tar.gz
qemu-bb45ded93115ad4303471c9a492579dc36716547.tar.bz2
qemu-bb45ded93115ad4303471c9a492579dc36716547.zip
VMDK: bugfix, opening vSphere 4 exported image
The vSphere 4 exported image is streamOptimized extent, which is not quite correctly handled. Ignore rdgOffset when RGD flag bit not set. Signed-off-by: Fam Zheng <famcool@gmail.com> Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/vmdk.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/block/vmdk.c b/block/vmdk.c
index 892b18e0cf..6c8edfc190 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -31,6 +31,7 @@
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
#define VMDK4_COMPRESSION_DEFLATE 1
+#define VMDK4_FLAG_RGD (1 << 1)
#define VMDK4_FLAG_COMPRESS (1 << 16)
#define VMDK4_FLAG_MARKER (1 << 17)
@@ -55,8 +56,8 @@ typedef struct {
int64_t desc_offset;
int64_t desc_size;
int32_t num_gtes_per_gte;
- int64_t rgd_offset;
int64_t gd_offset;
+ int64_t rgd_offset;
int64_t grain_offset;
char filler[1];
char check_bytes[4];
@@ -420,6 +421,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
uint32_t l1_size, l1_entry_sectors;
VMDK4Header header;
VmdkExtent *extent;
+ int64_t l1_backup_offset = 0;
ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
if (ret < 0) {
@@ -435,10 +437,13 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
}
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
/ l1_entry_sectors;
+ if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
+ l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
+ }
extent = vmdk_add_extent(bs, file, false,
le64_to_cpu(header.capacity),
le64_to_cpu(header.gd_offset) << 9,
- le64_to_cpu(header.rgd_offset) << 9,
+ l1_backup_offset,
l1_size,
le32_to_cpu(header.num_gtes_per_gte),
le64_to_cpu(header.granularity));