block: extract bdrv_drain_poll/bdrv_co_yield_to_drain from bdrv_drain/bdrv_co_drain
Do not call bdrv_drain_recurse twice in bdrv_co_drain. A small tweak to the logic in Fam's patch, which is harmless since no one implements bdrv_drain anyway. But better get it right. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
a72f641407
commit
b6e84c97ed
35
block/io.c
35
block/io.c
@ -243,18 +243,30 @@ typedef struct {
|
||||
bool done;
|
||||
} BdrvCoDrainData;
|
||||
|
||||
static void bdrv_drain_poll(BlockDriverState *bs)
|
||||
{
|
||||
bool busy = true;
|
||||
|
||||
while (busy) {
|
||||
/* Keep iterating */
|
||||
bdrv_flush_io_queue(bs);
|
||||
busy = bdrv_requests_pending(bs);
|
||||
busy |= aio_poll(bdrv_get_aio_context(bs), busy);
|
||||
}
|
||||
}
|
||||
|
||||
static void bdrv_co_drain_bh_cb(void *opaque)
|
||||
{
|
||||
BdrvCoDrainData *data = opaque;
|
||||
Coroutine *co = data->co;
|
||||
|
||||
qemu_bh_delete(data->bh);
|
||||
bdrv_drain(data->bs);
|
||||
bdrv_drain_poll(data->bs);
|
||||
data->done = true;
|
||||
qemu_coroutine_enter(co, NULL);
|
||||
}
|
||||
|
||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||
static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
|
||||
{
|
||||
BdrvCoDrainData data;
|
||||
|
||||
@ -288,20 +300,19 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||
* not depend on events in other AioContexts. In that case, use
|
||||
* bdrv_drain_all() instead.
|
||||
*/
|
||||
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||
{
|
||||
bdrv_drain_recurse(bs);
|
||||
bdrv_co_yield_to_drain(bs);
|
||||
}
|
||||
|
||||
void bdrv_drain(BlockDriverState *bs)
|
||||
{
|
||||
bool busy = true;
|
||||
|
||||
bdrv_drain_recurse(bs);
|
||||
if (qemu_in_coroutine()) {
|
||||
bdrv_co_drain(bs);
|
||||
return;
|
||||
}
|
||||
while (busy) {
|
||||
/* Keep iterating */
|
||||
bdrv_flush_io_queue(bs);
|
||||
busy = bdrv_requests_pending(bs);
|
||||
busy |= aio_poll(bdrv_get_aio_context(bs), busy);
|
||||
bdrv_co_yield_to_drain(bs);
|
||||
} else {
|
||||
bdrv_drain_poll(bs);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user