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

int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
                          char *next_out, unsigned int avail_out);

int (*dmg_uncompress_lzfse)(char *next_in, unsigned int avail_in,
                            char *next_out, unsigned int avail_out);

enum {
    /* Limit chunk sizes to prevent unreasonable amounts of memory being used
     * or truncating when converting to 32-bit types
     */
    DMG_LENGTHS_MAX = 64 * 1024 * 1024, /* 64 MB */
    DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512,
};

enum {
    /* DMG Block Type */
    UDZE = 0, /* Zeroes */
    UDRW,     /* RAW type */
    UDIG,     /* Ignore */
    UDCO = 0x80000004,
    UDZO,
    UDBZ,
    ULFO,
    UDCM = 0x7ffffffe, /* Comments */
    UDLE = 0xffffffff  /* Last Entry */
};

static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
{
    int len;

    if (!filename) {
        return 0;
    }

    len = strlen(filename);
    if (len > 4 && !strcmp(filename + len - 4, ".dmg")) {
        return 2;
    }
    return 0;
}

static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
{
    uint64_t buffer;
    int ret;

    ret = bdrv_pread(bs->file, offset, &buffer, 8);
    if (ret < 0) {
        return ret;
    }

    *result = be64_to_cpu(buffer);
    return 0;
}

static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
{
    uint32_t buffer;
    int ret;

    ret = bdrv_pread(bs->file, offset, &buffer, 4);
    if (ret < 0) {
        return ret;
    }

    *result = be32_to_cpu(buffer);
    return 0;
}

static inline uint64_t buff_read_uint64(const uint8_t *buffer, int64_t offset)
{
    return be64_to_cpu(*(uint64_t *)&buffer[offset]);
}

static inline uint32_t buff_read_uint32(const uint8_t *buffer, int64_t offset)
{
    return be32_to_cpu(*(uint32_t *)&buffer[offset]);
}

/* Increase max chunk sizes, if necessary.  This function is used to calculate
 * the buffer sizes needed for compressed/uncompressed chunk I/O.
 */
static void update_max_chunk_size(BDRVDMGState *s, uint32_t chunk,
                                  uint32_t *max_compressed_size,
                                  uint32_t *max_sectors_per_chunk)
{
    uint32_t compressed_size = 0;
    uint32_t uncompressed_sectors = 0;

    switch (s->types[chunk]) {
    case UDZO: /* zlib compressed */
    case UDBZ: /* bzip2 compressed */
    case ULFO: /* lzfse compressed */
        compressed_size = s->lengths[chunk];
        uncompressed_sectors = s->sectorcounts[chunk];
        break;
    case UDRW: /* copy */
        uncompressed_sectors = DIV_ROUND_UP(s->lengths[chunk], 512);
        break;
    case UDZE: /* zero */
    case UDIG: /* ignore */
        /* as the all-zeroes block may be large, it is treated specially: the
         * sector is not copied from a large buffer, a simple memset is used
         * instead. Therefore uncompressed_sectors does not need to be set. */
        break;
    }

    if (compressed_size > *max_compressed_size) {
        *max_compressed_size = compressed_size;
    }
    if (uncompressed_sectors > *max_sectors_per_chunk) {
        *max_sectors_per_chunk = uncompressed_sectors;
    }
}

static int64_t dmg_find_koly_offset(BdrvChild *file, Error **errp)
{
    BlockDriverState *file_bs = file->bs;
    int64_t length;
    int64_t offset = 0;
    uint8_t buffer[515];
    int i, ret;

    /* bdrv_getlength returns a multiple of block size (512), rounded up. Since
     * dmg images can have odd sizes, try to look for the "koly" magic which
     * marks the begin of the UDIF trailer (512 bytes). This magic can be found
     * in the last 511 bytes of the second-last sector or the first 4 bytes of
     * the last sector (search space: 515 bytes) */
    length = bdrv_getlength(file_bs);
    if (length < 0) {
        error_setg_errno(errp, -length,
            "Failed to get file size while reading UDIF trailer");
        return length;
    } else if (length < 512) {
        error_setg(errp, "dmg file must be at least 512 bytes long");
        return -EINVAL;
    }
    if (length > 511 + 512) {
        offset = length - 511 - 512;
    }
    length = length < 515 ? length : 515;
    ret = bdrv_pread(file, offset, buffer, length);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Failed while reading UDIF trailer");
        return ret;
    }
    for (i = 0; i < length - 3; i++) {
        if (buffer[i] == 'k' && buffer[i+1] == 'o' &&
            buffer[i+2] == 'l' && buffer[i+3] == 'y') {
            return offset + i;
        }
    }
    error_setg(errp, "Could not locate UDIF trailer in dmg file");
    return -EINVAL;
}

/* used when building the sector table */
typedef struct DmgHeaderState {
    /* used internally by dmg_read_mish_block to remember offsets of blocks
     * across calls */
    uint64_t data_fork_offset;
    /* exported for dmg_open */
    uint32_t max_compressed_size;
    uint32_t max_sectors_per_chunk;
} DmgHeaderState;

static bool dmg_is_known_block_type(uint32_t entry_type)
{
    switch (entry_type) {
    case UDZE:    /* zeros */
    case UDRW:    /* uncompressed */
    case UDIG:    /* ignore */
    case UDZO:    /* zlib */
        return true;
    case UDBZ:    /* bzip2 */
        return !!dmg_uncompress_bz2;
    case ULFO:    /* lzfse */
        return !!dmg_uncompress_lzfse;
    default:
        return false;
    }
}

static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
                               uint8_t *buffer, uint32_t count)
{
    uint32_t type, i;
    int ret;
    size_t new_size;
    uint32_t chunk_count;
    int64_t offset = 0;
    uint64_t data_offset;
    uint64_t in_offset = ds->data_fork_offset;
    uint64_t out_offset;

    type = buff_read_uint32(buffer, offset);
    /* skip data that is not a valid MISH block (invalid magic or too small) */
    if (type != 0x6d697368 || count < 244) {
        /* assume success for now */
        return 0;
    }

    /* chunk offsets are relative to this sector number */
    out_offset = buff_read_uint64(buffer, offset + 8);

    /* location in data fork for (compressed) blob (in bytes) */
    data_offset = buff_read_uint64(buffer, offset + 0x18);
    in_offset += data_offset;

    /* move to begin of chunk entries */
    offset += 204;

    chunk_count = (count - 204) / 40;
    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
    s->types = g_realloc(s->types, new_size / 2);
    s->offsets = g_realloc(s->offsets, new_size);
    s->lengths = g_realloc(s->lengths, new_size);
    s->sectors = g_realloc(s->sectors, new_size);
    s->sectorcounts = g_realloc(s->sectorcounts, new_size);

    for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
        s->types[i] = buff_read_uint32(buffer, offset);
        if (!dmg_is_known_block_type(s->types[i])) {
            chunk_count--;
            i--;
            offset += 40;
            continue;
        }

        /* sector number */
        s->sectors[i] = buff_read_uint64(buffer, offset + 8);
        s->sectors[i] += out_offset;

        /* sector count */
        s->sectorcounts[i] = buff_read_uint64(buffer, offset + 0x10);

        /* all-zeroes sector (type UDZE and UDIG) does not need to be
         * "uncompressed" and can therefore be unbounded. */
        if (s->types[i] != UDZE && s->types[i] != UDIG
            && s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
            error_report("sector count %" PRIu64 " for chunk %" PRIu32
                         " is larger than max (%u)",
                         s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
            ret = -EINVAL;
            goto fail;
        }

        /* offset in (compressed) data fork */
        s->offsets[i] = buff_read_uint64(buffer, offset + 0x18);
        s->offsets[i] += in_offset;

        /* length in (compressed) data fork */
        s->lengths[i] = buff_read_uint64(buffer, offset + 0x20);

        if (s->lengths[i] > DMG_LENGTHS_MAX) {
            error_report("length %" PRIu64 " for chunk %" PRIu32
                         " is larger than max (%u)",
                         s->lengths[i], i, DMG_LENGTHS_MAX);
            ret = -EINVAL;
            goto fail;
        }

        update_max_chunk_size(s, i, &ds->max_compressed_size,
                              &ds->max_sectors_per_chunk);
        offset += 40;
    }
    s->n_chunks += chunk_count;
    return 0;

fail:
    return ret;
}

static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
                                  uint64_t info_begin, uint64_t info_length)
{
    BDRVDMGState *s = bs->opaque;
    int ret;
    uint32_t count, rsrc_data_offset;
    uint8_t *buffer = NULL;
    uint64_t info_end;
    uint64_t offset;

    /* read offset from begin of resource fork (info_begin) to resource data */
    ret = read_uint32(bs, info_begin, &rsrc_data_offset);
    if (ret < 0) {
        goto fail;
    } else if (rsrc_data_offset > info_length) {
        ret = -EINVAL;
        goto fail;
    }

    /* read length of resource data */
    ret = read_uint32(bs, info_begin + 8, &count);
    if (ret < 0) {
        goto fail;
    } else if (count == 0 || rsrc_data_offset + count > info_length) {
        ret = -EINVAL;
        goto fail;
    }

    /* begin of resource data (consisting of one or more resources) */
    offset = info_begin + rsrc_data_offset;

    /* end of resource data (there is possibly a following resource map
     * which will be ignored). */
    info_end = offset + count;

    /* read offsets (mish blocks) from one or more resources in resource data */
    while (offset < info_end) {
        /* size of following resource */
        ret = read_uint32(bs, offset, &count);
        if (ret < 0) {
            goto fail;
        } else if (count == 0 || count > info_end - offset) {
            ret = -EINVAL;
            goto fail;
        }
        offset += 4;

        buffer = g_realloc(buffer, count);
        ret = bdrv_pread(bs->file, offset, buffer, count);
        if (ret < 0) {
            goto fail;
        }

        ret = dmg_read_mish_block(s, ds, buffer, count);
        if (ret < 0) {
            goto fail;
        }
        /* advance offset by size of resource */
        offset += count;
    }
    ret = 0;

fail:
    g_free(buffer);
    return ret;
}

static int dmg_read_plist_xml(BlockDriverState *bs, DmgHeaderState *ds,
                              uint64_t info_begin, uint64_t info_length)
{
    BDRVDMGState *s = bs->opaque;
    int ret;
    uint8_t *buffer = NULL;
    char *data_begin, *data_end;

    /* Have at least some length to avoid NULL for g_malloc. Attempt to set a
     * safe upper cap on the data length. A test sample had a XML length of
     * about 1 MiB. */
    if (info_length == 0 || info_length > 16 * 1024 * 1024) {
        ret = -EINVAL;
        goto fail;
    }

    buffer = g_malloc(info_length + 1);
    buffer[info_length] = '\0';
    ret = bdrv_pread(bs->file, info_begin, buffer, info_length);
    if (ret != info_length) {
        ret = -EINVAL;
        goto fail;
    }

    /* look for <data>...</data>. The data is 284 (0x11c) bytes after base64
     * decode. The actual data element has 431 (0x1af) bytes which includes tabs
     * and line feeds. */
    data_end = (char *)buffer;
    while ((data_begin = strstr(data_end, "<data>")) != NULL) {
        guchar *mish;
        gsize out_len = 0;

        data_begin += 6;
        data_end = strstr(data_begin, "</data>");
        /* malformed XML? */
        if (data_end == NULL) {
            ret = -EINVAL;
            goto fail;
        }
        *data_end++ = '\0';
        mish = g_base64_decode(data_begin, &out_len);
        ret = dmg_read_mish_block(s, ds, mish, (uint32_t)out_len);
        g_free(mish);
        if (ret < 0) {
            goto fail;
        }
    }
    ret = 0;

fail:
    g_free(buffer);
    return ret;
}

static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    BDRVDMGState *s = bs->opaque;
    DmgHeaderState ds;
    uint64_t rsrc_fork_offset, rsrc_fork_length;
    uint64_t plist_xml_offset, plist_xml_length;
    int64_t offset;
    int ret;

    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
    if (ret < 0) {
        return ret;
    }

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
                               BDRV_CHILD_IMAGE, false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    block_module_load_one("dmg-bz2");
    block_module_load_one("dmg-lzfse");

    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
    /* used by dmg_read_mish_block to keep track of the current I/O position */
    ds.data_fork_offset = 0;
    ds.max_compressed_size = 1;
    ds.max_sectors_per_chunk = 1;

    /* locate the UDIF trailer */
    offset = dmg_find_koly_offset(bs->file, errp);
    if (offset < 0) {
        ret = offset;
        goto fail;
    }

    /* offset of data fork (DataForkOffset) */
    ret = read_uint64(bs, offset + 0x18, &ds.data_fork_offset);
    if (ret < 0) {
        goto fail;
    } else if (ds.data_fork_offset > offset) {
        ret = -EINVAL;
        goto fail;
    }

    /* offset of resource fork (RsrcForkOffset) */
    ret = read_uint64(bs, offset + 0x28, &rsrc_fork_offset);
    if (ret < 0) {
        goto fail;
    }
    ret = read_uint64(bs, offset + 0x30, &rsrc_fork_length);
    if (ret < 0) {
        goto fail;
    }
    if (rsrc_fork_offset >= offset ||
        rsrc_fork_length > offset - rsrc_fork_offset) {
        ret = -EINVAL;
        goto fail;
    }
    /* offset of property list (XMLOffset) */
    ret = read_uint64(bs, offset + 0xd8, &plist_xml_offset);
    if (ret < 0) {
        goto fail;
    }
    ret = read_uint64(bs, offset + 0xe0, &plist_xml_length);
    if (ret < 0) {
        goto fail;
    }
    if (plist_xml_offset >= offset ||
        plist_xml_length > offset - plist_xml_offset) {
        ret = -EINVAL;
        goto fail;
    }
    ret = read_uint64(bs, offset + 0x1ec, (uint64_t *)&bs->total_sectors);
    if (ret < 0) {
        goto fail;
    }
    if (bs->total_sectors < 0) {
        ret = -EINVAL;
        goto fail;
    }
    if (rsrc_fork_length != 0) {
        ret = dmg_read_resource_fork(bs, &ds,
                                     rsrc_fork_offset, rsrc_fork_length);
        if (ret < 0) {
            goto fail;
        }
    } else if (plist_xml_length != 0) {
        ret = dmg_read_plist_xml(bs, &ds, plist_xml_offset, plist_xml_length);
        if (ret < 0) {
            goto fail;
        }
    } else {
        ret = -EINVAL;
        goto fail;
    }

    /* initialize zlib engine */
    s->compressed_chunk = qemu_try_blockalign(bs->file->bs,
                                              ds.max_compressed_size + 1);
    s->uncompressed_chunk = qemu_try_blockalign(bs->file->bs,
                                                512 * ds.max_sectors_per_chunk);
    if (s->compressed_chunk == NULL || s->uncompressed_chunk == NULL) {
        ret = -ENOMEM;
        goto fail;
    }

    if (inflateInit(&s->zstream) != Z_OK) {
        ret = -EINVAL;
        goto fail;
    }

    s->current_chunk = s->n_chunks;

    qemu_co_mutex_init(&s->lock);
    return 0;

fail:
    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    qemu_vfree(s->compressed_chunk);
    qemu_vfree(s->uncompressed_chunk);
    return ret;
}

static void dmg_refresh_limits(BlockDriverState *bs, Error **errp)
{
    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
}

static inline int is_sector_in_chunk(BDRVDMGState *s,
                uint32_t chunk_num, uint64_t sector_num)
{
    if (chunk_num >= s->n_chunks || s->sectors[chunk_num] > sector_num ||
            s->sectors[chunk_num] + s->sectorcounts[chunk_num] <= sector_num) {
        return 0;
    } else {
        return -1;
    }
}

static inline uint32_t search_chunk(BDRVDMGState *s, uint64_t sector_num)
{
    /* binary search */
    uint32_t chunk1 = 0, chunk2 = s->n_chunks, chunk3;
    while (chunk1 <= chunk2) {
        chunk3 = (chunk1 + chunk2) / 2;
        if (s->sectors[chunk3] > sector_num) {
            if (chunk3 == 0) {
                goto err;
            }
            chunk2 = chunk3 - 1;
        } else if (s->sectors[chunk3] + s->sectorcounts[chunk3] > sector_num) {
            return chunk3;
        } else {
            chunk1 = chunk3 + 1;
        }
    }
err:
    return s->n_chunks; /* error */
}

static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
{
    BDRVDMGState *s = bs->opaque;

    if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
        int ret;
        uint32_t chunk = search_chunk(s, sector_num);

        if (chunk >= s->n_chunks) {
            return -1;
        }

        s->current_chunk = s->n_chunks;
        switch (s->types[chunk]) { /* block entry type */
        case UDZO: { /* zlib compressed */
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            s->zstream.next_in = s->compressed_chunk;
            s->zstream.avail_in = s->lengths[chunk];
            s->zstream.next_out = s->uncompressed_chunk;
            s->zstream.avail_out = 512 * s->sectorcounts[chunk];
            ret = inflateReset(&s->zstream);
            if (ret != Z_OK) {
                return -1;
            }
            ret = inflate(&s->zstream, Z_FINISH);
            if (ret != Z_STREAM_END ||
                s->zstream.total_out != 512 * s->sectorcounts[chunk]) {
                return -1;
            }
            break; }
        case UDBZ: /* bzip2 compressed */
            if (!dmg_uncompress_bz2) {
                break;
            }
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            ret = dmg_uncompress_bz2((char *)s->compressed_chunk,
                                     (unsigned int) s->lengths[chunk],
                                     (char *)s->uncompressed_chunk,
                                     (unsigned int)
                                         (512 * s->sectorcounts[chunk]));
            if (ret < 0) {
                return ret;
            }
            break;
        case ULFO:
            if (!dmg_uncompress_lzfse) {
                break;
            }
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            ret = dmg_uncompress_lzfse((char *)s->compressed_chunk,
                                       (unsigned int) s->lengths[chunk],
                                       (char *)s->uncompressed_chunk,
                                       (unsigned int)
                                           (512 * s->sectorcounts[chunk]));
            if (ret < 0) {
                return ret;
            }
            break;
        case UDRW: /* copy */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->uncompressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }
            break;
        case UDZE: /* zeros */
        case UDIG: /* ignore */
            /* see dmg_read, it is treated specially. No buffer needs to be
             * pre-filled, the zeroes can be set directly. */
            break;
        }
        s->current_chunk = chunk;
    }
    return 0;
}

static int coroutine_fn
dmg_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
              QEMUIOVector *qiov, BdrvRequestFlags flags)
{
    BDRVDMGState *s = bs->opaque;
    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
    int ret, i;

    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));

    qemu_co_mutex_lock(&s->lock);

    for (i = 0; i < nb_sectors; i++) {
        uint32_t sector_offset_in_chunk;
        void *data;

        if (dmg_read_chunk(bs, sector_num + i) != 0) {
            ret = -EIO;
            goto fail;
        }
        /* Special case: current chunk is all zeroes. Do not perform a memcpy as
         * s->uncompressed_chunk may be too small to cover the large all-zeroes
         * section. dmg_read_chunk is called to find s->current_chunk */
        if (s->types[s->current_chunk] == UDZE
            || s->types[s->current_chunk] == UDIG) { /* all zeroes block entry */
            qemu_iovec_memset(qiov, i * 512, 0, 512);
            continue;
        }
        sector_offset_in_chunk = sector_num + i - s->sectors[s->current_chunk];
        data = s->uncompressed_chunk + sector_offset_in_chunk * 512;
        qemu_iovec_from_buf(qiov, i * 512, data, 512);
    }

    ret = 0;
fail:
    qemu_co_mutex_unlock(&s->lock);
    return ret;
}

static void dmg_close(BlockDriverState *bs)
{
    BDRVDMGState *s = bs->opaque;

    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    qemu_vfree(s->compressed_chunk);
    qemu_vfree(s->uncompressed_chunk);

    inflateEnd(&s->zstream);
}

static BlockDriver bdrv_dmg = {
    .format_name    = "dmg",
    .instance_size  = sizeof(BDRVDMGState),
    .bdrv_probe     = dmg_probe,
    .bdrv_open      = dmg_open,
    .bdrv_refresh_limits = dmg_refresh_limits,
    .bdrv_child_perm     = bdrv_default_perms,
    .bdrv_co_preadv = dmg_co_preadv,
    .bdrv_close     = dmg_close,
    .is_format      = true,
};

static void bdrv_dmg_init(void)
{
    bdrv_register(&bdrv_dmg);
}

block_init(bdrv_dmg_init);
