The commit is pushed to "branch-rh7-3.10.0-327.18.2.vz7.14.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-327.18.2.vz7.14.17 ------> commit c2247f374581173c476bf88e82b9650ba263b37d Author: Maxim Patlasov <mpatla...@virtuozzo.com> Date: Wed Jun 22 16:42:43 2016 +0400
ploop: fix barriers for ordinary requests The way how io_direct.c handles FLUSH|FUA: b1:FLUSH,b2,b3,b4,b5:FLUSH|FUA is completely wrong: to make sure that b1:FLUSH made effect we have to wait for its completion. Similarly, even if we're sure that FUA will be processed as post-FLUSH (also dubious!), we have to wait for completion b1..b4 to make sure that that flush will cover them. The patch fixes all these issues pretty simple: let's mark outgouing bio-s with FLUSH|FUA based on those flags in *corresponing* incoming bio-s. Signed-off-by: Maxim Patlasov <mpatla...@virtuozzo.com> Acked-by: Dmitry Monakhov <dmonak...@virtuozzo.com> khorenko@: v2 changes: Drop 2 hunks like: > - submit_bio(rw, b); > + submit_bio(rw | b->bi_rw, b); This is redundant ^^^^^^^^^^^^^ submit_bio looks like following: void submit_bio(int rw, struct bio *bio) { bio->bi_rw |= rw; ... --- drivers/block/ploop/dev.c | 1 - drivers/block/ploop/io_direct.c | 43 +++++++++++++---------------------------- 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 2ef1449..6b5702f 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -498,7 +498,6 @@ ploop_bio_queue(struct ploop_device * plo, struct bio * bio, preq->req_sector = bio->bi_sector; preq->req_size = bio->bi_size >> 9; preq->req_rw = bio->bi_rw; - bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA); preq->eng_state = PLOOP_E_ENTRY; preq->state = 0; preq->error = 0; diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c index 6ef9cd8..50c0ed1 100644 --- a/drivers/block/ploop/io_direct.c +++ b/drivers/block/ploop/io_direct.c @@ -92,7 +92,6 @@ dio_submit(struct ploop_io *io, struct ploop_request * preq, int preflush; int postfua = 0; int write = !!(rw & REQ_WRITE); - int bio_num; trace_submit(preq); @@ -233,13 +232,13 @@ flush_bio: goto flush_bio; } + bio->bi_rw |= bw.cur->bi_rw & (REQ_FLUSH | REQ_FUA); bw.bv_off += copy; size -= copy >> 9; sec += copy >> 9; } ploop_extent_put(em); - bio_num = 0; while (bl.head) { struct bio * b = bl.head; unsigned long rw2 = rw; @@ -255,11 +254,10 @@ flush_bio: preflush = 0; } if (unlikely(postfua && !bl.head)) - rw2 |= (REQ_FUA | ((bio_num) ? REQ_FLUSH : 0)); + rw2 |= REQ_FUA; ploop_acc_ff_out(preq->plo, rw2 | b->bi_rw); submit_bio(rw2, b); - bio_num++; } ploop_complete_io_request(preq); @@ -567,7 +565,6 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq, sector_t sec, end_sec, nsec, start, end; struct bio_list_walk bw; int err; - int preflush = !!(preq->req_rw & REQ_FLUSH); bio_list_init(&bl); @@ -598,14 +595,17 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq, while (sec < end_sec) { struct page * page; unsigned int poff, plen; + bool zero_page; if (sec < start) { + zero_page = true; page = ZERO_PAGE(0); poff = 0; plen = start - sec; if (plen > (PAGE_SIZE>>9)) plen = (PAGE_SIZE>>9); } else if (sec >= end) { + zero_page = true; page = ZERO_PAGE(0); poff = 0; plen = end_sec - sec; @@ -614,6 +614,7 @@ dio_submit_pad(struct ploop_io *io, struct ploop_request * preq, } else { /* sec >= start && sec < end */ struct bio_vec * bv; + zero_page = false; if (sec == start) { bw.cur = sbl->head; @@ -672,6 +673,10 @@ flush_bio: goto flush_bio; } + /* Handle FLUSH here, dio_post_submit will handle FUA */ + if (!zero_page) + bio->bi_rw |= bw.cur->bi_rw & REQ_FLUSH; + bw.bv_off += (plen<<9); BUG_ON(plen == 0); sec += plen; @@ -688,11 +693,7 @@ flush_bio: b->bi_private = preq; b->bi_end_io = dio_endio_async; - rw = sbl->head->bi_rw | WRITE; - if (unlikely(preflush)) { - rw |= REQ_FLUSH; - preflush = 0; - } + rw = preq->req_rw & ~(REQ_FLUSH | REQ_FUA); ploop_acc_ff_out(preq->plo, rw | b->bi_rw); submit_bio(rw, b); } @@ -1422,13 +1423,6 @@ dio_io_page(struct ploop_io * io, unsigned long rw, sector_t nsec; int err; int off; - int postfua; - int bio_num; - int preflush; - - preflush = !!(rw & REQ_FLUSH); - postfua = !!(rw & REQ_FUA); - rw &= ~(REQ_FUA|REQ_FLUSH); bio_list_init(&bl); bio = NULL; @@ -1481,27 +1475,16 @@ flush_bio: if (em) ploop_extent_put(em); - bio_num = 0; while (bl.head) { - unsigned long rw2 = rw; struct bio * b = bl.head; bl.head = b->bi_next; - if (unlikely(preflush)) { - rw2 |= REQ_FLUSH; - preflush = 0; - } - - if (unlikely(postfua && !bl.head)) - rw2 |= (REQ_FUA | ((bio_num) ? REQ_FLUSH : 0)); - b->bi_next = NULL; b->bi_end_io = dio_endio_async; b->bi_private = preq; atomic_inc(&preq->io_count); - ploop_acc_ff_out(preq->plo, rw2 | b->bi_rw); - submit_bio(rw2, b); - bio_num++; + ploop_acc_ff_out(preq->plo, rw | b->bi_rw); + submit_bio(rw, b); } ploop_complete_io_request(preq); _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel