aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2016-10-20 15:07:27 +0200
committerKevin Wolf <kwolf@redhat.com>2016-10-27 19:05:23 +0200
commit16a389dc9ecc05e9d8d6ebd3eff6dc98158523e0 (patch)
tree14975d3b373c2269a84f79cf6c1f58e23ca1f1ca
parent61b2450414ee052c8f2561e999852fad0534899e (diff)
block: Introduce .bdrv_co_ioctl() driver callback
This allows drivers to implement ioctls in a coroutine-based way. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
-rw-r--r--block/io.c16
-rw-r--r--include/block/block_int.h2
2 files changed, 12 insertions, 6 deletions
diff --git a/block/io.c b/block/io.c
index 35fdcca747..370c7d8128 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2502,17 +2502,21 @@ int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
BlockAIOCB *acb;
tracked_request_begin(&tracked_req, bs, 0, 0, BDRV_TRACKED_IOCTL);
- if (!drv || !drv->bdrv_aio_ioctl) {
+ if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
co.ret = -ENOTSUP;
goto out;
}
- acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co);
- if (!acb) {
- co.ret = -ENOTSUP;
- goto out;
+ if (drv->bdrv_co_ioctl) {
+ co.ret = drv->bdrv_co_ioctl(bs, req, buf);
+ } else {
+ acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co);
+ if (!acb) {
+ co.ret = -ENOTSUP;
+ goto out;
+ }
+ qemu_coroutine_yield();
}
- qemu_coroutine_yield();
out:
tracked_request_end(&tracked_req);
return co.ret;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 3e79228eb0..e96e9ada57 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -244,6 +244,8 @@ struct BlockDriver {
BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
unsigned long int req, void *buf,
BlockCompletionFunc *cb, void *opaque);
+ int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs,
+ unsigned long int req, void *buf);
/* List of options for creating images, terminated by name == NULL */
QemuOptsList *create_opts;