The patch titled Subject: iomap: use kiocb_write_and_wait and kiocb_invalidate_pages has been added to the -mm mm-unstable branch. Its filename is iomap-use-kiocb_write_and_wait-and-kiocb_invalidate_pages.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/iomap-use-kiocb_write_and_wait-and-kiocb_invalidate_pages.patch This patch will later appear in the mm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Christoph Hellwig <hch@xxxxxx> Subject: iomap: use kiocb_write_and_wait and kiocb_invalidate_pages Date: Thu, 1 Jun 2023 16:59:00 +0200 Use the common helpers for direct I/O page invalidation instead of open coding the logic. This leads to a slight reordering of checks in __iomap_dio_rw to keep the logic straight. Link: https://lkml.kernel.org/r/20230601145904.1385409-9-hch@xxxxxx Signed-off-by: Christoph Hellwig <hch@xxxxxx> Reviewed-by: Damien Le Moal <dlemoal@xxxxxxxxxx> Reviewed-by: Hannes Reinecke <hare@xxxxxxx> Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Andreas Gruenbacher <agruenba@xxxxxxxxxx> Cc: Anna Schumaker <anna@xxxxxxxxxx> Cc: Chao Yu <chao@xxxxxxxxxx> Cc: Christian Brauner <brauner@xxxxxxxxxx> Cc: Ilya Dryomov <idryomov@xxxxxxxxx> Cc: Jaegeuk Kim <jaegeuk@xxxxxxxxxx> Cc: Jens Axboe <axboe@xxxxxxxxx> Cc: Johannes Thumshirn <johannes.thumshirn@xxxxxxx> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> Cc: Miklos Szeredi <miklos@xxxxxxxxxx> Cc: Miklos Szeredi <mszeredi@xxxxxxxxxx> Cc: Theodore Ts'o <tytso@xxxxxxx> Cc: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Cc: Xiubo Li <xiubli@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/iomap/direct-io.c | 55 ++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) --- a/fs/iomap/direct-io.c~iomap-use-kiocb_write_and_wait-and-kiocb_invalidate_pages +++ a/fs/iomap/direct-io.c @@ -472,7 +472,6 @@ __iomap_dio_rw(struct kiocb *iocb, struc const struct iomap_ops *ops, const struct iomap_dio_ops *dops, unsigned int dio_flags, void *private, size_t done_before) { - struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = file_inode(iocb->ki_filp); struct iomap_iter iomi = { .inode = inode, @@ -481,11 +480,11 @@ __iomap_dio_rw(struct kiocb *iocb, struc .flags = IOMAP_DIRECT, .private = private, }; - loff_t end = iomi.pos + iomi.len - 1, ret = 0; bool wait_for_completion = is_sync_kiocb(iocb) || (dio_flags & IOMAP_DIO_FORCE_WAIT); struct blk_plug plug; struct iomap_dio *dio; + loff_t ret = 0; trace_iomap_dio_rw_begin(iocb, iter, dio_flags, done_before); @@ -509,31 +508,29 @@ __iomap_dio_rw(struct kiocb *iocb, struc dio->submit.waiter = current; dio->submit.poll_bio = NULL; + if (iocb->ki_flags & IOCB_NOWAIT) + iomi.flags |= IOMAP_NOWAIT; + if (iov_iter_rw(iter) == READ) { if (iomi.pos >= dio->i_size) goto out_free_dio; - if (iocb->ki_flags & IOCB_NOWAIT) { - if (filemap_range_needs_writeback(mapping, iomi.pos, - end)) { - ret = -EAGAIN; - goto out_free_dio; - } - iomi.flags |= IOMAP_NOWAIT; - } - if (user_backed_iter(iter)) dio->flags |= IOMAP_DIO_DIRTY; + + ret = kiocb_write_and_wait(iocb, iomi.len); + if (ret) + goto out_free_dio; } else { iomi.flags |= IOMAP_WRITE; dio->flags |= IOMAP_DIO_WRITE; - if (iocb->ki_flags & IOCB_NOWAIT) { - if (filemap_range_has_page(mapping, iomi.pos, end)) { - ret = -EAGAIN; + if (dio_flags & IOMAP_DIO_OVERWRITE_ONLY) { + ret = -EAGAIN; + if (iomi.pos >= dio->i_size || + iomi.pos + iomi.len > dio->i_size) goto out_free_dio; - } - iomi.flags |= IOMAP_NOWAIT; + iomi.flags |= IOMAP_OVERWRITE_ONLY; } /* for data sync or sync, we need sync completion processing */ @@ -549,31 +546,19 @@ __iomap_dio_rw(struct kiocb *iocb, struc if (!(iocb->ki_flags & IOCB_SYNC)) dio->flags |= IOMAP_DIO_WRITE_FUA; } - } - - if (dio_flags & IOMAP_DIO_OVERWRITE_ONLY) { - ret = -EAGAIN; - if (iomi.pos >= dio->i_size || - iomi.pos + iomi.len > dio->i_size) - goto out_free_dio; - iomi.flags |= IOMAP_OVERWRITE_ONLY; - } - - ret = filemap_write_and_wait_range(mapping, iomi.pos, end); - if (ret) - goto out_free_dio; - if (iov_iter_rw(iter) == WRITE) { /* * Try to invalidate cache pages for the range we are writing. * If this invalidation fails, let the caller fall back to * buffered I/O. */ - if (invalidate_inode_pages2_range(mapping, - iomi.pos >> PAGE_SHIFT, end >> PAGE_SHIFT)) { - trace_iomap_dio_invalidate_fail(inode, iomi.pos, - iomi.len); - ret = -ENOTBLK; + ret = kiocb_invalidate_pages(iocb, iomi.len); + if (ret) { + if (ret != -EAGAIN) { + trace_iomap_dio_invalidate_fail(inode, iomi.pos, + iomi.len); + ret = -ENOTBLK; + } goto out_free_dio; } _ Patches currently in -mm which might be from hch@xxxxxx are backing_dev-remove-current-backing_dev_info.patch iomap-update-ki_pos-a-little-later-in-iomap_dio_complete.patch filemap-update-ki_pos-in-generic_perform_write.patch filemap-add-a-kiocb_write_and_wait-helper.patch filemap-add-a-kiocb_invalidate_pages-helper.patch filemap-add-a-kiocb_invalidate_post_direct_write-helper.patch iomap-update-ki_pos-in-iomap_file_buffered_write.patch iomap-use-kiocb_write_and_wait-and-kiocb_invalidate_pages.patch fs-factor-out-a-direct_write_fallback-helper.patch fuse-update-ki_pos-in-fuse_perform_write.patch fuse-drop-redundant-arguments-to-fuse_perform_write.patch fuse-use-direct_write_fallback.patch squashfs-dont-include-buffer_headh.patch