/*
 * Block driver for the VMDK format
 *
 * Copyright (c) 2004 Fabrice Bellard
 * Copyright (c) 2005 Filip Navara
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "sysemu/block-backend.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/bswap.h"
#include "qemu/memalign.h"
#include "migration/blocker.h"
#include "qemu/cutils.h"
#include <zlib.h>

#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_NL_DETECT (1 << 0)
#define VMDK4_FLAG_RGD (1 << 1)
/* Zeroed-grain enable bit */
#define VMDK4_FLAG_ZERO_GRAIN   (1 << 2)
#define VMDK4_FLAG_COMPRESS (1 << 16)
#define VMDK4_FLAG_MARKER (1 << 17)
#define VMDK4_GD_AT_END 0xffffffffffffffffULL

#define VMDK_EXTENT_MAX_SECTORS (1ULL << 32)

#define VMDK_GTE_ZEROED 0x1

/* VMDK internal error codes */
#define VMDK_OK      0
#define VMDK_ERROR   (-1)
/* Cluster not allocated */
#define VMDK_UNALLOC (-2)
#define VMDK_ZEROED  (-3)

#define BLOCK_OPT_ZEROED_GRAIN "zeroed_grain"
#define BLOCK_OPT_TOOLSVERSION "toolsversion"

typedef struct {
    uint32_t version;
    uint32_t flags;
    uint32_t disk_sectors;
    uint32_t granularity;
    uint32_t l1dir_offset;
    uint32_t l1dir_size;
    uint32_t file_sectors;
    uint32_t cylinders;
    uint32_t heads;
    uint32_t sectors_per_track;
} QEMU_PACKED VMDK3Header;

typedef struct {
    uint32_t version;
    uint32_t flags;
    uint64_t capacity;
    uint64_t granularity;
    uint64_t desc_offset;
    uint64_t desc_size;
    /* Number of GrainTableEntries per GrainTable */
    uint32_t num_gtes_per_gt;
    uint64_t rgd_offset;
    uint64_t gd_offset;
    uint64_t grain_offset;
    char filler[1];
    char check_bytes[4];
    uint16_t compressAlgorithm;
} QEMU_PACKED VMDK4Header;

typedef struct VMDKSESparseConstHeader {
    uint64_t magic;
    uint64_t version;
    uint64_t capacity;
    uint64_t grain_size;
    uint64_t grain_table_size;
    uint64_t flags;
    uint64_t reserved1;
    uint64_t reserved2;
    uint64_t reserved3;
    uint64_t reserved4;
    uint64_t volatile_header_offset;
    uint64_t volatile_header_size;
    uint64_t journal_header_offset;
    uint64_t journal_header_size;
    uint64_t journal_offset;
    uint64_t journal_size;
    uint64_t grain_dir_offset;
    uint64_t grain_dir_size;
    uint64_t grain_tables_offset;
    uint64_t grain_tables_size;
    uint64_t free_bitmap_offset;
    uint64_t free_bitmap_size;
    uint64_t backmap_offset;
    uint64_t backmap_size;
    uint64_t grains_offset;
    uint64_t grains_size;
    uint8_t pad[304];
} QEMU_PACKED VMDKSESparseConstHeader;

typedef struct VMDKSESparseVolatileHeader {
    uint64_t magic;
    uint64_t free_gt_number;
    uint64_t next_txn_seq_number;
    uint64_t replay_journal;
    uint8_t pad[480];
} QEMU_PACKED VMDKSESparseVolatileHeader;

#define L2_CACHE_SIZE 16

typedef struct VmdkExtent {
    BdrvChild *file;
    bool flat;
    bool compressed;
    bool has_marker;
    bool has_zero_grain;
    bool sesparse;
    uint64_t sesparse_l2_tables_offset;
    uint64_t sesparse_clusters_offset;
    int32_t entry_size;
    int version;
    int64_t sectors;
    int64_t end_sector;
    int64_t flat_start_offset;
    int64_t l1_table_offset;
    int64_t l1_backup_table_offset;
    void *l1_table;
    uint32_t *l1_backup_table;
    unsigned int l1_size;
    uint32_t l1_entry_sectors;

    unsigned int l2_size;
    void *l2_cache;
    uint32_t l2_cache_offsets[L2_CACHE_SIZE];
    uint32_t l2_cache_counts[L2_CACHE_SIZE];

    int64_t cluster_sectors;
    int64_t next_cluster_sector;
    char *type;
} VmdkExtent;

typedef struct BDRVVmdkState {
    CoMutex lock;
    uint64_t desc_offset;
    bool cid_updated;
    bool cid_checked;
    uint32_t cid;
    uint32_t parent_cid;
    int num_extents;
    /* Extent array with num_extents entries, ascend ordered by address */
    VmdkExtent *extents;
    Error *migration_blocker;
    char *create_type;
} BDRVVmdkState;

typedef struct BDRVVmdkReopenState {
    bool *extents_using_bs_file;
} BDRVVmdkReopenState;

typedef struct VmdkMetaData {
    unsigned int l1_index;
    unsigned int l2_index;
    unsigned int l2_offset;
    bool new_allocation;
    uint32_t *l2_cache_entry;
} VmdkMetaData;

typedef struct VmdkGrainMarker {
    uint64_t lba;
    uint32_t size;
    uint8_t  data[];
} QEMU_PACKED VmdkGrainMarker;

enum {
    MARKER_END_OF_STREAM    = 0,
    MARKER_GRAIN_TABLE      = 1,
    MARKER_GRAIN_DIRECTORY  = 2,
    MARKER_FOOTER           = 3,
};

static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
{
    uint32_t magic;

    if (buf_size < 4) {
        return 0;
    }
    magic = be32_to_cpu(*(uint32_t *)buf);
    if (magic == VMDK3_MAGIC ||
        magic == VMDK4_MAGIC) {
        return 100;
    } else {
        const char *p = (const char *)buf;
        const char *end = p + buf_size;
        while (p < end) {
            if (*p == '#') {
                /* skip comment line */
                while (p < end && *p != '\n') {
                    p++;
                }
                p++;
                continue;
            }
            if (*p == ' ') {
                while (p < end && *p == ' ') {
                    p++;
                }
                /* skip '\r' if windows line endings used. */
                if (p < end && *p == '\r') {
                    p++;
                }
                /* only accept blank lines before 'version=' line */
                if (p == end || *p != '\n') {
                    return 0;
                }
                p++;
                continue;
            }
            if (end - p >= strlen("version=X\n")) {
                if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 ||
                    strncmp("version=2\n", p, strlen("version=2\n")) == 0 ||
                    strncmp("version=3\n", p, strlen("version=3\n")) == 0) {
                    return 100;
                }
            }
            if (end - p >= strlen("version=X\r\n")) {
                if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 ||
                    strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0 ||
                    strncmp("version=3\r\n", p, strlen("version=3\r\n")) == 0) {
                    return 100;
                }
            }
            return 0;
        }
        return 0;
    }
}

#define SECTOR_SIZE 512
#define DESC_SIZE (20 * SECTOR_SIZE)    /* 20 sectors of 512 bytes each */
#define BUF_SIZE 4096
#define HEADER_SIZE 512                 /* first sector of 512 bytes */

static void vmdk_free_extents(BlockDriverState *bs)
{
    int i;
    BDRVVmdkState *s = bs->opaque;
    VmdkExtent *e;

    for (i = 0; i < s->num_extents; i++) {
        e = &s->extents[i];
        g_free(e->l1_table);
        g_free(e->l2_cache);
        g_free(e->l1_backup_table);
        g_free(e->type);
        if (e->file != bs->file) {
            bdrv_unref_child(bs, e->file);
        }
    }
    g_free(s->extents);
}

static void vmdk_free_last_extent(BlockDriverState *bs)
{
    BDRVVmdkState *s = bs->opaque;

    if (s->num_extents == 0) {
        return;
    }
    s->num_extents--;
    s->extents = g_renew(VmdkExtent, s->extents, s->num_extents);
}

/* Return -ve errno, or 0 on success and write CID into *pcid. */
static int vmdk_read_cid(BlockDriverState *bs, int parent, uint32_t *pcid)
{
    char *desc;
    uint32_t cid;
    const char *p_name, *cid_str;
    size_t cid_str_size;
    BDRVVmdkState *s = bs->opaque;
    int ret;

    desc = g_malloc0(DESC_SIZE);
    ret = bdrv_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
    if (ret < 0) {
        goto out;
    }

    if (parent) {
        cid_str = "parentCID";
        cid_str_size = sizeof("parentCID");
    } else {
        cid_str = "CID";
        cid_str_size = sizeof("CID");
    }

    desc[DESC_SIZE - 1] = '\0';
    p_name = strstr(desc, cid_str);
    if (p_name == NULL) {
        ret = -EINVAL;
        goto out;
    }
    p_name += cid_str_size;
    if (sscanf(p_name, "%" SCNx32, &cid) != 1) {
        ret = -EINVAL;
        goto out;
    }
    *pcid = cid;
    ret = 0;

out:
    g_free(desc);
    return ret;
}

static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
{
    char *desc, *tmp_desc;
    char *p_name, *tmp_str;
    BDRVVmdkState *s = bs->opaque;
    int ret = 0;

    desc = g_malloc0(DESC_SIZE);
    tmp_desc = g_malloc0(DESC_SIZE);
    ret = bdrv_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
    if (ret < 0) {
        goto out;
    }

    desc[DESC_SIZE - 1] = '\0';
    tmp_str = strstr(desc, "parentCID");
    if (tmp_str == NULL) {
        ret = -EINVAL;
        goto out;
    }

    pstrcpy(tmp_desc, DESC_SIZE, tmp_str);
    p_name = strstr(desc, "CID");
    if (p_name != NULL) {
        p_name += sizeof("CID");
        snprintf(p_name, DESC_SIZE - (p_name - desc), "%" PRIx32 "\n", cid);
        pstrcat(desc, DESC_SIZE, tmp_desc);
    }

    ret = bdrv_pwrite_sync(bs->file, s->desc_offset, DESC_SIZE, desc, 0);

out:
    g_free(desc);
    g_free(tmp_desc);
    return ret;
}

static int coroutine_fn vmdk_is_cid_valid(BlockDriverState *bs)
{
    BDRVVmdkState *s = bs->opaque;
    uint32_t cur_pcid;

    if (!s->cid_checked && bs->backing) {
        BlockDriverState *p_bs = bs->backing->bs;

        if (strcmp(p_bs->drv->format_name, "vmdk")) {
            /* Backing file is not in vmdk format, so it does not have
             * a CID, which makes the overlay's parent CID invalid */
            return 0;
        }

        if (vmdk_read_cid(p_bs, 0, &cur_pcid) != 0) {
            /* read failure: report as not valid */
            return 0;
        }
        if (s->parent_cid != cur_pcid) {
            /* CID not valid */
            return 0;
        }
    }
    s->cid_checked = true;
    /* CID valid */
    return 1;
}

static int vmdk_reopen_prepare(BDRVReopenState *state,
                               BlockReopenQueue *queue, Error **errp)
{
    BDRVVmdkState *s;
    BDRVVmdkReopenState *rs;
    int i;

    assert(state != NULL);
    assert(state->bs != NULL);
    assert(state->opaque == NULL);

    s = state->bs->opaque;

    rs = g_new0(BDRVVmdkReopenState, 1);
    state->opaque = rs;

    /*
     * Check whether there are any extents stored in bs->file; if bs->file
     * changes, we will need to update their .file pointers to follow suit
     */
    rs->extents_using_bs_file = g_new(bool, s->num_extents);
    for (i = 0; i < s->num_extents; i++) {
        rs->extents_using_bs_file[i] = s->extents[i].file == state->bs->file;
    }

    return 0;
}

static void vmdk_reopen_clean(BDRVReopenState *state)
{
    BDRVVmdkReopenState *rs = state->opaque;

    g_free(rs->extents_using_bs_file);
    g_free(rs);
    state->opaque = NULL;
}

static void vmdk_reopen_commit(BDRVReopenState *state)
{
    BDRVVmdkState *s = state->bs->opaque;
    BDRVVmdkReopenState *rs = state->opaque;
    int i;

    for (i = 0; i < s->num_extents; i++) {
        if (rs->extents_using_bs_file[i]) {
            s->extents[i].file = state->bs->file;
        }
    }

    vmdk_reopen_clean(state);
}

static void vmdk_reopen_abort(BDRVReopenState *state)
{
    vmdk_reopen_clean(state);
}

static int vmdk_parent_open(BlockDriverState *bs)
{
    char *p_name;
    char *desc;
    BDRVVmdkState *s = bs->opaque;
    int ret;

    desc = g_malloc0(DESC_SIZE + 1);
    ret = bdrv_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
    if (ret < 0) {
        goto out;
    }

    p_name = strstr(desc, "parentFileNameHint");
    if (p_name != NULL) {
        char *end_name;

        p_name += sizeof("parentFileNameHint") + 1;
        end_name = strchr(p_name, '\"');
        if (end_name == NULL) {
            ret = -EINVAL;
            goto out;
        }
        if ((end_name - p_name) > sizeof(bs->auto_backing_file) - 1) {
            ret = -EINVAL;
            goto out;
        }

        pstrcpy(bs->auto_backing_file, end_name - p_name + 1, p_name);
        pstrcpy(bs->backing_file, sizeof(bs->backing_file),
                bs->auto_backing_file);
        pstrcpy(bs->backing_format, sizeof(bs->backing_format),
                "vmdk");
    }

out:
    g_free(desc);
    return ret;
}

/* Create and append extent to the extent array. Return the added VmdkExtent
 * address. return NULL if allocation failed. */
static int vmdk_add_extent(BlockDriverState *bs,
                           BdrvChild *file, bool flat, int64_t sectors,
                           int64_t l1_offset, int64_t l1_backup_offset,
                           uint32_t l1_size,
                           int l2_size, uint64_t cluster_sectors,
                           VmdkExtent **new_extent,
                           Error **errp)
{
    VmdkExtent *extent;
    BDRVVmdkState *s = bs->opaque;
    int64_t nb_sectors;

    if (cluster_sectors > 0x200000) {
        /* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
        error_setg(errp, "Invalid granularity, image may be corrupt");
        return -EFBIG;
    }
    if (l1_size > 32 * 1024 * 1024) {
        /*
         * Although with big capacity and small l1_entry_sectors, we can get a
         * big l1_size, we don't want unbounded value to allocate the table.
         * Limit it to 32M, which is enough to store:
         *     8TB  - for both VMDK3 & VMDK4 with
         *            minimal cluster size: 512B
         *            minimal L2 table size: 512 entries
         *            8 TB is still more than the maximal value supported for
         *            VMDK3 & VMDK4 which is 2TB.
         *     64TB - for "ESXi seSparse Extent"
         *            minimal cluster size: 512B (default is 4KB)
         *            L2 table size: 4096 entries (const).
         *            64TB is more than the maximal value supported for
         *            seSparse VMDKs (which is slightly less than 64TB)
         */
        error_setg(errp, "L1 size too big");
        return -EFBIG;
    }

    nb_sectors = bdrv_nb_sectors(file->bs);
    if (nb_sectors < 0) {
        return nb_sectors;
    }

    s->extents = g_renew(VmdkExtent, s->extents, s->num_extents + 1);
    extent = &s->extents[s->num_extents];
    s->num_extents++;

    memset(extent, 0, sizeof(VmdkExtent));
    extent->file = file;
    extent->flat = flat;
    extent->sectors = sectors;
    extent->l1_table_offset = l1_offset;
    extent->l1_backup_table_offset = l1_backup_offset;
    extent->l1_size = l1_size;
    extent->l1_entry_sectors = l2_size * cluster_sectors;
    extent->l2_size = l2_size;
    extent->cluster_sectors = flat ? sectors : cluster_sectors;
    extent->next_cluster_sector = ROUND_UP(nb_sectors, cluster_sectors);
    extent->entry_size = sizeof(uint32_t);

    if (s->num_extents > 1) {
        extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
    } else {
        extent->end_sector = extent->sectors;
    }
    bs->total_sectors = extent->end_sector;
    if (new_extent) {
        *new_extent = extent;
    }
    return 0;
}

static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent,
                            Error **errp)
{
    int ret;
    size_t l1_size;
    int i;

    /* read the L1 table */
    l1_size = extent->l1_size * extent->entry_size;
    extent->l1_table = g_try_malloc(l1_size);
    if (l1_size && extent->l1_table == NULL) {
        return -ENOMEM;
    }

    ret = bdrv_pread(extent->file, extent->l1_table_offset, l1_size,
                     extent->l1_table, 0);
    if (ret < 0) {
        bdrv_refresh_filename(extent->file->bs);
        error_setg_errno(errp, -ret,
                         "Could not read l1 table from extent '%s'",
                         extent->file->bs->filename);
        goto fail_l1;
    }
    for (i = 0; i < extent->l1_size; i++) {
        if (extent->entry_size == sizeof(uint64_t)) {
            le64_to_cpus((uint64_t *)extent->l1_table + i);
        } else {
            assert(extent->entry_size == sizeof(uint32_t));
            le32_to_cpus((uint32_t *)extent->l1_table + i);
        }
    }

    if (extent->l1_backup_table_offset) {
        assert(!extent->sesparse);
        extent->l1_backup_table = g_try_malloc(l1_size);
        if (l1_size && extent->l1_backup_table == NULL) {
            ret = -ENOMEM;
            goto fail_l1;
        }
        ret = bdrv_pread(extent->file, extent->l1_backup_table_offset,
                         l1_size, extent->l1_backup_table, 0);
        if (ret < 0) {
            bdrv_refresh_filename(extent->file->bs);
            error_setg_errno(errp, -ret,
                             "Could not read l1 backup table from extent '%s'",
                             extent->file->bs->filename);
            goto fail_l1b;
        }
        for (i = 0; i < extent->l1_size; i++) {
            le32_to_cpus(&extent->l1_backup_table[i]);
        }
    }

    extent->l2_cache =
        g_malloc(extent->entry_size * extent->l2_size * L2_CACHE_SIZE);
    return 0;
 fail_l1b:
    g_free(extent->l1_backup_table);
 fail_l1:
    g_free(extent->l1_table);
    return ret;
}

static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
                                 BdrvChild *file,
                                 int flags, Error **errp)
{
    int ret;
    uint32_t magic;
    VMDK3Header header;
    VmdkExtent *extent = NULL;

    ret = bdrv_pread(file, sizeof(magic), sizeof(header), &header, 0);
    if (ret < 0) {
        bdrv_refresh_filename(file->bs);
        error_setg_errno(errp, -ret,
                         "Could not read header from file '%s'",
                         file->bs->filename);
        return ret;
    }
    ret = vmdk_add_extent(bs, file, false,
                          le32_to_cpu(header.disk_sectors),
                          (int64_t)le32_to_cpu(header.l1dir_offset) << 9,
                          0,
                          le32_to_cpu(header.l1dir_size),
                          4096,
                          le32_to_cpu(header.granularity),
                          &extent,
                          errp);
    if (ret < 0) {
        return ret;
    }
    ret = vmdk_init_tables(bs, extent, errp);
    if (ret) {
        /* free extent allocated by vmdk_add_extent */
        vmdk_free_last_extent(bs);
    }
    return ret;
}

#define SESPARSE_CONST_HEADER_MAGIC UINT64_C(0x00000000cafebabe)
#define SESPARSE_VOLATILE_HEADER_MAGIC UINT64_C(0x00000000cafecafe)

/* Strict checks - format not officially documented */
static int check_se_sparse_const_header(VMDKSESparseConstHeader *header,
                                        Error **errp)
{
    header->magic = le64_to_cpu(header->magic);
    header->version = le64_to_cpu(header->version);
    header->grain_size = le64_to_cpu(header->grain_size);
    header->grain_table_size = le64_to_cpu(header->grain_table_size);
    header->flags = le64_to_cpu(header->flags);
    header->reserved1 = le64_to_cpu(header->reserved1);
    header->reserved2 = le64_to_cpu(header->reserved2);
    header->reserved3 = le64_to_cpu(header->reserved3);
    header->reserved4 = le64_to_cpu(header->reserved4);

    header->volatile_header_offset =
        le64_to_cpu(header->volatile_header_offset);
    header->volatile_header_size = le64_to_cpu(header->volatile_header_size);

    header->journal_header_offset = le64_to_cpu(header->journal_header_offset);
    header->journal_header_size = le64_to_cpu(header->journal_header_size);

    header->journal_offset = le64_to_cpu(header->journal_offset);
    header->journal_size = le64_to_cpu(header->journal_size);

    header->grain_dir_offset = le64_to_cpu(header->grain_dir_offset);
    header->grain_dir_size = le64_to_cpu(header->grain_dir_size);

    header->grain_tables_offset = le64_to_cpu(header->grain_tables_offset);
    header->grain_tables_size = le64_to_cpu(header->grain_tables_size);

    header->free_bitmap_offset = le64_to_cpu(header->free_bitmap_offset);
    header->free_bitmap_size = le64_to_cpu(header->free_bitmap_size);

    header->backmap_offset = le64_to_cpu(header->backmap_offset);
    header->backmap_size = le64_to_cpu(header->backmap_size);

    header->grains_offset = le64_to_cpu(header->grains_offset);
    header->grains_size = le64_to_cpu(header->grains_size);

    if (header->magic != SESPARSE_CONST_HEADER_MAGIC) {
        error_setg(errp, "Bad const header magic: 0x%016" PRIx64,
                   header->magic);
        return -EINVAL;
    }

    if (header->version != 0x0000000200000001) {
        error_setg(errp, "Unsupported version: 0x%016" PRIx64,
                   header->version);
        return -ENOTSUP;
    }

    if (header->grain_size != 8) {
        error_setg(errp, "Unsupported grain size: %" PRIu64,
                   header->grain_size);
        return -ENOTSUP;
    }

    if (header->grain_table_size != 64) {
        error_setg(errp, "Unsupported grain table size: %" PRIu64,
                   header->grain_table_size);
        return -ENOTSUP;
    }

    if (header->flags != 0) {
        error_setg(errp, "Unsupported flags: 0x%016" PRIx64,
                   header->flags);
        return -ENOTSUP;
    }

    if (header->reserved1 != 0 || header->reserved2 != 0 ||
        header->reserved3 != 0 || header->reserved4 != 0) {
        error_setg(errp, "Unsupported reserved bits:"
                   " 0x%016" PRIx64 " 0x%016" PRIx64
                   " 0x%016" PRIx64 " 0x%016" PRIx64,
                   header->reserved1, header->reserved2,
                   header->reserved3, header->reserved4);
        return -ENOTSUP;
    }

    /* check that padding is 0 */
    if (!buffer_is_zero(header->pad, sizeof(header->pad))) {
        error_setg(errp, "Unsupported non-zero const header padding");
        return -ENOTSUP;
    }

    return 0;
}

static int check_se_sparse_volatile_header(VMDKSESparseVolatileHeader *header,
                                           Error **errp)
{
    header->magic = le64_to_cpu(header->magic);
    header->free_gt_number = le64_to_cpu(header->free_gt_number);
    header->next_txn_seq_number = le64_to_cpu(header->next_txn_seq_number);
    header->replay_journal = le64_to_cpu(header->replay_journal);

    if (header->magic != SESPARSE_VOLATILE_HEADER_MAGIC) {
        error_setg(errp, "Bad volatile header magic: 0x%016" PRIx64,
                   header->magic);
        return -EINVAL;
    }

    if (header->replay_journal) {
        error_setg(errp, "Image is dirty, Replaying journal not supported");
        return -ENOTSUP;
    }

    /* check that padding is 0 */
    if (!buffer_is_zero(header->pad, sizeof(header->pad))) {
        error_setg(errp, "Unsupported non-zero volatile header padding");
        return -ENOTSUP;
    }

    return 0;
}

static int vmdk_open_se_sparse(BlockDriverState *bs,
                               BdrvChild *file,
                               int flags, Error **errp)
{
    int ret;
    VMDKSESparseConstHeader const_header;
    VMDKSESparseVolatileHeader volatile_header;
    VmdkExtent *extent = NULL;

    ret = bdrv_apply_auto_read_only(bs,
            "No write support for seSparse images available", errp);
    if (ret < 0) {
        return ret;
    }

    assert(sizeof(const_header) == SECTOR_SIZE);

    ret = bdrv_pread(file, 0, sizeof(const_header), &const_header, 0);
    if (ret < 0) {
        bdrv_refresh_filename(file->bs);
        error_setg_errno(errp, -ret,
                         "Could not read const header from file '%s'",
                         file->bs->filename);
        return ret;
    }

    /* check const header */
    ret = check_se_sparse_const_header(&const_header, errp);
    if (ret < 0) {
        return ret;
    }

    assert(sizeof(volatile_header) == SECTOR_SIZE);

    ret = bdrv_pread(file, const_header.volatile_header_offset * SECTOR_SIZE,
                     sizeof(volatile_header), &volatile_header, 0);
    if (ret < 0) {
        bdrv_refresh_filename(file->bs);
        error_setg_errno(errp, -ret,
                         "Could not read volatile header from file '%s'",
                         file->bs->filename);
        return ret;
    }

    /* check volatile header */
    ret = check_se_sparse_volatile_header(&volatile_header, errp);
    if (ret < 0) {
        return ret;
    }

    ret = vmdk_add_extent(bs, file, false,
                          const_header.capacity,
                          const_header.grain_dir_offset * SECTOR_SIZE,
                          0,
                          const_header.grain_dir_size *
                          SECTOR_SIZE / sizeof(uint64_t),
                          const_header.grain_table_size *
                          SECTOR_SIZE / sizeof(uint64_t),
                          const_header.grain_size,
                          &extent,
                          errp);
    if (ret < 0) {
        return ret;
    }

    extent->sesparse = true;
    extent->sesparse_l2_tables_offset = const_header.grain_tables_offset;
    extent->sesparse_clusters_offset = const_header.grains_offset;
    extent->entry_size = sizeof(uint64_t);

    ret = vmdk_init_tables(bs, extent, errp);
    if (ret) {
        /* free extent allocated by vmdk_add_extent */
        vmdk_free_last_extent(bs);
    }

    return ret;
}

static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
                               QDict *options, Error **errp);

static char *vmdk_read_desc(BdrvChild *file, uint64_t desc_offset, Error **errp)
{
    int64_t size;
    char *buf;
    int ret;

    size = bdrv_getlength(file->bs);
    if (size < 0) {
        error_setg_errno(errp, -size, "Could not access file");
        return NULL;
    }

    if (size < 4) {
        /* Both descriptor file and sparse image must be much larger than 4
         * bytes, also callers of vmdk_read_desc want to compare the first 4
         * bytes with VMDK4_MAGIC, let's error out if less is read. */
        error_setg(errp, "File is too small, not a valid image");
        return NULL;
    }

    size = MIN(size, (1 << 20) - 1);  /* avoid unbounded allocation */
    buf = g_malloc(size + 1);

    ret = bdrv_pread(file, desc_offset, size, buf, 0);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not read from file");
        g_free(buf);
        return NULL;
    }
    buf[size] = 0;

    return buf;
}

static int vmdk_open_vmdk4(BlockDriverState *bs,
                           BdrvChild *file,
                           int flags, QDict *options, Error **errp)
{
    int ret;
    uint32_t magic;
    uint32_t l1_size, l1_entry_sectors;
    VMDK4Header header;
    VmdkExtent *extent = NULL;
    BDRVVmdkState *s = bs->opaque;
    int64_t l1_backup_offset = 0;
    bool compressed;

    ret = bdrv_pread(file, sizeof(magic), sizeof(header), &header, 0);
    if (ret < 0) {
        bdrv_refresh_filename(file->bs);
        error_setg_errno(errp, -ret,
                         "Could not read header from file '%s'",
                         file->bs->filename);
        return -EINVAL;
    }
    if (header.capacity == 0) {
        uint64_t desc_offset = le64_to_cpu(header.desc_offset);
        if (desc_offset) {
            char *buf = vmdk_read_desc(file, desc_offset << 9, errp);
            if (!buf) {
                return -EINVAL;
            }
            ret = vmdk_open_desc_file(bs, flags, buf, options, errp);
            g_free(buf);
            return ret;
        }
    }

    if (!s->create_type) {
        s->create_type = g_strdup("monolithicSparse");
    }

    if (le64_to_cpu(header.gd_offset) == VMDK4_GD_AT_END) {
        /*
         * The footer takes precedence over the header, so read it in. The
         * footer starts at offset -1024 from the end: One sector for the
         * footer, and another one for the end-of-stream marker.
         */
        struct {
            struct {
                uint64_t val;
                uint32_t size;
                uint32_t type;
                uint8_t pad[512 - 16];
            } QEMU_PACKED footer_marker;

            uint32_t magic;
            VMDK4Header header;
            uint8_t pad[512 - 4 - sizeof(VMDK4Header)];

            struct {
                uint64_t val;
                uint32_t size;
                uint32_t type;
                uint8_t pad[512 - 16];
            } QEMU_PACKED eos_marker;
        } QEMU_PACKED footer;

        ret = bdrv_pread(file, bs->file->bs->total_sectors * 512 - 1536,
                         sizeof(footer), &footer, 0);
        if (ret < 0) {
            error_setg_errno(errp, -ret, "Failed to read footer");
            return ret;
        }

        /* Some sanity checks for the footer */
        if (be32_to_cpu(footer.magic) != VMDK4_MAGIC ||
            le32_to_cpu(footer.footer_marker.size) != 0  ||
            le32_to_cpu(footer.footer_marker.type) != MARKER_FOOTER ||
            le64_to_cpu(footer.eos_marker.val) != 0  ||
            le32_to_cpu(footer.eos_marker.size) != 0  ||
            le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
        {
            error_setg(errp, "Invalid footer");
            return -EINVAL;
        }

        header = footer.header;
    }

    compressed =
        le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
    if (le32_to_cpu(header.version) > 3) {
        error_setg(errp, "Unsupported VMDK version %" PRIu32,
                   le32_to_cpu(header.version));
        return -ENOTSUP;
    } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
               !compressed) {
        /* VMware KB 2064959 explains that version 3 added support for
         * persistent changed block tracking (CBT), and backup software can
         * read it as version=1 if it doesn't care about the changed area
         * information. So we are safe to enable read only. */
        error_setg(errp, "VMDK version 3 must be read only");
        return -EINVAL;
    }

    if (le32_to_cpu(header.num_gtes_per_gt) > 512) {
        error_setg(errp, "L2 table size too big");
        return -EINVAL;
    }

    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
                        * le64_to_cpu(header.granularity);
    if (l1_entry_sectors == 0) {
        error_setg(errp, "L1 entry size is invalid");
        return -EINVAL;
    }
    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;
    }
    if (bdrv_nb_sectors(file->bs) < le64_to_cpu(header.grain_offset)) {
        error_setg(errp, "File truncated, expecting at least %" PRId64 " bytes",
                   (int64_t)(le64_to_cpu(header.grain_offset)
                             * BDRV_SECTOR_SIZE));
        return -EINVAL;
    }

    ret = vmdk_add_extent(bs, file, false,
                          le64_to_cpu(header.capacity),
                          le64_to_cpu(header.gd_offset) << 9,
                          l1_backup_offset,
                          l1_size,
                          le32_to_cpu(header.num_gtes_per_gt),
                          le64_to_cpu(header.granularity),
                          &extent,
                          errp);
    if (ret < 0) {
        return ret;
    }
    extent->compressed =
        le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
    if (extent->compressed) {
        g_free(s->create_type);
        s->create_type = g_strdup("streamOptimized");
    }
    extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER;
    extent->version = le32_to_cpu(header.version);
    extent->has_zero_grain = le32_to_cpu(header.flags) & VMDK4_FLAG_ZERO_GRAIN;
    ret = vmdk_init_tables(bs, extent, errp);
    if (ret) {
        /* free extent allocated by vmdk_add_extent */
        vmdk_free_last_extent(bs);
    }
    return ret;
}

/* find an option value out of descriptor file */
static int vmdk_parse_description(const char *desc, const char *opt_name,
        char *buf, int buf_size)
{
    char *opt_pos, *opt_end;
    const char *end = desc + strlen(desc);

    opt_pos = strstr(desc, opt_name);
    if (!opt_pos) {
        return VMDK_ERROR;
    }
    /* Skip "=\"" following opt_name */
    opt_pos += strlen(opt_name) + 2;
    if (opt_pos >= end) {
        return VMDK_ERROR;
    }
    opt_end = opt_pos;
    while (opt_end < end && *opt_end != '"') {
        opt_end++;
    }
    if (opt_end == end || buf_size < opt_end - opt_pos + 1) {
        return VMDK_ERROR;
    }
    pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
    return VMDK_OK;
}

/* Open an extent file and append to bs array */
static int vmdk_open_sparse(BlockDriverState *bs, BdrvChild *file, int flags,
                            char *buf, QDict *options, Error **errp)
{
    uint32_t magic;

    magic = ldl_be_p(buf);
    switch (magic) {
        case VMDK3_MAGIC:
            return vmdk_open_vmfs_sparse(bs, file, flags, errp);
        case VMDK4_MAGIC:
            return vmdk_open_vmdk4(bs, file, flags, options, errp);
        default:
            error_setg(errp, "Image not in VMDK format");
            return -EINVAL;
    }
}

static const char *next_line(const char *s)
{
    while (*s) {
        if (*s == '\n') {
            return s + 1;
        }
        s++;
    }
    return s;
}

static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
                              QDict *options, Error **errp)
{
    int ret;
    int matches;
    char access[11];
    char type[11];
    char fname[512];
    const char *p, *np;
    int64_t sectors = 0;
    int64_t flat_offset;
    char *desc_file_dir = NULL;
    char *extent_path;
    BdrvChild *extent_file;
    BdrvChildRole extent_role;
    BDRVVmdkState *s = bs->opaque;
    VmdkExtent *extent = NULL;
    char extent_opt_prefix[32];
    Error *local_err = NULL;

    for (p = desc; *p; p = next_line(p)) {
        /* parse extent line in one of below formats:
         *
         * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
         * RW [size in sectors] SPARSE "file-name.vmdk"
         * RW [size in sectors] VMFS "file-name.vmdk"
         * RW [size in sectors] VMFSSPARSE "file-name.vmdk"
         * RW [size in sectors] SESPARSE "file-name.vmdk"
         */
        flat_offset = -1;
        matches = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
                         access, &sectors, type, fname, &flat_offset);
        if (matches < 4 || strcmp(access, "RW")) {
            continue;
        } else if (!strcmp(type, "FLAT")) {
            if (matches != 5 || flat_offset < 0) {
                goto invalid;
            }
        } else if (!strcmp(type, "VMFS")) {
            if (matches == 4) {
                flat_offset = 0;
            } else {
                goto invalid;
            }
        } else if (matches != 4) {
            goto invalid;
        }

        if (sectors <= 0 ||
            (strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
             strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE") &&
             strcmp(type, "SESPARSE")) ||
            (strcmp(access, "RW"))) {
            continue;
        }

        if (path_is_absolute(fname)) {
            extent_path = g_strdup(fname);
        } else {
            if (!desc_file_dir) {
                desc_file_dir = bdrv_dirname(bs->file->bs, errp);
                if (!desc_file_dir) {
                    bdrv_refresh_filename(bs->file->bs);
                    error_prepend(errp, "Cannot use relative paths with VMDK "
                                  "descriptor file '%s': ",
                                  bs->file->bs->filename);
                    ret = -EINVAL;
                    goto out;
                }
            }

            extent_path = g_strconcat(desc_file_dir, fname, NULL);
        }

        ret = snprintf(extent_opt_prefix, 32, "extents.%d", s->num_extents);
        assert(ret < 32);

        extent_role = BDRV_CHILD_DATA;
        if (strcmp(type, "FLAT") != 0 && strcmp(type, "VMFS") != 0) {
            /* non-flat extents have metadata */
            extent_role |= BDRV_CHILD_METADATA;
        }

        extent_file = bdrv_open_child(extent_path, options, extent_opt_prefix,
                                      bs, &child_of_bds, extent_role, false,
                                      &local_err);
        g_free(extent_path);
        if (local_err) {
            error_propagate(errp, local_err);
            ret = -EINVAL;
            goto out;
        }

        /* save to extents array */
        if (!strcmp(type, "FLAT") || !strcmp(type, "VMFS")) {
            /* FLAT extent */

            ret = vmdk_add_extent(bs, extent_file, true, sectors,
                            0, 0, 0, 0, 0, &extent, errp);
            if (ret < 0) {
                bdrv_unref_child(bs, extent_file);
                goto out;
            }
            extent->flat_start_offset = flat_offset << 9;
        } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
            /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
            char *buf = vmdk_read_desc(extent_file, 0, errp);
            if (!buf) {
                ret = -EINVAL;
            } else {
                ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf,
                                       options, errp);
            }
            g_free(buf);
            if (ret) {
                bdrv_unref_child(bs, extent_file);
                goto out;
            }
            extent = &s->extents[s->num_extents - 1];
        } else if (!strcmp(type, "SESPARSE")) {
            ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
            if (ret) {
                bdrv_unref_child(bs, extent_file);
                goto out;
            }
            extent = &s->extents[s->num_extents - 1];
        } else {
            error_setg(errp, "Unsupported extent type '%s'", type);
            bdrv_unref_child(bs, extent_file);
            ret = -ENOTSUP;
            goto out;
        }
        extent->type = g_strdup(type);
    }

    ret = 0;
    goto out;

invalid:
    np = next_line(p);
    assert(np != p);
    if (np[-1] == '\n') {
        np--;
    }
    error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p);
    ret = -EINVAL;

out:
    g_free(desc_file_dir);
    return ret;
}

static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
                               QDict *options, Error **errp)
{
    int ret;
    char ct[128];
    BDRVVmdkState *s = bs->opaque;

    if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
        error_setg(errp, "invalid VMDK image descriptor");
        ret = -EINVAL;
        goto exit;
    }
    if (strcmp(ct, "monolithicFlat") &&
        strcmp(ct, "vmfs") &&
        strcmp(ct, "vmfsSparse") &&
        strcmp(ct, "seSparse") &&
        strcmp(ct, "twoGbMaxExtentSparse") &&
        strcmp(ct, "twoGbMaxExtentFlat")) {
        error_setg(errp, "Unsupported image type '%s'", ct);
        ret = -ENOTSUP;
        goto exit;
    }
    s->create_type = g_strdup(ct);
    s->desc_offset = 0;
    ret = vmdk_parse_extents(buf, bs, options, errp);
exit:
    return ret;
}

static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
{
    char *buf;
    int ret;
    BDRVVmdkState *s = bs->opaque;
    uint32_t magic;

    ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
    if (ret < 0) {
        return ret;
    }

    buf = vmdk_read_desc(bs->file, 0, errp);
    if (!buf) {
        return -EINVAL;
    }

    magic = ldl_be_p(buf);
    switch (magic) {
        case VMDK3_MAGIC:
        case VMDK4_MAGIC:
            ret = vmdk_open_sparse(bs, bs->file, flags, buf, options,
                                   errp);
            s->desc_offset = 0x200;
            break;
        default:
            /* No data in the descriptor file */
            bs->file->role &= ~BDRV_CHILD_DATA;

            /* Must succeed because we have given up permissions if anything */
            bdrv_child_refresh_perms(bs, bs->file, &error_abort);

            ret = vmdk_open_desc_file(bs, flags, buf, options, errp);
            break;
    }
    if (ret) {
        goto fail;
    }

    /* try to open parent images, if exist */
    ret = vmdk_parent_open(bs);
    if (ret) {
        goto fail;
    }
    ret = vmdk_read_cid(bs, 0, &s->cid);
    if (ret) {
        goto fail;
    }
    ret = vmdk_read_cid(bs, 1, &s->parent_cid);
    if (ret) {
        goto fail;
    }
    qemu_co_mutex_init(&s->lock);

    /* Disable migration when VMDK images are used */
    error_setg(&s->migration_blocker, "The vmdk format used by node '%s' "
               "does not support live migration",
               bdrv_get_device_or_node_name(bs));
    ret = migrate_add_blocker(s->migration_blocker, errp);
    if (ret < 0) {
        error_free(s->migration_blocker);
        goto fail;
    }

    g_free(buf);
    return 0;

fail:
    g_free(buf);
    g_free(s->create_type);
    s->create_type = NULL;
    vmdk_free_extents(bs);
    return ret;
}


static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
{
    BDRVVmdkState *s = bs->opaque;
    int i;

    for (i = 0; i < s->num_extents; i++) {
        if (!s->extents[i].flat) {
            bs->bl.pwrite_zeroes_alignment =
                MAX(bs->bl.pwrite_zeroes_alignment,
                    s->extents[i].cluster_sectors << BDRV_SECTOR_BITS);
        }
    }
}

/**
 * get_whole_cluster
 *
 * Copy backing file's cluster that covers @sector_num, otherwise write zero,
 * to the cluster at @cluster_sector_num. If @zeroed is true, we're overwriting
 * a zeroed cluster in the current layer and must not copy data from the
 * backing file.
 *
 * If @skip_start_sector < @skip_end_sector, the relative range
 * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
 * it for call to write user data in the request.
 */
static int coroutine_fn GRAPH_RDLOCK
get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
                  uint64_t cluster_offset, uint64_t offset,
                  uint64_t skip_start_bytes, uint64_t skip_end_bytes,
                  bool zeroed)
{
    int ret = VMDK_OK;
    int64_t cluster_bytes;
    uint8_t *whole_grain;
    bool copy_from_backing;

    /* For COW, align request sector_num to cluster start */
    cluster_bytes = extent->cluster_sectors << BDRV_SECTOR_BITS;
    offset = QEMU_ALIGN_DOWN(offset, cluster_bytes);
    whole_grain = qemu_blockalign(bs, cluster_bytes);
    copy_from_backing = bs->backing && !zeroed;

    if (!copy_from_backing) {
        memset(whole_grain, 0, skip_start_bytes);
        memset(whole_grain + skip_end_bytes, 0, cluster_bytes - skip_end_bytes);
    }

    assert(skip_end_bytes <= cluster_bytes);
    /* we will be here if it's first write on non-exist grain(cluster).
     * try to read from parent image, if exist */
    if (bs->backing && !vmdk_is_cid_valid(bs)) {
        ret = VMDK_ERROR;
        goto exit;
    }

    /* Read backing data before skip range */
    if (skip_start_bytes > 0) {
        if (copy_from_backing) {
            /* qcow2 emits this on bs->file instead of bs->backing */
            BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
            ret = bdrv_co_pread(bs->backing, offset, skip_start_bytes,
                                whole_grain, 0);
            if (ret < 0) {
                ret = VMDK_ERROR;
                goto exit;
            }
        }
        BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
        ret = bdrv_co_pwrite(extent->file, cluster_offset, skip_start_bytes,
                             whole_grain, 0);
        if (ret < 0) {
            ret = VMDK_ERROR;
            goto exit;
        }
    }
    /* Read backing data after skip range */
    if (skip_end_bytes < cluster_bytes) {
        if (copy_from_backing) {
            /* qcow2 emits this on bs->file instead of bs->backing */
            BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
            ret = bdrv_co_pread(bs->backing, offset + skip_end_bytes,
                                cluster_bytes - skip_end_bytes,
                                whole_grain + skip_end_bytes, 0);
            if (ret < 0) {
                ret = VMDK_ERROR;
                goto exit;
            }
        }
        BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
        ret = bdrv_co_pwrite(extent->file, cluster_offset + skip_end_bytes,
                             cluster_bytes - skip_end_bytes,
                             whole_grain + skip_end_bytes, 0);
        if (ret < 0) {
            ret = VMDK_ERROR;
            goto exit;
        }
    }

    ret = VMDK_OK;
exit:
    qemu_vfree(whole_grain);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
{
    offset = cpu_to_le32(offset);
    /* update L2 table */
    BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE);
    if (bdrv_co_pwrite(extent->file,
                       ((int64_t)m_data->l2_offset * 512)
                           + (m_data->l2_index * sizeof(offset)),
                       sizeof(offset), &offset, 0) < 0) {
        return VMDK_ERROR;
    }
    /* update backup L2 table */
    if (extent->l1_backup_table_offset != 0) {
        m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
        if (bdrv_co_pwrite(extent->file,
                           ((int64_t)m_data->l2_offset * 512)
                               + (m_data->l2_index * sizeof(offset)),
                           sizeof(offset), &offset, 0) < 0) {
            return VMDK_ERROR;
        }
    }
    if (bdrv_co_flush(extent->file->bs) < 0) {
        return VMDK_ERROR;
    }
    if (m_data->l2_cache_entry) {
        *m_data->l2_cache_entry = offset;
    }

    return VMDK_OK;
}

/**
 * get_cluster_offset
 *
 * Look up cluster offset in extent file by sector number, and store in
 * @cluster_offset.
 *
 * For flat extents, the start offset as parsed from the description file is
 * returned.
 *
 * For sparse extents, look up in L1, L2 table. If allocate is true, return an
 * offset for a new cluster and update L2 cache. If there is a backing file,
 * COW is done before returning; otherwise, zeroes are written to the allocated
 * cluster. Both COW and zero writing skips the sector range
 * [@skip_start_sector, @skip_end_sector) passed in by caller, because caller
 * has new data to write there.
 *
 * Returns: VMDK_OK if cluster exists and mapped in the image.
 *          VMDK_UNALLOC if cluster is not mapped and @allocate is false.
 *          VMDK_ERROR if failed.
 */
static int coroutine_fn GRAPH_RDLOCK
get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent,
                   VmdkMetaData *m_data, uint64_t offset, bool allocate,
                   uint64_t *cluster_offset, uint64_t skip_start_bytes,
                   uint64_t skip_end_bytes)
{
    unsigned int l1_index, l2_offset, l2_index;
    int min_index, i, j;
    uint32_t min_count;
    void *l2_table;
    bool zeroed = false;
    int64_t ret;
    int64_t cluster_sector;
    unsigned int l2_size_bytes = extent->l2_size * extent->entry_size;

    if (m_data) {
        m_data->new_allocation = false;
    }
    if (extent->flat) {
        *cluster_offset = extent->flat_start_offset;
        return VMDK_OK;
    }

    offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE;
    l1_index = (offset >> 9) / extent->l1_entry_sectors;
    if (l1_index >= extent->l1_size) {
        return VMDK_ERROR;
    }
    if (extent->sesparse) {
        uint64_t l2_offset_u64;

        assert(extent->entry_size == sizeof(uint64_t));

        l2_offset_u64 = ((uint64_t *)extent->l1_table)[l1_index];
        if (l2_offset_u64 == 0) {
            l2_offset = 0;
        } else if ((l2_offset_u64 & 0xffffffff00000000) != 0x1000000000000000) {
            /*
             * Top most nibble is 0x1 if grain table is allocated.
             * strict check - top most 4 bytes must be 0x10000000 since max
             * supported size is 64TB for disk - so no more than 64TB / 16MB
             * grain directories which is smaller than uint32,
             * where 16MB is the only supported default grain table coverage.
             */
            return VMDK_ERROR;
        } else {
            l2_offset_u64 = l2_offset_u64 & 0x00000000ffffffff;
            l2_offset_u64 = extent->sesparse_l2_tables_offset +
                l2_offset_u64 * l2_size_bytes / SECTOR_SIZE;
            if (l2_offset_u64 > 0x00000000ffffffff) {
                return VMDK_ERROR;
            }
            l2_offset = (unsigned int)(l2_offset_u64);
        }
    } else {
        assert(extent->entry_size == sizeof(uint32_t));
        l2_offset = ((uint32_t *)extent->l1_table)[l1_index];
    }
    if (!l2_offset) {
        return VMDK_UNALLOC;
    }
    for (i = 0; i < L2_CACHE_SIZE; i++) {
        if (l2_offset == extent->l2_cache_offsets[i]) {
            /* increment the hit count */
            if (++extent->l2_cache_counts[i] == 0xffffffff) {
                for (j = 0; j < L2_CACHE_SIZE; j++) {
                    extent->l2_cache_counts[j] >>= 1;
                }
            }
            l2_table = (char *)extent->l2_cache + (i * l2_size_bytes);
            goto found;
        }
    }
    /* not found: load a new entry in the least used one */
    min_index = 0;
    min_count = 0xffffffff;
    for (i = 0; i < L2_CACHE_SIZE; i++) {
        if (extent->l2_cache_counts[i] < min_count) {
            min_count = extent->l2_cache_counts[i];
            min_index = i;
        }
    }
    l2_table = (char *)extent->l2_cache + (min_index * l2_size_bytes);
    BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD);
    if (bdrv_co_pread(extent->file,
                (int64_t)l2_offset * 512,
                l2_size_bytes,
                l2_table, 0
            ) < 0) {
        return VMDK_ERROR;
    }

    extent->l2_cache_offsets[min_index] = l2_offset;
    extent->l2_cache_counts[min_index] = 1;
 found:
    l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
    if (m_data) {
        m_data->l1_index = l1_index;
        m_data->l2_index = l2_index;
        m_data->l2_offset = l2_offset;
        m_data->l2_cache_entry = ((uint32_t *)l2_table) + l2_index;
    }

    if (extent->sesparse) {
        cluster_sector = le64_to_cpu(((uint64_t *)l2_table)[l2_index]);
        switch (cluster_sector & 0xf000000000000000) {
        case 0x0000000000000000:
            /* unallocated grain */
            if (cluster_sector != 0) {
                return VMDK_ERROR;
            }
            break;
        case 0x1000000000000000:
            /* scsi-unmapped grain - fallthrough */
        case 0x2000000000000000:
            /* zero grain */
            zeroed = true;
            break;
        case 0x3000000000000000:
            /* allocated grain */
            cluster_sector = (((cluster_sector & 0x0fff000000000000) >> 48) |
                              ((cluster_sector & 0x0000ffffffffffff) << 12));
            cluster_sector = extent->sesparse_clusters_offset +
                cluster_sector * extent->cluster_sectors;
            break;
        default:
            return VMDK_ERROR;
        }
    } else {
        cluster_sector = le32_to_cpu(((uint32_t *)l2_table)[l2_index]);

        if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
            zeroed = true;
        }
    }

    if (!cluster_sector || zeroed) {
        if (!allocate) {
            return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
        }
        assert(!extent->sesparse);

        if (extent->next_cluster_sector >= VMDK_EXTENT_MAX_SECTORS) {
            return VMDK_ERROR;
        }

        cluster_sector = extent->next_cluster_sector;
        extent->next_cluster_sector += extent->cluster_sectors;

        /* First of all we write grain itself, to avoid race condition
         * that may to corrupt the image.
         * This problem may occur because of insufficient space on host disk
         * or inappropriate VM shutdown.
         */
        ret = get_whole_cluster(bs, extent, cluster_sector * BDRV_SECTOR_SIZE,
                                offset, skip_start_bytes, skip_end_bytes,
                                zeroed);
        if (ret) {
            return ret;
        }
        if (m_data) {
            m_data->new_allocation = true;
        }
    }
    *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
    return VMDK_OK;
}

static VmdkExtent *find_extent(BDRVVmdkState *s,
                                int64_t sector_num, VmdkExtent *start_hint)
{
    VmdkExtent *extent = start_hint;

    if (!extent) {
        extent = &s->extents[0];
    }
    while (extent < &s->extents[s->num_extents]) {
        if (sector_num < extent->end_sector) {
            return extent;
        }
        extent++;
    }
    return NULL;
}

static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
                                                   int64_t offset)
{
    uint64_t extent_begin_offset, extent_relative_offset;
    uint64_t cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE;

    extent_begin_offset =
        (extent->end_sector - extent->sectors) * BDRV_SECTOR_SIZE;
    extent_relative_offset = offset - extent_begin_offset;
    return extent_relative_offset % cluster_size;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_block_status(BlockDriverState *bs, bool want_zero,
                     int64_t offset, int64_t bytes, int64_t *pnum,
                     int64_t *map, BlockDriverState **file)
{
    BDRVVmdkState *s = bs->opaque;
    int64_t index_in_cluster, n, ret;
    uint64_t cluster_offset;
    VmdkExtent *extent;

    extent = find_extent(s, offset >> BDRV_SECTOR_BITS, NULL);
    if (!extent) {
        return -EIO;
    }
    qemu_co_mutex_lock(&s->lock);
    ret = get_cluster_offset(bs, extent, NULL, offset, false, &cluster_offset,
                             0, 0);
    qemu_co_mutex_unlock(&s->lock);

    index_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
    switch (ret) {
    case VMDK_ERROR:
        ret = -EIO;
        break;
    case VMDK_UNALLOC:
        ret = 0;
        break;
    case VMDK_ZEROED:
        ret = BDRV_BLOCK_ZERO;
        break;
    case VMDK_OK:
        ret = BDRV_BLOCK_DATA;
        if (!extent->compressed) {
            ret |= BDRV_BLOCK_OFFSET_VALID;
            *map = cluster_offset + index_in_cluster;
            if (extent->flat) {
                ret |= BDRV_BLOCK_RECURSE;
            }
        }
        *file = extent->file->bs;
        break;
    }

    n = extent->cluster_sectors * BDRV_SECTOR_SIZE - index_in_cluster;
    *pnum = MIN(n, bytes);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
                  int64_t offset_in_cluster, QEMUIOVector *qiov,
                  uint64_t qiov_offset, uint64_t n_bytes,
                  uint64_t offset)
{
    int ret;
    VmdkGrainMarker *data = NULL;
    uLongf buf_len;
    QEMUIOVector local_qiov;
    int64_t write_offset;
    int64_t write_end_sector;

    if (extent->compressed) {
        void *compressed_data;

        /* Only whole clusters */
        if (offset_in_cluster ||
            n_bytes > (extent->cluster_sectors * SECTOR_SIZE) ||
            (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) &&
             offset + n_bytes != extent->end_sector * SECTOR_SIZE))
        {
            ret = -EINVAL;
            goto out;
        }

        if (!extent->has_marker) {
            ret = -EINVAL;
            goto out;
        }
        buf_len = (extent->cluster_sectors << 9) * 2;
        data = g_malloc(buf_len + sizeof(VmdkGrainMarker));

        compressed_data = g_malloc(n_bytes);
        qemu_iovec_to_buf(qiov, qiov_offset, compressed_data, n_bytes);
        ret = compress(data->data, &buf_len, compressed_data, n_bytes);
        g_free(compressed_data);

        if (ret != Z_OK || buf_len == 0) {
            ret = -EINVAL;
            goto out;
        }

        data->lba = cpu_to_le64(offset >> BDRV_SECTOR_BITS);
        data->size = cpu_to_le32(buf_len);

        n_bytes = buf_len + sizeof(VmdkGrainMarker);
        qemu_iovec_init_buf(&local_qiov, data, n_bytes);

        BLKDBG_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED);
    } else {
        qemu_iovec_init(&local_qiov, qiov->niov);
        qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes);

        BLKDBG_EVENT(extent->file, BLKDBG_WRITE_AIO);
    }

    write_offset = cluster_offset + offset_in_cluster;
    ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes,
                          &local_qiov, 0);

    write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE);

    if (extent->compressed) {
        extent->next_cluster_sector = write_end_sector;
    } else {
        extent->next_cluster_sector = MAX(extent->next_cluster_sector,
                                          write_end_sector);
    }

    if (ret < 0) {
        goto out;
    }
    ret = 0;
 out:
    g_free(data);
    if (!extent->compressed) {
        qemu_iovec_destroy(&local_qiov);
    }
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
                 int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes)
{
    int ret;
    int cluster_bytes, buf_bytes;
    uint8_t *cluster_buf, *compressed_data;
    uint8_t *uncomp_buf;
    uint32_t data_len;
    VmdkGrainMarker *marker;
    uLongf buf_len;


    if (!extent->compressed) {
        BLKDBG_EVENT(extent->file, BLKDBG_READ_AIO);
        ret = bdrv_co_preadv(extent->file,
                             cluster_offset + offset_in_cluster, bytes,
                             qiov, 0);
        if (ret < 0) {
            return ret;
        }
        return 0;
    }
    cluster_bytes = extent->cluster_sectors * 512;
    /* Read two clusters in case GrainMarker + compressed data > one cluster */
    buf_bytes = cluster_bytes * 2;
    cluster_buf = g_malloc(buf_bytes);
    uncomp_buf = g_malloc(cluster_bytes);
    BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED);
    ret = bdrv_co_pread(extent->file, cluster_offset, buf_bytes, cluster_buf,
                        0);
    if (ret < 0) {
        goto out;
    }
    compressed_data = cluster_buf;
    buf_len = cluster_bytes;
    data_len = cluster_bytes;
    if (extent->has_marker) {
        marker = (VmdkGrainMarker *)cluster_buf;
        compressed_data = marker->data;
        data_len = le32_to_cpu(marker->size);
    }
    if (!data_len || data_len > buf_bytes) {
        ret = -EINVAL;
        goto out;
    }
    ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len);
    if (ret != Z_OK) {
        ret = -EINVAL;
        goto out;

    }
    if (offset_in_cluster < 0 ||
            offset_in_cluster + bytes > buf_len) {
        ret = -EINVAL;
        goto out;
    }
    qemu_iovec_from_buf(qiov, 0, uncomp_buf + offset_in_cluster, bytes);
    ret = 0;

 out:
    g_free(uncomp_buf);
    g_free(cluster_buf);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
               QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    BDRVVmdkState *s = bs->opaque;
    int ret;
    uint64_t n_bytes, offset_in_cluster;
    VmdkExtent *extent = NULL;
    QEMUIOVector local_qiov;
    uint64_t cluster_offset;
    uint64_t bytes_done = 0;

    qemu_iovec_init(&local_qiov, qiov->niov);
    qemu_co_mutex_lock(&s->lock);

    while (bytes > 0) {
        extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent);
        if (!extent) {
            ret = -EIO;
            goto fail;
        }
        ret = get_cluster_offset(bs, extent, NULL,
                                 offset, false, &cluster_offset, 0, 0);
        offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);

        n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
                             - offset_in_cluster);

        if (ret != VMDK_OK) {
            /* if not allocated, try to read from parent image, if exist */
            if (bs->backing && ret != VMDK_ZEROED) {
                if (!vmdk_is_cid_valid(bs)) {
                    ret = -EINVAL;
                    goto fail;
                }

                qemu_iovec_reset(&local_qiov);
                qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);

                /* qcow2 emits this on bs->file instead of bs->backing */
                BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
                                     &local_qiov, 0);
                if (ret < 0) {
                    goto fail;
                }
            } else {
                qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
            }
        } else {
            qemu_iovec_reset(&local_qiov);
            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);

            ret = vmdk_read_extent(extent, cluster_offset, offset_in_cluster,
                                   &local_qiov, n_bytes);
            if (ret) {
                goto fail;
            }
        }
        bytes -= n_bytes;
        offset += n_bytes;
        bytes_done += n_bytes;
    }

    ret = 0;
fail:
    qemu_co_mutex_unlock(&s->lock);
    qemu_iovec_destroy(&local_qiov);

    return ret;
}

/**
 * vmdk_write:
 * @zeroed:       buf is ignored (data is zero), use zeroed_grain GTE feature
 *                if possible, otherwise return -ENOTSUP.
 * @zero_dry_run: used for zeroed == true only, don't update L2 table, just try
 *                with each cluster. By dry run we can find if the zero write
 *                is possible without modifying image data.
 *
 * Returns: error code with 0 for success.
 */
static int coroutine_fn GRAPH_RDLOCK
vmdk_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
             QEMUIOVector *qiov, bool zeroed, bool zero_dry_run)
{
    BDRVVmdkState *s = bs->opaque;
    VmdkExtent *extent = NULL;
    int ret;
    int64_t offset_in_cluster, n_bytes;
    uint64_t cluster_offset;
    uint64_t bytes_done = 0;
    VmdkMetaData m_data;

    if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) {
        error_report("Wrong offset: offset=0x%" PRIx64
                     " total_sectors=0x%" PRIx64,
                     offset, bs->total_sectors);
        return -EIO;
    }

    while (bytes > 0) {
        extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent);
        if (!extent) {
            return -EIO;
        }
        if (extent->sesparse) {
            return -ENOTSUP;
        }
        offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
        n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
                             - offset_in_cluster);

        ret = get_cluster_offset(bs, extent, &m_data, offset,
                                 !(extent->compressed || zeroed),
                                 &cluster_offset, offset_in_cluster,
                                 offset_in_cluster + n_bytes);
        if (extent->compressed) {
            if (ret == VMDK_OK) {
                /* Refuse write to allocated cluster for streamOptimized */
                error_report("Could not write to allocated cluster"
                              " for streamOptimized");
                return -EIO;
            } else if (!zeroed) {
                /* allocate */
                ret = get_cluster_offset(bs, extent, &m_data, offset,
                                         true, &cluster_offset, 0, 0);
            }
        }
        if (ret == VMDK_ERROR) {
            return -EINVAL;
        }
        if (zeroed) {
            /* Do zeroed write, buf is ignored */
            if (extent->has_zero_grain &&
                    offset_in_cluster == 0 &&
                    n_bytes >= extent->cluster_sectors * BDRV_SECTOR_SIZE) {
                n_bytes = extent->cluster_sectors * BDRV_SECTOR_SIZE;
                if (!zero_dry_run && ret != VMDK_ZEROED) {
                    /* update L2 tables */
                    if (vmdk_L2update(extent, &m_data, VMDK_GTE_ZEROED)
                            != VMDK_OK) {
                        return -EIO;
                    }
                }
            } else {
                return -ENOTSUP;
            }
        } else {
            ret = vmdk_write_extent(extent, cluster_offset, offset_in_cluster,
                                    qiov, bytes_done, n_bytes, offset);
            if (ret) {
                return ret;
            }
            if (m_data.new_allocation) {
                /* update L2 tables */
                if (vmdk_L2update(extent, &m_data,
                                  cluster_offset >> BDRV_SECTOR_BITS)
                        != VMDK_OK) {
                    return -EIO;
                }
            }
        }
        bytes -= n_bytes;
        offset += n_bytes;
        bytes_done += n_bytes;

        /* update CID on the first write every time the virtual disk is
         * opened */
        if (!s->cid_updated) {
            ret = vmdk_write_cid(bs, g_random_int());
            if (ret < 0) {
                return ret;
            }
            s->cid_updated = true;
        }
    }
    return 0;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
                QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    int ret;
    BDRVVmdkState *s = bs->opaque;
    qemu_co_mutex_lock(&s->lock);
    ret = vmdk_pwritev(bs, offset, bytes, qiov, false, false);
    qemu_co_mutex_unlock(&s->lock);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
                           QEMUIOVector *qiov)
{
    if (bytes == 0) {
        /* The caller will write bytes 0 to signal EOF.
         * When receive it, we align EOF to a sector boundary. */
        BDRVVmdkState *s = bs->opaque;
        int i, ret;
        int64_t length;

        for (i = 0; i < s->num_extents; i++) {
            length = bdrv_getlength(s->extents[i].file->bs);
            if (length < 0) {
                return length;
            }
            length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
            ret = bdrv_co_truncate(s->extents[i].file, length, false,
                                   PREALLOC_MODE_OFF, 0, NULL);
            if (ret < 0) {
                return ret;
            }
        }
        return 0;
    }
    return vmdk_co_pwritev(bs, offset, bytes, qiov, 0);
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
                      BdrvRequestFlags flags)
{
    int ret;
    BDRVVmdkState *s = bs->opaque;

    qemu_co_mutex_lock(&s->lock);
    /* write zeroes could fail if sectors not aligned to cluster, test it with
     * dry_run == true before really updating image */
    ret = vmdk_pwritev(bs, offset, bytes, NULL, true, true);
    if (!ret) {
        ret = vmdk_pwritev(bs, offset, bytes, NULL, true, false);
    }
    qemu_co_mutex_unlock(&s->lock);
    return ret;
}

static int vmdk_init_extent(BlockBackend *blk,
                            int64_t filesize, bool flat,
                            bool compress, bool zeroed_grain,
                            Error **errp)
{
    int ret, i;
    VMDK4Header header;
    uint32_t tmp, magic, grains, gd_sectors, gt_size, gt_count;
    uint32_t *gd_buf = NULL;
    int gd_buf_size;

    if (flat) {
        ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
        goto exit;
    }
    magic = cpu_to_be32(VMDK4_MAGIC);
    memset(&header, 0, sizeof(header));
    if (compress) {
        header.version = 3;
    } else if (zeroed_grain) {
        header.version = 2;
    } else {
        header.version = 1;
    }
    header.flags = VMDK4_FLAG_RGD | VMDK4_FLAG_NL_DETECT
                   | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0)
                   | (zeroed_grain ? VMDK4_FLAG_ZERO_GRAIN : 0);
    header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0;
    header.capacity = filesize / BDRV_SECTOR_SIZE;
    header.granularity = 128;
    header.num_gtes_per_gt = BDRV_SECTOR_SIZE;

    grains = DIV_ROUND_UP(filesize / BDRV_SECTOR_SIZE, header.granularity);
    gt_size = DIV_ROUND_UP(header.num_gtes_per_gt * sizeof(uint32_t),
                           BDRV_SECTOR_SIZE);
    gt_count = DIV_ROUND_UP(grains, header.num_gtes_per_gt);
    gd_sectors = DIV_ROUND_UP(gt_count * sizeof(uint32_t), BDRV_SECTOR_SIZE);

    header.desc_offset = 1;
    header.desc_size = 20;
    header.rgd_offset = header.desc_offset + header.desc_size;
    header.gd_offset = header.rgd_offset + gd_sectors + (gt_size * gt_count);
    header.grain_offset =
        ROUND_UP(header.gd_offset + gd_sectors + (gt_size * gt_count),
                 header.granularity);
    /* swap endianness for all header fields */
    header.version = cpu_to_le32(header.version);
    header.flags = cpu_to_le32(header.flags);
    header.capacity = cpu_to_le64(header.capacity);
    header.granularity = cpu_to_le64(header.granularity);
    header.num_gtes_per_gt = cpu_to_le32(header.num_gtes_per_gt);
    header.desc_offset = cpu_to_le64(header.desc_offset);
    header.desc_size = cpu_to_le64(header.desc_size);
    header.rgd_offset = cpu_to_le64(header.rgd_offset);
    header.gd_offset = cpu_to_le64(header.gd_offset);
    header.grain_offset = cpu_to_le64(header.grain_offset);
    header.compressAlgorithm = cpu_to_le16(header.compressAlgorithm);

    header.check_bytes[0] = 0xa;
    header.check_bytes[1] = 0x20;
    header.check_bytes[2] = 0xd;
    header.check_bytes[3] = 0xa;

    /* write all the data */
    ret = blk_pwrite(blk, 0, sizeof(magic), &magic, 0);
    if (ret < 0) {
        error_setg(errp, QERR_IO_ERROR);
        goto exit;
    }
    ret = blk_pwrite(blk, sizeof(magic), sizeof(header), &header, 0);
    if (ret < 0) {
        error_setg(errp, QERR_IO_ERROR);
        goto exit;
    }

    ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
                       PREALLOC_MODE_OFF, 0, errp);
    if (ret < 0) {
        goto exit;
    }

    /* write grain directory */
    gd_buf_size = gd_sectors * BDRV_SECTOR_SIZE;
    gd_buf = g_malloc0(gd_buf_size);
    for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_sectors;
         i < gt_count; i++, tmp += gt_size) {
        gd_buf[i] = cpu_to_le32(tmp);
    }
    ret = blk_pwrite(blk, le64_to_cpu(header.rgd_offset) * BDRV_SECTOR_SIZE,
                     gd_buf_size, gd_buf, 0);
    if (ret < 0) {
        error_setg(errp, QERR_IO_ERROR);
        goto exit;
    }

    /* write backup grain directory */
    for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_sectors;
         i < gt_count; i++, tmp += gt_size) {
        gd_buf[i] = cpu_to_le32(tmp);
    }
    ret = blk_pwrite(blk, le64_to_cpu(header.gd_offset) * BDRV_SECTOR_SIZE,
                     gd_buf_size, gd_buf, 0);
    if (ret < 0) {
        error_setg(errp, QERR_IO_ERROR);
    }

    ret = 0;
exit:
    g_free(gd_buf);
    return ret;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_create_extent(const char *filename, int64_t filesize, bool flat,
                   bool compress, bool zeroed_grain, BlockBackend **pbb,
                   QemuOpts *opts, Error **errp)
{
    int ret;
    BlockBackend *blk = NULL;

    ret = bdrv_co_create_file(filename, opts, errp);
    if (ret < 0) {
        goto exit;
    }

    blk = blk_co_new_open(filename, NULL, NULL,
                          BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
                          errp);
    if (blk == NULL) {
        ret = -EIO;
        goto exit;
    }

    blk_set_allow_write_beyond_eof(blk, true);

    ret = vmdk_init_extent(blk, filesize, flat, compress, zeroed_grain, errp);
exit:
    if (blk) {
        if (pbb) {
            *pbb = blk;
        } else {
            blk_co_unref(blk);
            blk = NULL;
        }
    }
    return ret;
}

static int filename_decompose(const char *filename, char *path, char *prefix,
                              char *postfix, size_t buf_len, Error **errp)
{
    const char *p, *q;

    if (filename == NULL || !strlen(filename)) {
        error_setg(errp, "No filename provided");
        return VMDK_ERROR;
    }
    p = strrchr(filename, '/');
    if (p == NULL) {
        p = strrchr(filename, '\\');
    }
    if (p == NULL) {
        p = strrchr(filename, ':');
    }
    if (p != NULL) {
        p++;
        if (p - filename >= buf_len) {
            return VMDK_ERROR;
        }
        pstrcpy(path, p - filename + 1, filename);
    } else {
        p = filename;
        path[0] = '\0';
    }
    q = strrchr(p, '.');
    if (q == NULL) {
        pstrcpy(prefix, buf_len, p);
        postfix[0] = '\0';
    } else {
        if (q - p >= buf_len) {
            return VMDK_ERROR;
        }
        pstrcpy(prefix, q - p + 1, p);
        pstrcpy(postfix, buf_len, q);
    }
    return VMDK_OK;
}

/*
 * idx == 0: get or create the descriptor file (also the image file if in a
 *           non-split format.
 * idx >= 1: get the n-th extent if in a split subformat
 */
typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */
    (*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split,
                             bool compress, bool zeroed_grain, void *opaque,
                             Error **errp);

static void vmdk_desc_add_extent(GString *desc,
                                 const char *extent_line_fmt,
                                 int64_t size, const char *filename)
{
    char *basename = g_path_get_basename(filename);

    g_string_append_printf(desc, extent_line_fmt,
                           DIV_ROUND_UP(size, BDRV_SECTOR_SIZE), basename);
    g_free(basename);
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_do_create(int64_t size,
                  BlockdevVmdkSubformat subformat,
                  BlockdevVmdkAdapterType adapter_type,
                  const char *backing_file,
                  const char *hw_version,
                  const char *toolsversion,
                  bool compat6,
                  bool zeroed_grain,
                  vmdk_create_extent_fn extent_fn,
                  void *opaque,
                  Error **errp)
{
    int extent_idx;
    BlockBackend *blk = NULL;
    BlockBackend *extent_blk;
    Error *local_err = NULL;
    char *desc = NULL;
    int ret = 0;
    bool flat, split, compress;
    GString *ext_desc_lines;
    const int64_t split_size = 0x80000000;  /* VMDK has constant split size */
    int64_t extent_size;
    int64_t created_size = 0;
    const char *extent_line_fmt;
    char *parent_desc_line = g_malloc0(BUF_SIZE);
    uint32_t parent_cid = 0xffffffff;
    uint32_t number_heads = 16;
    uint32_t desc_offset = 0, desc_len;
    const char desc_template[] =
        "# Disk DescriptorFile\n"
        "version=1\n"
        "CID=%" PRIx32 "\n"
        "parentCID=%" PRIx32 "\n"
        "createType=\"%s\"\n"
        "%s"
        "\n"
        "# Extent description\n"
        "%s"
        "\n"
        "# The Disk Data Base\n"
        "#DDB\n"
        "\n"
        "ddb.virtualHWVersion = \"%s\"\n"
        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
        "ddb.geometry.heads = \"%" PRIu32 "\"\n"
        "ddb.geometry.sectors = \"63\"\n"
        "ddb.adapterType = \"%s\"\n"
        "ddb.toolsVersion = \"%s\"\n";

    ext_desc_lines = g_string_new(NULL);

    /* Read out options */
    if (compat6) {
        if (hw_version) {
            error_setg(errp,
                       "compat6 cannot be enabled with hwversion set");
            ret = -EINVAL;
            goto exit;
        }
        hw_version = "6";
    }
    if (!hw_version) {
        hw_version = "4";
    }
    if (!toolsversion) {
        toolsversion = "2147483647";
    }

    if (adapter_type != BLOCKDEV_VMDK_ADAPTER_TYPE_IDE) {
        /* that's the number of heads with which vmware operates when
           creating, exporting, etc. vmdk files with a non-ide adapter type */
        number_heads = 255;
    }
    split = (subformat == BLOCKDEV_VMDK_SUBFORMAT_TWOGBMAXEXTENTFLAT) ||
            (subformat == BLOCKDEV_VMDK_SUBFORMAT_TWOGBMAXEXTENTSPARSE);
    flat = (subformat == BLOCKDEV_VMDK_SUBFORMAT_MONOLITHICFLAT) ||
           (subformat == BLOCKDEV_VMDK_SUBFORMAT_TWOGBMAXEXTENTFLAT);
    compress = subformat == BLOCKDEV_VMDK_SUBFORMAT_STREAMOPTIMIZED;

    if (flat) {
        extent_line_fmt = "RW %" PRId64 " FLAT \"%s\" 0\n";
    } else {
        extent_line_fmt = "RW %" PRId64 " SPARSE \"%s\"\n";
    }
    if (flat && backing_file) {
        error_setg(errp, "Flat image can't have backing file");
        ret = -ENOTSUP;
        goto exit;
    }
    if (flat && zeroed_grain) {
        error_setg(errp, "Flat image can't enable zeroed grain");
        ret = -ENOTSUP;
        goto exit;
    }

    /* Create extents */
    if (split) {
        extent_size = split_size;
    } else {
        extent_size = size;
    }
    if (!split && !flat) {
        created_size = extent_size;
    } else {
        created_size = 0;
    }
    /* Get the descriptor file BDS */
    blk = extent_fn(created_size, 0, flat, split, compress, zeroed_grain,
                    opaque, errp);
    if (!blk) {
        ret = -EIO;
        goto exit;
    }
    if (!split && !flat) {
        vmdk_desc_add_extent(ext_desc_lines, extent_line_fmt, created_size,
                             blk_bs(blk)->filename);
    }

    if (backing_file) {
        BlockBackend *backing;
        char *full_backing =
            bdrv_get_full_backing_filename_from_filename(blk_bs(blk)->filename,
                                                         backing_file,
                                                         &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            ret = -ENOENT;
            goto exit;
        }
        assert(full_backing);

        backing = blk_co_new_open(full_backing, NULL, NULL,
                                  BDRV_O_NO_BACKING, errp);
        g_free(full_backing);
        if (backing == NULL) {
            ret = -EIO;
            goto exit;
        }
        if (strcmp(blk_bs(backing)->drv->format_name, "vmdk")) {
            error_setg(errp, "Invalid backing file format: %s. Must be vmdk",
                       blk_bs(backing)->drv->format_name);
            blk_co_unref(backing);
            ret = -EINVAL;
            goto exit;
        }
        ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid);
        blk_co_unref(backing);
        if (ret) {
            error_setg(errp, "Failed to read parent CID");
            goto exit;
        }
        snprintf(parent_desc_line, BUF_SIZE,
                "parentFileNameHint=\"%s\"", backing_file);
    }
    extent_idx = 1;
    while (created_size < size) {
        int64_t cur_size = MIN(size - created_size, extent_size);
        extent_blk = extent_fn(cur_size, extent_idx, flat, split, compress,
                               zeroed_grain, opaque, errp);
        if (!extent_blk) {
            ret = -EINVAL;
            goto exit;
        }
        vmdk_desc_add_extent(ext_desc_lines, extent_line_fmt, cur_size,
                             blk_bs(extent_blk)->filename);
        created_size += cur_size;
        extent_idx++;
        blk_co_unref(extent_blk);
    }

    /* Check whether we got excess extents */
    extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain,
                           opaque, NULL);
    if (extent_blk) {
        blk_co_unref(extent_blk);
        error_setg(errp, "List of extents contains unused extents");
        ret = -EINVAL;
        goto exit;
    }

    /* generate descriptor file */
    desc = g_strdup_printf(desc_template,
                           g_random_int(),
                           parent_cid,
                           BlockdevVmdkSubformat_str(subformat),
                           parent_desc_line,
                           ext_desc_lines->str,
                           hw_version,
                           size /
                               (int64_t)(63 * number_heads * BDRV_SECTOR_SIZE),
                           number_heads,
                           BlockdevVmdkAdapterType_str(adapter_type),
                           toolsversion);
    desc_len = strlen(desc);
    /* the descriptor offset = 0x200 */
    if (!split && !flat) {
        desc_offset = 0x200;
    }

    ret = blk_co_pwrite(blk, desc_offset, desc_len, desc, 0);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not write description");
        goto exit;
    }
    /* bdrv_pwrite write padding zeros to align to sector, we don't need that
     * for description file */
    if (desc_offset == 0) {
        ret = blk_co_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
        if (ret < 0) {
            goto exit;
        }
    }
    ret = 0;
exit:
    if (blk) {
        blk_co_unref(blk);
    }
    g_free(desc);
    g_free(parent_desc_line);
    g_string_free(ext_desc_lines, true);
    return ret;
}

typedef struct {
    char *path;
    char *prefix;
    char *postfix;
    QemuOpts *opts;
} VMDKCreateOptsData;

static BlockBackend * coroutine_fn GRAPH_RDLOCK
vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
                       bool compress, bool zeroed_grain, void *opaque,
                       Error **errp)
{
    BlockBackend *blk = NULL;
    BlockDriverState *bs = NULL;
    VMDKCreateOptsData *data = opaque;
    char *ext_filename = NULL;
    char *rel_filename = NULL;

    /* We're done, don't create excess extents. */
    if (size == -1) {
        assert(errp == NULL);
        return NULL;
    }

    if (idx == 0) {
        rel_filename = g_strdup_printf("%s%s", data->prefix, data->postfix);
    } else if (split) {
        rel_filename = g_strdup_printf("%s-%c%03d%s",
                                       data->prefix,
                                       flat ? 'f' : 's', idx, data->postfix);
    } else {
        assert(idx == 1);
        rel_filename = g_strdup_printf("%s-flat%s", data->prefix, data->postfix);
    }

    ext_filename = g_strdup_printf("%s%s", data->path, rel_filename);
    g_free(rel_filename);

    if (vmdk_create_extent(ext_filename, size,
                           flat, compress, zeroed_grain, &blk, data->opts,
                           errp)) {
        goto exit;
    }
    bdrv_co_unref(bs);
exit:
    g_free(ext_filename);
    return blk;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_create_opts(BlockDriver *drv, const char *filename,
                    QemuOpts *opts, Error **errp)
{
    Error *local_err = NULL;
    char *desc = NULL;
    int64_t total_size = 0;
    char *adapter_type = NULL;
    BlockdevVmdkAdapterType adapter_type_enum;
    char *backing_file = NULL;
    char *hw_version = NULL;
    char *toolsversion = NULL;
    char *fmt = NULL;
    BlockdevVmdkSubformat subformat;
    int ret = 0;
    char *path = g_malloc0(PATH_MAX);
    char *prefix = g_malloc0(PATH_MAX);
    char *postfix = g_malloc0(PATH_MAX);
    char *desc_line = g_malloc0(BUF_SIZE);
    char *ext_filename = g_malloc0(PATH_MAX);
    char *desc_filename = g_malloc0(PATH_MAX);
    char *parent_desc_line = g_malloc0(BUF_SIZE);
    bool zeroed_grain;
    bool compat6;
    VMDKCreateOptsData data;
    char *backing_fmt = NULL;

    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
    if (backing_fmt && strcmp(backing_fmt, "vmdk") != 0) {
        error_setg(errp, "backing_file must be a vmdk image");
        ret = -EINVAL;
        goto exit;
    }

    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {
        ret = -EINVAL;
        goto exit;
    }
    /* Read out options */
    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
                          BDRV_SECTOR_SIZE);
    adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
    hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION);
    toolsversion = qemu_opt_get_del(opts, BLOCK_OPT_TOOLSVERSION);
    compat6 = qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false);
    if (strcmp(hw_version, "undefined") == 0) {
        g_free(hw_version);
        hw_version = NULL;
    }
    fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
    zeroed_grain = qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false);

    if (adapter_type) {
        adapter_type_enum = qapi_enum_parse(&BlockdevVmdkAdapterType_lookup,
                                            adapter_type,
                                            BLOCKDEV_VMDK_ADAPTER_TYPE_IDE,
                                            &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            ret = -EINVAL;
            goto exit;
        }
    } else {
        adapter_type_enum = BLOCKDEV_VMDK_ADAPTER_TYPE_IDE;
    }

    if (!fmt) {
        /* Default format to monolithicSparse */
        subformat = BLOCKDEV_VMDK_SUBFORMAT_MONOLITHICSPARSE;
    } else {
        subformat = qapi_enum_parse(&BlockdevVmdkSubformat_lookup,
                                    fmt,
                                    BLOCKDEV_VMDK_SUBFORMAT_MONOLITHICSPARSE,
                                    &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            ret = -EINVAL;
            goto exit;
        }
    }
    data = (VMDKCreateOptsData){
        .prefix = prefix,
        .postfix = postfix,
        .path = path,
        .opts = opts,
    };
    ret = vmdk_co_do_create(total_size, subformat, adapter_type_enum,
                            backing_file, hw_version, toolsversion, compat6,
                            zeroed_grain, vmdk_co_create_opts_cb, &data, errp);

exit:
    g_free(backing_fmt);
    g_free(adapter_type);
    g_free(backing_file);
    g_free(hw_version);
    g_free(toolsversion);
    g_free(fmt);
    g_free(desc);
    g_free(path);
    g_free(prefix);
    g_free(postfix);
    g_free(desc_line);
    g_free(ext_filename);
    g_free(desc_filename);
    g_free(parent_desc_line);
    return ret;
}

static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
                                                     bool flat, bool split,
                                                     bool compress,
                                                     bool zeroed_grain,
                                                     void *opaque, Error **errp)
{
    int ret;
    BlockDriverState *bs;
    BlockBackend *blk;
    BlockdevCreateOptionsVmdk *opts = opaque;

    if (idx == 0) {
        bs = bdrv_co_open_blockdev_ref(opts->file, errp);
    } else {
        int i;
        BlockdevRefList *list = opts->extents;
        for (i = 1; i < idx; i++) {
            if (!list || !list->next) {
                error_setg(errp, "Extent [%d] not specified", i);
                return NULL;
            }
            list = list->next;
        }
        if (!list) {
            error_setg(errp, "Extent [%d] not specified", idx - 1);
            return NULL;
        }
        bs = bdrv_co_open_blockdev_ref(list->value, errp);
    }
    if (!bs) {
        return NULL;
    }
    blk = blk_co_new_with_bs(bs,
                             BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
                                BLK_PERM_RESIZE,
                             BLK_PERM_ALL,
                             errp);
    if (!blk) {
        return NULL;
    }
    blk_set_allow_write_beyond_eof(blk, true);
    bdrv_co_unref(bs);

    if (size != -1) {
        ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
        if (ret) {
            blk_co_unref(blk);
            blk = NULL;
        }
    }
    return blk;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp)
{
    BlockdevCreateOptionsVmdk *opts;

    opts = &create_options->u.vmdk;

    /* Validate options */
    if (!QEMU_IS_ALIGNED(opts->size, BDRV_SECTOR_SIZE)) {
        error_setg(errp, "Image size must be a multiple of 512 bytes");
        return -EINVAL;
    }

    return vmdk_co_do_create(opts->size,
                             opts->subformat,
                             opts->adapter_type,
                             opts->backing_file,
                             opts->hwversion,
                             opts->toolsversion,
                             false,
                             opts->zeroed_grain,
                             vmdk_co_create_cb,
                             opts, errp);
}

static void vmdk_close(BlockDriverState *bs)
{
    BDRVVmdkState *s = bs->opaque;

    vmdk_free_extents(bs);
    g_free(s->create_type);

    migrate_del_blocker(s->migration_blocker);
    error_free(s->migration_blocker);
}

static int64_t coroutine_fn GRAPH_RDLOCK
vmdk_co_get_allocated_file_size(BlockDriverState *bs)
{
    int i;
    int64_t ret = 0;
    int64_t r;
    BDRVVmdkState *s = bs->opaque;

    ret = bdrv_co_get_allocated_file_size(bs->file->bs);
    if (ret < 0) {
        return ret;
    }
    for (i = 0; i < s->num_extents; i++) {
        if (s->extents[i].file == bs->file) {
            continue;
        }
        r = bdrv_co_get_allocated_file_size(s->extents[i].file->bs);
        if (r < 0) {
            return r;
        }
        ret += r;
    }
    return ret;
}

static int vmdk_has_zero_init(BlockDriverState *bs)
{
    int i;
    BDRVVmdkState *s = bs->opaque;

    /* If has a flat extent and its underlying storage doesn't have zero init,
     * return 0. */
    for (i = 0; i < s->num_extents; i++) {
        if (s->extents[i].flat) {
            if (!bdrv_has_zero_init(s->extents[i].file->bs)) {
                return 0;
            }
        }
    }
    return 1;
}

static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
{
    VmdkExtentInfo *info = g_new0(VmdkExtentInfo, 1);

    bdrv_refresh_filename(extent->file->bs);
    *info = (VmdkExtentInfo){
        .filename         = g_strdup(extent->file->bs->filename),
        .format           = g_strdup(extent->type),
        .virtual_size     = extent->sectors * BDRV_SECTOR_SIZE,
        .compressed       = extent->compressed,
        .has_compressed   = extent->compressed,
        .cluster_size     = extent->cluster_sectors * BDRV_SECTOR_SIZE,
        .has_cluster_size = !extent->flat,
    };

    return info;
}

static int coroutine_fn GRAPH_RDLOCK
vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
{
    BDRVVmdkState *s = bs->opaque;
    VmdkExtent *extent = NULL;
    int64_t sector_num = 0;
    int64_t total_sectors = bdrv_nb_sectors(bs);
    int ret;
    uint64_t cluster_offset;

    if (fix) {
        return -ENOTSUP;
    }

    for (;;) {
        if (sector_num >= total_sectors) {
            return 0;
        }
        extent = find_extent(s, sector_num, extent);
        if (!extent) {
            fprintf(stderr,
                    "ERROR: could not find extent for sector %" PRId64 "\n",
                    sector_num);
            ret = -EINVAL;
            break;
        }
        ret = get_cluster_offset(bs, extent, NULL,
                                 sector_num << BDRV_SECTOR_BITS,
                                 false, &cluster_offset, 0, 0);
        if (ret == VMDK_ERROR) {
            fprintf(stderr,
                    "ERROR: could not get cluster_offset for sector %"
                    PRId64 "\n", sector_num);
            break;
        }
        if (ret == VMDK_OK) {
            int64_t extent_len = bdrv_getlength(extent->file->bs);
            if (extent_len < 0) {
                fprintf(stderr,
                        "ERROR: could not get extent file length for sector %"
                        PRId64 "\n", sector_num);
                ret = extent_len;
                break;
            }
            if (cluster_offset >= extent_len) {
                fprintf(stderr,
                        "ERROR: cluster offset for sector %"
                        PRId64 " points after EOF\n", sector_num);
                ret = -EINVAL;
                break;
            }
        }
        sector_num += extent->cluster_sectors;
    }

    result->corruptions++;
    return ret;
}

static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs,
                                                 Error **errp)
{
    int i;
    BDRVVmdkState *s = bs->opaque;
    ImageInfoSpecific *spec_info = g_new0(ImageInfoSpecific, 1);
    VmdkExtentInfoList **tail;

    *spec_info = (ImageInfoSpecific){
        .type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
        .u = {
            .vmdk.data = g_new0(ImageInfoSpecificVmdk, 1),
        },
    };

    *spec_info->u.vmdk.data = (ImageInfoSpecificVmdk) {
        .create_type = g_strdup(s->create_type),
        .cid = s->cid,
        .parent_cid = s->parent_cid,
    };

    tail = &spec_info->u.vmdk.data->extents;
    for (i = 0; i < s->num_extents; i++) {
        QAPI_LIST_APPEND(tail, vmdk_get_extent_info(&s->extents[i]));
    }

    return spec_info;
}

static bool vmdk_extents_type_eq(const VmdkExtent *a, const VmdkExtent *b)
{
    return a->flat == b->flat &&
           a->compressed == b->compressed &&
           (a->flat || a->cluster_sectors == b->cluster_sectors);
}

static int coroutine_fn
vmdk_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
    int i;
    BDRVVmdkState *s = bs->opaque;
    assert(s->num_extents);

    /* See if we have multiple extents but they have different cases */
    for (i = 1; i < s->num_extents; i++) {
        if (!vmdk_extents_type_eq(&s->extents[0], &s->extents[i])) {
            return -ENOTSUP;
        }
    }
    bdi->needs_compressed_writes = s->extents[0].compressed;
    if (!s->extents[0].flat) {
        bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
    }
    return 0;
}

static void vmdk_gather_child_options(BlockDriverState *bs, QDict *target,
                                      bool backing_overridden)
{
    /* No children but file and backing can be explicitly specified (TODO) */
    qdict_put(target, "file",
              qobject_ref(bs->file->bs->full_open_options));

    if (backing_overridden) {
        if (bs->backing) {
            qdict_put(target, "backing",
                      qobject_ref(bs->backing->bs->full_open_options));
        } else {
            qdict_put_null(target, "backing");
        }
    }
}

static QemuOptsList vmdk_create_opts = {
    .name = "vmdk-create-opts",
    .head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head),
    .desc = {
        {
            .name = BLOCK_OPT_SIZE,
            .type = QEMU_OPT_SIZE,
            .help = "Virtual disk size"
        },
        {
            .name = BLOCK_OPT_ADAPTER_TYPE,
            .type = QEMU_OPT_STRING,
            .help = "Virtual adapter type, can be one of "
                    "ide (default), lsilogic, buslogic or legacyESX"
        },
        {
            .name = BLOCK_OPT_BACKING_FILE,
            .type = QEMU_OPT_STRING,
            .help = "File name of a base image"
        },
        {
            .name = BLOCK_OPT_BACKING_FMT,
            .type = QEMU_OPT_STRING,
            .help = "Must be 'vmdk' if present",
        },
        {
            .name = BLOCK_OPT_COMPAT6,
            .type = QEMU_OPT_BOOL,
            .help = "VMDK version 6 image",
            .def_value_str = "off"
        },
        {
            .name = BLOCK_OPT_HWVERSION,
            .type = QEMU_OPT_STRING,
            .help = "VMDK hardware version",
            .def_value_str = "undefined"
        },
        {
            .name = BLOCK_OPT_TOOLSVERSION,
            .type = QEMU_OPT_STRING,
            .help = "VMware guest tools version",
        },
        {
            .name = BLOCK_OPT_SUBFMT,
            .type = QEMU_OPT_STRING,
            .help =
                "VMDK flat extent format, can be one of "
                "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
        },
        {
            .name = BLOCK_OPT_ZEROED_GRAIN,
            .type = QEMU_OPT_BOOL,
            .help = "Enable efficient zero writes "
                    "using the zeroed-grain GTE feature"
        },
        { /* end of list */ }
    }
};

static BlockDriver bdrv_vmdk = {
    .format_name                  = "vmdk",
    .instance_size                = sizeof(BDRVVmdkState),
    .bdrv_probe                   = vmdk_probe,
    .bdrv_open                    = vmdk_open,
    .bdrv_co_check                = vmdk_co_check,
    .bdrv_reopen_prepare          = vmdk_reopen_prepare,
    .bdrv_reopen_commit           = vmdk_reopen_commit,
    .bdrv_reopen_abort            = vmdk_reopen_abort,
    .bdrv_child_perm              = bdrv_default_perms,
    .bdrv_co_preadv               = vmdk_co_preadv,
    .bdrv_co_pwritev              = vmdk_co_pwritev,
    .bdrv_co_pwritev_compressed   = vmdk_co_pwritev_compressed,
    .bdrv_co_pwrite_zeroes        = vmdk_co_pwrite_zeroes,
    .bdrv_close                   = vmdk_close,
    .bdrv_co_create_opts          = vmdk_co_create_opts,
    .bdrv_co_create               = vmdk_co_create,
    .bdrv_co_block_status         = vmdk_co_block_status,
    .bdrv_co_get_allocated_file_size = vmdk_co_get_allocated_file_size,
    .bdrv_has_zero_init           = vmdk_has_zero_init,
    .bdrv_get_specific_info       = vmdk_get_specific_info,
    .bdrv_refresh_limits          = vmdk_refresh_limits,
    .bdrv_co_get_info             = vmdk_co_get_info,
    .bdrv_gather_child_options    = vmdk_gather_child_options,

    .is_format                    = true,
    .supports_backing             = true,
    .create_opts                  = &vmdk_create_opts,
};

static void bdrv_vmdk_init(void)
{
    bdrv_register(&bdrv_vmdk);
}

block_init(bdrv_vmdk_init);
