Sashiko complained about bio_iov_iter_align_down potentially dropping
bvecs, and thus losing bounce folios. While losing bio_vecs is real,
bio_iov_iter_bounce_write allocates all segments and thus the entire bio
in multiples of the minsize, thus making the rounding down redundant.
Replace it with a safety rounding down of this_len in case something odd
happens to the greedy folio allocation helper.
Fixes: e7b8b3c5b2a6 ("block: align down bounces bios")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index f95b63c0604a..57ee335899f3 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1389,6 +1389,14 @@ static int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter,
folio = folio_alloc_greedy(GFP_KERNEL, &this_len, minsize);
if (!folio)
break;
+
+ /*
+ * Align down the size to the minimum alignment. In practice
+ * this should not happen as minsize is expected to be a power
+ * of two, as is the allocation size, but it offers us a cheap
+ * extra safety belt.
+ */
+ this_len &= ~(minsize - 1);
bio_add_folio_nofail(bio, folio, this_len, 0);
if (iter->nofault)
@@ -1416,8 +1424,7 @@ static int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter,
if (!bio->bi_iter.bi_size)
return -ENOMEM;
- return bio_iov_iter_align_down(bio, iter,
- &bio->bi_io_vec[bio->bi_vcnt - 1], minsize - 1);
+ return 0;
}
static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter,
--
2.53.0