stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec
       [not found] <1455852022-14188-1-git-send-email-ming.lei@canonical.com>
@ 2016-02-19  3:20 ` Ming Lei
  2016-02-21  9:38   ` Sagi Grimberg
  2016-02-22  8:59   ` Christoph Hellwig
  2016-02-19  3:20 ` [PATCH v1 3/4] block: get the 1st and last bvec via helpers Ming Lei
  1 sibling, 2 replies; 6+ messages in thread
From: Ming Lei @ 2016-02-19  3:20 UTC (permalink / raw)
  To: Jens Axboe, linux-kernel
  Cc: linux-block, Christoph Hellwig, Sagi Grimberg, Kent Overstreet,
	Keith Busch, Elliott Robert, Ming Lei, stable

The bio passed to bio_will_gap() may be fast cloned from upper
layer(dm, md, bcache, fs, ...), or from bio splitting in block
core.

Unfortunately bio_will_gap() just figures out the last bvec via
'bi_io_vec[prev->bi_vcnt - 1]' directly, and this way is obviously
wrong.

This patch introduces two helpers for getting the first and last
bvec of one bio for fixing the issue.

Cc: stable@vger.kernel.org
Reported-by: Sagi Grimberg <sagig@dev.mellanox.co.il>
Cc: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 include/linux/bio.h | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index 5349e68..3ce2e45 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -310,6 +310,47 @@ static inline void bio_clear_flag(struct bio *bio, unsigned int bit)
 	bio->bi_flags &= ~(1U << bit);
 }
 
+static inline void bio_get_first_bvec(struct bio *bio, struct bio_vec *bv)
+{
+	*bv = bio_iovec(bio);
+}
+
+/*
+ * bio_get_last_bvec() is introduced to get the last bvec of one
+ * bio for bio_will_gap().
+ */
+static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
+{
+	struct bvec_iter iter = bio->bi_iter;
+	int idx;
+
+	if (!bio_flagged(bio, BIO_CLONED)) {
+		*bv = bio->bi_io_vec[bio->bi_vcnt - 1];
+		return;
+	}
+
+	if (unlikely(!bio_multiple_segments(bio))) {
+		*bv = bio_iovec(bio);
+		return;
+	}
+
+	bio_advance_iter(bio, &iter, iter.bi_size);
+
+	if (!iter.bi_bvec_done)
+		idx = iter.bi_idx - 1;
+	else	/* in the middle of bvec */
+		idx = iter.bi_idx;
+
+	*bv = bio->bi_io_vec[idx];
+
+	/*
+	 * iter.bi_bvec_done records actual length of the last bvec
+	 * if this bio ends in the middle of one io vector
+	 */
+	if (iter.bi_bvec_done)
+		bv->bv_len = iter.bi_bvec_done;
+}
+
 enum bip_flags {
 	BIP_BLOCK_INTEGRITY	= 1 << 0, /* block layer owns integrity data */
 	BIP_MAPPED_INTEGRITY	= 1 << 1, /* ref tag has been remapped */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1 3/4] block: get the 1st and last bvec via helpers
       [not found] <1455852022-14188-1-git-send-email-ming.lei@canonical.com>
  2016-02-19  3:20 ` [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec Ming Lei
@ 2016-02-19  3:20 ` Ming Lei
  2016-02-21  9:39   ` Sagi Grimberg
  2016-02-22  9:01   ` Christoph Hellwig
  1 sibling, 2 replies; 6+ messages in thread
From: Ming Lei @ 2016-02-19  3:20 UTC (permalink / raw)
  To: Jens Axboe, linux-kernel
  Cc: linux-block, Christoph Hellwig, Sagi Grimberg, Kent Overstreet,
	Keith Busch, Elliott Robert, Ming Lei, stable

This patch applies the two introduced helpers to
figure out the 1st and last bvec, and fixes the
original way after bio splitting.

Cc: stable@vger.kernel.org
Reported-by: Sagi Grimberg <sagig@dev.mellanox.co.il>
Cc: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 include/linux/blkdev.h | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5023401..de4fc002 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1394,11 +1394,16 @@ static inline bool bvec_gap_to_prev(struct request_queue *q,
 static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
 			 struct bio *next)
 {
-	if (!bio_has_data(prev) || !queue_virt_boundary(q))
+	if (!bio_has_data(prev) || !queue_virt_boundary(q)) {
 		return false;
+	} else {
+		struct bio_vec pb, nb;
 
-	return bvec_gap_to_prev(q, &prev->bi_io_vec[prev->bi_vcnt - 1],
-				next->bi_io_vec[0].bv_offset);
+		bio_get_last_bvec(prev, &pb);
+		bio_get_first_bvec(next, &nb);
+
+		return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
+	}
 }
 
 static inline bool req_gap_back_merge(struct request *req, struct bio *bio)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec
  2016-02-19  3:20 ` [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec Ming Lei
@ 2016-02-21  9:38   ` Sagi Grimberg
  2016-02-22  8:59   ` Christoph Hellwig
  1 sibling, 0 replies; 6+ messages in thread
From: Sagi Grimberg @ 2016-02-21  9:38 UTC (permalink / raw)
  To: Ming Lei, Jens Axboe, linux-kernel
  Cc: linux-block, Christoph Hellwig, Kent Overstreet, Keith Busch,
	Elliott Robert, stable

Looks fine,

Reviewed-by: Sagi Grimberg <sagig@mellanox.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 3/4] block: get the 1st and last bvec via helpers
  2016-02-19  3:20 ` [PATCH v1 3/4] block: get the 1st and last bvec via helpers Ming Lei
@ 2016-02-21  9:39   ` Sagi Grimberg
  2016-02-22  9:01   ` Christoph Hellwig
  1 sibling, 0 replies; 6+ messages in thread
From: Sagi Grimberg @ 2016-02-21  9:39 UTC (permalink / raw)
  To: Ming Lei, Jens Axboe, linux-kernel
  Cc: linux-block, Christoph Hellwig, Kent Overstreet, Keith Busch,
	Elliott Robert, stable

Looks fine,

Reviewed-by: Sagi Grimberg <sagig@mellanox.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec
  2016-02-19  3:20 ` [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec Ming Lei
  2016-02-21  9:38   ` Sagi Grimberg
@ 2016-02-22  8:59   ` Christoph Hellwig
  1 sibling, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2016-02-22  8:59 UTC (permalink / raw)
  To: Ming Lei
  Cc: Jens Axboe, linux-kernel, linux-block, Christoph Hellwig,
	Sagi Grimberg, Kent Overstreet, Keith Busch, Elliott Robert,
	stable

> +/*
> + * bio_get_last_bvec() is introduced to get the last bvec of one
> + * bio for bio_will_gap().
> + */

I don't think this comment adds any value.

Otherwise looks fine:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 3/4] block: get the 1st and last bvec via helpers
  2016-02-19  3:20 ` [PATCH v1 3/4] block: get the 1st and last bvec via helpers Ming Lei
  2016-02-21  9:39   ` Sagi Grimberg
@ 2016-02-22  9:01   ` Christoph Hellwig
  1 sibling, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2016-02-22  9:01 UTC (permalink / raw)
  To: Ming Lei
  Cc: Jens Axboe, linux-kernel, linux-block, Christoph Hellwig,
	Sagi Grimberg, Kent Overstreet, Keith Busch, Elliott Robert,
	stable

On Fri, Feb 19, 2016 at 11:20:21AM +0800, Ming Lei wrote:
> This patch applies the two introduced helpers to
> figure out the 1st and last bvec, and fixes the
> original way after bio splitting.

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-02-22  9:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1455852022-14188-1-git-send-email-ming.lei@canonical.com>
2016-02-19  3:20 ` [PATCH v1 1/4] block: bio: introduce helpers to get the 1st and last bvec Ming Lei
2016-02-21  9:38   ` Sagi Grimberg
2016-02-22  8:59   ` Christoph Hellwig
2016-02-19  3:20 ` [PATCH v1 3/4] block: get the 1st and last bvec via helpers Ming Lei
2016-02-21  9:39   ` Sagi Grimberg
2016-02-22  9:01   ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).