qemu/block/dmg.c
<<
>>
Prefs
   1/*
   2 * QEMU Block driver for DMG images
   3 *
   4 * Copyright (c) 2004 Johannes E. Schindelin
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24#include "qemu/osdep.h"
  25#include "qapi/error.h"
  26#include "block/block_int.h"
  27#include "qemu/bswap.h"
  28#include "qemu/error-report.h"
  29#include "qemu/module.h"
  30#include "qemu/memalign.h"
  31#include "dmg.h"
  32
  33int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
  34                          char *next_out, unsigned int avail_out);
  35
  36int (*dmg_uncompress_lzfse)(char *next_in, unsigned int avail_in,
  37                            char *next_out, unsigned int avail_out);
  38
  39enum {
  40    /* Limit chunk sizes to prevent unreasonable amounts of memory being used
  41     * or truncating when converting to 32-bit types
  42     */
  43    DMG_LENGTHS_MAX = 64 * 1024 * 1024, /* 64 MB */
  44    DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512,
  45};
  46
  47enum {
  48    /* DMG Block Type */
  49    UDZE = 0, /* Zeroes */
  50    UDRW,     /* RAW type */
  51    UDIG,     /* Ignore */
  52    UDCO = 0x80000004,
  53    UDZO,
  54    UDBZ,
  55    ULFO,
  56    UDCM = 0x7ffffffe, /* Comments */
  57    UDLE = 0xffffffff  /* Last Entry */
  58};
  59
  60static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
  61{
  62    int len;
  63
  64    if (!filename) {
  65        return 0;
  66    }
  67
  68    len = strlen(filename);
  69    if (len > 4 && !strcmp(filename + len - 4, ".dmg")) {
  70        return 2;
  71    }
  72    return 0;
  73}
  74
  75static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
  76{
  77    uint64_t buffer;
  78    int ret;
  79
  80    ret = bdrv_pread(bs->file, offset, &buffer, 8);
  81    if (ret < 0) {
  82        return ret;
  83    }
  84
  85    *result = be64_to_cpu(buffer);
  86    return 0;
  87}
  88
  89static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
  90{
  91    uint32_t buffer;
  92    int ret;
  93
  94    ret = bdrv_pread(bs->file, offset, &buffer, 4);
  95    if (ret < 0) {
  96        return ret;
  97    }
  98
  99    *result = be32_to_cpu(buffer);
 100    return 0;
 101}
 102
 103static inline uint64_t buff_read_uint64(const uint8_t *buffer, int64_t offset)
 104{
 105    return be64_to_cpu(*(uint64_t *)&buffer[offset]);
 106}
 107
 108static inline uint32_t buff_read_uint32(const uint8_t *buffer, int64_t offset)
 109{
 110    return be32_to_cpu(*(uint32_t *)&buffer[offset]);
 111}
 112
 113/* Increase max chunk sizes, if necessary.  This function is used to calculate
 114 * the buffer sizes needed for compressed/uncompressed chunk I/O.
 115 */
 116static void update_max_chunk_size(BDRVDMGState *s, uint32_t chunk,
 117                                  uint32_t *max_compressed_size,
 118                                  uint32_t *max_sectors_per_chunk)
 119{
 120    uint32_t compressed_size = 0;
 121    uint32_t uncompressed_sectors = 0;
 122
 123    switch (s->types[chunk]) {
 124    case UDZO: /* zlib compressed */
 125    case UDBZ: /* bzip2 compressed */
 126    case ULFO: /* lzfse compressed */
 127        compressed_size = s->lengths[chunk];
 128        uncompressed_sectors = s->sectorcounts[chunk];
 129        break;
 130    case UDRW: /* copy */
 131        uncompressed_sectors = DIV_ROUND_UP(s->lengths[chunk], 512);
 132        break;
 133    case UDZE: /* zero */
 134    case UDIG: /* ignore */
 135        /* as the all-zeroes block may be large, it is treated specially: the
 136         * sector is not copied from a large buffer, a simple memset is used
 137         * instead. Therefore uncompressed_sectors does not need to be set. */
 138        break;
 139    }
 140
 141    if (compressed_size > *max_compressed_size) {
 142        *max_compressed_size = compressed_size;
 143    }
 144    if (uncompressed_sectors > *max_sectors_per_chunk) {
 145        *max_sectors_per_chunk = uncompressed_sectors;
 146    }
 147}
 148
 149static int64_t dmg_find_koly_offset(BdrvChild *file, Error **errp)
 150{
 151    BlockDriverState *file_bs = file->bs;
 152    int64_t length;
 153    int64_t offset = 0;
 154    uint8_t buffer[515];
 155    int i, ret;
 156
 157    /* bdrv_getlength returns a multiple of block size (512), rounded up. Since
 158     * dmg images can have odd sizes, try to look for the "koly" magic which
 159     * marks the begin of the UDIF trailer (512 bytes). This magic can be found
 160     * in the last 511 bytes of the second-last sector or the first 4 bytes of
 161     * the last sector (search space: 515 bytes) */
 162    length = bdrv_getlength(file_bs);
 163    if (length < 0) {
 164        error_setg_errno(errp, -length,
 165            "Failed to get file size while reading UDIF trailer");
 166        return length;
 167    } else if (length < 512) {
 168        error_setg(errp, "dmg file must be at least 512 bytes long");
 169        return -EINVAL;
 170    }
 171    if (length > 511 + 512) {
 172        offset = length - 511 - 512;
 173    }
 174    length = length < 515 ? length : 515;
 175    ret = bdrv_pread(file, offset, buffer, length);
 176    if (ret < 0) {
 177        error_setg_errno(errp, -ret, "Failed while reading UDIF trailer");
 178        return ret;
 179    }
 180    for (i = 0; i < length - 3; i++) {
 181        if (buffer[i] == 'k' && buffer[i+1] == 'o' &&
 182            buffer[i+2] == 'l' && buffer[i+3] == 'y') {
 183            return offset + i;
 184        }
 185    }
 186    error_setg(errp, "Could not locate UDIF trailer in dmg file");
 187    return -EINVAL;
 188}
 189
 190/* used when building the sector table */
 191typedef struct DmgHeaderState {
 192    /* used internally by dmg_read_mish_block to remember offsets of blocks
 193     * across calls */
 194    uint64_t data_fork_offset;
 195    /* exported for dmg_open */
 196    uint32_t max_compressed_size;
 197    uint32_t max_sectors_per_chunk;
 198} DmgHeaderState;
 199
 200static bool dmg_is_known_block_type(uint32_t entry_type)
 201{
 202    switch (entry_type) {
 203    case UDZE:    /* zeros */
 204    case UDRW:    /* uncompressed */
 205    case UDIG:    /* ignore */
 206    case UDZO:    /* zlib */
 207        return true;
 208    case UDBZ:    /* bzip2 */
 209        return !!dmg_uncompress_bz2;
 210    case ULFO:    /* lzfse */
 211        return !!dmg_uncompress_lzfse;
 212    default:
 213        return false;
 214    }
 215}
 216
 217static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
 218                               uint8_t *buffer, uint32_t count)
 219{
 220    uint32_t type, i;
 221    int ret;
 222    size_t new_size;
 223    uint32_t chunk_count;
 224    int64_t offset = 0;
 225    uint64_t data_offset;
 226    uint64_t in_offset = ds->data_fork_offset;
 227    uint64_t out_offset;
 228
 229    type = buff_read_uint32(buffer, offset);
 230    /* skip data that is not a valid MISH block (invalid magic or too small) */
 231    if (type != 0x6d697368 || count < 244) {
 232        /* assume success for now */
 233        return 0;
 234    }
 235
 236    /* chunk offsets are relative to this sector number */
 237    out_offset = buff_read_uint64(buffer, offset + 8);
 238
 239    /* location in data fork for (compressed) blob (in bytes) */
 240    data_offset = buff_read_uint64(buffer, offset + 0x18);
 241    in_offset += data_offset;
 242
 243    /* move to begin of chunk entries */
 244    offset += 204;
 245
 246    chunk_count = (count - 204) / 40;
 247    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
 248    s->types = g_realloc(s->types, new_size / 2);
 249    s->offsets = g_realloc(s->offsets, new_size);
 250    s->lengths = g_realloc(s->lengths, new_size);
 251    s->sectors = g_realloc(s->sectors, new_size);
 252    s->sectorcounts = g_realloc(s->sectorcounts, new_size);
 253
 254    for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {
 255        s->types[i] = buff_read_uint32(buffer, offset);
 256        if (!dmg_is_known_block_type(s->types[i])) {
 257            chunk_count--;
 258            i--;
 259            offset += 40;
 260            continue;
 261        }
 262
 263        /* sector number */
 264        s->sectors[i] = buff_read_uint64(buffer, offset + 8);
 265        s->sectors[i] += out_offset;
 266
 267        /* sector count */
 268        s->sectorcounts[i] = buff_read_uint64(buffer, offset + 0x10);
 269
 270        /* all-zeroes sector (type UDZE and UDIG) does not need to be
 271         * "uncompressed" and can therefore be unbounded. */
 272        if (s->types[i] != UDZE && s->types[i] != UDIG
 273            && s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
 274            error_report("sector count %" PRIu64 " for chunk %" PRIu32
 275                         " is larger than max (%u)",
 276                         s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
 277            ret = -EINVAL;
 278            goto fail;
 279        }
 280
 281        /* offset in (compressed) data fork */
 282        s->offsets[i] = buff_read_uint64(buffer, offset + 0x18);
 283        s->offsets[i] += in_offset;
 284
 285        /* length in (compressed) data fork */
 286        s->lengths[i] = buff_read_uint64(buffer, offset + 0x20);
 287
 288        if (s->lengths[i] > DMG_LENGTHS_MAX) {
 289            error_report("length %" PRIu64 " for chunk %" PRIu32
 290                         " is larger than max (%u)",
 291                         s->lengths[i], i, DMG_LENGTHS_MAX);
 292            ret = -EINVAL;
 293            goto fail;
 294        }
 295
 296        update_max_chunk_size(s, i, &ds->max_compressed_size,
 297                              &ds->max_sectors_per_chunk);
 298        offset += 40;
 299    }
 300    s->n_chunks += chunk_count;
 301    return 0;
 302
 303fail:
 304    return ret;
 305}
 306
 307static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
 308                                  uint64_t info_begin, uint64_t info_length)
 309{
 310    BDRVDMGState *s = bs->opaque;
 311    int ret;
 312    uint32_t count, rsrc_data_offset;
 313    uint8_t *buffer = NULL;
 314    uint64_t info_end;
 315    uint64_t offset;
 316
 317    /* read offset from begin of resource fork (info_begin) to resource data */
 318    ret = read_uint32(bs, info_begin, &rsrc_data_offset);
 319    if (ret < 0) {
 320        goto fail;
 321    } else if (rsrc_data_offset > info_length) {
 322        ret = -EINVAL;
 323        goto fail;
 324    }
 325
 326    /* read length of resource data */
 327    ret = read_uint32(bs, info_begin + 8, &count);
 328    if (ret < 0) {
 329        goto fail;
 330    } else if (count == 0 || rsrc_data_offset + count > info_length) {
 331        ret = -EINVAL;
 332        goto fail;
 333    }
 334
 335    /* begin of resource data (consisting of one or more resources) */
 336    offset = info_begin + rsrc_data_offset;
 337
 338    /* end of resource data (there is possibly a following resource map
 339     * which will be ignored). */
 340    info_end = offset + count;
 341
 342    /* read offsets (mish blocks) from one or more resources in resource data */
 343    while (offset < info_end) {
 344        /* size of following resource */
 345        ret = read_uint32(bs, offset, &count);
 346        if (ret < 0) {
 347            goto fail;
 348        } else if (count == 0 || count > info_end - offset) {
 349            ret = -EINVAL;
 350            goto fail;
 351        }
 352        offset += 4;
 353
 354        buffer = g_realloc(buffer, count);
 355        ret = bdrv_pread(bs->file, offset, buffer, count);
 356        if (ret < 0) {
 357            goto fail;
 358        }
 359
 360        ret = dmg_read_mish_block(s, ds, buffer, count);
 361        if (ret < 0) {
 362            goto fail;
 363        }
 364        /* advance offset by size of resource */
 365        offset += count;
 366    }
 367    ret = 0;
 368
 369fail:
 370    g_free(buffer);
 371    return ret;
 372}
 373
 374static int dmg_read_plist_xml(BlockDriverState *bs, DmgHeaderState *ds,
 375                              uint64_t info_begin, uint64_t info_length)
 376{
 377    BDRVDMGState *s = bs->opaque;
 378    int ret;
 379    uint8_t *buffer = NULL;
 380    char *data_begin, *data_end;
 381
 382    /* Have at least some length to avoid NULL for g_malloc. Attempt to set a
 383     * safe upper cap on the data length. A test sample had a XML length of
 384     * about 1 MiB. */
 385    if (info_length == 0 || info_length > 16 * 1024 * 1024) {
 386        ret = -EINVAL;
 387        goto fail;
 388    }
 389
 390    buffer = g_malloc(info_length + 1);
 391    buffer[info_length] = '\0';
 392    ret = bdrv_pread(bs->file, info_begin, buffer, info_length);
 393    if (ret != info_length) {
 394        ret = -EINVAL;
 395        goto fail;
 396    }
 397
 398    /* look for <data>...</data>. The data is 284 (0x11c) bytes after base64
 399     * decode. The actual data element has 431 (0x1af) bytes which includes tabs
 400     * and line feeds. */
 401    data_end = (char *)buffer;
 402    while ((data_begin = strstr(data_end, "<data>")) != NULL) {
 403        guchar *mish;
 404        gsize out_len = 0;
 405
 406        data_begin += 6;
 407        data_end = strstr(data_begin, "</data>");
 408        /* malformed XML? */
 409        if (data_end == NULL) {
 410            ret = -EINVAL;
 411            goto fail;
 412        }
 413        *data_end++ = '\0';
 414        mish = g_base64_decode(data_begin, &out_len);
 415        ret = dmg_read_mish_block(s, ds, mish, (uint32_t)out_len);
 416        g_free(mish);
 417        if (ret < 0) {
 418            goto fail;
 419        }
 420    }
 421    ret = 0;
 422
 423fail:
 424    g_free(buffer);
 425    return ret;
 426}
 427
 428static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
 429                    Error **errp)
 430{
 431    BDRVDMGState *s = bs->opaque;
 432    DmgHeaderState ds;
 433    uint64_t rsrc_fork_offset, rsrc_fork_length;
 434    uint64_t plist_xml_offset, plist_xml_length;
 435    int64_t offset;
 436    int ret;
 437
 438    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
 439    if (ret < 0) {
 440        return ret;
 441    }
 442
 443    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
 444                               BDRV_CHILD_IMAGE, false, errp);
 445    if (!bs->file) {
 446        return -EINVAL;
 447    }
 448
 449    block_module_load_one("dmg-bz2");
 450    block_module_load_one("dmg-lzfse");
 451
 452    s->n_chunks = 0;
 453    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
 454    /* used by dmg_read_mish_block to keep track of the current I/O position */
 455    ds.data_fork_offset = 0;
 456    ds.max_compressed_size = 1;
 457    ds.max_sectors_per_chunk = 1;
 458
 459    /* locate the UDIF trailer */
 460    offset = dmg_find_koly_offset(bs->file, errp);
 461    if (offset < 0) {
 462        ret = offset;
 463        goto fail;
 464    }
 465
 466    /* offset of data fork (DataForkOffset) */
 467    ret = read_uint64(bs, offset + 0x18, &ds.data_fork_offset);
 468    if (ret < 0) {
 469        goto fail;
 470    } else if (ds.data_fork_offset > offset) {
 471        ret = -EINVAL;
 472        goto fail;
 473    }
 474
 475    /* offset of resource fork (RsrcForkOffset) */
 476    ret = read_uint64(bs, offset + 0x28, &rsrc_fork_offset);
 477    if (ret < 0) {
 478        goto fail;
 479    }
 480    ret = read_uint64(bs, offset + 0x30, &rsrc_fork_length);
 481    if (ret < 0) {
 482        goto fail;
 483    }
 484    if (rsrc_fork_offset >= offset ||
 485        rsrc_fork_length > offset - rsrc_fork_offset) {
 486        ret = -EINVAL;
 487        goto fail;
 488    }
 489    /* offset of property list (XMLOffset) */
 490    ret = read_uint64(bs, offset + 0xd8, &plist_xml_offset);
 491    if (ret < 0) {
 492        goto fail;
 493    }
 494    ret = read_uint64(bs, offset + 0xe0, &plist_xml_length);
 495    if (ret < 0) {
 496        goto fail;
 497    }
 498    if (plist_xml_offset >= offset ||
 499        plist_xml_length > offset - plist_xml_offset) {
 500        ret = -EINVAL;
 501        goto fail;
 502    }
 503    ret = read_uint64(bs, offset + 0x1ec, (uint64_t *)&bs->total_sectors);
 504    if (ret < 0) {
 505        goto fail;
 506    }
 507    if (bs->total_sectors < 0) {
 508        ret = -EINVAL;
 509        goto fail;
 510    }
 511    if (rsrc_fork_length != 0) {
 512        ret = dmg_read_resource_fork(bs, &ds,
 513                                     rsrc_fork_offset, rsrc_fork_length);
 514        if (ret < 0) {
 515            goto fail;
 516        }
 517    } else if (plist_xml_length != 0) {
 518        ret = dmg_read_plist_xml(bs, &ds, plist_xml_offset, plist_xml_length);
 519        if (ret < 0) {
 520            goto fail;
 521        }
 522    } else {
 523        ret = -EINVAL;
 524        goto fail;
 525    }
 526
 527    /* initialize zlib engine */
 528    s->compressed_chunk = qemu_try_blockalign(bs->file->bs,
 529                                              ds.max_compressed_size + 1);
 530    s->uncompressed_chunk = qemu_try_blockalign(bs->file->bs,
 531                                                512 * ds.max_sectors_per_chunk);
 532    if (s->compressed_chunk == NULL || s->uncompressed_chunk == NULL) {
 533        ret = -ENOMEM;
 534        goto fail;
 535    }
 536
 537    if (inflateInit(&s->zstream) != Z_OK) {
 538        ret = -EINVAL;
 539        goto fail;
 540    }
 541
 542    s->current_chunk = s->n_chunks;
 543
 544    qemu_co_mutex_init(&s->lock);
 545    return 0;
 546
 547fail:
 548    g_free(s->types);
 549    g_free(s->offsets);
 550    g_free(s->lengths);
 551    g_free(s->sectors);
 552    g_free(s->sectorcounts);
 553    qemu_vfree(s->compressed_chunk);
 554    qemu_vfree(s->uncompressed_chunk);
 555    return ret;
 556}
 557
 558static void dmg_refresh_limits(BlockDriverState *bs, Error **errp)
 559{
 560    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
 561}
 562
 563static inline int is_sector_in_chunk(BDRVDMGState *s,
 564                uint32_t chunk_num, uint64_t sector_num)
 565{
 566    if (chunk_num >= s->n_chunks || s->sectors[chunk_num] > sector_num ||
 567            s->sectors[chunk_num] + s->sectorcounts[chunk_num] <= sector_num) {
 568        return 0;
 569    } else {
 570        return -1;
 571    }
 572}
 573
 574static inline uint32_t search_chunk(BDRVDMGState *s, uint64_t sector_num)
 575{
 576    /* binary search */
 577    uint32_t chunk1 = 0, chunk2 = s->n_chunks, chunk3;
 578    while (chunk1 <= chunk2) {
 579        chunk3 = (chunk1 + chunk2) / 2;
 580        if (s->sectors[chunk3] > sector_num) {
 581            if (chunk3 == 0) {
 582                goto err;
 583            }
 584            chunk2 = chunk3 - 1;
 585        } else if (s->sectors[chunk3] + s->sectorcounts[chunk3] > sector_num) {
 586            return chunk3;
 587        } else {
 588            chunk1 = chunk3 + 1;
 589        }
 590    }
 591err:
 592    return s->n_chunks; /* error */
 593}
 594
 595static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
 596{
 597    BDRVDMGState *s = bs->opaque;
 598
 599    if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
 600        int ret;
 601        uint32_t chunk = search_chunk(s, sector_num);
 602
 603        if (chunk >= s->n_chunks) {
 604            return -1;
 605        }
 606
 607        s->current_chunk = s->n_chunks;
 608        switch (s->types[chunk]) { /* block entry type */
 609        case UDZO: { /* zlib compressed */
 610            /* we need to buffer, because only the chunk as whole can be
 611             * inflated. */
 612            ret = bdrv_pread(bs->file, s->offsets[chunk],
 613                             s->compressed_chunk, s->lengths[chunk]);
 614            if (ret != s->lengths[chunk]) {
 615                return -1;
 616            }
 617
 618            s->zstream.next_in = s->compressed_chunk;
 619            s->zstream.avail_in = s->lengths[chunk];
 620            s->zstream.next_out = s->uncompressed_chunk;
 621            s->zstream.avail_out = 512 * s->sectorcounts[chunk];
 622            ret = inflateReset(&s->zstream);
 623            if (ret != Z_OK) {
 624                return -1;
 625            }
 626            ret = inflate(&s->zstream, Z_FINISH);
 627            if (ret != Z_STREAM_END ||
 628                s->zstream.total_out != 512 * s->sectorcounts[chunk]) {
 629                return -1;
 630            }
 631            break; }
 632        case UDBZ: /* bzip2 compressed */
 633            if (!dmg_uncompress_bz2) {
 634                break;
 635            }
 636            /* we need to buffer, because only the chunk as whole can be
 637             * inflated. */
 638            ret = bdrv_pread(bs->file, s->offsets[chunk],
 639                             s->compressed_chunk, s->lengths[chunk]);
 640            if (ret != s->lengths[chunk]) {
 641                return -1;
 642            }
 643
 644            ret = dmg_uncompress_bz2((char *)s->compressed_chunk,
 645                                     (unsigned int) s->lengths[chunk],
 646                                     (char *)s->uncompressed_chunk,
 647                                     (unsigned int)
 648                                         (512 * s->sectorcounts[chunk]));
 649            if (ret < 0) {
 650                return ret;
 651            }
 652            break;
 653        case ULFO:
 654            if (!dmg_uncompress_lzfse) {
 655                break;
 656            }
 657            /* we need to buffer, because only the chunk as whole can be
 658             * inflated. */
 659            ret = bdrv_pread(bs->file, s->offsets[chunk],
 660                             s->compressed_chunk, s->lengths[chunk]);
 661            if (ret != s->lengths[chunk]) {
 662                return -1;
 663            }
 664
 665            ret = dmg_uncompress_lzfse((char *)s->compressed_chunk,
 666                                       (unsigned int) s->lengths[chunk],
 667                                       (char *)s->uncompressed_chunk,
 668                                       (unsigned int)
 669                                           (512 * s->sectorcounts[chunk]));
 670            if (ret < 0) {
 671                return ret;
 672            }
 673            break;
 674        case UDRW: /* copy */
 675            ret = bdrv_pread(bs->file, s->offsets[chunk],
 676                             s->uncompressed_chunk, s->lengths[chunk]);
 677            if (ret != s->lengths[chunk]) {
 678                return -1;
 679            }
 680            break;
 681        case UDZE: /* zeros */
 682        case UDIG: /* ignore */
 683            /* see dmg_read, it is treated specially. No buffer needs to be
 684             * pre-filled, the zeroes can be set directly. */
 685            break;
 686        }
 687        s->current_chunk = chunk;
 688    }
 689    return 0;
 690}
 691
 692static int coroutine_fn
 693dmg_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
 694              QEMUIOVector *qiov, BdrvRequestFlags flags)
 695{
 696    BDRVDMGState *s = bs->opaque;
 697    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
 698    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
 699    int ret, i;
 700
 701    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
 702    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
 703
 704    qemu_co_mutex_lock(&s->lock);
 705
 706    for (i = 0; i < nb_sectors; i++) {
 707        uint32_t sector_offset_in_chunk;
 708        void *data;
 709
 710        if (dmg_read_chunk(bs, sector_num + i) != 0) {
 711            ret = -EIO;
 712            goto fail;
 713        }
 714        /* Special case: current chunk is all zeroes. Do not perform a memcpy as
 715         * s->uncompressed_chunk may be too small to cover the large all-zeroes
 716         * section. dmg_read_chunk is called to find s->current_chunk */
 717        if (s->types[s->current_chunk] == UDZE
 718            || s->types[s->current_chunk] == UDIG) { /* all zeroes block entry */
 719            qemu_iovec_memset(qiov, i * 512, 0, 512);
 720            continue;
 721        }
 722        sector_offset_in_chunk = sector_num + i - s->sectors[s->current_chunk];
 723        data = s->uncompressed_chunk + sector_offset_in_chunk * 512;
 724        qemu_iovec_from_buf(qiov, i * 512, data, 512);
 725    }
 726
 727    ret = 0;
 728fail:
 729    qemu_co_mutex_unlock(&s->lock);
 730    return ret;
 731}
 732
 733static void dmg_close(BlockDriverState *bs)
 734{
 735    BDRVDMGState *s = bs->opaque;
 736
 737    g_free(s->types);
 738    g_free(s->offsets);
 739    g_free(s->lengths);
 740    g_free(s->sectors);
 741    g_free(s->sectorcounts);
 742    qemu_vfree(s->compressed_chunk);
 743    qemu_vfree(s->uncompressed_chunk);
 744
 745    inflateEnd(&s->zstream);
 746}
 747
 748static BlockDriver bdrv_dmg = {
 749    .format_name    = "dmg",
 750    .instance_size  = sizeof(BDRVDMGState),
 751    .bdrv_probe     = dmg_probe,
 752    .bdrv_open      = dmg_open,
 753    .bdrv_refresh_limits = dmg_refresh_limits,
 754    .bdrv_child_perm     = bdrv_default_perms,
 755    .bdrv_co_preadv = dmg_co_preadv,
 756    .bdrv_close     = dmg_close,
 757    .is_format      = true,
 758};
 759
 760static void bdrv_dmg_init(void)
 761{
 762    bdrv_register(&bdrv_dmg);
 763}
 764
 765block_init(bdrv_dmg_init);
 766