提交 b6e84c97 编写于 作者: P Paolo Bonzini 提交者: Kevin Wolf

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: NPaolo Bonzini <pbonzini@redhat.com>
Acked-by: NStefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 a72f6414
...@@ -243,18 +243,30 @@ typedef struct { ...@@ -243,18 +243,30 @@ typedef struct {
bool done; bool done;
} BdrvCoDrainData; } 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) static void bdrv_co_drain_bh_cb(void *opaque)
{ {
BdrvCoDrainData *data = opaque; BdrvCoDrainData *data = opaque;
Coroutine *co = data->co; Coroutine *co = data->co;
qemu_bh_delete(data->bh); qemu_bh_delete(data->bh);
bdrv_drain(data->bs); bdrv_drain_poll(data->bs);
data->done = true; data->done = true;
qemu_coroutine_enter(co, NULL); 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; BdrvCoDrainData data;
...@@ -288,20 +300,19 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs) ...@@ -288,20 +300,19 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
* not depend on events in other AioContexts. In that case, use * not depend on events in other AioContexts. In that case, use
* bdrv_drain_all() instead. * bdrv_drain_all() instead.
*/ */
void bdrv_drain(BlockDriverState *bs) void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
{ {
bool busy = true; bdrv_drain_recurse(bs);
bdrv_co_yield_to_drain(bs);
}
void bdrv_drain(BlockDriverState *bs)
{
bdrv_drain_recurse(bs); bdrv_drain_recurse(bs);
if (qemu_in_coroutine()) { if (qemu_in_coroutine()) {
bdrv_co_drain(bs); bdrv_co_yield_to_drain(bs);
return; } else {
} bdrv_drain_poll(bs);
while (busy) {
/* Keep iterating */
bdrv_flush_io_queue(bs);
busy = bdrv_requests_pending(bs);
busy |= aio_poll(bdrv_get_aio_context(bs), busy);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册