Commit a9aa6045 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: pass a maxlen argument to bio_iov_iter_bounce



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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarAnuj Gupta <anuj20.g@samsung.com>
Reviewed-by: default avatarKanchan Joshi <joshi.k@samsung.com>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Tested-by: default avatarAnuj Gupta <anuj20.g@samsung.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 0bde8a12
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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,