/*
 * Block driver for Hyper-V VHDX Images
 *
 * Copyright (c) 2013 Red Hat, Inc.,
 *
 * Authors:
 *  Jeff Cody <jcody@redhat.com>
 *
 *  This is based on the "VHDX Format Specification v1.00", published 8/25/2012
 *  by Microsoft:
 *      https://www.microsoft.com/en-us/download/details.aspx?id=34750
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"
#include "qemu/crc32c.h"
#include "block/vhdx.h"
#include "migration/migration.h"

#include <uuid/uuid.h>
#include <glib.h>

/* Options for VHDX creation */

#define VHDX_BLOCK_OPT_LOG_SIZE   "log_size"
#define VHDX_BLOCK_OPT_BLOCK_SIZE "block_size"
#define VHDX_BLOCK_OPT_ZERO "block_state_zero"

typedef enum VHDXImageType {
    VHDX_TYPE_DYNAMIC = 0,
    VHDX_TYPE_FIXED,
    VHDX_TYPE_DIFFERENCING,   /* Currently unsupported */
} VHDXImageType;

/* Several metadata and region table data entries are identified by
 * guids in  a MS-specific GUID format. */


/* ------- Known Region Table GUIDs ---------------------- */
static const MSGUID bat_guid =      { .data1 = 0x2dc27766,
                                      .data2 = 0xf623,
                                      .data3 = 0x4200,
                                      .data4 = { 0x9d, 0x64, 0x11, 0x5e,
                                                 0x9b, 0xfd, 0x4a, 0x08} };

static const MSGUID metadata_guid = { .data1 = 0x8b7ca206,
                                      .data2 = 0x4790,
                                      .data3 = 0x4b9a,
                                      .data4 = { 0xb8, 0xfe, 0x57, 0x5f,
                                                 0x05, 0x0f, 0x88, 0x6e} };



/* ------- Known Metadata Entry GUIDs ---------------------- */
static const MSGUID file_param_guid =   { .data1 = 0xcaa16737,
                                          .data2 = 0xfa36,
                                          .data3 = 0x4d43,
                                          .data4 = { 0xb3, 0xb6, 0x33, 0xf0,
                                                     0xaa, 0x44, 0xe7, 0x6b} };

static const MSGUID virtual_size_guid = { .data1 = 0x2FA54224,
                                          .data2 = 0xcd1b,
                                          .data3 = 0x4876,
                                          .data4 = { 0xb2, 0x11, 0x5d, 0xbe,
                                                     0xd8, 0x3b, 0xf4, 0xb8} };

static const MSGUID page83_guid =       { .data1 = 0xbeca12ab,
                                          .data2 = 0xb2e6,
                                          .data3 = 0x4523,
                                          .data4 = { 0x93, 0xef, 0xc3, 0x09,
                                                     0xe0, 0x00, 0xc7, 0x46} };


static const MSGUID phys_sector_guid =  { .data1 = 0xcda348c7,
                                          .data2 = 0x445d,
                                          .data3 = 0x4471,
                                          .data4 = { 0x9c, 0xc9, 0xe9, 0x88,
                                                     0x52, 0x51, 0xc5, 0x56} };

static const MSGUID parent_locator_guid = { .data1 = 0xa8d35f2d,
                                            .data2 = 0xb30b,
                                            .data3 = 0x454d,
                                            .data4 = { 0xab, 0xf7, 0xd3,
                                                       0xd8, 0x48, 0x34,
                                                       0xab, 0x0c} };

static const MSGUID logical_sector_guid = { .data1 = 0x8141bf1d,
                                            .data2 = 0xa96f,
                                            .data3 = 0x4709,
                                            .data4 = { 0xba, 0x47, 0xf2,
                                                       0x33, 0xa8, 0xfa,
                                                       0xab, 0x5f} };

/* Each parent type must have a valid GUID; this is for parent images
 * of type 'VHDX'.  If we were to allow e.g. a QCOW2 parent, we would
 * need to make up our own QCOW2 GUID type */
static const MSGUID parent_vhdx_guid = { .data1 = 0xb04aefb7,
                                         .data2 = 0xd19e,
                                         .data3 = 0x4a81,
                                         .data4 = { 0xb7, 0x89, 0x25, 0xb8,
                                                    0xe9, 0x44, 0x59, 0x13} };


#define META_FILE_PARAMETER_PRESENT      0x01
#define META_VIRTUAL_DISK_SIZE_PRESENT   0x02
#define META_PAGE_83_PRESENT             0x04
#define META_LOGICAL_SECTOR_SIZE_PRESENT 0x08
#define META_PHYS_SECTOR_SIZE_PRESENT    0x10
#define META_PARENT_LOCATOR_PRESENT      0x20

#define META_ALL_PRESENT    \
    (META_FILE_PARAMETER_PRESENT | META_VIRTUAL_DISK_SIZE_PRESENT | \
     META_PAGE_83_PRESENT | META_LOGICAL_SECTOR_SIZE_PRESENT | \
     META_PHYS_SECTOR_SIZE_PRESENT)


typedef struct VHDXSectorInfo {
    uint32_t bat_idx;       /* BAT entry index */
    uint32_t sectors_avail; /* sectors available in payload block */
    uint32_t bytes_left;    /* bytes left in the block after data to r/w */
    uint32_t bytes_avail;   /* bytes available in payload block */
    uint64_t file_offset;   /* absolute offset in bytes, in file */
    uint64_t block_offset;  /* block offset, in bytes */
} VHDXSectorInfo;

/* Calculates new checksum.
 *
 * Zero is substituted during crc calculation for the original crc field
 * crc_offset: byte offset in buf of the buffer crc
 * buf: buffer pointer
 * size: size of buffer (must be > crc_offset+4)
 *
 * Note: The resulting checksum is in the CPU endianness, not necessarily
 *       in the file format endianness (LE).  Any header export to disk should
 *       make sure that vhdx_header_le_export() is used to convert to the
 *       correct endianness
 */
uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
{
    uint32_t crc;

    assert(buf != NULL);
    assert(size > (crc_offset + sizeof(crc)));

    memset(buf + crc_offset, 0, sizeof(crc));
    crc =  crc32c(0xffffffff, buf, size);
    memcpy(buf + crc_offset, &crc, sizeof(crc));

    return crc;
}

uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
                            int crc_offset)
{
    uint32_t crc_new;
    uint32_t crc_orig;
    assert(buf != NULL);

    if (crc_offset > 0) {
        memcpy(&crc_orig, buf + crc_offset, sizeof(crc_orig));
        memset(buf + crc_offset, 0, sizeof(crc_orig));
    }

    crc_new = crc32c(crc, buf, size);
    if (crc_offset > 0) {
        memcpy(buf + crc_offset, &crc_orig, sizeof(crc_orig));
    }

    return crc_new;
}

/* Validates the checksum of the buffer, with an in-place CRC.
 *
 * Zero is substituted during crc calculation for the original crc field,
 * and the crc field is restored afterwards.  But the buffer will be modifed
 * during the calculation, so this may not be not suitable for multi-threaded
 * use.
 *
 * crc_offset: byte offset in buf of the buffer crc
 * buf: buffer pointer
 * size: size of buffer (must be > crc_offset+4)
 *
 * returns true if checksum is valid, false otherwise
 */
bool vhdx_checksum_is_valid(uint8_t *buf, size_t size, int crc_offset)
{
    uint32_t crc_orig;
    uint32_t crc;

    assert(buf != NULL);
    assert(size > (crc_offset + 4));

    memcpy(&crc_orig, buf + crc_offset, sizeof(crc_orig));
    crc_orig = le32_to_cpu(crc_orig);

    crc = vhdx_checksum_calc(0xffffffff, buf, size, crc_offset);

    return crc == crc_orig;
}


/*
 * This generates a UUID that is compliant with the MS GUIDs used
 * in the VHDX spec (and elsewhere).
 */
void vhdx_guid_generate(MSGUID *guid)
{
    uuid_t uuid;
    assert(guid != NULL);

    uuid_generate(uuid);
    memcpy(guid, uuid, sizeof(MSGUID));
}

/* Check for region overlaps inside the VHDX image */
static int vhdx_region_check(BDRVVHDXState *s, uint64_t start, uint64_t length)
{
    int ret = 0;
    uint64_t end;
    VHDXRegionEntry *r;

    end = start + length;
    QLIST_FOREACH(r, &s->regions, entries) {
        if (!((start >= r->end) || (end <= r->start))) {
            ret = -EINVAL;
            goto exit;
        }
    }

exit:
    return ret;
}

/* Register a region for future checks */
static void vhdx_region_register(BDRVVHDXState *s,
                                 uint64_t start, uint64_t length)
{
    VHDXRegionEntry *r;

    r = g_malloc0(sizeof(*r));

    r->start = start;
    r->end = start + length;

    QLIST_INSERT_HEAD(&s->regions, r, entries);
}

/* Free all registered regions */
static void vhdx_region_unregister_all(BDRVVHDXState *s)
{
    VHDXRegionEntry *r, *r_next;

    QLIST_FOREACH_SAFE(r, &s->regions, entries, r_next) {
        QLIST_REMOVE(r, entries);
        g_free(r);
    }
}

static void vhdx_set_shift_bits(BDRVVHDXState *s)
{
    s->logical_sector_size_bits = 31 - clz32(s->logical_sector_size);
    s->sectors_per_block_bits =   31 - clz32(s->sectors_per_block);
    s->chunk_ratio_bits =         63 - clz64(s->chunk_ratio);
    s->block_size_bits =          31 - clz32(s->block_size);
}

/*
 * Per the MS VHDX Specification, for every VHDX file:
 *      - The header section is fixed size - 1 MB
 *      - The header section is always the first "object"
 *      - The first 64KB of the header is the File Identifier
 *      - The first uint64 (8 bytes) is the VHDX Signature ("vhdxfile")
 *      - The following 512 bytes constitute a UTF-16 string identifiying the
 *        software that created the file, and is optional and diagnostic only.
 *
 *  Therefore, we probe by looking for the vhdxfile signature "vhdxfile"
 */
static int vhdx_probe(const uint8_t *buf, int buf_size, const char *filename)
{
    if (buf_size >= 8 && !memcmp(buf, "vhdxfile", 8)) {
        return 100;
    }
    return 0;
}

/*
 * Writes the header to the specified offset.
 *
 * This will optionally read in buffer data from disk (otherwise zero-fill),
 * and then update the header checksum.  Header is converted to proper
 * endianness before being written to the specified file offset
 */
static int vhdx_write_header(BlockDriverState *bs_file, VHDXHeader *hdr,
                             uint64_t offset, bool read)
{
    uint8_t *buffer = NULL;
    int ret;
    VHDXHeader header_le;

    assert(bs_file != NULL);
    assert(hdr != NULL);

    /* the header checksum is not over just the packed size of VHDXHeader,
     * but rather over the entire 'reserved' range for the header, which is
     * 4KB (VHDX_HEADER_SIZE). */

    buffer = qemu_blockalign(bs_file, VHDX_HEADER_SIZE);
    if (read) {
        /* if true, we can't assume the extra reserved bytes are 0 */
        ret = bdrv_pread(bs_file, offset, buffer, VHDX_HEADER_SIZE);
        if (ret < 0) {
            goto exit;
        }
    } else {
        memset(buffer, 0, VHDX_HEADER_SIZE);
    }

    /* overwrite the actual VHDXHeader portion */
    memcpy(buffer, hdr, sizeof(VHDXHeader));
    hdr->checksum = vhdx_update_checksum(buffer, VHDX_HEADER_SIZE,
                                         offsetof(VHDXHeader, checksum));
    vhdx_header_le_export(hdr, &header_le);
    ret = bdrv_pwrite_sync(bs_file, offset, &header_le, sizeof(VHDXHeader));

exit:
    qemu_vfree(buffer);
    return ret;
}

/* Update the VHDX headers
 *
 * This follows the VHDX spec procedures for header updates.
 *
 *  - non-current header is updated with largest sequence number
 */
static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
                              bool generate_data_write_guid, MSGUID *log_guid)
{
    int ret = 0;
    int hdr_idx = 0;
    uint64_t header_offset = VHDX_HEADER1_OFFSET;

    VHDXHeader *active_header;
    VHDXHeader *inactive_header;

    /* operate on the non-current header */
    if (s->curr_header == 0) {
        hdr_idx = 1;
        header_offset = VHDX_HEADER2_OFFSET;
    }

    active_header   = s->headers[s->curr_header];
    inactive_header = s->headers[hdr_idx];

    inactive_header->sequence_number = active_header->sequence_number + 1;

    /* a new file guid must be generated before any file write, including
     * headers */
    inactive_header->file_write_guid = s->session_guid;

    /* a new data guid only needs to be generated before any guest-visible
     * writes (i.e. something observable via virtual disk read) */
    if (generate_data_write_guid) {
        vhdx_guid_generate(&inactive_header->data_write_guid);
    }

    /* update the log guid if present */
    if (log_guid) {
        inactive_header->log_guid = *log_guid;
    }

    vhdx_write_header(bs->file, inactive_header, header_offset, true);
    if (ret < 0) {
        goto exit;
    }
    s->curr_header = hdr_idx;

exit:
    return ret;
}

/*
 * The VHDX spec calls for header updates to be performed twice, so that both
 * the current and non-current header have valid info
 */
int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
                        bool generate_data_write_guid, MSGUID *log_guid)
{
    int ret;

    ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
    if (ret < 0) {
        return ret;
    }
    ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
    return ret;
}

/* opens the specified header block from the VHDX file header section */
static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s)
{
    int ret = 0;
    VHDXHeader *header1;
    VHDXHeader *header2;
    bool h1_valid = false;
    bool h2_valid = false;
    uint64_t h1_seq = 0;
    uint64_t h2_seq = 0;
    uint8_t *buffer;

    /* header1 & header2 are freed in vhdx_close() */
    header1 = qemu_blockalign(bs, sizeof(VHDXHeader));
    header2 = qemu_blockalign(bs, sizeof(VHDXHeader));

    buffer = qemu_blockalign(bs, VHDX_HEADER_SIZE);

    s->headers[0] = header1;
    s->headers[1] = header2;

    /* We have to read the whole VHDX_HEADER_SIZE instead of
     * sizeof(VHDXHeader), because the checksum is over the whole
     * region */
    ret = bdrv_pread(bs->file, VHDX_HEADER1_OFFSET, buffer, VHDX_HEADER_SIZE);
    if (ret < 0) {
        goto fail;
    }
    /* copy over just the relevant portion that we need */
    memcpy(header1, buffer, sizeof(VHDXHeader));
    vhdx_header_le_import(header1);

    if (vhdx_checksum_is_valid(buffer, VHDX_HEADER_SIZE, 4) &&
        !memcmp(&header1->signature, "head", 4)             &&
        header1->version == 1) {
        h1_seq = header1->sequence_number;
        h1_valid = true;
    }

    ret = bdrv_pread(bs->file, VHDX_HEADER2_OFFSET, buffer, VHDX_HEADER_SIZE);
    if (ret < 0) {
        goto fail;
    }
    /* copy over just the relevant portion that we need */
    memcpy(header2, buffer, sizeof(VHDXHeader));
    vhdx_header_le_import(header2);

    if (vhdx_checksum_is_valid(buffer, VHDX_HEADER_SIZE, 4) &&
        !memcmp(&header2->signature, "head", 4)             &&
        header2->version == 1) {
        h2_seq = header2->sequence_number;
        h2_valid = true;
    }

    /* If there is only 1 valid header (or no valid headers), we
     * don't care what the sequence numbers are */
    if (h1_valid && !h2_valid) {
        s->curr_header = 0;
    } else if (!h1_valid && h2_valid) {
        s->curr_header = 1;
    } else if (!h1_valid && !h2_valid) {
        ret = -EINVAL;
        goto fail;
    } else {
        /* If both headers are valid, then we choose the active one by the
         * highest sequence number.  If the sequence numbers are equal, that is
         * invalid */
        if (h1_seq > h2_seq) {
            s->curr_header = 0;
        } else if (h2_seq > h1_seq) {
            s->curr_header = 1;
        } else {
            ret = -EINVAL;
            goto fail;
        }
    }

    vhdx_region_register(s, s->headers[s->curr_header]->log_offset,
                            s->headers[s->curr_header]->log_length);

    ret = 0;

    goto exit;

fail:
    qerror_report(ERROR_CLASS_GENERIC_ERROR, "No valid VHDX header found");
    qemu_vfree(header1);
    qemu_vfree(header2);
    s->headers[0] = NULL;
    s->headers[1] = NULL;
exit:
    qemu_vfree(buffer);
    return ret;
}


static int vhdx_open_region_tables(BlockDriverState *bs, BDRVVHDXState *s)
{
    int ret = 0;
    uint8_t *buffer;
    int offset = 0;
    VHDXRegionTableEntry rt_entry;
    uint32_t i;
    bool bat_rt_found = false;
    bool metadata_rt_found = false;

    /* We have to read the whole 64KB block, because the crc32 is over the
     * whole block */
    buffer = qemu_blockalign(bs, VHDX_HEADER_BLOCK_SIZE);

    ret = bdrv_pread(bs->file, VHDX_REGION_TABLE_OFFSET, buffer,
                     VHDX_HEADER_BLOCK_SIZE);
    if (ret < 0) {
        goto fail;
    }
    memcpy(&s->rt, buffer, sizeof(s->rt));
    vhdx_region_header_le_import(&s->rt);
    offset += sizeof(s->rt);

    if (!vhdx_checksum_is_valid(buffer, VHDX_HEADER_BLOCK_SIZE, 4) ||
        memcmp(&s->rt.signature, "regi", 4)) {
        ret = -EINVAL;
        goto fail;
    }

    /* Per spec, maximum region table entry count is 2047 */
    if (s->rt.entry_count > 2047) {
        ret = -EINVAL;
        goto fail;
    }

    for (i = 0; i < s->rt.entry_count; i++) {
        memcpy(&rt_entry, buffer + offset, sizeof(rt_entry));
        offset += sizeof(rt_entry);

        vhdx_region_entry_le_import(&rt_entry);

        /* check for region overlap between these entries, and any
         * other memory regions in the file */
        ret = vhdx_region_check(s, rt_entry.file_offset, rt_entry.length);
        if (ret < 0) {
            goto fail;
        }

        vhdx_region_register(s, rt_entry.file_offset, rt_entry.length);

        /* see if we recognize the entry */
        if (guid_eq(rt_entry.guid, bat_guid)) {
            /* must be unique; if we have already found it this is invalid */
            if (bat_rt_found) {
                ret = -EINVAL;
                goto fail;
            }
            bat_rt_found = true;
            s->bat_rt = rt_entry;
            continue;
        }

        if (guid_eq(rt_entry.guid, metadata_guid)) {
            /* must be unique; if we have already found it this is invalid */
            if (metadata_rt_found) {
                ret = -EINVAL;
                goto fail;
            }
            metadata_rt_found = true;
            s->metadata_rt = rt_entry;
            continue;
        }

        if (rt_entry.data_bits & VHDX_REGION_ENTRY_REQUIRED) {
            /* cannot read vhdx file - required region table entry that
             * we do not understand.  per spec, we must fail to open */
            ret = -ENOTSUP;
            goto fail;
        }
    }

    if (!bat_rt_found || !metadata_rt_found) {
        ret = -EINVAL;
        goto fail;
    }

    ret = 0;

fail:
    qemu_vfree(buffer);
    return ret;
}



/* Metadata initial parser
 *
 * This loads all the metadata entry fields.  This may cause additional
 * fields to be processed (e.g. parent locator, etc..).
 *
 * There are 5 Metadata items that are always required:
 *      - File Parameters (block size, has a parent)
 *      - Virtual Disk Size (size, in bytes, of the virtual drive)
 *      - Page 83 Data (scsi page 83 guid)
 *      - Logical Sector Size (logical sector size in bytes, either 512 or
 *                             4096.  We only support 512 currently)
 *      - Physical Sector Size (512 or 4096)
 *
 * Also, if the File Parameters indicate this is a differencing file,
 * we must also look for the Parent Locator metadata item.
 */
static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
{
    int ret = 0;
    uint8_t *buffer;
    int offset = 0;
    uint32_t i = 0;
    VHDXMetadataTableEntry md_entry;

    buffer = qemu_blockalign(bs, VHDX_METADATA_TABLE_MAX_SIZE);

    ret = bdrv_pread(bs->file, s->metadata_rt.file_offset, buffer,
                     VHDX_METADATA_TABLE_MAX_SIZE);
    if (ret < 0) {
        goto exit;
    }
    memcpy(&s->metadata_hdr, buffer, sizeof(s->metadata_hdr));
    offset += sizeof(s->metadata_hdr);

    vhdx_metadata_header_le_import(&s->metadata_hdr);

    if (memcmp(&s->metadata_hdr.signature, "metadata", 8)) {
        ret = -EINVAL;
        goto exit;
    }

    s->metadata_entries.present = 0;

    if ((s->metadata_hdr.entry_count * sizeof(md_entry)) >
        (VHDX_METADATA_TABLE_MAX_SIZE - offset)) {
        ret = -EINVAL;
        goto exit;
    }

    for (i = 0; i < s->metadata_hdr.entry_count; i++) {
        memcpy(&md_entry, buffer + offset, sizeof(md_entry));
        offset += sizeof(md_entry);

        vhdx_metadata_entry_le_import(&md_entry);

        if (guid_eq(md_entry.item_id, file_param_guid)) {
            if (s->metadata_entries.present & META_FILE_PARAMETER_PRESENT) {
                ret = -EINVAL;
                goto exit;
            }
            s->metadata_entries.file_parameters_entry = md_entry;
            s->metadata_entries.present |= META_FILE_PARAMETER_PRESENT;
            continue;
        }

        if (guid_eq(md_entry.item_id, virtual_size_guid)) {
            if (s->metadata_entries.present & META_VIRTUAL_DISK_SIZE_PRESENT) {
                ret = -EINVAL;
                goto exit;
            }
            s->metadata_entries.virtual_disk_size_entry = md_entry;
            s->metadata_entries.present |= META_VIRTUAL_DISK_SIZE_PRESENT;
            continue;
        }

        if (guid_eq(md_entry.item_id, page83_guid)) {
            if (s->metadata_entries.present & META_PAGE_83_PRESENT) {
                ret = -EINVAL;
                goto exit;
            }
            s->metadata_entries.page83_data_entry = md_entry;
            s->metadata_entries.present |= META_PAGE_83_PRESENT;
            continue;
        }

        if (guid_eq(md_entry.item_id, logical_sector_guid)) {
            if (s->metadata_entries.present &
                META_LOGICAL_SECTOR_SIZE_PRESENT) {
                ret = -EINVAL;
                goto exit;
            }
            s->metadata_entries.logical_sector_size_entry = md_entry;
            s->metadata_entries.present |= META_LOGICAL_SECTOR_SIZE_PRESENT;
            continue;
        }

        if (guid_eq(md_entry.item_id, phys_sector_guid)) {
            if (s->metadata_entries.present & META_PHYS_SECTOR_SIZE_PRESENT) {
                ret = -EINVAL;
                goto exit;
            }
            s->metadata_entries.phys_sector_size_entry = md_entry;
            s->metadata_entries.present |= META_PHYS_SECTOR_SIZE_PRESENT;
            continue;
        }

        if (guid_eq(md_entry.item_id, parent_locator_guid)) {
            if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) {
                ret = -EINVAL;
                goto exit;
            }
            s->metadata_entries.parent_locator_entry = md_entry;
            s->metadata_entries.present |= META_PARENT_LOCATOR_PRESENT;
            continue;
        }

        if (md_entry.data_bits & VHDX_META_FLAGS_IS_REQUIRED) {
            /* cannot read vhdx file - required region table entry that
             * we do not understand.  per spec, we must fail to open */
            ret = -ENOTSUP;
            goto exit;
        }
    }

    if (s->metadata_entries.present != META_ALL_PRESENT) {
        ret = -ENOTSUP;
        goto exit;
    }

    ret = bdrv_pread(bs->file,
                     s->metadata_entries.file_parameters_entry.offset
                                         + s->metadata_rt.file_offset,
                     &s->params,
                     sizeof(s->params));

    if (ret < 0) {
        goto exit;
    }

    le32_to_cpus(&s->params.block_size);
    le32_to_cpus(&s->params.data_bits);


    /* We now have the file parameters, so we can tell if this is a
     * differencing file (i.e.. has_parent), is dynamic or fixed
     * sized (leave_blocks_allocated), and the block size */

    /* The parent locator required iff the file parameters has_parent set */
    if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) {
        if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) {
            /* TODO: parse  parent locator fields */
            ret = -ENOTSUP; /* temp, until differencing files are supported */
            goto exit;
        } else {
            /* if has_parent is set, but there is not parent locator present,
             * then that is an invalid combination */
            ret = -EINVAL;
            goto exit;
        }
    }

    /* determine virtual disk size, logical sector size,
     * and phys sector size */

    ret = bdrv_pread(bs->file,
                     s->metadata_entries.virtual_disk_size_entry.offset
                                           + s->metadata_rt.file_offset,
                     &s->virtual_disk_size,
                     sizeof(uint64_t));
    if (ret < 0) {
        goto exit;
    }
    ret = bdrv_pread(bs->file,
                     s->metadata_entries.logical_sector_size_entry.offset
                                             + s->metadata_rt.file_offset,
                     &s->logical_sector_size,
                     sizeof(uint32_t));
    if (ret < 0) {
        goto exit;
    }
    ret = bdrv_pread(bs->file,
                     s->metadata_entries.phys_sector_size_entry.offset
                                          + s->metadata_rt.file_offset,
                     &s->physical_sector_size,
                     sizeof(uint32_t));
    if (ret < 0) {
        goto exit;
    }

    le64_to_cpus(&s->virtual_disk_size);
    le32_to_cpus(&s->logical_sector_size);
    le32_to_cpus(&s->physical_sector_size);

    if (s->logical_sector_size == 0 || s->params.block_size == 0) {
        ret = -EINVAL;
        goto exit;
    }

    /* both block_size and sector_size are guaranteed powers of 2 */
    s->sectors_per_block = s->params.block_size / s->logical_sector_size;
    s->chunk_ratio = (VHDX_MAX_SECTORS_PER_BLOCK) *
                     (uint64_t)s->logical_sector_size /
                     (uint64_t)s->params.block_size;

    /* These values are ones we will want to use for division / multiplication
     * later on, and they are all guaranteed (per the spec) to be powers of 2,
     * so we can take advantage of that for shift operations during
     * reads/writes */
    if (s->logical_sector_size & (s->logical_sector_size - 1)) {
        ret = -EINVAL;
        goto exit;
    }
    if (s->sectors_per_block & (s->sectors_per_block - 1)) {
        ret = -EINVAL;
        goto exit;
    }
    if (s->chunk_ratio & (s->chunk_ratio - 1)) {
        ret = -EINVAL;
        goto exit;
    }
    s->block_size = s->params.block_size;
    if (s->block_size & (s->block_size - 1)) {
        ret = -EINVAL;
        goto exit;
    }

    vhdx_set_shift_bits(s);

    ret = 0;

exit:
    qemu_vfree(buffer);
    return ret;
}

/*
 * Calculate the number of BAT entries, including sector
 * bitmap entries.
 */
static void vhdx_calc_bat_entries(BDRVVHDXState *s)
{
    uint32_t data_blocks_cnt, bitmap_blocks_cnt;

    data_blocks_cnt = s->virtual_disk_size >> s->block_size_bits;
    if (s->virtual_disk_size - (data_blocks_cnt << s->block_size_bits)) {
        data_blocks_cnt++;
    }
    bitmap_blocks_cnt = data_blocks_cnt >> s->chunk_ratio_bits;
    if (data_blocks_cnt - (bitmap_blocks_cnt << s->chunk_ratio_bits)) {
        bitmap_blocks_cnt++;
    }

    if (s->parent_entries) {
        s->bat_entries = bitmap_blocks_cnt * (s->chunk_ratio + 1);
    } else {
        s->bat_entries = data_blocks_cnt +
                         ((data_blocks_cnt - 1) >> s->chunk_ratio_bits);
    }

}

static void vhdx_close(BlockDriverState *bs)
{
    BDRVVHDXState *s = bs->opaque;
    qemu_vfree(s->headers[0]);
    s->headers[0] = NULL;
    qemu_vfree(s->headers[1]);
    s->headers[1] = NULL;
    qemu_vfree(s->bat);
    s->bat = NULL;
    qemu_vfree(s->parent_entries);
    s->parent_entries = NULL;
    migrate_del_blocker(s->migration_blocker);
    error_free(s->migration_blocker);
    qemu_vfree(s->log.hdr);
    s->log.hdr = NULL;
    vhdx_region_unregister_all(s);
}

static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
{
    BDRVVHDXState *s = bs->opaque;
    int ret = 0;
    uint32_t i;
    uint64_t signature;
    bool log_flushed = false;


    s->bat = NULL;
    s->first_visible_write = true;

    qemu_co_mutex_init(&s->lock);
    QLIST_INIT(&s->regions);

    /* validate the file signature */
    ret = bdrv_pread(bs->file, 0, &signature, sizeof(uint64_t));
    if (ret < 0) {
        goto fail;
    }
    if (memcmp(&signature, "vhdxfile", 8)) {
        ret = -EINVAL;
        goto fail;
    }

    /* This is used for any header updates, for the file_write_guid.
     * The spec dictates that a new value should be used for the first
     * header update */
    vhdx_guid_generate(&s->session_guid);

    ret = vhdx_parse_header(bs, s);
    if (ret < 0) {
        goto fail;
    }

    ret = vhdx_parse_log(bs, s, &log_flushed);
    if (ret < 0) {
        goto fail;
    }

    ret = vhdx_open_region_tables(bs, s);
    if (ret < 0) {
        goto fail;
    }

    ret = vhdx_parse_metadata(bs, s);
    if (ret < 0) {
        goto fail;
    }

    s->block_size = s->params.block_size;

    /* the VHDX spec dictates that virtual_disk_size is always a multiple of
     * logical_sector_size */
    bs->total_sectors = s->virtual_disk_size >> s->logical_sector_size_bits;

    vhdx_calc_bat_entries(s);

    s->bat_offset = s->bat_rt.file_offset;

    if (s->bat_entries > s->bat_rt.length / sizeof(VHDXBatEntry)) {
        /* BAT allocation is not large enough for all entries */
        ret = -EINVAL;
        goto fail;
    }

    /* s->bat is freed in vhdx_close() */
    s->bat = qemu_blockalign(bs, s->bat_rt.length);

    ret = bdrv_pread(bs->file, s->bat_offset, s->bat, s->bat_rt.length);
    if (ret < 0) {
        goto fail;
    }

    uint64_t payblocks = s->chunk_ratio;
    /* endian convert, and verify populated BAT field file offsets against
     * region table and log entries */
    for (i = 0; i < s->bat_entries; i++) {
        le64_to_cpus(&s->bat[i]);
        if (payblocks--) {
            /* payload bat entries */
            if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==
                    PAYLOAD_BLOCK_FULLY_PRESENT) {
                ret = vhdx_region_check(s, s->bat[i] & VHDX_BAT_FILE_OFF_MASK,
                                        s->block_size);
                if (ret < 0) {
                    goto fail;
                }
            }
        } else {
            payblocks = s->chunk_ratio;
            /* Once differencing files are supported, verify sector bitmap
             * blocks here */
        }
    }

    if (flags & BDRV_O_RDWR) {
        ret = vhdx_update_headers(bs, s, false, NULL);
        if (ret < 0) {
            goto fail;
        }
    }

    /* TODO: differencing files */

    /* Disable migration when VHDX images are used */
    error_set(&s->migration_blocker,
            QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
            "vhdx", bs->device_name, "live migration");
    migrate_add_blocker(s->migration_blocker);

    return 0;
fail:
    vhdx_close(bs);
    return ret;
}

static int vhdx_reopen_prepare(BDRVReopenState *state,
                               BlockReopenQueue *queue, Error **errp)
{
    return 0;
}


/*
 * Perform sector to block offset translations, to get various
 * sector and file offsets into the image.  See VHDXSectorInfo
 */
static void vhdx_block_translate(BDRVVHDXState *s, int64_t sector_num,
                                 int nb_sectors, VHDXSectorInfo *sinfo)
{
    uint32_t block_offset;

    sinfo->bat_idx = sector_num >> s->sectors_per_block_bits;
    /* effectively a modulo - this gives us the offset into the block
     * (in sector sizes) for our sector number */
    block_offset = sector_num - (sinfo->bat_idx << s->sectors_per_block_bits);
    /* the chunk ratio gives us the interleaving of the sector
     * bitmaps, so we need to advance our page block index by the
     * sector bitmaps entry number */
    sinfo->bat_idx += sinfo->bat_idx >> s->chunk_ratio_bits;

    /* the number of sectors we can read/write in this cycle */
    sinfo->sectors_avail = s->sectors_per_block - block_offset;

    sinfo->bytes_left = sinfo->sectors_avail << s->logical_sector_size_bits;

    if (sinfo->sectors_avail > nb_sectors) {
        sinfo->sectors_avail = nb_sectors;
    }

    sinfo->bytes_avail = sinfo->sectors_avail << s->logical_sector_size_bits;

    sinfo->file_offset = s->bat[sinfo->bat_idx] & VHDX_BAT_FILE_OFF_MASK;

    sinfo->block_offset = block_offset << s->logical_sector_size_bits;

    /* The file offset must be past the header section, so must be > 0 */
    if (sinfo->file_offset == 0) {
        return;
    }

    /* block offset is the offset in vhdx logical sectors, in
     * the payload data block. Convert that to a byte offset
     * in the block, and add in the payload data block offset
     * in the file, in bytes, to get the final read address */

    sinfo->file_offset += sinfo->block_offset;
}



static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
                                      int nb_sectors, QEMUIOVector *qiov)
{
    BDRVVHDXState *s = bs->opaque;
    int ret = 0;
    VHDXSectorInfo sinfo;
    uint64_t bytes_done = 0;
    QEMUIOVector hd_qiov;

    qemu_iovec_init(&hd_qiov, qiov->niov);

    qemu_co_mutex_lock(&s->lock);

    while (nb_sectors > 0) {
        /* We are a differencing file, so we need to inspect the sector bitmap
         * to see if we have the data or not */
        if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) {
            /* not supported yet */
            ret = -ENOTSUP;
            goto exit;
        } else {
            vhdx_block_translate(s, sector_num, nb_sectors, &sinfo);

            qemu_iovec_reset(&hd_qiov);
            qemu_iovec_concat(&hd_qiov, qiov,  bytes_done, sinfo.bytes_avail);

            /* check the payload block state */
            switch (s->bat[sinfo.bat_idx] & VHDX_BAT_STATE_BIT_MASK) {
            case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
            case PAYLOAD_BLOCK_UNDEFINED:   /* fall through */
            case PAYLOAD_BLOCK_UNMAPPED:    /* fall through */
            case PAYLOAD_BLOCK_ZERO:
                /* return zero */
                qemu_iovec_memset(&hd_qiov, 0, 0, sinfo.bytes_avail);
                break;
            case PAYLOAD_BLOCK_FULLY_PRESENT:
                qemu_co_mutex_unlock(&s->lock);
                ret = bdrv_co_readv(bs->file,
                                    sinfo.file_offset >> BDRV_SECTOR_BITS,
                                    sinfo.sectors_avail, &hd_qiov);
                qemu_co_mutex_lock(&s->lock);
                if (ret < 0) {
                    goto exit;
                }
                break;
            case PAYLOAD_BLOCK_PARTIALLY_PRESENT:
                /* we don't yet support difference files, fall through
                 * to error */
            default:
                ret = -EIO;
                goto exit;
                break;
            }
            nb_sectors -= sinfo.sectors_avail;
            sector_num += sinfo.sectors_avail;
            bytes_done += sinfo.bytes_avail;
        }
    }
    ret = 0;
exit:
    qemu_co_mutex_unlock(&s->lock);
    qemu_iovec_destroy(&hd_qiov);
    return ret;
}

/*
 * Allocate a new payload block at the end of the file.
 *
 * Allocation will happen at 1MB alignment inside the file
 *
 * Returns the file offset start of the new payload block
 */
static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
                                    uint64_t *new_offset)
{
    *new_offset = bdrv_getlength(bs->file);

    /* per the spec, the address for a block is in units of 1MB */
    *new_offset = ROUND_UP(*new_offset, 1024 * 1024);

    return bdrv_truncate(bs->file, *new_offset + s->block_size);
}

/*
 * Update the BAT table entry with the new file offset, and the new entry
 * state */
static void vhdx_update_bat_table_entry(BlockDriverState *bs, BDRVVHDXState *s,
                                       VHDXSectorInfo *sinfo,
                                       uint64_t *bat_entry_le,
                                       uint64_t *bat_offset, int state)
{
    /* The BAT entry is a uint64, with 44 bits for the file offset in units of
     * 1MB, and 3 bits for the block state. */
    s->bat[sinfo->bat_idx]  = sinfo->file_offset;

    s->bat[sinfo->bat_idx] |= state & VHDX_BAT_STATE_BIT_MASK;

    *bat_entry_le = cpu_to_le64(s->bat[sinfo->bat_idx]);
    *bat_offset = s->bat_offset + sinfo->bat_idx * sizeof(VHDXBatEntry);

}

/* Per the spec, on the first write of guest-visible data to the file the
 * data write guid must be updated in the header */
int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
{
    int ret = 0;
    if (s->first_visible_write) {
        s->first_visible_write = false;
        ret = vhdx_update_headers(bs, s, true, NULL);
    }
    return ret;
}

static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
                                      int nb_sectors, QEMUIOVector *qiov)
{
    int ret = -ENOTSUP;
    BDRVVHDXState *s = bs->opaque;
    VHDXSectorInfo sinfo;
    uint64_t bytes_done = 0;
    uint64_t bat_entry = 0;
    uint64_t bat_entry_offset = 0;
    QEMUIOVector hd_qiov;
    struct iovec iov1 = { 0 };
    struct iovec iov2 = { 0 };
    int sectors_to_write;
    int bat_state;
    uint64_t bat_prior_offset = 0;
    bool bat_update = false;

    qemu_iovec_init(&hd_qiov, qiov->niov);

    qemu_co_mutex_lock(&s->lock);

    ret = vhdx_user_visible_write(bs, s);
    if (ret < 0) {
        goto exit;
    }

    while (nb_sectors > 0) {
        bool use_zero_buffers = false;
        bat_update = false;
        if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) {
            /* not supported yet */
            ret = -ENOTSUP;
            goto exit;
        } else {
            vhdx_block_translate(s, sector_num, nb_sectors, &sinfo);
            sectors_to_write = sinfo.sectors_avail;

            qemu_iovec_reset(&hd_qiov);
            /* check the payload block state */
            bat_state = s->bat[sinfo.bat_idx] & VHDX_BAT_STATE_BIT_MASK;
            switch (bat_state) {
            case PAYLOAD_BLOCK_ZERO:
                /* in this case, we need to preserve zero writes for
                 * data that is not part of this write, so we must pad
                 * the rest of the buffer to zeroes */

                /* if we are on a posix system with ftruncate() that extends
                 * a file, then it is zero-filled for us.  On Win32, the raw
                 * layer uses SetFilePointer and SetFileEnd, which does not
                 * zero fill AFAIK */

                /* Queue another write of zero buffers if the underlying file
                 * does not zero-fill on file extension */

                if (bdrv_has_zero_init(bs->file) == 0) {
                    use_zero_buffers = true;

                    /* zero fill the front, if any */
                    if (sinfo.block_offset) {
                        iov1.iov_len = sinfo.block_offset;
                        iov1.iov_base = qemu_blockalign(bs, iov1.iov_len);
                        memset(iov1.iov_base, 0, iov1.iov_len);
                        qemu_iovec_concat_iov(&hd_qiov, &iov1, 1, 0,
                                              sinfo.block_offset);
                        sectors_to_write += iov1.iov_len >> BDRV_SECTOR_BITS;
                    }

                    /* our actual data */
                    qemu_iovec_concat(&hd_qiov, qiov,  bytes_done,
                                      sinfo.bytes_avail);

                    /* zero fill the back, if any */
                    if ((sinfo.bytes_avail - sinfo.block_offset) <
                         s->block_size) {
                        iov2.iov_len = s->block_size -
                                      (sinfo.bytes_avail + sinfo.block_offset);
                        iov2.iov_base = qemu_blockalign(bs, iov2.iov_len);
                        memset(iov2.iov_base, 0, iov2.iov_len);
                        qemu_iovec_concat_iov(&hd_qiov, &iov2, 1, 0,
                                              sinfo.block_offset);
                        sectors_to_write += iov2.iov_len >> BDRV_SECTOR_BITS;
                    }
                }

                /* fall through */
            case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
            case PAYLOAD_BLOCK_UNMAPPED:    /* fall through */
            case PAYLOAD_BLOCK_UNDEFINED:   /* fall through */
                bat_prior_offset = sinfo.file_offset;
                ret = vhdx_allocate_block(bs, s, &sinfo.file_offset);
                if (ret < 0) {
                    goto exit;
                }
                /* once we support differencing files, this may also be
                 * partially present */
                /* update block state to the newly specified state */
                vhdx_update_bat_table_entry(bs, s, &sinfo, &bat_entry,
                                            &bat_entry_offset,
                                            PAYLOAD_BLOCK_FULLY_PRESENT);
                bat_update = true;
                /* since we just allocated a block, file_offset is the
                 * beginning of the payload block. It needs to be the
                 * write address, which includes the offset into the block */
                if (!use_zero_buffers) {
                    sinfo.file_offset += sinfo.block_offset;
                }
                /* fall through */
            case PAYLOAD_BLOCK_FULLY_PRESENT:
                /* if the file offset address is in the header zone,
                 * there is a problem */
                if (sinfo.file_offset < (1024 * 1024)) {
                    ret = -EFAULT;
                    goto error_bat_restore;
                }

                if (!use_zero_buffers) {
                    qemu_iovec_concat(&hd_qiov, qiov,  bytes_done,
                                      sinfo.bytes_avail);
                }
                /* block exists, so we can just overwrite it */
                qemu_co_mutex_unlock(&s->lock);
                ret = bdrv_co_writev(bs->file,
                                    sinfo.file_offset >> BDRV_SECTOR_BITS,
                                    sectors_to_write, &hd_qiov);
                qemu_co_mutex_lock(&s->lock);
                if (ret < 0) {
                    goto error_bat_restore;
                }
                break;
            case PAYLOAD_BLOCK_PARTIALLY_PRESENT:
                /* we don't yet support difference files, fall through
                 * to error */
            default:
                ret = -EIO;
                goto exit;
                break;
            }

            if (bat_update) {
                /* this will update the BAT entry into the log journal, and
                 * then flush the log journal out to disk */
                ret =  vhdx_log_write_and_flush(bs, s, &bat_entry,
                                                sizeof(VHDXBatEntry),
                                                bat_entry_offset);
                if (ret < 0) {
                    goto exit;
                }
            }

            nb_sectors -= sinfo.sectors_avail;
            sector_num += sinfo.sectors_avail;
            bytes_done += sinfo.bytes_avail;

        }
    }

    goto exit;

error_bat_restore:
    if (bat_update) {
        /* keep metadata in sync, and restore the bat entry state
         * if error. */
        sinfo.file_offset = bat_prior_offset;
        vhdx_update_bat_table_entry(bs, s, &sinfo, &bat_entry,
                                    &bat_entry_offset, bat_state);
    }
exit:
    qemu_vfree(iov1.iov_base);
    qemu_vfree(iov2.iov_base);
    qemu_co_mutex_unlock(&s->lock);
    qemu_iovec_destroy(&hd_qiov);
    return ret;
}



/*
 * Create VHDX Headers
 *
 * There are 2 headers, and the highest sequence number will represent
 * the active header
 */
static int vhdx_create_new_headers(BlockDriverState *bs, uint64_t image_size,
                                   uint32_t log_size)
{
    int ret = 0;
    VHDXHeader *hdr = NULL;

    hdr = g_malloc0(sizeof(VHDXHeader));

    hdr->signature       = VHDX_HEADER_SIGNATURE;
    hdr->sequence_number = g_random_int();
    hdr->log_version     = 0;
    hdr->version         = 1;
    hdr->log_length      = log_size;
    hdr->log_offset      = VHDX_HEADER_SECTION_END;
    vhdx_guid_generate(&hdr->file_write_guid);
    vhdx_guid_generate(&hdr->data_write_guid);

    ret = vhdx_write_header(bs, hdr, VHDX_HEADER1_OFFSET, false);
    if (ret < 0) {
        goto exit;
    }
    hdr->sequence_number++;
    ret = vhdx_write_header(bs, hdr, VHDX_HEADER2_OFFSET, false);
    if (ret < 0) {
        goto exit;
    }

exit:
    g_free(hdr);
    return ret;
}


/*
 * Create the Metadata entries.
 *
 * For more details on the entries, see section 3.5 (pg 29) in the
 * VHDX 1.00 specification.
 *
 * We support 5 metadata entries (all required by spec):
 *          File Parameters,
 *          Virtual Disk Size,
 *          Page 83 Data,
 *          Logical Sector Size,
 *          Physical Sector Size
 *
 * The first 64KB of the Metadata section is reserved for the metadata
 * header and entries; beyond that, the metadata items themselves reside.
 */
static int vhdx_create_new_metadata(BlockDriverState *bs,
                                    uint64_t image_size,
                                    uint32_t block_size,
                                    uint32_t sector_size,
                                    uint64_t metadata_offset,
                                    VHDXImageType type)
{
    int ret = 0;
    uint32_t offset = 0;
    void *buffer = NULL;
    void *entry_buffer;
    VHDXMetadataTableHeader *md_table;;
    VHDXMetadataTableEntry  *md_table_entry;

    /* Metadata entries */
    VHDXFileParameters     *mt_file_params;
    VHDXVirtualDiskSize    *mt_virtual_size;
    VHDXPage83Data         *mt_page83;
    VHDXVirtualDiskLogicalSectorSize  *mt_log_sector_size;
    VHDXVirtualDiskPhysicalSectorSize *mt_phys_sector_size;

    entry_buffer = g_malloc0(sizeof(VHDXFileParameters)               +
                             sizeof(VHDXVirtualDiskSize)              +
                             sizeof(VHDXPage83Data)                   +
                             sizeof(VHDXVirtualDiskLogicalSectorSize) +
                             sizeof(VHDXVirtualDiskPhysicalSectorSize));

    mt_file_params = entry_buffer;
    offset += sizeof(VHDXFileParameters);
    mt_virtual_size = entry_buffer + offset;
    offset += sizeof(VHDXVirtualDiskSize);
    mt_page83 = entry_buffer + offset;
    offset += sizeof(VHDXPage83Data);
    mt_log_sector_size = entry_buffer + offset;
    offset += sizeof(VHDXVirtualDiskLogicalSectorSize);
    mt_phys_sector_size = entry_buffer + offset;

    mt_file_params->block_size = cpu_to_le32(block_size);
    if (type == VHDX_TYPE_FIXED) {
        mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;
        cpu_to_le32s(&mt_file_params->data_bits);
    }

    vhdx_guid_generate(&mt_page83->page_83_data);
    cpu_to_leguids(&mt_page83->page_83_data);
    mt_virtual_size->virtual_disk_size        = cpu_to_le64(image_size);
    mt_log_sector_size->logical_sector_size   = cpu_to_le32(sector_size);
    mt_phys_sector_size->physical_sector_size = cpu_to_le32(sector_size);

    buffer = g_malloc0(VHDX_HEADER_BLOCK_SIZE);
    md_table = buffer;

    md_table->signature   = VHDX_METADATA_SIGNATURE;
    md_table->entry_count = 5;
    vhdx_metadata_header_le_export(md_table);


    /* This will reference beyond the reserved table portion */
    offset = 64 * KiB;

    md_table_entry = buffer + sizeof(VHDXMetadataTableHeader);

    md_table_entry[0].item_id = file_param_guid;
    md_table_entry[0].offset  = offset;
    md_table_entry[0].length  = sizeof(VHDXFileParameters);
    md_table_entry[0].data_bits |= VHDX_META_FLAGS_IS_REQUIRED;
    offset += md_table_entry[0].length;
    vhdx_metadata_entry_le_export(&md_table_entry[0]);

    md_table_entry[1].item_id = virtual_size_guid;
    md_table_entry[1].offset  = offset;
    md_table_entry[1].length  = sizeof(VHDXVirtualDiskSize);
    md_table_entry[1].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |
                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;
    offset += md_table_entry[1].length;
    vhdx_metadata_entry_le_export(&md_table_entry[1]);

    md_table_entry[2].item_id = page83_guid;
    md_table_entry[2].offset  = offset;
    md_table_entry[2].length  = sizeof(VHDXPage83Data);
    md_table_entry[2].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |
                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;
    offset += md_table_entry[2].length;
    vhdx_metadata_entry_le_export(&md_table_entry[2]);

    md_table_entry[3].item_id = logical_sector_guid;
    md_table_entry[3].offset  = offset;
    md_table_entry[3].length  = sizeof(VHDXVirtualDiskLogicalSectorSize);
    md_table_entry[3].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |
                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;
    offset += md_table_entry[3].length;
    vhdx_metadata_entry_le_export(&md_table_entry[3]);

    md_table_entry[4].item_id = phys_sector_guid;
    md_table_entry[4].offset  = offset;
    md_table_entry[4].length  = sizeof(VHDXVirtualDiskPhysicalSectorSize);
    md_table_entry[4].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |
                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;
    vhdx_metadata_entry_le_export(&md_table_entry[4]);

    ret = bdrv_pwrite(bs, metadata_offset, buffer, VHDX_HEADER_BLOCK_SIZE);
    if (ret < 0) {
        goto exit;
    }

    ret = bdrv_pwrite(bs, metadata_offset + (64 * KiB), entry_buffer,
                      VHDX_HEADER_BLOCK_SIZE);
    if (ret < 0) {
        goto exit;
    }


exit:
    g_free(buffer);
    g_free(entry_buffer);
    return ret;
}

/* This create the actual BAT itself.  We currently only support
 * 'Dynamic' and 'Fixed' image types.
 *
 *  Dynamic images: default state of the BAT is all zeroes.
 *
 *  Fixed images: default state of the BAT is fully populated, with
 *                file offsets and state PAYLOAD_BLOCK_FULLY_PRESENT.
 */
static int vhdx_create_bat(BlockDriverState *bs, BDRVVHDXState *s,
                           uint64_t image_size, VHDXImageType type,
                           bool use_zero_blocks, VHDXRegionTableEntry *rt_bat)
{
    int ret = 0;
    uint64_t data_file_offset;
    uint64_t total_sectors = 0;
    uint64_t sector_num = 0;
    uint64_t unused;
    int block_state;
    VHDXSectorInfo sinfo;

    assert(s->bat == NULL);

    /* this gives a data start after BAT/bitmap entries, and well
     * past any metadata entries (with a 4 MB buffer for future
     * expansion */
    data_file_offset = rt_bat->file_offset + rt_bat->length + 5 * MiB;
    total_sectors = image_size >> s->logical_sector_size_bits;

    if (type == VHDX_TYPE_DYNAMIC) {
        /* All zeroes, so we can just extend the file - the end of the BAT
         * is the furthest thing we have written yet */
        ret = bdrv_truncate(bs, data_file_offset);
        if (ret < 0) {
            goto exit;
        }
    } else if (type == VHDX_TYPE_FIXED) {
        ret = bdrv_truncate(bs, data_file_offset + image_size);
        if (ret < 0) {
            goto exit;
        }
    } else {
        ret = -ENOTSUP;
        goto exit;
    }

    if (type == VHDX_TYPE_FIXED ||
                use_zero_blocks ||
                bdrv_has_zero_init(bs) == 0) {
        /* for a fixed file, the default BAT entry is not zero */
        s->bat = g_malloc0(rt_bat->length);
        block_state = type == VHDX_TYPE_FIXED ? PAYLOAD_BLOCK_FULLY_PRESENT :
                                                PAYLOAD_BLOCK_NOT_PRESENT;
        block_state = use_zero_blocks ? PAYLOAD_BLOCK_ZERO : block_state;
        /* fill the BAT by emulating sector writes of sectors_per_block size */
        while (sector_num < total_sectors) {
            vhdx_block_translate(s, sector_num, s->sectors_per_block, &sinfo);
            sinfo.file_offset = data_file_offset +
                                (sector_num << s->logical_sector_size_bits);
            sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
            vhdx_update_bat_table_entry(bs, s, &sinfo, &unused, &unused,
                                        block_state);
            cpu_to_le64s(&s->bat[sinfo.bat_idx]);
            sector_num += s->sectors_per_block;
        }
        ret = bdrv_pwrite(bs, rt_bat->file_offset, s->bat, rt_bat->length);
        if (ret < 0) {
            goto exit;
        }
    }



exit:
    g_free(s->bat);
    return ret;
}

/* Creates the region table header, and region table entries.
 * There are 2 supported region table entries: BAT, and Metadata/
 *
 * As the calculations for the BAT region table are also needed
 * to create the BAT itself, we will also cause the BAT to be
 * created.
 */
static int vhdx_create_new_region_table(BlockDriverState *bs,
                                        uint64_t image_size,
                                        uint32_t block_size,
                                        uint32_t sector_size,
                                        uint32_t log_size,
                                        bool use_zero_blocks,
                                        VHDXImageType type,
                                        uint64_t *metadata_offset)
{
    int ret = 0;
    uint32_t offset = 0;
    void *buffer = NULL;
    BDRVVHDXState *s = NULL;
    VHDXRegionTableHeader *region_table;
    VHDXRegionTableEntry *rt_bat;
    VHDXRegionTableEntry *rt_metadata;

    assert(metadata_offset != NULL);

    /* Populate enough of the BDRVVHDXState to be able to use the
     * pre-existing BAT calculation, translation, and update functions */
    s = g_malloc0(sizeof(BDRVVHDXState));

    s->chunk_ratio = (VHDX_MAX_SECTORS_PER_BLOCK) *
                     (uint64_t) sector_size / (uint64_t) block_size;

    s->sectors_per_block = block_size / sector_size;
    s->virtual_disk_size = image_size;
    s->block_size = block_size;
    s->logical_sector_size = sector_size;

    vhdx_set_shift_bits(s);

    vhdx_calc_bat_entries(s);

    /* At this point the VHDX state is populated enough for creation */

    /* a single buffer is used so we can calculate the checksum over the
     * entire 64KB block */
    buffer = g_malloc0(VHDX_HEADER_BLOCK_SIZE);
    region_table = buffer;
    offset += sizeof(VHDXRegionTableHeader);
    rt_bat = buffer + offset;
    offset += sizeof(VHDXRegionTableEntry);
    rt_metadata  = buffer + offset;

    region_table->signature = VHDX_REGION_SIGNATURE;
    region_table->entry_count = 2;   /* BAT and Metadata */

    rt_bat->guid        = bat_guid;
    rt_bat->length      = ROUND_UP(s->bat_entries * sizeof(VHDXBatEntry), MiB);
    rt_bat->file_offset = ROUND_UP(VHDX_HEADER_SECTION_END + log_size, MiB);
    s->bat_offset = rt_bat->file_offset;

    rt_metadata->guid        = metadata_guid;
    rt_metadata->file_offset = ROUND_UP(rt_bat->file_offset + rt_bat->length,
                                        MiB);
    rt_metadata->length      = 1 * MiB; /* min size, and more than enough */
    *metadata_offset = rt_metadata->file_offset;

    vhdx_update_checksum(buffer, VHDX_HEADER_BLOCK_SIZE,
                         offsetof(VHDXRegionTableHeader, checksum));


    /* The region table gives us the data we need to create the BAT,
     * so do that now */
    ret = vhdx_create_bat(bs, s, image_size, type, use_zero_blocks, rt_bat);

    /* Now write out the region headers to disk */
    vhdx_region_header_le_export(region_table);
    vhdx_region_entry_le_export(rt_bat);
    vhdx_region_entry_le_export(rt_metadata);

    ret = bdrv_pwrite(bs, VHDX_REGION_TABLE_OFFSET, buffer,
                      VHDX_HEADER_BLOCK_SIZE);
    if (ret < 0) {
        goto exit;
    }

    ret = bdrv_pwrite(bs, VHDX_REGION_TABLE2_OFFSET, buffer,
                      VHDX_HEADER_BLOCK_SIZE);
    if (ret < 0) {
        goto exit;
    }


exit:
    g_free(s);
    g_free(buffer);
    return ret;
}

/* We need to create the following elements:
 *
 *    .-----------------------------------------------------------------.
 *    |   (A)    |   (B)    |    (C)    |     (D)       |     (E)       |
 *    |  File ID |  Header1 |  Header 2 |  Region Tbl 1 |  Region Tbl 2 |
 *    |          |          |           |               |               |
 *    .-----------------------------------------------------------------.
 *    0         64KB      128KB       192KB           256KB           320KB
 *
 *
 *    .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
 *    |     (F)     |     (G)       |    (H)    |                        |
 *    | Journal Log |  BAT / Bitmap |  Metadata |  .... data ......      |
 *    |             |               |           |                        |
 *    .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
 *   1MB
 */
static int vhdx_create(const char *filename, QEMUOptionParameter *options,
                       Error **errp)
{
    int ret = 0;
    uint64_t image_size = (uint64_t) 2 * GiB;
    uint32_t log_size   = 1 * MiB;
    uint32_t block_size = 0;
    uint64_t signature;
    uint64_t metadata_offset;
    bool use_zero_blocks = false;

    gunichar2 *creator = NULL;
    glong creator_items;
    BlockDriverState *bs;
    const char *type = NULL;
    VHDXImageType image_type;
    Error *local_err = NULL;

    while (options && options->name) {
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
            image_size = options->value.n;
        } else if (!strcmp(options->name, VHDX_BLOCK_OPT_LOG_SIZE)) {
            log_size = options->value.n;
        } else if (!strcmp(options->name, VHDX_BLOCK_OPT_BLOCK_SIZE)) {
            block_size = options->value.n;
        } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
            type = options->value.s;
        } else if (!strcmp(options->name, VHDX_BLOCK_OPT_ZERO)) {
            use_zero_blocks = options->value.n != 0;
        }
        options++;
    }

    if (image_size > VHDX_MAX_IMAGE_SIZE) {
        error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
        ret = -EINVAL;
        goto exit;
    }

    if (type == NULL) {
        type = "dynamic";
    }

    if (!strcmp(type, "dynamic")) {
        image_type = VHDX_TYPE_DYNAMIC;
    } else if (!strcmp(type, "fixed")) {
        image_type = VHDX_TYPE_FIXED;
    } else if (!strcmp(type, "differencing")) {
        error_setg_errno(errp, ENOTSUP,
                         "Differencing files not yet supported");
        ret = -ENOTSUP;
        goto exit;
    } else {
        ret = -EINVAL;
        goto exit;
    }

    /* These are pretty arbitrary, and mainly designed to keep the BAT
     * size reasonable to load into RAM */
    if (block_size == 0) {
        if (image_size > 32 * TiB) {
            block_size = 64 * MiB;
        } else if (image_size > (uint64_t) 100 * GiB) {
            block_size = 32 * MiB;
        } else if (image_size > 1 * GiB) {
            block_size = 16 * MiB;
        } else {
            block_size = 8 * MiB;
        }
    }


    /* make the log size close to what was specified, but must be
     * min 1MB, and multiple of 1MB */
    log_size = ROUND_UP(log_size, MiB);

    block_size = ROUND_UP(block_size, MiB);
    block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
                                                    block_size;

    ret = bdrv_create_file(filename, options, &local_err);
    if (ret < 0) {
        error_propagate(errp, local_err);
        goto exit;
    }

    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR, &local_err);
    if (ret < 0) {
        error_propagate(errp, local_err);
        goto exit;
    }

    /* Create (A) */

    /* The creator field is optional, but may be useful for
     * debugging / diagnostics */
    creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL,
                              &creator_items, NULL);
    signature = cpu_to_le64(VHDX_FILE_SIGNATURE);
    bdrv_pwrite(bs, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature));
    if (ret < 0) {
        goto delete_and_exit;
    }
    if (creator) {
        bdrv_pwrite(bs, VHDX_FILE_ID_OFFSET + sizeof(signature), creator,
                    creator_items * sizeof(gunichar2));
        if (ret < 0) {
            goto delete_and_exit;
        }
    }


    /* Creates (B),(C) */
    ret = vhdx_create_new_headers(bs, image_size, log_size);
    if (ret < 0) {
        goto delete_and_exit;
    }

    /* Creates (D),(E),(G) explicitly. (F) created as by-product */
    ret = vhdx_create_new_region_table(bs, image_size, block_size, 512,
                                       log_size, use_zero_blocks, image_type,
                                       &metadata_offset);
    if (ret < 0) {
        goto delete_and_exit;
    }

    /* Creates (H) */
    ret = vhdx_create_new_metadata(bs, image_size, block_size, 512,
                                   metadata_offset, image_type);
    if (ret < 0) {
        goto delete_and_exit;
    }



delete_and_exit:
    bdrv_unref(bs);
exit:
    g_free(creator);
    return ret;
}

static QEMUOptionParameter vhdx_create_options[] = {
    {
        .name = BLOCK_OPT_SIZE,
        .type = OPT_SIZE,
        .help = "Virtual disk size; max of 64TB."
    },
    {
        .name = VHDX_BLOCK_OPT_LOG_SIZE,
        .type = OPT_SIZE,
        .value.n = 1 * MiB,
        .help = "Log size; min 1MB."
    },
    {
        .name = VHDX_BLOCK_OPT_BLOCK_SIZE,
        .type = OPT_SIZE,
        .value.n = 0,
        .help = "Block Size; min 1MB, max 256MB. " \
                "0 means auto-calculate based on image size."
    },
    {
        .name = BLOCK_OPT_SUBFMT,
        .type = OPT_STRING,
        .help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\
                "Default is 'dynamic'."
    },
    {
        .name = VHDX_BLOCK_OPT_ZERO,
        .type = OPT_FLAG,
        .help = "Force use of payload blocks of type 'ZERO'.  Non-standard."
    },
    { NULL }
};

static BlockDriver bdrv_vhdx = {
    .format_name            = "vhdx",
    .instance_size          = sizeof(BDRVVHDXState),
    .bdrv_probe             = vhdx_probe,
    .bdrv_open              = vhdx_open,
    .bdrv_close             = vhdx_close,
    .bdrv_reopen_prepare    = vhdx_reopen_prepare,
    .bdrv_co_readv          = vhdx_co_readv,
    .bdrv_co_writev         = vhdx_co_writev,
    .bdrv_create            = vhdx_create,

    .create_options         = vhdx_create_options,
};

static void bdrv_vhdx_init(void)
{
    bdrv_register(&bdrv_vhdx);
}

block_init(bdrv_vhdx_init);
