diff --git a/fs/iomap/bio.c b/fs/iomap/bio.c index 153b779949e9..256564ebe238 100644 --- a/fs/iomap/bio.c +++ b/fs/iomap/bio.c @@ -109,7 +109,7 @@ int iomap_bio_read_folio_range(const struct iomap_iter *iter, if (!bio || bio_end_sector(bio) != iomap_sector(&iter->iomap, iter->pos) || - bio->bi_iter.bi_size > iomap_max_bio_size(&iter->iomap) - plen || + !iomap_bio_has_room(&iter->iomap, bio, plen) || !bio_add_folio(bio, folio, plen, offset_in_folio(folio, iter->pos))) iomap_read_alloc_bio(iter, ctx, plen); return 0; diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 678f4c5329e7..a6ab6f31cbbf 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -920,6 +920,7 @@ static int __iomap_write_begin(const struct iomap_iter *iter, if (iomap_block_needs_zeroing(iter, block_start)) { if (WARN_ON_ONCE(iter->flags & IOMAP_UNSHARE)) return -EIO; + /* uptodate once copied, see __iomap_write_end() */ folio_zero_segments(folio, poff, from, to, poff + plen); } else { const struct iomap *iomap = iomap_iter_srcmap(iter); @@ -943,8 +944,8 @@ static int __iomap_write_begin(const struct iomap_iter *iter, if (iomap->flags & IOMAP_F_ZERO_TAIL) folio_zero_segment(folio, to, poff + plen); + iomap_set_range_uptodate(folio, poff, plen); } - iomap_set_range_uptodate(folio, poff, plen); } while ((block_start += plen) < block_end); return 0; diff --git a/fs/iomap/internal.h b/fs/iomap/internal.h index 74e898b196dc..e69b3ac02cc2 100644 --- a/fs/iomap/internal.h +++ b/fs/iomap/internal.h @@ -17,6 +17,15 @@ static inline size_t iomap_max_bio_size(const struct iomap *iomap) return BIO_MAX_SIZE; } +/* Can @len more bytes go into @bio? */ +static inline bool iomap_bio_has_room(const struct iomap *iomap, + const struct bio *bio, size_t len) +{ + size_t max_size = iomap_max_bio_size(iomap); + + return len <= max_size && bio->bi_iter.bi_size <= max_size - len; +} + u32 iomap_finish_ioend_buffered_read(struct iomap_ioend *ioend); u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend); diff --git a/fs/iomap/ioend.c b/fs/iomap/ioend.c index 92b89fbf95b9..4da248ff99f8 100644 --- a/fs/iomap/ioend.c +++ b/fs/iomap/ioend.c @@ -133,8 +133,7 @@ static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos, { struct iomap_ioend *ioend = wpc->wb_ctx; - if (ioend->io_bio.bi_iter.bi_size > - iomap_max_bio_size(&wpc->iomap) - map_len) + if (!iomap_bio_has_room(&wpc->iomap, &ioend->io_bio, map_len)) return false; if (ioend_flags & IOMAP_IOEND_BOUNDARY) return false;