On Tue, Jul 29, 2025 at 03:01:28PM -0400, Tony Battersby wrote: > Yes, you understand correctly. The test creates a number of sequential > writes, and this patch cuts the stream of sequential bios on the stripe > boundaries rather than letting the bios span stripes, so that MD doesn't > have to do extra work for writes that cross the boundary. I am actually > working on an out-of-tree RAID driver that benefits hugely from this > because it doesn't have the complexity of the MD caching layer. But > benchmarks showed that MD benefited from it (slightly) also, so I > figured it was worth submitting. > > The problem with using iomap_can_add_to_ioend() is that it returns > true/false, whereas sometimes it is necessary to add some of the folio > to the current bio and the rest to a new bio. Hm. Maybe something like this would be more clear? (contents and indeed name of iomap_should_split_ioend() very much TBD) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 9f541c05103b..429890fb7763 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1684,6 +1684,7 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct iomap_folio_state *ifs = folio->private; size_t poff = offset_in_folio(folio, pos); unsigned int ioend_flags = 0; + unsigned thislen; int error; if (wpc->iomap.type == IOMAP_UNWRITTEN) @@ -1704,8 +1705,16 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, ioend_flags); } - if (!bio_add_folio(&wpc->ioend->io_bio, folio, len, poff)) + thislen = iomap_should_split_ioend(wpc, pos, len); + + if (!bio_add_folio(&wpc->ioend->io_bio, folio, thislen, poff)) + goto new_ioend; + if (thislen < len) { + pos += thislen; + len -= thislen; + wbc_account_cgroup_owner(wbc, folio, thislen); goto new_ioend; + } if (ifs) atomic_add(len, &ifs->write_bytes_pending);