aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2014-08-18 16:07:12 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2014-08-29 16:01:10 +0100
commit8ad4202bf61bc1d124ff26016cfe17cb261cc392 (patch)
tree3a3a924610494044c38c8aa3fd5289501671ab9b
parent2cdff7f620ebd3b5246cf0c0d1f6fa0eededa4ca (diff)
block: acquire AioContext in do_drive_del()
Make drive_del safe for dataplane where another thread may be running the BlockDriverState's AioContext. Note the assumption that AioContext's lifetime exceeds DriveInfo and BlockDriverState. We release AioContext after DriveInfo and BlockDriverState are potentially freed. This is clearly safe with the global AioContext but also with -object iothread and implicit iothreads created by -device virtio-blk-pci,x-data-plane=on (their lifetime is tied to DeviceState, not BlockDriverState). Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--blockdev.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/blockdev.c b/blockdev.c
index eeb414efc0..e37b068e9e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1757,6 +1757,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *id = qdict_get_str(qdict, "id");
BlockDriverState *bs;
+ AioContext *aio_context;
Error *local_err = NULL;
bs = bdrv_find(id);
@@ -1764,9 +1765,14 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
error_report("Device '%s' not found", id);
return -1;
}
+
+ aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
+ aio_context_release(aio_context);
return -1;
}
@@ -1790,6 +1796,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
drive_del(drive_get_by_blockdev(bs));
}
+ aio_context_release(aio_context);
return 0;
}