alloc track: acquire BS AIO context during dropping

ran into this when live-restoring a backup configured for IO-threads,
got the good ol':
> qemu: qemu_mutex_unlock_impl: Operation not permitted
error.

Checking out the history of the related bdrv_backup_top_drop(*bs)
method, we can see that it used to do the AIO context acquiring too,
but in the backup path this was problematic and was changed to be
higher up in the call path in a upstream series from Stefan[0].

That said, this is a completely different code path and it is safe to
do so here. We always run from the main threads's AIO context here
and we call it only indirectly once, guarded by checking for
`s->drop_state == DropNone` and set `s->drop_state = DropRequested`
shortly before we schedule the track_drop() in a bh.

[0]: https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg09139.html

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht 2021-04-06 16:02:56 +02:00
parent aa42ea267e
commit b36e8acc31

View File

@ -34,7 +34,7 @@ new file mode 100644
index 0000000000..b579380279 index 0000000000..b579380279
--- /dev/null --- /dev/null
+++ b/block/alloc-track.c +++ b/block/alloc-track.c
@@ -0,0 +1,342 @@ @@ -0,0 +1,345 @@
+/* +/*
+ * Node to allow backing images to be applied to any node. Assumes a blank + * Node to allow backing images to be applied to any node. Assumes a blank
+ * image to begin with, only new writes are tracked as allocated, thus this + * image to begin with, only new writes are tracked as allocated, thus this
@ -313,6 +313,8 @@ index 0000000000..b579380279
+ aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, opaque); + aio_bh_schedule_oneshot(qemu_get_aio_context(), track_drop, opaque);
+ return; + return;
+ } + }
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+ aio_context_acquire(aio_context);
+ +
+ bdrv_drained_begin(bs); + bdrv_drained_begin(bs);
+ +
@ -324,6 +326,7 @@ index 0000000000..b579380279
+ bdrv_set_backing_hd(bs, NULL, &error_abort); + bdrv_set_backing_hd(bs, NULL, &error_abort);
+ bdrv_drained_end(bs); + bdrv_drained_end(bs);
+ bdrv_unref(bs); + bdrv_unref(bs);
+ aio_context_release(aio_context);
+} +}
+ +
+static int track_change_backing_file(BlockDriverState *bs, +static int track_change_backing_file(BlockDriverState *bs,