On Thu, Dec 16, 2021 at 09:07:06PM +0000, Matthew Wilcox (Oracle) wrote: > The zero iterator can work in folio-sized chunks instead of page-sized > chunks. This will save a lot of page cache lookups if the file is cached > in large folios. This patch (and a few others) end up conflicting with what Christoph did that's now in the nvdimm tree. In an effort to make the merge cleaner, I took the next-20211220 tag and did the following: Revert de291b590286 Apply: https://lore.kernel.org/linux-xfs/20211221044450.517558-1-willy@xxxxxxxxxxxxx/ (these two things are likely to happen in the nvdimm tree imminently) I then checked out iomap-folio-5.17e and added this patch: iomap: Inline __iomap_zero_iter into its caller To make the merge easier, replicate the inlining of __iomap_zero_iter() into iomap_zero_iter() that is currently in the nvdimm tree. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index ba80bedd9590..c6b3a148e898 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -895,27 +895,6 @@ iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len, } EXPORT_SYMBOL_GPL(iomap_file_unshare); -static s64 __iomap_zero_iter(struct iomap_iter *iter, loff_t pos, u64 length) -{ - struct folio *folio; - int status; - size_t offset; - size_t bytes = min_t(u64, SIZE_MAX, length); - - status = iomap_write_begin(iter, pos, bytes, &folio); - if (status) - return status; - - offset = offset_in_folio(folio, pos); - if (bytes > folio_size(folio) - offset) - bytes = folio_size(folio) - offset; - - folio_zero_range(folio, offset, bytes); - folio_mark_accessed(folio); - - return iomap_write_end(iter, pos, bytes, bytes, folio); -} - static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero) { struct iomap *iomap = &iter->iomap; @@ -929,14 +908,34 @@ static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero) return length; do { - s64 bytes; + struct folio *folio; + int status; + size_t offset; + size_t bytes = min_t(u64, SIZE_MAX, length); + + if (IS_DAX(iter->inode)) { + s64 tmp = dax_iomap_zero(pos, bytes, iomap); + if (tmp < 0) + return tmp; + bytes = tmp; + goto good; + } - if (IS_DAX(iter->inode)) - bytes = dax_iomap_zero(pos, length, iomap); - else - bytes = __iomap_zero_iter(iter, pos, length); - if (bytes < 0) - return bytes; + status = iomap_write_begin(iter, pos, bytes, &folio); + if (status) + return status; + + offset = offset_in_folio(folio, pos); + if (bytes > folio_size(folio) - offset) + bytes = folio_size(folio) - offset; + + folio_zero_range(folio, offset, bytes); + folio_mark_accessed(folio); + + bytes = iomap_write_end(iter, pos, bytes, bytes, folio); +good: + if (WARN_ON_ONCE(bytes == 0)) + return -EIO; pos += bytes; length -= bytes; Then I did the merge, and the merge commit looks pretty sensible afterwards: Merge branch 'iomap-folio-5.17f' into fixup diff --cc fs/iomap/buffered-io.c index 955f51f94b3f,c6b3a148e898..c938bbad075e --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@@ -888,19 -908,32 +907,23 @@@ static loff_t iomap_zero_iter(struct io return length; do { - unsigned offset = offset_in_page(pos); - size_t bytes = min_t(u64, PAGE_SIZE - offset, length); - struct page *page; + struct folio *folio; int status; + size_t offset; + size_t bytes = min_t(u64, SIZE_MAX, length); - status = iomap_write_begin(iter, pos, bytes, &page); - if (IS_DAX(iter->inode)) { - s64 tmp = dax_iomap_zero(pos, bytes, iomap); - if (tmp < 0) - return tmp; - bytes = tmp; - goto good; - } - + status = iomap_write_begin(iter, pos, bytes, &folio); if (status) return status; - zero_user(page, offset, bytes); - mark_page_accessed(page); + offset = offset_in_folio(folio, pos); + if (bytes > folio_size(folio) - offset) + bytes = folio_size(folio) - offset; + + folio_zero_range(folio, offset, bytes); + folio_mark_accessed(folio); - bytes = iomap_write_end(iter, pos, bytes, bytes, page); + bytes = iomap_write_end(iter, pos, bytes, bytes, folio); -good: if (WARN_ON_ONCE(bytes == 0)) return -EIO; Shall I push out a version of this patch series which includes the "iomap: Inline __iomap_zero_iter into its caller" patch I pasted above?