[Devel] [PATCH rh7] ploop: fix barriers for ordinary requests

Dmitry Monakhov dmonakhov at openvz.org
Wed Jun 22 01:40:59 PDT 2016


Maxim Patlasov <mpatlasov at virtuozzo.com> writes:

> 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 <mpatlasov at virtuozzo.com>
> ---
>  drivers/block/ploop/dev.c       |    1 -
>  drivers/block/ploop/io_direct.c |   47 ++++++++++++---------------------------
>  2 files changed, 15 insertions(+), 33 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);
Wow. I can't even imagine that we clear barrier flags from original bios
>  	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..84c9a48 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++;
> +		submit_bio(rw2 | b->bi_rw, b);
>  	}
>  
>  	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,13 +693,9 @@ 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);
> +		submit_bio(rw | b->bi_rw, b);
This is useless statement ^^^^^^^^^^^^^^
submit_bio looks like follows:
void submit_bio(int rw, struct bio *bio)
{
        bio->bi_rw |= rw;
.....        
>  	}
>  
>  	ploop_complete_io_request(preq);
> @@ -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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <http://lists.openvz.org/pipermail/devel/attachments/20160622/69c981a4/attachment.sig>


More information about the Devel mailing list