diff options
author | Fam Zheng <famcool@gmail.com> | 2011-08-12 23:19:34 +0800 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-09-06 12:33:29 +0200 |
commit | bb45ded93115ad4303471c9a492579dc36716547 (patch) | |
tree | 1ddc2be55e6113c63ab807a07dcb1822c9573d5d | |
parent | f16f509d17de295300404f94598b558ac5b8cfdd (diff) |
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>
-rw-r--r-- | block/vmdk.c | 9 |
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)); |