On Wed, Jan 21, 2026 at 07:43:15AM +0100, Christoph Hellwig wrote: > 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 <[email protected]> > --- > block/bio.c | 17 ++++++++++------- > fs/iomap/direct-io.c | 2 +- > include/linux/bio.h | 2 +- > 3 files changed, 12 insertions(+), 9 deletions(-) > > diff --git a/block/bio.c b/block/bio.c > index da795b1df52a..e89b24dc0283 100644 > --- a/block/bio.c > +++ b/block/bio.c > @@ -1293,9 +1293,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; > @@ -1333,9 +1334,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); > @@ -1372,6 +1374,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 > @@ -1379,11 +1382,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) > diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c > index 9c572de0d596..842fc7fecb2d 100644 > --- a/fs/iomap/direct-io.c > +++ b/fs/iomap/direct-io.c > @@ -326,7 +326,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, UINT_MAX);
Nitpicking here, but shouldn't this be SIZE_MAX? --D > else > ret = bio_iov_iter_get_pages(bio, dio->submit.iter, > alignment - 1); > diff --git a/include/linux/bio.h b/include/linux/bio.h > index 95cfc79b88b8..df0d7e71372a 100644 > --- a/include/linux/bio.h > +++ b/include/linux/bio.h > @@ -479,7 +479,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, > -- > 2.47.3 > >
