[GIT PULL 08/18 for v7.3] vfs iomap
Christian Brauner <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel,org.kernel.vger.linux-fsdevel |
|---|---|
| Message-ID | <20260814-vfs-7.3-rc1.iomap-78c92ce13812@brauner> |
Hey Linus, /* Summary */ The bulk of this is the conversion of iomap to a single ->iomap_next() callback and thus finishing the move to an iterator model. Every iomap operation drove its iteration through a struct iomap_ops holding ->iomap_begin() and ->iomap_end(). iomap_iter() only ever sees those as pointers. That means every step of every iteration is an indirect call. This collapses both into one ->iomap_next() callback that finishes the previous mapping and produces the next one. This lets callers inline the iteration loop and pass its ->iomap_next() as a compile time constant. That means the compiler can turn it into a direct and hence inlineable call. This also allows future callers to express custom logic to drive the iteration forward better. xfs, btrfs, ext4, ext2, erofs, f2fs, gfs2, hpfs, fuse, exfat, zonefs, ntfs, ntfs3 and the block device mapping are all converted. No functional changes are intended. This also adds a simple direct I/O path for small reads. On Gen5 NVMe the __iomap_dio_rw() dominates 4K random reads. The same single-core io_uring poll mode workload reaches ~3.2M IOPS against the raw block device but only ~1.92M through ext4 or XFS. __iomap_dio_rw(), iomap_iter(), iomap_dio_bio_iter() and kfree() were at the top of the profile. The new path is very lightweight if no special behavior is requested. The bio comes from a dedicated bioset and laid out so the whole request is a single cacheline aligned allocation. Completion runs inline. That takes ext4 from 1.92M to 2.19M IOPS in the original workload. fio shows around: * 4% at libaio queue depths of 64 and up * around 5% for io_uring * up to 10% for io_uring poll mode at depth 256 on both ext4 and xfs. A few other patches: - iomap_folio_mark_uptodate() lets a filesystem that writes into the page cache outside the iomap read and write paths keep iomap's internal uptodate bitmap in sync, which fuse needs for server-pushed notify stores before it can enable large folios; - two fixes for iomap_bio_read_folio_range_sync(): a potential crash when device integrity behavior is changed and a missing bio_uninit(). - a folio batch release fix on iomap callback failures - FGP_NOFS is dropped from iomap_get_folio() - documentation fix /* Testing */ No build failures or warnings were observed. /* Conflicts */ Merge conflicts with mainline ============================= No known conflicts. Merge conflicts with other trees ================================ [1]: https://lore.kernel.org/linux-next/[email protected] https://lore.kernel.org/linux-next/CAJnrk1ZqzifYSFNg1tBNz15p2WBe+rMVfRT5yq=B+wCemLt+4g@mail.gmail.com This conflicts with the ntfs tree in fs/ntfs/iomap.c between commit 9cf6ac617e8e9 ("ntfs: serialize resident iomap reads with mrec_lock") from the ntfs tree and commit 7a7bf7551624f ("ntfs: convert iomap ops to ->iomap_next()") from this tree: diff --cc fs/ntfs/iomap.c index 73c50171285aa,d0964ac840d9f..0000000000000 --- a/fs/ntfs/iomap.c +++ b/fs/ntfs/iomap.c @@@ -283,22 -274,13 +283,24 @@@ static int ntfs_read_iomap_begin(struc unsigned int flags, struct iomap *iomap, struct iomap *srcmap) { return __ntfs_read_iomap_begin(inode, offset, length, flags, iomap, - srcmap, true); + srcmap, true, true); } -static DEFINE_IOMAP_ITER_NEXT(ntfs_read_iomap_next, ntfs_read_iomap_begin); +static int ntfs_read_iomap_end(struct inode *inode, loff_t pos, loff_t length, + ssize_t written, unsigned int flags, struct iomap *iomap) +{ + struct ntfs_inode *base_ni = iomap->private; + + if (base_ni) + mutex_unlock(&base_ni->mrec_lock); + return written; +} + ++static DEFINE_IOMAP_ITER_NEXT_END(ntfs_read_iomap_next, ntfs_read_iomap_begin, ++ ntfs_read_iomap_end); + const struct iomap_ops ntfs_read_iomap_ops = { - .iomap_begin = ntfs_read_iomap_begin, - .iomap_end = ntfs_read_iomap_end, + .iomap_next = ntfs_read_iomap_next, }; /* The following changes since commit dc59e4fea9d83f03bad6bddf3fa2e52491777482: Linux 7.2-rc1 (2026-06-28 12:01:31 -0700) are available in the Git repository at: [email protected]:pub/scm/linux/kernel/git/vfs/vfs tags/vfs-7.3-rc1.iomap for you to fetch changes up to 9948bc9aa1c2e5e77ab989a8e5d5eec829e967d5: Merge patch series "fixes for iomap_bio_read_folio_range_sync" (2026-08-12 09:22:40 +0200) ---------------------------------------------------------------- vfs-7.3-rc1.iomap Please consider pulling these changes from the signed vfs-7.3-rc1.iomap tag. Thanks! Christian ---------------------------------------------------------------- Benjamin Wu (1): docs: fix grammatical error in iomap docs Brian Foster (1): iomap: release the folio batch on iomap callback failures Christian Brauner (4): Merge patch series "iomap: add simple dio path for small direct I/O" Merge patch series "iomap/fuse: add helper to keep uptodate bitmap in sync" Merge patch series "iomap: convert to in-iter iomap_next() model" Merge patch series "fixes for iomap_bio_read_folio_range_sync" Christoph Hellwig (4): iomap: decouple simple direct I/O reads from iomap_dio_rw iomap: use GFP_NOWAIT when application for iomap_dio_simple allocations iomap: don't free integrity payload that doesn't exist iomap: iomap_bio_read_folio_range_sync is missing a call to bio_uninit Fengnan Chang (3): iomap: factor out iomap_dio_alignment helper iomap: pass error code to should_report_dio_fserror directly iomap: add simple dio path for small direct I/O Joanne Koong (19): fuse: don't clear folio uptodate on writethrough errors iomap: add helper to mark folio uptodate fuse: use iomap helper to mark folio uptodate iomap: split iomap_iter() logic into iomap_iter_next() iomap: add ->iomap_next() xfs: convert iomap ops to ->iomap_next() btrfs: convert iomap ops to ->iomap_next() ntfs3: convert iomap ops to ->iomap_next() ntfs: convert iomap ops to ->iomap_next() ext4: convert iomap ops to ->iomap_next() erofs: convert iomap ops to ->iomap_next() zonefs: convert iomap ops to ->iomap_next() ext2: convert iomap ops to ->iomap_next() block: convert iomap ops to ->iomap_next() f2fs: convert iomap ops to ->iomap_next() gfs2: convert iomap ops to ->iomap_next() hpfs: convert iomap ops to ->iomap_next() fuse: convert iomap ops to ->iomap_next() exfat: convert iomap ops to ->iomap_next() Matthew Wilcox (Oracle) (1): iomap: Remove FGP_NOFS from iomap_get_folio() Documentation/filesystems/iomap/design.rst | 2 +- block/fops.c | 4 +- fs/btrfs/direct-io.c | 6 +- fs/erofs/data.c | 6 +- fs/erofs/zmap.c | 5 +- fs/exfat/iomap.c | 10 +- fs/ext2/inode.c | 6 +- fs/ext4/ext4.h | 3 + fs/ext4/extents.c | 4 +- fs/ext4/file.c | 4 +- fs/ext4/inode.c | 10 +- fs/f2fs/data.c | 4 +- fs/fuse/dax.c | 6 +- fs/fuse/file.c | 24 +--- fs/fuse/notify.c | 4 +- fs/fuse/virtio_fs.c | 3 +- fs/gfs2/bmap.c | 6 +- fs/hpfs/file.c | 4 +- fs/iomap/bio.c | 3 +- fs/iomap/buffered-io.c | 8 +- fs/iomap/direct-io.c | 190 +++++++++++++++++++++++++++-- fs/iomap/iter.c | 128 ++++++++++--------- fs/ntfs/iomap.c | 32 +++-- fs/ntfs3/inode.c | 6 +- fs/xfs/xfs_file.c | 18 +-- fs/xfs/xfs_iomap.c | 41 +++++-- fs/xfs/xfs_iomap.h | 4 + fs/zonefs/file.c | 9 +- include/linux/iomap.h | 178 ++++++++++++++++++++++++--- 29 files changed, 569 insertions(+), 159 deletions(-)