From bb45ded93115ad4303471c9a492579dc36716547 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Fri, 12 Aug 2011 23:19:34 +0800 Subject: 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 Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block/vmdk.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'block/vmdk.c') 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)); -- cgit v1.2.1