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:
parent
48cc565e76
commit
c0e8f98927
43
block/qed.c
43
block/qed.c
|
@ -264,28 +264,10 @@ static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
|
||||||
qemu_co_enter_next(&s->allocating_write_reqs);
|
qemu_co_enter_next(&s->allocating_write_reqs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qed_clear_need_check(void *opaque, int ret)
|
static void qed_need_check_timer_entry(void *opaque)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = opaque;
|
BDRVQEDState *s = opaque;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* The timer should only fire when allocating writes have drained */
|
/* The timer should only fire when allocating writes have drained */
|
||||||
assert(!s->allocating_acb);
|
assert(!s->allocating_acb);
|
||||||
|
@ -296,8 +278,27 @@ static void qed_need_check_timer_cb(void *opaque)
|
||||||
qed_plug_allocating_write_reqs(s);
|
qed_plug_allocating_write_reqs(s);
|
||||||
|
|
||||||
/* Ensure writes are on disk before clearing flag */
|
/* 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);
|
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)
|
void qed_acquire(BDRVQEDState *s)
|
||||||
|
|
Loading…
Reference in New Issue