Commit bb45ded9 authored by Fam Zheng's avatar Fam Zheng Committed by Kevin Wolf
Browse files

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: default avatarFam Zheng <famcool@gmail.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent f16f509d
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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));