generic_file_read_iter() and its kiocb_write_and_wait() helper are VFS-level read functions: Their callers are filesystems, and their job is to glue direct I/O or the page cache (filemap_read) to a struct kiocb and iov_iter caller. Move both to fs/read_write.c, alongside vfs_iter_read. Drop the extern from generic_file_read_iter()'s declaration and reflow the generic_file_read_iter() definition to fit on one line too. Signed-off-by: Tal Zussman --- fs/read_write.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 3 +- include/linux/pagemap.h | 1 - mm/filemap.c | 82 ------------------------------------------------- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 50bff7edc91f..59ceea85c163 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -989,6 +989,88 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos, } EXPORT_SYMBOL(vfs_iter_write); +int kiocb_write_and_wait(struct kiocb *iocb, size_t count) +{ + struct address_space *mapping = iocb->ki_filp->f_mapping; + loff_t pos = iocb->ki_pos; + loff_t end = pos + count - 1; + + if (iocb->ki_flags & IOCB_NOWAIT) { + if (filemap_range_needs_writeback(mapping, pos, end)) + return -EAGAIN; + return 0; + } + + return filemap_write_and_wait_range(mapping, pos, end); +} +EXPORT_SYMBOL_GPL(kiocb_write_and_wait); + +/** + * generic_file_read_iter - generic filesystem read routine + * @iocb: kernel I/O control block + * @iter: destination for the data read + * + * This is the "read_iter()" routine for all filesystems + * that can use the page cache directly. + * + * The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall + * be returned when no data can be read without waiting for I/O requests + * to complete; it doesn't prevent readahead. + * + * The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O + * requests shall be made for the read or for readahead. When no data + * can be read, -EAGAIN shall be returned. When readahead would be + * triggered, a partial, possibly empty read shall be returned. + * + * Return: + * * number of bytes copied, even for partial reads + * * negative error code (or 0 if IOCB_NOIO) if nothing was read + */ +ssize_t generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + size_t count = iov_iter_count(iter); + ssize_t retval = 0; + + if (!count) + return 0; /* skip atime */ + + if (iocb->ki_flags & IOCB_DIRECT) { + struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + + retval = kiocb_write_and_wait(iocb, count); + if (retval < 0) + return retval; + file_accessed(file); + + retval = mapping->a_ops->direct_IO(iocb, iter); + if (retval >= 0) { + iocb->ki_pos += retval; + count -= retval; + } + if (retval != -EIOCBQUEUED) + iov_iter_revert(iter, count - iov_iter_count(iter)); + + /* + * Btrfs can have a short DIO read if we encounter + * compressed extents, so if there was an error, or if + * we've already read everything we wanted to, or if + * there was a short read because we hit EOF, go ahead + * and return. Otherwise fallthrough to buffered io for + * the rest of the read. Buffered reads will not work for + * DAX files, so don't bother trying. + */ + if (retval < 0 || !count || IS_DAX(inode)) + return retval; + if (iocb->ki_pos >= i_size_read(inode)) + return retval; + } + + return filemap_read(iocb, iter, retval); +} +EXPORT_SYMBOL(generic_file_read_iter); + static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, unsigned long vlen, loff_t *pos, rwf_t flags) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 776cc82932a7..c0151ced8e7a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3055,7 +3055,8 @@ extern int generic_write_check_limits(struct file *file, loff_t pos, extern int generic_file_rw_checks(struct file *file_in, struct file *file_out); ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *to, ssize_t already_read); -extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); +ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); +int kiocb_write_and_wait(struct kiocb *iocb, size_t count); extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index f86a550ad516..46cefd552a51 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -59,7 +59,6 @@ int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end); int filemap_check_errors(struct address_space *mapping); void __filemap_set_wb_err(struct address_space *mapping, int err); -int kiocb_write_and_wait(struct kiocb *iocb, size_t count); static inline int filemap_write_and_wait(struct address_space *mapping) { diff --git a/mm/filemap.c b/mm/filemap.c index 079f9c3ac8a2..db7c53cd681b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2251,22 +2251,6 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, } EXPORT_SYMBOL_GPL(filemap_read); -int kiocb_write_and_wait(struct kiocb *iocb, size_t count) -{ - struct address_space *mapping = iocb->ki_filp->f_mapping; - loff_t pos = iocb->ki_pos; - loff_t end = pos + count - 1; - - if (iocb->ki_flags & IOCB_NOWAIT) { - if (filemap_range_needs_writeback(mapping, pos, end)) - return -EAGAIN; - return 0; - } - - return filemap_write_and_wait_range(mapping, pos, end); -} -EXPORT_SYMBOL_GPL(kiocb_write_and_wait); - int filemap_invalidate_pages(struct address_space *mapping, loff_t pos, loff_t end, bool nowait) { @@ -2302,72 +2286,6 @@ int kiocb_invalidate_pages(struct kiocb *iocb, size_t count) } EXPORT_SYMBOL_GPL(kiocb_invalidate_pages); -/** - * generic_file_read_iter - generic filesystem read routine - * @iocb: kernel I/O control block - * @iter: destination for the data read - * - * This is the "read_iter()" routine for all filesystems - * that can use the page cache directly. - * - * The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall - * be returned when no data can be read without waiting for I/O requests - * to complete; it doesn't prevent readahead. - * - * The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O - * requests shall be made for the read or for readahead. When no data - * can be read, -EAGAIN shall be returned. When readahead would be - * triggered, a partial, possibly empty read shall be returned. - * - * Return: - * * number of bytes copied, even for partial reads - * * negative error code (or 0 if IOCB_NOIO) if nothing was read - */ -ssize_t -generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) -{ - size_t count = iov_iter_count(iter); - ssize_t retval = 0; - - if (!count) - return 0; /* skip atime */ - - if (iocb->ki_flags & IOCB_DIRECT) { - struct file *file = iocb->ki_filp; - struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - - retval = kiocb_write_and_wait(iocb, count); - if (retval < 0) - return retval; - file_accessed(file); - - retval = mapping->a_ops->direct_IO(iocb, iter); - if (retval >= 0) { - iocb->ki_pos += retval; - count -= retval; - } - if (retval != -EIOCBQUEUED) - iov_iter_revert(iter, count - iov_iter_count(iter)); - - /* - * Btrfs can have a short DIO read if we encounter - * compressed extents, so if there was an error, or if - * we've already read everything we wanted to, or if - * there was a short read because we hit EOF, go ahead - * and return. Otherwise fallthrough to buffered io for - * the rest of the read. Buffered reads will not work for - * DAX files, so don't bother trying. - */ - if (retval < 0 || !count || IS_DAX(inode)) - return retval; - if (iocb->ki_pos >= i_size_read(inode)) - return retval; - } - - return filemap_read(iocb, iter, retval); -} -EXPORT_SYMBOL(generic_file_read_iter); /* * Splice subpages from a folio into a pipe. -- 2.39.5