static int vdi_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVVdiState *s = bs->opaque; VdiHeader header; size_t bmap_size; int ret; Error *local_err = NULL; QemuUUID uuid_link, uuid_parent; bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false, errp); if (!bs->file) { return -EINVAL; } logout("\n"); ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1); if (ret < 0) { goto fail; } vdi_header_to_cpu(&header); if (VDI_DEBUG) { vdi_header_print(&header); } if (header.disk_size > VDI_DISK_SIZE_MAX) { error_setg(errp, "Unsupported VDI image size (size is 0x%" PRIx64 ", max supported is 0x%" PRIx64 ")", header.disk_size, VDI_DISK_SIZE_MAX); ret = -ENOTSUP; goto fail; } uuid_link = header.uuid_link; uuid_parent = header.uuid_parent; if (header.disk_size % SECTOR_SIZE != 0) { /* 'VBoxManage convertfromraw' can create images with odd disk sizes. We accept them but round the disk size to the next multiple of SECTOR_SIZE. */ logout("odd disk size %" PRIu64 " B, round up\n", header.disk_size); header.disk_size = ROUND_UP(header.disk_size, SECTOR_SIZE); } if (header.signature != VDI_SIGNATURE) { error_setg(errp, "Image not in VDI format (bad signature %08" PRIx32 ")", header.signature); ret = -EINVAL; goto fail; } else if (header.version != VDI_VERSION_1_1) { error_setg(errp, "unsupported VDI image (version %" PRIu32 ".%" PRIu32 ")", header.version >> 16, header.version & 0xffff); ret = -ENOTSUP; goto fail; } else if (header.offset_bmap % SECTOR_SIZE != 0) {
static int block_crypto_open_generic(QCryptoBlockFormat format, QemuOptsList *opts_spec, BlockDriverState *bs, QDict *options, int flags, Error **errp) { BlockCrypto *crypto = bs->opaque; QemuOpts *opts = NULL; Error *local_err = NULL; int ret = -EINVAL; QCryptoBlockOpenOptions *open_opts = NULL; unsigned int cflags = 0; bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false, errp); if (!bs->file) { return -EINVAL; } opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { error_propagate(errp, local_err); goto cleanup; } open_opts = block_crypto_open_opts_init(format, opts, errp); if (!open_opts) { goto cleanup; } if (flags & BDRV_O_NO_IO) { cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; } crypto->block = qcrypto_block_open(open_opts, block_crypto_read_func, bs, cflags, errp); if (!crypto->block) { ret = -EIO; goto cleanup; } bs->encrypted = true; bs->valid_key = true; ret = 0; cleanup: qapi_free_QCryptoBlockOpenOptions(open_opts); return ret; }
static int cor_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false, errp); if (!bs->file) { return -EINVAL; } bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED | (BDRV_REQ_FUA & bs->file->bs->supported_write_flags); bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED | ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) & bs->file->bs->supported_zero_flags); return 0; }
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_file, false, errp); if (!bs->file) { return -EINVAL; } block_module_load_one("dmg-bz2"); 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; }