Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches:

- vmdk: Support for blockdev-create
- block: Apply auto-read-only for ro-whitelist drivers
- virtio-scsi: Fixes related to attaching/detaching iothreads
- scsi-disk: Fixed erroneously detected multipath setup with multiple
  disks created with node-names. Added device_id property.
- block: Fix hangs in synchronous APIs with iothreads
- block: Fix invalidate_cache error path for parent activation
- block-backend, mirror, qcow2, vpc, vdi, qemu-iotests:
  Minor fixes and code improvements

# gpg: Signature made Fri 01 Feb 2019 15:23:10 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (27 commits)
  scsi-disk: Add device_id property
  scsi-disk: Don't use empty string as device id
  qtest.py: Wait for the result of qtest commands
  block: Fix invalidate_cache error path for parent activation
  iotests/236: fix transaction kwarg order
  iotests: Filter second BLOCK_JOB_ERROR from 229
  virtio-scsi: Forbid devices with different iothreads sharing a blockdev
  scsi-disk: Acquire the AioContext in scsi_*_realize()
  virtio-scsi: Move BlockBackend back to the main AioContext on unplug
  block: Eliminate the S_1KiB, S_2KiB, ... macros
  block: Remove blk_attach_dev_legacy() / legacy_dev code
  block: Apply auto-read-only for ro-whitelist drivers
  uuid: Make qemu_uuid_bswap() take and return a QemuUUID
  block/vdi: Don't take address of fields in packed structs
  block/vpc: Don't take address of fields in packed structs
  vmdk: Reject excess extents in blockdev-create
  iotests: Add VMDK tests for blockdev-create
  iotests: Filter cid numbers in VMDK extent info
  vmdk: Implement .bdrv_co_create callback
  vmdk: Refactor vmdk_create_extent
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2019-02-01 17:58:27 +00:00
44 changed files with 1936 additions and 422 deletions
+18 -9
View File
@@ -1438,13 +1438,19 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
bs->read_only = !(bs->open_flags & BDRV_O_RDWR);
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
error_setg(errp,
!bs->read_only && bdrv_is_whitelisted(drv, true)
? "Driver '%s' can only be used for read-only devices"
: "Driver '%s' is not whitelisted",
drv->format_name);
ret = -ENOTSUP;
goto fail_opts;
if (!bs->read_only && bdrv_is_whitelisted(drv, true)) {
ret = bdrv_apply_auto_read_only(bs, NULL, NULL);
} else {
ret = -ENOTSUP;
}
if (ret < 0) {
error_setg(errp,
!bs->read_only && bdrv_is_whitelisted(drv, true)
? "Driver '%s' can only be used for read-only devices"
: "Driver '%s' is not whitelisted",
drv->format_name);
goto fail_opts;
}
}
/* bdrv_new() and bdrv_close() make it so */
@@ -3725,6 +3731,7 @@ static void bdrv_check_co_entry(void *opaque)
{
CheckCo *cco = opaque;
cco->ret = bdrv_co_check(cco->bs, cco->res, cco->fix);
aio_wait_kick();
}
int bdrv_check(BlockDriverState *bs,
@@ -3743,7 +3750,7 @@ int bdrv_check(BlockDriverState *bs,
bdrv_check_co_entry(&cco);
} else {
co = qemu_coroutine_create(bdrv_check_co_entry, &cco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, cco.ret == -EINPROGRESS);
}
@@ -4690,6 +4697,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
if (parent->role->activate) {
parent->role->activate(parent, &local_err);
if (local_err) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
@@ -4708,6 +4716,7 @@ static void coroutine_fn bdrv_invalidate_cache_co_entry(void *opaque)
InvalidateCacheCo *ico = opaque;
bdrv_co_invalidate_cache(ico->bs, ico->errp);
ico->done = true;
aio_wait_kick();
}
void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
@@ -4724,7 +4733,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
bdrv_invalidate_cache_co_entry(&ico);
} else {
co = qemu_coroutine_create(bdrv_invalidate_cache_co_entry, &ico);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, !ico.done);
}
}
+2 -3
View File
@@ -295,10 +295,9 @@ static void blk_log_writes_refresh_filename(BlockDriverState *bs,
qdict_put_str(opts, "driver", "blklogwrites");
qobject_ref(bs->file->bs->full_open_options);
qdict_put_obj(opts, "file", QOBJECT(bs->file->bs->full_open_options));
qdict_put(opts, "file", bs->file->bs->full_open_options);
qobject_ref(s->log_file->bs->full_open_options);
qdict_put_obj(opts, "log",
QOBJECT(s->log_file->bs->full_open_options));
qdict_put(opts, "log", s->log_file->bs->full_open_options);
qdict_put_int(opts, "log-sector-size", s->sectorsize);
bs->full_open_options = opts;
+14 -45
View File
@@ -47,9 +47,7 @@ struct BlockBackend {
QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
BlockBackendPublic public;
void *dev; /* attached device model, if any */
bool legacy_dev; /* true if dev is not a DeviceState */
/* TODO change to DeviceState when all users are qdevified */
DeviceState *dev; /* attached device model, if any */
const BlockDevOps *dev_ops;
void *dev_opaque;
@@ -836,7 +834,11 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
*shared_perm = blk->shared_perm;
}
static int blk_do_attach_dev(BlockBackend *blk, void *dev)
/*
* Attach device model @dev to @blk.
* Return 0 on success, -EBUSY when a device model is attached already.
*/
int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
{
if (blk->dev) {
return -EBUSY;
@@ -851,40 +853,16 @@ static int blk_do_attach_dev(BlockBackend *blk, void *dev)
blk_ref(blk);
blk->dev = dev;
blk->legacy_dev = false;
blk_iostatus_reset(blk);
return 0;
}
/*
* Attach device model @dev to @blk.
* Return 0 on success, -EBUSY when a device model is attached already.
*/
int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
{
return blk_do_attach_dev(blk, dev);
}
/*
* Attach device model @dev to @blk.
* @blk must not have a device model attached already.
* TODO qdevified devices don't use this, remove when devices are qdevified
*/
void blk_attach_dev_legacy(BlockBackend *blk, void *dev)
{
if (blk_do_attach_dev(blk, dev) < 0) {
abort();
}
blk->legacy_dev = true;
}
/*
* Detach device model @dev from @blk.
* @dev must be currently attached to @blk.
*/
void blk_detach_dev(BlockBackend *blk, void *dev)
/* TODO change to DeviceState *dev when all users are qdevified */
void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
{
assert(blk->dev == dev);
blk->dev = NULL;
@@ -898,8 +876,7 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
/*
* Return the device model attached to @blk if any, else null.
*/
void *blk_get_attached_dev(BlockBackend *blk)
/* TODO change to return DeviceState * when all users are qdevified */
DeviceState *blk_get_attached_dev(BlockBackend *blk)
{
return blk->dev;
}
@@ -908,10 +885,7 @@ void *blk_get_attached_dev(BlockBackend *blk)
* device attached to the BlockBackend. */
char *blk_get_attached_dev_id(BlockBackend *blk)
{
DeviceState *dev;
assert(!blk->legacy_dev);
dev = blk->dev;
DeviceState *dev = blk->dev;
if (!dev) {
return g_strdup("");
@@ -949,11 +923,6 @@ BlockBackend *blk_by_dev(void *dev)
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
void *opaque)
{
/* All drivers that use blk_set_dev_ops() are qdevified and we want to keep
* it that way, so we can assume blk->dev, if present, is a DeviceState if
* blk->dev_ops is set. Non-device users may use dev_ops without device. */
assert(!blk->legacy_dev);
blk->dev_ops = ops;
blk->dev_opaque = opaque;
@@ -979,8 +948,6 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
bool tray_was_open, tray_is_open;
Error *local_err = NULL;
assert(!blk->legacy_dev);
tray_was_open = blk_dev_is_tray_open(blk);
blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err);
if (local_err) {
@@ -1220,6 +1187,7 @@ static void blk_read_entry(void *opaque)
rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, qiov->size,
qiov, rwco->flags);
aio_wait_kick();
}
static void blk_write_entry(void *opaque)
@@ -1229,6 +1197,7 @@ static void blk_write_entry(void *opaque)
rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, qiov->size,
qiov, rwco->flags);
aio_wait_kick();
}
static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
@@ -1540,6 +1509,7 @@ static void blk_ioctl_entry(void *opaque)
rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
qiov->iov[0].iov_base);
aio_wait_kick();
}
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
@@ -1586,6 +1556,7 @@ static void blk_flush_entry(void *opaque)
{
BlkRwCo *rwco = opaque;
rwco->ret = blk_co_flush(rwco->blk);
aio_wait_kick();
}
int blk_flush(BlockBackend *blk)
@@ -1779,9 +1750,6 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
BlockDriverState *bs = blk_bs(blk);
char *id;
/* blk_eject is only called by qdevified devices */
assert(!blk->legacy_dev);
if (bs) {
bdrv_eject(bs, eject_flag);
}
@@ -2018,6 +1986,7 @@ static void blk_pdiscard_entry(void *opaque)
QEMUIOVector *qiov = rwco->iobuf;
rwco->ret = blk_co_pdiscard(rwco->blk, rwco->offset, qiov->size);
aio_wait_kick();
}
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
+7 -1
View File
@@ -806,6 +806,7 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
rwco->qiov->size, rwco->qiov,
rwco->flags);
}
aio_wait_kick();
}
/*
@@ -2279,6 +2280,7 @@ static void coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
data->offset, data->bytes,
data->pnum, data->map, data->file);
data->done = true;
aio_wait_kick();
}
/*
@@ -2438,6 +2440,7 @@ static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
{
BdrvVmstateCo *co = opaque;
co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
aio_wait_kick();
}
static inline int
@@ -2559,6 +2562,7 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque)
FlushCo *rwco = opaque;
rwco->ret = bdrv_co_flush(rwco->bs);
aio_wait_kick();
}
int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
@@ -2704,6 +2708,7 @@ static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
DiscardCo *rwco = opaque;
rwco->ret = bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
aio_wait_kick();
}
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
@@ -3217,6 +3222,7 @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
TruncateCo *tco = opaque;
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->prealloc,
tco->errp);
aio_wait_kick();
}
int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
@@ -3236,7 +3242,7 @@ int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
bdrv_truncate_co_entry(&tco);
} else {
co = qemu_coroutine_create(bdrv_truncate_co_entry, &tco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(child->bs, co);
BDRV_POLL_WHILE(child->bs, tco.ret == NOT_DONE);
}
+11
View File
@@ -1612,6 +1612,14 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
goto fail;
}
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
BLK_PERM_CONSISTENT_READ,
errp);
if (ret < 0) {
goto fail;
}
/* Required permissions are already taken with blk_new() */
block_job_add_bdrv(&s->common, "target", target, 0, BLK_PERM_ALL,
&error_abort);
@@ -1649,6 +1657,9 @@ fail:
g_free(s->replaces);
blk_unref(s->target);
bs_opaque->job = NULL;
if (s->dirty_bitmap) {
bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
}
job_early_fail(&s->common.job);
}
+1
View File
@@ -119,6 +119,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
s->quit = true;
nbd_recv_coroutines_wake_all(s);
s->read_reply_co = NULL;
aio_wait_kick();
}
static int nbd_co_send_request(BlockDriverState *bs,
+1
View File
@@ -390,6 +390,7 @@ static void nvme_cmd_sync_cb(void *opaque, int ret)
{
int *pret = opaque;
*pret = ret;
aio_wait_kick();
}
static int nvme_cmd_sync(BlockDriverState *bs, NVMeQueuePair *q,
+3
View File
@@ -368,6 +368,9 @@ static int alloc_refcount_block(BlockDriverState *bs,
return new_block;
}
/* The offset must fit in the offset field of the refcount table entry */
assert((new_block & REFT_OFFSET_MASK) == new_block);
/* If we're allocating the block at offset 0 then something is wrong */
if (new_block == 0) {
qcow2_signal_corruption(bs, true, -1, -1, "Preventing invalid "
+1
View File
@@ -1671,6 +1671,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
/* From bdrv_co_create. */
qcow2_open_entry(&qoc);
} else {
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
qemu_coroutine_enter(qemu_coroutine_create(qcow2_open_entry, &qoc));
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
}
+5 -5
View File
@@ -50,11 +50,11 @@
/* 8 MB refcount table is enough for 2 PB images at 64k cluster size
* (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
#define QCOW_MAX_REFTABLE_SIZE S_8MiB
#define QCOW_MAX_REFTABLE_SIZE (8 * MiB)
/* 32 MB L1 table is enough for 2 PB images at 64k cluster size
* (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
#define QCOW_MAX_L1_SIZE S_32MiB
#define QCOW_MAX_L1_SIZE (32 * MiB)
/* Allow for an average of 1k per snapshot table entry, should be plenty of
* space for snapshot names and IDs */
@@ -81,15 +81,15 @@
#define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
#ifdef CONFIG_LINUX
#define DEFAULT_L2_CACHE_MAX_SIZE S_32MiB
#define DEFAULT_L2_CACHE_MAX_SIZE (32 * MiB)
#define DEFAULT_CACHE_CLEAN_INTERVAL 600 /* seconds */
#else
#define DEFAULT_L2_CACHE_MAX_SIZE S_8MiB
#define DEFAULT_L2_CACHE_MAX_SIZE (8 * MiB)
/* Cache clean interval is currently available only on Linux, so must be 0 */
#define DEFAULT_CACHE_CLEAN_INTERVAL 0
#endif
#define DEFAULT_CLUSTER_SIZE S_64KiB
#define DEFAULT_CLUSTER_SIZE 65536
#define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
#define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
+1
View File
@@ -559,6 +559,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
if (qemu_in_coroutine()) {
bdrv_qed_open_entry(&qoc);
} else {
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
}
+35 -22
View File
@@ -85,7 +85,8 @@
#define BLOCK_OPT_STATIC "static"
#define SECTOR_SIZE 512
#define DEFAULT_CLUSTER_SIZE S_1MiB
#define DEFAULT_CLUSTER_SIZE 1048576
/* Note: can't use 1 * MiB, because it's passed to stringify() */
#if defined(CONFIG_VDI_DEBUG)
#define VDI_DEBUG 1
@@ -203,10 +204,10 @@ static void vdi_header_to_cpu(VdiHeader *header)
header->block_extra = le32_to_cpu(header->block_extra);
header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
qemu_uuid_bswap(&header->uuid_image);
qemu_uuid_bswap(&header->uuid_last_snap);
qemu_uuid_bswap(&header->uuid_link);
qemu_uuid_bswap(&header->uuid_parent);
header->uuid_image = qemu_uuid_bswap(header->uuid_image);
header->uuid_last_snap = qemu_uuid_bswap(header->uuid_last_snap);
header->uuid_link = qemu_uuid_bswap(header->uuid_link);
header->uuid_parent = qemu_uuid_bswap(header->uuid_parent);
}
static void vdi_header_to_le(VdiHeader *header)
@@ -227,15 +228,16 @@ static void vdi_header_to_le(VdiHeader *header)
header->block_extra = cpu_to_le32(header->block_extra);
header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
qemu_uuid_bswap(&header->uuid_image);
qemu_uuid_bswap(&header->uuid_last_snap);
qemu_uuid_bswap(&header->uuid_link);
qemu_uuid_bswap(&header->uuid_parent);
header->uuid_image = qemu_uuid_bswap(header->uuid_image);
header->uuid_last_snap = qemu_uuid_bswap(header->uuid_last_snap);
header->uuid_link = qemu_uuid_bswap(header->uuid_link);
header->uuid_parent = qemu_uuid_bswap(header->uuid_parent);
}
static void vdi_header_print(VdiHeader *header)
{
char uuid[37];
char uuidstr[37];
QemuUUID uuid;
logout("text %s", header->text);
logout("signature 0x%08x\n", header->signature);
logout("header size 0x%04x\n", header->header_size);
@@ -254,14 +256,18 @@ static void vdi_header_print(VdiHeader *header)
logout("block extra 0x%04x\n", header->block_extra);
logout("blocks tot. 0x%04x\n", header->blocks_in_image);
logout("blocks all. 0x%04x\n", header->blocks_allocated);
qemu_uuid_unparse(&header->uuid_image, uuid);
logout("uuid image %s\n", uuid);
qemu_uuid_unparse(&header->uuid_last_snap, uuid);
logout("uuid snap %s\n", uuid);
qemu_uuid_unparse(&header->uuid_link, uuid);
logout("uuid link %s\n", uuid);
qemu_uuid_unparse(&header->uuid_parent, uuid);
logout("uuid parent %s\n", uuid);
uuid = header->uuid_image;
qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid image %s\n", uuidstr);
uuid = header->uuid_last_snap;
qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid snap %s\n", uuidstr);
uuid = header->uuid_link;
qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid link %s\n", uuidstr);
uuid = header->uuid_parent;
qemu_uuid_unparse(&uuid, uuidstr);
logout("uuid parent %s\n", uuidstr);
}
static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
@@ -368,6 +374,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
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);
@@ -395,6 +402,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
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
@@ -444,11 +454,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
(uint64_t)header.blocks_in_image * header.block_size);
ret = -ENOTSUP;
goto fail;
} else if (!qemu_uuid_is_null(&header.uuid_link)) {
} else if (!qemu_uuid_is_null(&uuid_link)) {
error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
ret = -ENOTSUP;
goto fail;
} else if (!qemu_uuid_is_null(&header.uuid_parent)) {
} else if (!qemu_uuid_is_null(&uuid_parent)) {
error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
ret = -ENOTSUP;
goto fail;
@@ -733,6 +743,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
BlockDriverState *bs_file = NULL;
BlockBackend *blk = NULL;
uint32_t *bmap = NULL;
QemuUUID uuid;
assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
vdi_opts = &create_options->u.vdi;
@@ -819,8 +830,10 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
if (image_type == VDI_TYPE_STATIC) {
header.blocks_allocated = blocks;
}
qemu_uuid_generate(&header.uuid_image);
qemu_uuid_generate(&header.uuid_last_snap);
qemu_uuid_generate(&uuid);
header.uuid_image = uuid;
qemu_uuid_generate(&uuid);
header.uuid_last_snap = uuid;
/* There is no need to set header.uuid_link or header.uuid_parent here. */
if (VDI_DEBUG) {
vdi_header_print(&header);
+384 -154
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -979,6 +979,7 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
int64_t total_size;
int disk_type;
int ret = -EIO;
QemuUUID uuid;
assert(opts->driver == BLOCKDEV_DRIVER_VPC);
vpc_opts = &opts->u.vpc;
@@ -1062,7 +1063,8 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
footer->type = cpu_to_be32(disk_type);
qemu_uuid_generate(&footer->uuid);
qemu_uuid_generate(&uuid);
footer->uuid = uuid;
footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
+2 -4
View File
@@ -30,8 +30,7 @@ void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *guid,
* first, since that's what the guest expects
*/
g_array_set_size(guid, VMGENID_FW_CFG_SIZE - ARRAY_SIZE(guid_le.data));
guid_le = vms->guid;
qemu_uuid_bswap(&guid_le);
guid_le = qemu_uuid_bswap(vms->guid);
/* The GUID is written at a fixed offset into the fw_cfg file
* in order to implement the "OVMF SDT Header probe suppressor"
* see docs/specs/vmgenid.txt for more details
@@ -149,8 +148,7 @@ static void vmgenid_update_guest(VmGenIdState *vms)
* however, will expect the fields to be little-endian.
* Perform a byte swap immediately before writing.
*/
guid_le = vms->guid;
qemu_uuid_bswap(&guid_le);
guid_le = qemu_uuid_bswap(vms->guid);
/* The GUID is written at a fixed offset into the fw_cfg file
* in order to implement the "OVMF SDT Header probe suppressor"
* see docs/specs/vmgenid.txt for more details.
+43 -16
View File
@@ -104,6 +104,7 @@ typedef struct SCSIDiskState
char *serial;
char *vendor;
char *product;
char *device_id;
bool tray_open;
bool tray_locked;
/*
@@ -642,22 +643,19 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
case 0x83: /* Device identification page, mandatory */
{
const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
int max_len = s->serial ? 20 : 255 - 8;
int id_len = strlen(str);
int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0;
if (id_len > max_len) {
id_len = max_len;
}
DPRINTF("Inquiry EVPD[Device identification] "
"buffer size %zd\n", req->cmd.xfer);
outbuf[buflen++] = 0x2; /* ASCII */
outbuf[buflen++] = 0; /* not officially assigned */
outbuf[buflen++] = 0; /* reserved */
outbuf[buflen++] = id_len; /* length of data following */
memcpy(outbuf + buflen, str, id_len);
buflen += id_len;
if (id_len) {
outbuf[buflen++] = 0x2; /* ASCII */
outbuf[buflen++] = 0; /* not officially assigned */
outbuf[buflen++] = 0; /* reserved */
outbuf[buflen++] = id_len; /* length of data following */
memcpy(outbuf + buflen, s->device_id, id_len);
buflen += id_len;
}
if (s->qdev.wwn) {
outbuf[buflen++] = 0x1; /* Binary */
@@ -2361,6 +2359,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
if (!s->vendor) {
s->vendor = g_strdup("QEMU");
}
if (!s->device_id) {
if (s->serial) {
s->device_id = g_strdup_printf("%.20s", s->serial);
} else {
const char *str = blk_name(s->qdev.conf.blk);
if (str && *str) {
s->device_id = g_strdup(str);
}
}
}
if (blk_is_sg(s->qdev.conf.blk)) {
error_setg(errp, "unwanted /dev/sg*");
@@ -2381,10 +2389,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
AioContext *ctx = NULL;
/* can happen for devices without drive. The error message for missing
* backend will be issued in scsi_realize
*/
if (s->qdev.conf.blk) {
ctx = blk_get_aio_context(s->qdev.conf.blk);
aio_context_acquire(ctx);
blkconf_blocksizes(&s->qdev.conf);
}
s->qdev.blocksize = s->qdev.conf.logical_block_size;
@@ -2393,11 +2404,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
s->product = g_strdup("QEMU HARDDISK");
}
scsi_realize(&s->qdev, errp);
if (ctx) {
aio_context_release(ctx);
}
}
static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
AioContext *ctx;
int ret;
if (!dev->conf.blk) {
@@ -2408,6 +2423,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
assert(ret == 0);
}
ctx = blk_get_aio_context(dev->conf.blk);
aio_context_acquire(ctx);
s->qdev.blocksize = 2048;
s->qdev.type = TYPE_ROM;
s->features |= 1 << SCSI_DISK_F_REMOVABLE;
@@ -2415,6 +2432,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
s->product = g_strdup("QEMU CD-ROM");
}
scsi_realize(&s->qdev, errp);
aio_context_release(ctx);
}
static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
@@ -2553,6 +2571,7 @@ static int get_device_type(SCSIDiskState *s)
static void scsi_block_realize(SCSIDevice *dev, Error **errp)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
AioContext *ctx;
int sg_version;
int rc;
@@ -2567,6 +2586,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
"be removed in a future version");
}
ctx = blk_get_aio_context(s->qdev.conf.blk);
aio_context_acquire(ctx);
/* check we are using a driver managing SG_IO (version 3 and after) */
rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
if (rc < 0) {
@@ -2574,18 +2596,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
if (rc != -EPERM) {
error_append_hint(errp, "Is this a SCSI device?\n");
}
return;
goto out;
}
if (sg_version < 30000) {
error_setg(errp, "scsi generic interface too old");
return;
goto out;
}
/* get device type from INQUIRY data */
rc = get_device_type(s);
if (rc < 0) {
error_setg(errp, "INQUIRY failed");
return;
goto out;
}
/* Make a guess for the block size, we'll fix it when the guest sends.
@@ -2605,6 +2627,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
scsi_realize(&s->qdev, errp);
scsi_generic_read_device_inquiry(&s->qdev);
out:
aio_context_release(ctx);
}
typedef struct SCSIBlockReq {
@@ -2902,7 +2927,9 @@ static const TypeInfo scsi_disk_base_info = {
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
DEFINE_PROP_STRING("product", SCSIDiskState, product)
DEFINE_PROP_STRING("product", SCSIDiskState, product), \
DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
static Property scsi_hd_properties[] = {
DEFINE_SCSI_DISK_PROPERTIES(),
+13
View File
@@ -791,9 +791,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
SCSIDevice *sd = SCSI_DEVICE(dev);
if (s->ctx && !s->dataplane_fenced) {
AioContext *ctx;
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
return;
}
ctx = blk_get_aio_context(sd->conf.blk);
if (ctx != s->ctx && ctx != qemu_get_aio_context()) {
error_setg(errp, "Cannot attach a blockdev that is using "
"a different iothread");
return;
}
virtio_scsi_acquire(s);
blk_set_aio_context(sd->conf.blk, s->ctx);
virtio_scsi_release(s);
@@ -824,6 +831,12 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
virtio_scsi_release(s);
}
if (s->ctx) {
virtio_scsi_acquire(s);
blk_set_aio_context(sd->conf.blk, qemu_get_aio_context());
virtio_scsi_release(s);
}
qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
}
-73
View File
@@ -17,77 +17,4 @@
#define PiB (INT64_C(1) << 50)
#define EiB (INT64_C(1) << 60)
/*
* The following lookup table is intended to be used when a literal string of
* the number of bytes is required (for example if it needs to be stringified).
* It can also be used for generic shortcuts of power-of-two sizes.
* This table is generated using the AWK script below:
*
* BEGIN {
* suffix="KMGTPE";
* for(i=10; i<64; i++) {
* val=2**i;
* s=substr(suffix, int(i/10), 1);
* n=2**(i%10);
* pad=21-int(log(n)/log(10));
* printf("#define S_%d%siB %*d\n", n, s, pad, val);
* }
* }
*/
#define S_1KiB 1024
#define S_2KiB 2048
#define S_4KiB 4096
#define S_8KiB 8192
#define S_16KiB 16384
#define S_32KiB 32768
#define S_64KiB 65536
#define S_128KiB 131072
#define S_256KiB 262144
#define S_512KiB 524288
#define S_1MiB 1048576
#define S_2MiB 2097152
#define S_4MiB 4194304
#define S_8MiB 8388608
#define S_16MiB 16777216
#define S_32MiB 33554432
#define S_64MiB 67108864
#define S_128MiB 134217728
#define S_256MiB 268435456
#define S_512MiB 536870912
#define S_1GiB 1073741824
#define S_2GiB 2147483648
#define S_4GiB 4294967296
#define S_8GiB 8589934592
#define S_16GiB 17179869184
#define S_32GiB 34359738368
#define S_64GiB 68719476736
#define S_128GiB 137438953472
#define S_256GiB 274877906944
#define S_512GiB 549755813888
#define S_1TiB 1099511627776
#define S_2TiB 2199023255552
#define S_4TiB 4398046511104
#define S_8TiB 8796093022208
#define S_16TiB 17592186044416
#define S_32TiB 35184372088832
#define S_64TiB 70368744177664
#define S_128TiB 140737488355328
#define S_256TiB 281474976710656
#define S_512TiB 562949953421312
#define S_1PiB 1125899906842624
#define S_2PiB 2251799813685248
#define S_4PiB 4503599627370496
#define S_8PiB 9007199254740992
#define S_16PiB 18014398509481984
#define S_32PiB 36028797018963968
#define S_64PiB 72057594037927936
#define S_128PiB 144115188075855872
#define S_256PiB 288230376151711744
#define S_512PiB 576460752303423488
#define S_1EiB 1152921504606846976
#define S_2EiB 2305843009213693952
#define S_4EiB 4611686018427387904
#define S_8EiB 9223372036854775808
#endif
+1 -1
View File
@@ -56,6 +56,6 @@ char *qemu_uuid_unparse_strdup(const QemuUUID *uuid);
int qemu_uuid_parse(const char *str, QemuUUID *uuid);
void qemu_uuid_bswap(QemuUUID *uuid);
QemuUUID qemu_uuid_bswap(QemuUUID uuid);
#endif
+2 -3
View File
@@ -110,9 +110,8 @@ void blk_iostatus_disable(BlockBackend *blk);
void blk_iostatus_reset(BlockBackend *blk);
void blk_iostatus_set_err(BlockBackend *blk, int error);
int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
void blk_attach_dev_legacy(BlockBackend *blk, void *dev);
void blk_detach_dev(BlockBackend *blk, void *dev);
void *blk_get_attached_dev(BlockBackend *blk);
void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
DeviceState *blk_get_attached_dev(BlockBackend *blk);
char *blk_get_attached_dev_id(BlockBackend *blk);
BlockBackend *blk_by_dev(void *dev);
BlockBackend *blk_by_qdev_id(const char *id, Error **errp);

Some files were not shown because too many files have changed in this diff Show More