]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
block: pass a maxlen argument to bio_iov_iter_bounce
authorChristoph Hellwig <hch@lst.de>
Mon, 23 Feb 2026 13:20:07 +0000 (05:20 -0800)
committerJens Axboe <axboe@kernel.dk>
Mon, 9 Mar 2026 13:47:02 +0000 (07:47 -0600)
Allow the file system to limit the size processed in a single
bounce operation.  This is needed when generating integrity data
so that the size of a single integrity segment can't overflow.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Tested-by: Anuj Gupta <anuj20.g@samsung.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/bio.c
fs/iomap/direct-io.c
include/linux/bio.h

index d80d5d26804e32944bcfe4506ca190033308844f..784d2a66d3aef056e5efbdafd21b53c747ef824a 100644 (file)
@@ -1327,9 +1327,10 @@ static void bio_free_folios(struct bio *bio)
        }
 }
 
-static int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter)
+static int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter,
+               size_t maxlen)
 {
-       size_t total_len = iov_iter_count(iter);
+       size_t total_len = min(maxlen, iov_iter_count(iter));
 
        if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
                return -EINVAL;
@@ -1367,9 +1368,10 @@ static int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter)
        return 0;
 }
 
-static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter)
+static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter,
+               size_t maxlen)
 {
-       size_t len = min(iov_iter_count(iter), SZ_1M);
+       size_t len = min3(iov_iter_count(iter), maxlen, SZ_1M);
        struct folio *folio;
 
        folio = folio_alloc_greedy(GFP_KERNEL, &len);
@@ -1408,6 +1410,7 @@ static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter)
  * bio_iov_iter_bounce - bounce buffer data from an iter into a bio
  * @bio:       bio to send
  * @iter:      iter to read from / write into
+ * @maxlen:    maximum size to bounce
  *
  * Helper for direct I/O implementations that need to bounce buffer because
  * we need to checksum the data or perform other operations that require
@@ -1415,11 +1418,11 @@ static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter)
  * copies the data into it.  Needs to be paired with bio_iov_iter_unbounce()
  * called on completion.
  */
-int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter)
+int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter, size_t maxlen)
 {
        if (op_is_write(bio_op(bio)))
-               return bio_iov_iter_bounce_write(bio, iter);
-       return bio_iov_iter_bounce_read(bio, iter);
+               return bio_iov_iter_bounce_write(bio, iter, maxlen);
+       return bio_iov_iter_bounce_read(bio, iter, maxlen);
 }
 
 static void bvec_unpin(struct bio_vec *bv, bool mark_dirty)
index 95254aa1b6546a4e30dae45f18d2a578eb4c5559..21d4fad2eeb8fca3dde3dbdc56db0668560758c5 100644 (file)
@@ -338,7 +338,7 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter,
        bio->bi_end_io = iomap_dio_bio_end_io;
 
        if (dio->flags & IOMAP_DIO_BOUNCE)
-               ret = bio_iov_iter_bounce(bio, dio->submit.iter);
+               ret = bio_iov_iter_bounce(bio, dio->submit.iter, BIO_MAX_SIZE);
        else
                ret = bio_iov_iter_get_pages(bio, dio->submit.iter,
                                             alignment - 1);
index 36a3f2275ecd023af6dc5d7f195f49e9ea0dd1ed..9693a0d6fefecaa61f3f29b21f7ec54979b2d1be 100644 (file)
@@ -474,7 +474,7 @@ void __bio_release_pages(struct bio *bio, bool mark_dirty);
 extern void bio_set_pages_dirty(struct bio *bio);
 extern void bio_check_pages_dirty(struct bio *bio);
 
-int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter);
+int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter, size_t maxlen);
 void bio_iov_iter_unbounce(struct bio *bio, bool is_error, bool mark_dirty);
 
 extern void bio_copy_data_iter(struct bio *dst, struct bvec_iter *dst_iter,