qed: Use a coroutine for need_check_timer

This fixes the last place where we degraded from AIO to actual blocking
synchronous I/O requests. Putting it into a coroutine means that instead
of blocking, the coroutine simply yields while doing I/O.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Kevin Wolf 2016-11-18 16:04:59 +01:00
parent 48cc565e76
commit c0e8f98927
1 changed files with 22 additions and 21 deletions

View File

@ -264,28 +264,10 @@ static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
qemu_co_enter_next(&s->allocating_write_reqs);
}
static void qed_clear_need_check(void *opaque, int ret)
{
BDRVQEDState *s = opaque;
if (ret) {
qed_unplug_allocating_write_reqs(s);
return;
}
s->header.features &= ~QED_F_NEED_CHECK;
ret = qed_write_header(s);
(void) ret;
qed_unplug_allocating_write_reqs(s);
ret = bdrv_flush(s->bs);
(void) ret;
}
static void qed_need_check_timer_cb(void *opaque)
static void qed_need_check_timer_entry(void *opaque)
{
BDRVQEDState *s = opaque;
int ret;
/* The timer should only fire when allocating writes have drained */
assert(!s->allocating_acb);
@ -296,8 +278,27 @@ static void qed_need_check_timer_cb(void *opaque)
qed_plug_allocating_write_reqs(s);
/* Ensure writes are on disk before clearing flag */
bdrv_aio_flush(s->bs->file->bs, qed_clear_need_check, s);
ret = bdrv_co_flush(s->bs->file->bs);
qed_release(s);
if (ret < 0) {
qed_unplug_allocating_write_reqs(s);
return;
}
s->header.features &= ~QED_F_NEED_CHECK;
ret = qed_write_header(s);
(void) ret;
qed_unplug_allocating_write_reqs(s);
ret = bdrv_co_flush(s->bs);
(void) ret;
}
static void qed_need_check_timer_cb(void *opaque)
{
Coroutine *co = qemu_coroutine_create(qed_need_check_timer_entry, opaque);
qemu_coroutine_enter(co);
}
void qed_acquire(BDRVQEDState *s)