/*
 * 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 file covers the functionality of the metadata log writing, parsing, and
 * replay.
 *
 * 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/osdep.h"
#include "qapi/error.h"
#include "block/block-io.h"
#include "block/block_int.h"
#include "qemu/error-report.h"
#include "qemu/bswap.h"
#include "qemu/memalign.h"
#include "vhdx.h"


typedef struct VHDXLogSequence {
    bool valid;
    uint32_t count;
    VHDXLogEntries log;
    VHDXLogEntryHeader hdr;
} VHDXLogSequence;

typedef struct VHDXLogDescEntries {
    VHDXLogEntryHeader hdr;
    VHDXLogDescriptor desc[];
} VHDXLogDescEntries;

static const MSGUID zero_guid = { 0 };

/* The log located on the disk is circular buffer containing
 * sectors of 4096 bytes each.
 *
 * It is assumed for the read/write functions below that the
 * circular buffer scheme uses a 'one sector open' to indicate
 * the buffer is full.  Given the validation methods used for each
 * sector, this method should be compatible with other methods that
 * do not waste a sector.
 */


/* Allow peeking at the hdr entry at the beginning of the current
 * read index, without advancing the read index */
static int GRAPH_RDLOCK
vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log,
                  VHDXLogEntryHeader *hdr)
{
    int ret = 0;
    uint64_t offset;
    uint32_t read;

    assert(hdr != NULL);

    /* peek is only supported on sector boundaries */
    if (log->read % VHDX_LOG_SECTOR_SIZE) {
        ret = -EFAULT;
        goto exit;
    }

    read = log->read;
    /* we are guaranteed that a) log sectors are 4096 bytes,
     * and b) the log length is a multiple of 1MB. So, there
     * is always a round number of sectors in the buffer */
    if ((read + sizeof(VHDXLogEntryHeader)) > log->length) {
        read = 0;
    }

    if (read == log->write) {
        ret = -EINVAL;
        goto exit;
    }

    offset = log->offset + read;

    ret = bdrv_pread(bs->file, offset, sizeof(VHDXLogEntryHeader), hdr, 0);
    if (ret < 0) {
        goto exit;
    }
    vhdx_log_entry_hdr_le_import(hdr);

exit:
    return ret;
}

/* Index increment for log, based on sector boundaries */
static int vhdx_log_inc_idx(uint32_t idx, uint64_t length)
{
    idx += VHDX_LOG_SECTOR_SIZE;
    /* we are guaranteed that a) log sectors are 4096 bytes,
     * and b) the log length is a multiple of 1MB. So, there
     * is always a round number of sectors in the buffer */
    return idx >= length ? 0 : idx;
}


/* Reset the log to empty */
static void GRAPH_RDLOCK vhdx_log_reset(BlockDriverState *bs, BDRVVHDXState *s)
{
    MSGUID guid = { 0 };
    s->log.read = s->log.write = 0;
    /* a log guid of 0 indicates an empty log to any parser of v0
     * VHDX logs */
    vhdx_update_headers(bs, s, false, &guid);
}

/* Reads num_sectors from the log (all log sectors are 4096 bytes),
 * into buffer 'buffer'.  Upon return, *sectors_read will contain
 * the number of sectors successfully read.
 *
 * It is assumed that 'buffer' is already allocated, and of sufficient
 * size (i.e. >= 4096*num_sectors).
 *
 * If 'peek' is true, then the tail (read) pointer for the circular buffer is
 * not modified.
 *
 * 0 is returned on success, -errno otherwise.  */
static int GRAPH_RDLOCK
vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
                      uint32_t *sectors_read, void *buffer,
                      uint32_t num_sectors, bool peek)
{
    int ret = 0;
    uint64_t offset;
    uint32_t read;

    read = log->read;

    *sectors_read = 0;
    while (num_sectors) {
        if (read == log->write) {
            /* empty */
            break;
        }
        offset = log->offset + read;

        ret = bdrv_pread(bs->file, offset, VHDX_LOG_SECTOR_SIZE, buffer, 0);
        if (ret < 0) {
            goto exit;
        }
        read = vhdx_log_inc_idx(read, log->length);

        *sectors_read = *sectors_read + 1;
        num_sectors--;
    }

exit:
    if (!peek) {
        log->read = read;
    }
    return ret;
}

/* Writes num_sectors to the log (all log sectors are 4096 bytes),
 * from buffer 'buffer'.  Upon return, *sectors_written will contain
 * the number of sectors successfully written.
 *
 * It is assumed that 'buffer' is at least 4096*num_sectors large.
 *
 * 0 is returned on success, -errno otherwise */
static int coroutine_fn GRAPH_RDLOCK
vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
                       uint32_t *sectors_written, void *buffer,
                       uint32_t num_sectors)
{
    int ret = 0;
    uint64_t offset;
    uint32_t write;
    void *buffer_tmp;
    BDRVVHDXState *s = bs->opaque;

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

    write = log->write;

    buffer_tmp = buffer;
    while (num_sectors) {

        offset = log->offset + write;
        write = vhdx_log_inc_idx(write, log->length);
        if (write == log->read) {
            /* full */
            break;
        }
        ret = bdrv_co_pwrite(bs->file, offset, VHDX_LOG_SECTOR_SIZE, buffer_tmp, 0);
        if (ret < 0) {
            goto exit;
        }
        buffer_tmp += VHDX_LOG_SECTOR_SIZE;

        log->write = write;
        *sectors_written = *sectors_written + 1;
        num_sectors--;
    }

exit:
    return ret;
}


/* Validates a log entry header */
static bool vhdx_log_hdr_is_valid(VHDXLogEntries *log, VHDXLogEntryHeader *hdr,
                                  BDRVVHDXState *s)
{
    int valid = false;

    if (hdr->signature != VHDX_LOG_SIGNATURE) {
        goto exit;
    }

    /* if the individual entry length is larger than the whole log
     * buffer, that is obviously invalid */
    if (log->length < hdr->entry_length) {
        goto exit;
    }

    /* length of entire entry must be in units of 4KB (log sector size) */
    if (hdr->entry_length % (VHDX_LOG_SECTOR_SIZE)) {
        goto exit;
    }

    /* per spec, sequence # must be > 0 */
    if (hdr->sequence_number == 0) {
        goto exit;
    }

    /* log entries are only valid if they match the file-wide log guid
     * found in the active header */
    if (!guid_eq(hdr->log_guid, s->headers[s->curr_header]->log_guid)) {
        goto exit;
    }

    if (hdr->descriptor_count * sizeof(VHDXLogDescriptor) > hdr->entry_length) {
        goto exit;
    }

    valid = true;

exit:
    return valid;
}

/*
 * Given a log header, this will validate that the descriptors and the
 * corresponding data sectors (if applicable)
 *
 * Validation consists of:
 *      1. Making sure the sequence numbers matches the entry header
 *      2. Verifying a valid signature ('zero' or 'desc' for descriptors)
 *      3. File offset field is a multiple of 4KB
 *      4. If a data descriptor, the corresponding data sector
 *         has its signature ('data') and matching sequence number
 *
 * @desc: the data buffer containing the descriptor
 * @hdr:  the log entry header
 *
 * Returns true if valid
 */
static bool vhdx_log_desc_is_valid(VHDXLogDescriptor *desc,
                                   VHDXLogEntryHeader *hdr)
{
    bool ret = false;

    if (desc->sequence_number != hdr->sequence_number) {
        goto exit;
    }
    if (desc->file_offset % VHDX_LOG_SECTOR_SIZE) {
        goto exit;
    }

    if (desc->signature == VHDX_LOG_ZERO_SIGNATURE) {
        if (desc->zero_length % VHDX_LOG_SECTOR_SIZE == 0) {
            /* valid */
            ret = true;
        }
    } else if (desc->signature == VHDX_LOG_DESC_SIGNATURE) {
            /* valid */
            ret = true;
    }

exit:
    return ret;
}


/* Prior to sector data for a log entry, there is the header
 * and the descriptors referenced in the header:
 *
 * [] = 4KB sector
 *
 * [ hdr, desc ][   desc   ][ ... ][ data ][ ... ]
 *
 * The first sector in a log entry has a 64 byte header, and
 * up to 126 32-byte descriptors.  If more descriptors than
 * 126 are required, then subsequent sectors can have up to 128
 * descriptors.  Each sector is 4KB.  Data follows the descriptor
 * sectors.
 *
 * This will return the number of sectors needed to encompass
 * the passed number of descriptors in desc_cnt.
 *
 * This will never return 0, even if desc_cnt is 0.
 */
static int vhdx_compute_desc_sectors(uint32_t desc_cnt)
{
    uint32_t desc_sectors;

    desc_cnt += 2; /* account for header in first sector */
    desc_sectors = desc_cnt / 128;
    if (desc_cnt % 128) {
        desc_sectors++;
    }

    return desc_sectors;
}


/* Reads the log header, and subsequent descriptors (if any).  This
 * will allocate all the space for buffer, which must be NULL when
 * passed into this function. Each descriptor will also be validated,
 * and error returned if any are invalid. */
static int GRAPH_RDLOCK
vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogEntries *log,
                   VHDXLogDescEntries **buffer, bool convert_endian)
{
    int ret = 0;
    uint32_t desc_sectors;
    uint32_t sectors_read;
    VHDXLogEntryHeader hdr;
    VHDXLogDescEntries *desc_entries = NULL;
    VHDXLogDescriptor desc;
    int i;

    assert(*buffer == NULL);

    ret = vhdx_log_peek_hdr(bs, log, &hdr);
    if (ret < 0) {
        goto exit;
    }

    if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) {
        ret = -EINVAL;
        goto exit;
    }

    desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count);
    desc_entries = qemu_try_blockalign(bs->file->bs,
                                       desc_sectors * VHDX_LOG_SECTOR_SIZE);
    if (desc_entries == NULL) {
        ret = -ENOMEM;
        goto exit;
    }

    ret = vhdx_log_read_sectors(bs, log, &sectors_read, desc_entries,
                                desc_sectors, false);
    if (ret < 0) {
        goto free_and_exit;
    }
    if (sectors_read != desc_sectors) {
        ret = -EINVAL;
        goto free_and_exit;
    }

    /* put in proper endianness, and validate each desc */
    for (i = 0; i < hdr.descriptor_count; i++) {
        desc = desc_entries->desc[i];
        vhdx_log_desc_le_import(&desc);
        if (convert_endian) {
            desc_entries->desc[i] = desc;
        }
        if (vhdx_log_desc_is_valid(&desc, &hdr) == false) {
            ret = -EINVAL;
            goto free_and_exit;
        }
    }
    if (convert_endian) {
        desc_entries->hdr = hdr;
    }

    *buffer = desc_entries;
    goto exit;

free_and_exit:
    qemu_vfree(desc_entries);
exit:
    return ret;
}


/* Flushes the descriptor described by desc to the VHDX image file.
 * If the descriptor is a data descriptor, than 'data' must be non-NULL,
 * and >= 4096 bytes (VHDX_LOG_SECTOR_SIZE), containing the data to be
 * written.
 *
 * Verification is performed to make sure the sequence numbers of a data
 * descriptor match the sequence number in the desc.
 *
 * For a zero descriptor, it may describe multiple sectors to fill with zeroes.
 * In this case, it should be noted that zeroes are written to disk, and the
 * image file is not extended as a sparse file.  */
static int GRAPH_RDLOCK
vhdx_log_flush_desc(BlockDriverState *bs, VHDXLogDescriptor *desc,
                    VHDXLogDataSector *data)
{
    int ret = 0;
    uint64_t seq, file_offset;
    uint32_t offset = 0;
    void *buffer = NULL;
    uint64_t count = 1;
    int i;

    buffer = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);

    if (desc->signature == VHDX_LOG_DESC_SIGNATURE) {
        /* data sector */
        if (data == NULL) {
            ret = -EFAULT;
            goto exit;
        }

        /* The sequence number of the data sector must match that
         * in the descriptor */
        seq = data->sequence_high;
        seq <<= 32;
        seq |= data->sequence_low & 0xffffffff;

        if (seq != desc->sequence_number) {
            ret = -EINVAL;
            goto exit;
        }

        /* Each data sector is in total 4096 bytes, however the first
         * 8 bytes, and last 4 bytes, are located in the descriptor */
        memcpy(buffer, &desc->leading_bytes, 8);
        offset += 8;

        memcpy(buffer+offset, data->data, 4084);
        offset += 4084;

        memcpy(buffer+offset, &desc->trailing_bytes, 4);

    } else if (desc->signature == VHDX_LOG_ZERO_SIGNATURE) {
        /* write 'count' sectors of sector */
        memset(buffer, 0, VHDX_LOG_SECTOR_SIZE);
        count = desc->zero_length / VHDX_LOG_SECTOR_SIZE;
    } else {
        error_report("Invalid VHDX log descriptor entry signature 0x%" PRIx32,
                      desc->signature);
        ret = -EINVAL;
        goto exit;
    }

    file_offset = desc->file_offset;

    /* count is only > 1 if we are writing zeroes */
    for (i = 0; i < count; i++) {
        ret = bdrv_pwrite_sync(bs->file, file_offset, VHDX_LOG_SECTOR_SIZE,
                               buffer, 0);
        if (ret < 0) {
            goto exit;
        }
        file_offset += VHDX_LOG_SECTOR_SIZE;
    }

exit:
    qemu_vfree(buffer);
    return ret;
}

/* Flush the entire log (as described by 'logs') to the VHDX image
 * file, and then set the log to 'empty' status once complete.
 *
 * The log entries should be validate prior to flushing */
static int GRAPH_RDLOCK
vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogSequence *logs)
{
    int ret = 0;
    int i;
    uint32_t cnt, sectors_read;
    uint64_t new_file_size;
    void *data = NULL;
    int64_t file_length;
    VHDXLogDescEntries *desc_entries = NULL;
    VHDXLogEntryHeader hdr_tmp = { 0 };

    cnt = logs->count;

    data = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);

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

    /* each iteration represents one log sequence, which may span multiple
     * sectors */
    while (cnt--) {
        ret = vhdx_log_peek_hdr(bs, &logs->log, &hdr_tmp);
        if (ret < 0) {
            goto exit;
        }
        file_length = bdrv_getlength(bs->file->bs);
        if (file_length < 0) {
            ret = file_length;
            goto exit;
        }
        /* if the log shows a FlushedFileOffset larger than our current file
         * size, then that means the file has been truncated / corrupted, and
         * we must refused to open it / use it */
        if (hdr_tmp.flushed_file_offset > file_length) {
            ret = -EINVAL;
            goto exit;
        }

        ret = vhdx_log_read_desc(bs, s, &logs->log, &desc_entries, true);
        if (ret < 0) {
            goto exit;
        }

        for (i = 0; i < desc_entries->hdr.descriptor_count; i++) {
            if (desc_entries->desc[i].signature == VHDX_LOG_DESC_SIGNATURE) {
                /* data sector, so read a sector to flush */
                ret = vhdx_log_read_sectors(bs, &logs->log, &sectors_read,
                                            data, 1, false);
                if (ret < 0) {
                    goto exit;
                }
                if (sectors_read != 1) {
                    ret = -EINVAL;
                    goto exit;
                }
                vhdx_log_data_le_import(data);
            }

            ret = vhdx_log_flush_desc(bs, &desc_entries->desc[i], data);
            if (ret < 0) {
                goto exit;
            }
        }
        if (file_length < desc_entries->hdr.last_file_offset) {
            new_file_size = desc_entries->hdr.last_file_offset;
            if (new_file_size % (1 * MiB)) {
                /* round up to nearest 1MB boundary */
                new_file_size = QEMU_ALIGN_UP(new_file_size, MiB);
                if (new_file_size > INT64_MAX) {
                    ret = -EINVAL;
                    goto exit;
                }
                ret = bdrv_truncate(bs->file, new_file_size, false,
                                    PREALLOC_MODE_OFF, 0, NULL);
                if (ret < 0) {
                    goto exit;
                }
            }
        }
        qemu_vfree(desc_entries);
        desc_entries = NULL;
    }

    ret = bdrv_flush(bs);
    if (ret < 0) {
        goto exit;
    }
    /* once the log is fully flushed, indicate that we have an empty log
     * now.  This also sets the log guid to 0, to indicate an empty log */
    vhdx_log_reset(bs, s);

exit:
    qemu_vfree(data);
    qemu_vfree(desc_entries);
    return ret;
}

static int GRAPH_RDLOCK
vhdx_validate_log_entry(BlockDriverState *bs, BDRVVHDXState *s,
                        VHDXLogEntries *log, uint64_t seq,
                        bool *valid, VHDXLogEntryHeader *entry)
{
    int ret = 0;
    VHDXLogEntryHeader hdr;
    void *buffer = NULL;
    uint32_t i, desc_sectors, total_sectors, crc;
    uint32_t sectors_read = 0;
    VHDXLogDescEntries *desc_buffer = NULL;

    *valid = false;

    ret = vhdx_log_peek_hdr(bs, log, &hdr);
    if (ret < 0) {
        goto inc_and_exit;
    }

    if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) {
        goto inc_and_exit;
    }

    if (seq > 0) {
        if (hdr.sequence_number != seq + 1) {
            goto inc_and_exit;
        }
    }

    desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count);

    /* Read all log sectors, and calculate log checksum */

    total_sectors = hdr.entry_length / VHDX_LOG_SECTOR_SIZE;


    /* read_desc() will increment the read idx */
    ret = vhdx_log_read_desc(bs, s, log, &desc_buffer, false);
    if (ret < 0) {
        goto free_and_exit;
    }

    crc = vhdx_checksum_calc(0xffffffff, (void *)desc_buffer,
                            desc_sectors * VHDX_LOG_SECTOR_SIZE, 4);
    crc ^= 0xffffffff;

    buffer = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);
    if (total_sectors > desc_sectors) {
        for (i = 0; i < total_sectors - desc_sectors; i++) {
            sectors_read = 0;
            ret = vhdx_log_read_sectors(bs, log, &sectors_read, buffer,
                                        1, false);
            if (ret < 0 || sectors_read != 1) {
                goto free_and_exit;
            }
            crc = vhdx_checksum_calc(crc, buffer, VHDX_LOG_SECTOR_SIZE, -1);
            crc ^= 0xffffffff;
        }
    }
    crc ^= 0xffffffff;
    if (crc != hdr.checksum) {
        goto free_and_exit;
    }

    *valid = true;
    *entry = hdr;
    goto free_and_exit;

inc_and_exit:
    log->read = vhdx_log_inc_idx(log->read, log->length);

free_and_exit:
    qemu_vfree(buffer);
    qemu_vfree(desc_buffer);
    return ret;
}

/* Search through the log circular buffer, and find the valid, active
 * log sequence, if any exists
 * */
static int GRAPH_RDLOCK
vhdx_log_search(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogSequence *logs)
{
    int ret = 0;
    uint32_t tail;
    bool seq_valid = false;
    VHDXLogSequence candidate = { 0 };
    VHDXLogEntryHeader hdr = { 0 };
    VHDXLogEntries curr_log;

    memcpy(&curr_log, &s->log, sizeof(VHDXLogEntries));
    curr_log.write = curr_log.length;   /* assume log is full */
    curr_log.read = 0;


    /* now we will go through the whole log sector by sector, until
     * we find a valid, active log sequence, or reach the end of the
     * log buffer */
    for (;;) {
        uint64_t curr_seq = 0;
        VHDXLogSequence current = { 0 };

        tail = curr_log.read;

        ret = vhdx_validate_log_entry(bs, s, &curr_log, curr_seq,
                                      &seq_valid, &hdr);
        if (ret < 0) {
            goto exit;
        }

        if (seq_valid) {
            current.valid     = true;
            current.log       = curr_log;
            current.log.read  = tail;
            current.log.write = curr_log.read;
            current.count     = 1;
            current.hdr       = hdr;


            for (;;) {
                ret = vhdx_validate_log_entry(bs, s, &curr_log, curr_seq,
                                              &seq_valid, &hdr);
                if (ret < 0) {
                    goto exit;
                }
                if (seq_valid == false) {
                    break;
                }
                current.log.write = curr_log.read;
                current.count++;

                curr_seq = hdr.sequence_number;
            }
        }

        if (current.valid) {
            if (candidate.valid == false ||
                current.hdr.sequence_number > candidate.hdr.sequence_number) {
                candidate = current;
            }
        }

        if (curr_log.read < tail) {
            break;
        }
    }

    *logs = candidate;

    if (candidate.valid) {
        /* this is the next sequence number, for writes */
        s->log.sequence = candidate.hdr.sequence_number + 1;
    }


exit:
    return ret;
}

/* Parse the replay log.  Per the VHDX spec, if the log is present
 * it must be replayed prior to opening the file, even read-only.
 *
 * If read-only, we must replay the log in RAM (or refuse to open
 * a dirty VHDX file read-only) */
int vhdx_parse_log(BlockDriverState *bs, BDRVVHDXState *s, bool *flushed,
                   Error **errp)
{
    int ret = 0;
    VHDXHeader *hdr;
    VHDXLogSequence logs = { 0 };

    hdr = s->headers[s->curr_header];

    *flushed = false;

    /* s->log.hdr is freed in vhdx_close() */
    if (s->log.hdr == NULL) {
        s->log.hdr = qemu_blockalign(bs, sizeof(VHDXLogEntryHeader));
    }

    s->log.offset = hdr->log_offset;
    s->log.length = hdr->log_length;

    if (s->log.offset < VHDX_LOG_MIN_SIZE ||
        s->log.offset % VHDX_LOG_MIN_SIZE) {
        ret = -EINVAL;
        goto exit;
    }

    /* per spec, only log version of 0 is supported */
    if (hdr->log_version != 0) {
        ret = -EINVAL;
        goto exit;
    }

    /* If either the log guid, or log length is zero,
     * then a replay log is not present */
    if (guid_eq(hdr->log_guid, zero_guid)) {
        goto exit;
    }

    if (hdr->log_length == 0) {
        goto exit;
    }

    if (hdr->log_length % VHDX_LOG_MIN_SIZE) {
        ret = -EINVAL;
        goto exit;
    }


    /* The log is present, we need to find if and where there is an active
     * sequence of valid entries present in the log.  */

    ret = vhdx_log_search(bs, s, &logs);
    if (ret < 0) {
        goto exit;
    }

    if (logs.valid) {
        if (bdrv_is_read_only(bs)) {
            bdrv_refresh_filename(bs);
            ret = -EPERM;
            error_setg(errp,
                       "VHDX image file '%s' opened read-only, but "
                       "contains a log that needs to be replayed",
                       bs->filename);
            error_append_hint(errp,  "To replay the log, run:\n"
                              "qemu-img check -r all '%s'\n",
                              bs->filename);
            goto exit;
        }
        /* now flush the log */
        ret = vhdx_log_flush(bs, s, &logs);
        if (ret < 0) {
            goto exit;
        }
        *flushed = true;
    }


exit:
    return ret;
}



static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
                                      VHDXLogDataSector *sector, void *data,
                                      uint64_t seq)
{
    /* 8 + 4084 + 4 = 4096, 1 log sector */
    memcpy(&desc->leading_bytes, data, 8);
    data += 8;
    desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
    memcpy(sector->data, data, 4084);
    data += 4084;
    memcpy(&desc->trailing_bytes, data, 4);
    desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
    data += 4;

    sector->sequence_high  = (uint32_t) (seq >> 32);
    sector->sequence_low   = (uint32_t) (seq & 0xffffffff);
    sector->data_signature = VHDX_LOG_DATA_SIGNATURE;

    vhdx_log_desc_le_export(desc);
    vhdx_log_data_le_export(sector);
}


static int coroutine_fn GRAPH_RDLOCK
vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
               void *data, uint32_t length, uint64_t offset)
{
    int ret = 0;
    void *buffer = NULL;
    void *merged_sector = NULL;
    void *data_tmp, *sector_write;
    unsigned int i;
    int sector_offset;
    uint32_t desc_sectors, sectors, total_length;
    uint32_t sectors_written = 0;
    uint32_t aligned_length;
    uint32_t leading_length = 0;
    uint32_t trailing_length = 0;
    uint32_t partial_sectors = 0;
    uint32_t bytes_written = 0;
    uint64_t file_offset;
    int64_t file_length;
    VHDXHeader *header;
    VHDXLogEntryHeader new_hdr;
    VHDXLogDescriptor *new_desc = NULL;
    VHDXLogDataSector *data_sector = NULL;
    MSGUID new_guid = { 0 };

    header = s->headers[s->curr_header];

    /* need to have offset read data, and be on 4096 byte boundary */

    if (length > header->log_length) {
        /* no log present.  we could create a log here instead of failing */
        ret = -EINVAL;
        goto exit;
    }

    if (guid_eq(header->log_guid, zero_guid)) {
        vhdx_guid_generate(&new_guid);
        vhdx_update_headers(bs, s, false, &new_guid);
    } else {
        /* currently, we require that the log be flushed after
         * every write. */
        ret = -ENOTSUP;
        goto exit;
    }

    /* 0 is an invalid sequence number, but may also represent the first
     * log write (or a wrapped seq) */
    if (s->log.sequence == 0) {
        s->log.sequence = 1;
    }

    sector_offset = offset % VHDX_LOG_SECTOR_SIZE;
    file_offset = QEMU_ALIGN_DOWN(offset, VHDX_LOG_SECTOR_SIZE);

    aligned_length = length;

    /* add in the unaligned head and tail bytes */
    if (sector_offset) {
        leading_length = (VHDX_LOG_SECTOR_SIZE - sector_offset);
        leading_length = leading_length > length ? length : leading_length;
        aligned_length -= leading_length;
        partial_sectors++;
    }

    sectors = aligned_length / VHDX_LOG_SECTOR_SIZE;
    trailing_length = aligned_length - (sectors * VHDX_LOG_SECTOR_SIZE);
    if (trailing_length) {
        partial_sectors++;
    }

    sectors += partial_sectors;

    file_length = bdrv_co_getlength(bs->file->bs);
    if (file_length < 0) {
        ret = file_length;
        goto exit;
    }

    /* sectors is now how many sectors the data itself takes, not
     * including the header and descriptor metadata */

    new_hdr = (VHDXLogEntryHeader) {
                .signature           = VHDX_LOG_SIGNATURE,
                .tail                = s->log.tail,
                .sequence_number     = s->log.sequence,
                .descriptor_count    = sectors,
                .reserved            = 0,
                .flushed_file_offset = file_length,
                .last_file_offset    = file_length,
                .log_guid            = header->log_guid,
              };


    desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count);

    total_length = (desc_sectors + sectors) * VHDX_LOG_SECTOR_SIZE;
    new_hdr.entry_length = total_length;

    vhdx_log_entry_hdr_le_export(&new_hdr);

    buffer = qemu_blockalign(bs, total_length);
    memcpy(buffer, &new_hdr, sizeof(new_hdr));

    new_desc = buffer + sizeof(new_hdr);
    data_sector = buffer + (desc_sectors * VHDX_LOG_SECTOR_SIZE);
    data_tmp = data;

    /* All log sectors are 4KB, so for any partial sectors we must
     * merge the data with preexisting data from the final file
     * destination */
    merged_sector = qemu_blockalign(bs, VHDX_LOG_SECTOR_SIZE);

    for (i = 0; i < sectors; i++) {
        new_desc->signature       = VHDX_LOG_DESC_SIGNATURE;
        new_desc->sequence_number = s->log.sequence;
        new_desc->file_offset     = file_offset;

        if (i == 0 && leading_length) {
            /* partial sector at the front of the buffer */
            ret = bdrv_co_pread(bs->file, file_offset, VHDX_LOG_SECTOR_SIZE,
                                merged_sector, 0);
            if (ret < 0) {
                goto exit;
            }
            memcpy(merged_sector + sector_offset, data_tmp, leading_length);
            bytes_written = leading_length;
            sector_write = merged_sector;
        } else if (i == sectors - 1 && trailing_length) {
            /* partial sector at the end of the buffer */
            ret = bdrv_co_pread(bs->file, file_offset + trailing_length,
                                VHDX_LOG_SECTOR_SIZE - trailing_length,
                                merged_sector + trailing_length, 0);
            if (ret < 0) {
                goto exit;
            }
            memcpy(merged_sector, data_tmp, trailing_length);
            bytes_written = trailing_length;
            sector_write = merged_sector;
        } else {
            bytes_written = VHDX_LOG_SECTOR_SIZE;
            sector_write = data_tmp;
        }

        /* populate the raw sector data into the proper structures,
         * as well as update the descriptor, and convert to proper
         * endianness */
        vhdx_log_raw_to_le_sector(new_desc, data_sector, sector_write,
                                  s->log.sequence);

        data_tmp += bytes_written;
        data_sector++;
        new_desc++;
        file_offset += VHDX_LOG_SECTOR_SIZE;
    }

    /* checksum covers entire entry, from the log header through the
     * last data sector */
    vhdx_update_checksum(buffer, total_length,
                         offsetof(VHDXLogEntryHeader, checksum));

    /* now write to the log */
    ret = vhdx_log_write_sectors(bs, &s->log, &sectors_written, buffer,
                                 desc_sectors + sectors);
    if (ret < 0) {
        goto exit;
    }

    if (sectors_written != desc_sectors + sectors) {
        /* instead of failing, we could flush the log here */
        ret = -EINVAL;
        goto exit;
    }

    s->log.sequence++;
    /* write new tail */
    s->log.tail = s->log.write;

exit:
    qemu_vfree(buffer);
    qemu_vfree(merged_sector);
    return ret;
}

/* Perform a log write, and then immediately flush the entire log */
int coroutine_fn
vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
                         void *data, uint32_t length, uint64_t offset)
{
    int ret = 0;
    VHDXLogSequence logs = { .valid = true,
                             .count = 1,
                             .hdr = { 0 } };


    /* Make sure data written (new and/or changed blocks) is stable
     * on disk, before creating log entry */
    ret = bdrv_co_flush(bs);
    if (ret < 0) {
        goto exit;
    }

    ret = vhdx_log_write(bs, s, data, length, offset);
    if (ret < 0) {
        goto exit;
    }
    logs.log = s->log;

    /* Make sure log is stable on disk */
    ret = bdrv_co_flush(bs);
    if (ret < 0) {
        goto exit;
    }

    ret = vhdx_log_flush(bs, s, &logs);
    if (ret < 0) {
        goto exit;
    }

    s->log = logs.log;

exit:
    return ret;
}

