[Devel] [PATCH rh7 3/9] ploop: resurrect delayed_fua for io_kaio
Maxim Patlasov
mpatlasov at virtuozzo.com
Thu Jun 23 22:39:26 PDT 2016
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 <mpatlasov at 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);
More information about the Devel
mailing list