After long thinking it now seems to be clear how delayed_fua was supposed to work for io_kaio:
1) An incoming bio marked as REQ_FUA leads to this bit set in preq->req_rw. 2) kaio_submit does nothing with this bit in preq->req_rw. It only initiates sending data by aio_kernel_submit. 3) When userspace ACKs this WRITE, kaio_complete_io_state discovers that even though REQ_FUA bit is set in preq->req_rw, eng_state == E_DATA_WBI, so we can delay flush until index update. NB: It is crucial here, that preq->req_rw still needs REQ_FUA bit set! 4) index update calls ->write_page() with fua=1 because it detects REQ_FUA bit set in preq->req_rw. 5) kaio_write_page observes fua=1 and so set PLOOP_REQ_KAIO_FSYNC in preq->state. Then it initiates sending data (BAT update). 6) When userspace ACKs this WRITE (BAT update), kaio_complete_io_state detects PLOOP_REQ_KAIO_FSYNC bit set, so it clears it and enforces post_fsync=1. The patch fixes 3) that was broken so far. Signed-off-by: Maxim Patlasov <mpatla...@virtuozzo.com> --- drivers/block/ploop/io_kaio.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c index 69df456..e4e4411 100644 --- a/drivers/block/ploop/io_kaio.c +++ b/drivers/block/ploop/io_kaio.c @@ -68,6 +68,7 @@ static void kaio_complete_io_state(struct ploop_request * preq) struct ploop_device * plo = preq->plo; unsigned long flags; int post_fsync = 0; + int need_fua = !!(preq->req_rw & REQ_FUA); if (preq->error || !(preq->req_rw & REQ_FUA) || preq->eng_state == PLOOP_E_INDEX_READ || @@ -80,14 +81,11 @@ static void kaio_complete_io_state(struct ploop_request * preq) /* Convert requested fua to fsync */ if (test_and_clear_bit(PLOOP_REQ_FORCE_FUA, &preq->state) || - test_and_clear_bit(PLOOP_REQ_KAIO_FSYNC, &preq->state)) + test_and_clear_bit(PLOOP_REQ_KAIO_FSYNC, &preq->state) || + (need_fua && !ploop_req_delay_fua_possible(preq))) { post_fsync = 1; - - if (!post_fsync && - !(ploop_req_delay_fua_possible(preq) && (preq->req_rw & REQ_FUA))) - post_fsync = 1; - - preq->req_rw &= ~REQ_FUA; + preq->req_rw &= ~REQ_FUA; + } if (post_fsync) { spin_lock_irqsave(&plo->lock, flags); _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel