diff mbox series

[07/12] block: allow copying pre-registered bvecs

Message ID 20220630204212.1265638-8-kbusch@fb.com (mailing list archive)
State New, archived
Headers show
Series block: support for partial sector reads | expand

Commit Message

Keith Busch June 30, 2022, 8:42 p.m. UTC
From: Keith Busch <kbusch@kernel.org>

If a bio was initialized with bi_max_vecs, then append the requested
bvec instead of overriding it. This will allow mixing bvecs from
multiple sources.

Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 block/bio.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

Comments

Keith Busch July 1, 2022, 2:40 a.m. UTC | #1
On Thu, Jun 30, 2022 at 01:42:07PM -0700, Keith Busch wrote:
>  void bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
>  {
>  	size_t size = iov_iter_count(iter);
>  
>  	WARN_ON_ONCE(bio->bi_max_vecs);
>  
> +	if (bio->bi_max_vecs) {
> +		bio_copy_bvec(bio, iter);
> +		return;
> +	}

Obviously the WARN_ON_ONCE needs to go away with this.

And with the follow on users in this series, there's also a bug with putting
page references on these at bio_endio, so don't try testing pre-registered
buffers with this series. I'll send a fix in the v2 if we get that far.
diff mbox series

Patch

diff --git a/block/bio.c b/block/bio.c
index b0c85778257a..391cad726ff2 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1130,12 +1130,25 @@  void __bio_release_pages(struct bio *bio, bool mark_dirty)
 }
 EXPORT_SYMBOL_GPL(__bio_release_pages);
 
+static void bio_copy_bvec(struct bio *bio, struct iov_iter *iter)
+{
+	memcpy(&bio->bi_io_vec[bio->bi_vcnt], iter->bvec,
+	       iter->nr_segs * sizeof(struct bio_vec));
+	bio->bi_vcnt += iter->nr_segs;
+	bio->bi_iter.bi_size += iov_iter_count(iter);
+}
+
 void bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
 {
 	size_t size = iov_iter_count(iter);
 
 	WARN_ON_ONCE(bio->bi_max_vecs);
 
+	if (bio->bi_max_vecs) {
+		bio_copy_bvec(bio, iter);
+		return;
+	}
+
 	if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
 		struct request_queue *q = bdev_get_queue(bio->bi_bdev);
 		size_t max_sectors = queue_max_zone_append_sectors(q);