summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2026-08-01 16:46:18 +0100
committerJens Axboe <axboe@kernel.dk>2026-08-15 17:09:32 -0600
commit8b8755e00847da1027fe6624277e43d289e2300e (patch)
tree76986762e9a3c7b30cd9494d5ce212c834da080b /block
parente228404b05c8293f6a1286856e49ba3e55da1933 (diff)
downloadlinux-next-8b8755e00847da1027fe6624277e43d289e2300e.tar.gz
linux-next-8b8755e00847da1027fe6624277e43d289e2300e.zip
block: introduce bio_iov_iter_set()
In preparation to supporting dma-buf backed iterators and bios, introduce bio_iov_iter_set() which attempts to set up the bio directly from the given iterator. For now, it only supports bvec and expects users to check the result and fall back to other means if fails, but later we'll add more types. Suggested-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/4686a0e47fc14f3f888967a80d45a6f66044f1e0.1785596451.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/bio.c13
-rw-r--r--block/blk-map.c2
-rw-r--r--block/fops.c16
3 files changed, 16 insertions, 15 deletions
diff --git a/block/bio.c b/block/bio.c
index 00f99d03ac91..898b2f5ef8c8 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1181,8 +1181,11 @@ void __bio_release_pages(struct bio *bio, bool mark_dirty)
}
EXPORT_SYMBOL_GPL(__bio_release_pages);
-void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter)
+bool bio_iov_iter_set(struct bio *bio, const struct iov_iter *iter)
{
+ if (!iov_iter_is_bvec(iter))
+ return false;
+
WARN_ON_ONCE(bio->bi_max_vecs);
bio->bi_io_vec = (struct bio_vec *)iter->bvec;
@@ -1190,6 +1193,7 @@ void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter)
bio->bi_iter.bi_offset = iter->iov_offset;
bio->bi_iter.bi_size = iov_iter_count(iter);
bio_set_flag(bio, BIO_CLONED);
+ return true;
}
/*
@@ -1284,10 +1288,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return -EIO;
- if (iov_iter_is_bvec(iter)) {
- bio_iov_bvec_set(bio, iter);
-
- if (!bio_iov_bvec_aligned(bio, mem_align_mask))
+ if (bio_iov_iter_set(bio, iter)) {
+ if (iov_iter_is_bvec(iter) &&
+ !bio_iov_bvec_aligned(bio, mem_align_mask))
return -EINVAL;
iov_iter_advance(iter, bio->bi_iter.bi_size);
diff --git a/block/blk-map.c b/block/blk-map.c
index 615d29bb840e..9cb9605d1f62 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -473,7 +473,7 @@ static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter)
bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL);
if (!bio)
return -ENOMEM;
- bio_iov_bvec_set(bio, iter);
+ bio_iov_iter_set(bio, iter);
ret = blk_rq_append_bio(rq, bio);
if (ret)
diff --git a/block/fops.c b/block/fops.c
index 3c2099dfef1d..d11923053afe 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -342,15 +342,13 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
bio->bi_end_io = blkdev_bio_end_io_async;
bio->bi_ioprio = iocb->ki_ioprio;
- if (iov_iter_is_bvec(iter)) {
- /*
- * Users don't rely on the iterator being in any particular
- * state for async I/O returning -EIOCBQUEUED, hence we can
- * avoid expensive iov_iter_advance(). Bypass
- * bio_iov_iter_get_pages() and set the bvec directly.
- */
- bio_iov_bvec_set(bio, iter);
- } else {
+ /*
+ * Users don't rely on the iterator being in any particular
+ * state for async I/O returning -EIOCBQUEUED, hence we can
+ * avoid expensive iov_iter_advance(). Bypass
+ * bio_iov_iter_get_pages() and set the bvec directly.
+ */
+ if (!bio_iov_iter_set(bio, iter)) {
ret = blkdev_iov_iter_get_pages(bio, iter, bdev);
if (unlikely(ret))
goto out_bio_put;