diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2013-04-11 15:41:13 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2013-08-19 15:45:34 +0200 |
commit | 88266f5aa70fa71fd5cc20aa4dbeb7a7bd8d2e92 (patch) | |
tree | 59a8cc958f76256abfa69357edc131b69c566d8d /block | |
parent | e1b5c52e04d04bb93546c6e37e8884889d047cb1 (diff) | |
download | qemu-88266f5aa70fa71fd5cc20aa4dbeb7a7bd8d2e92.zip qemu-88266f5aa70fa71fd5cc20aa4dbeb7a7bd8d2e92.tar.gz qemu-88266f5aa70fa71fd5cc20aa4dbeb7a7bd8d2e92.tar.bz2 |
block: stop relying on io_flush() in bdrv_drain_all()
If a block driver has no file descriptors to monitor but there are still
active requests, it can return 1 from .io_flush(). This is used to spin
during synchronous I/O.
Stop relying on .io_flush() and instead check
QLIST_EMPTY(&bs->tracked_requests) to decide whether there are active
requests.
This is the first step in removing .io_flush() so that event loops no
longer need to have the concept of synchronous I/O. Eventually we may
be able to kill synchronous I/O completely by running everything in a
coroutine, but that is future work.
Note this patch moves bs->throttled_reqs initialization to bdrv_new() so
that bdrv_requests_pending(bs) can safely access it. In practice bs is
g_malloc0() so the memory is already zeroed but it's safer to initialize
the queue properly.
We also need to fix up block/stream.c:close_unused_images() to prevent
traversing a dangling pointer while it rearranges the backing file
chain. This is necessary since the new bdrv_drain_all() traverses the
backing file chain.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/stream.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/block/stream.c b/block/stream.c index 7fe9e48..db49b4d 100644 --- a/block/stream.c +++ b/block/stream.c @@ -57,6 +57,11 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, BlockDriverState *intermediate; intermediate = top->backing_hd; + /* Must assign before bdrv_delete() to prevent traversing dangling pointer + * while we delete backing image instances. + */ + top->backing_hd = base; + while (intermediate) { BlockDriverState *unused; @@ -70,7 +75,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, unused->backing_hd = NULL; bdrv_delete(unused); } - top->backing_hd = base; } static void coroutine_fn stream_run(void *opaque) |