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>
This commit is contained in:
parent
2cdff7f620
commit
8ad4202bf6
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user