From: Christoph Hellwig Date: Wed, 20 Jul 2016 01:36:57 +0000 (+1000) Subject: xfs: stop using generic_file_read_iter for direct I/O X-Git-Tag: v4.8-rc1~7^2~54^2~2 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=f1285ff0acf9040a39921355d07bd83a3308c402;p=cascardo%2Flinux.git xfs: stop using generic_file_read_iter for direct I/O XFS already implement it's own flushing of the pagecache because it implements proper synchronization for direct I/O reads. This means calling generic_file_read_iter for direct I/O is rather useless, as it doesn't do much but updating the atime and iocb position for us. This also gets rid of the buffered I/O fallback that isn't used for XFS. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index fdb123ffd616..440bb8b5c64d 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -289,12 +289,17 @@ xfs_file_dio_aio_read( struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; struct xfs_inode *ip = XFS_I(inode); + loff_t isize = i_size_read(inode); size_t count = iov_iter_count(to); + struct iov_iter data; struct xfs_buftarg *target; ssize_t ret = 0; trace_xfs_file_direct_read(ip, count, iocb->ki_pos); + if (!count) + return 0; /* skip atime */ + if (XFS_IS_REALTIME_INODE(ip)) target = ip->i_mount->m_rtdev_targp; else @@ -303,7 +308,7 @@ xfs_file_dio_aio_read( if (!IS_DAX(inode)) { /* DIO must be aligned to device logical sector size */ if ((iocb->ki_pos | count) & target->bt_logical_sectormask) { - if (iocb->ki_pos == i_size_read(inode)) + if (iocb->ki_pos == isize) return 0; return -EINVAL; } @@ -354,9 +359,15 @@ xfs_file_dio_aio_read( xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL); } - ret = generic_file_read_iter(iocb, to); + data = *to; + ret = mapping->a_ops->direct_IO(iocb, &data); + if (ret > 0) { + iocb->ki_pos += ret; + iov_iter_advance(to, ret); + } xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); + file_accessed(iocb->ki_filp); return ret; }