Unless direct I/O path of generic_file_read_iter() ended up with an error or a short read, it doesn't use inode. So, load inode and size later, only when they're needed. This cuts two memory reads and also imrpoves code generation, e.g. loads from stack. Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- NOTE: as a side effect, it reads inode->i_size after ->direct_IO(), and I'm not sure whether that's valid, so would be great to get feedback from someone who knows better. mm/filemap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index d1458ecf2f51..0030c454ec35 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2658,10 +2658,8 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) if (iocb->ki_flags & IOCB_DIRECT) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - loff_t size; + struct inode *inode; - size = i_size_read(inode); if (iocb->ki_flags & IOCB_NOWAIT) { if (filemap_range_needs_writeback(mapping, iocb->ki_pos, iocb->ki_pos + count - 1)) @@ -2693,8 +2691,10 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) * the rest of the read. Buffered reads will not work for * DAX files, so don't bother trying. */ - if (retval < 0 || !count || iocb->ki_pos >= size || - IS_DAX(inode)) + if (retval < 0 || !count) + return retval; + inode = mapping->host; + if (iocb->ki_pos >= i_size_read(inode) || IS_DAX(inode)) return retval; } -- 2.32.0