diff options
author | Christoph Hellwig <hch@lst.de> | 2016-07-19 21:36:57 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-07-19 21:36:57 -0400 |
commit | f1285ff0acf9040a39921355d07bd83a3308c402 (patch) | |
tree | ea0906759f357f47b8c1049615f1f44a7f817d5e | |
parent | bbc5a740c4f27a9732a3a3decf3186b4bce21108 (diff) |
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 <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/xfs/xfs_file.c | 15 |
1 files changed, 13 insertions, 2 deletions
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( | |||
289 | struct address_space *mapping = iocb->ki_filp->f_mapping; | 289 | struct address_space *mapping = iocb->ki_filp->f_mapping; |
290 | struct inode *inode = mapping->host; | 290 | struct inode *inode = mapping->host; |
291 | struct xfs_inode *ip = XFS_I(inode); | 291 | struct xfs_inode *ip = XFS_I(inode); |
292 | loff_t isize = i_size_read(inode); | ||
292 | size_t count = iov_iter_count(to); | 293 | size_t count = iov_iter_count(to); |
294 | struct iov_iter data; | ||
293 | struct xfs_buftarg *target; | 295 | struct xfs_buftarg *target; |
294 | ssize_t ret = 0; | 296 | ssize_t ret = 0; |
295 | 297 | ||
296 | trace_xfs_file_direct_read(ip, count, iocb->ki_pos); | 298 | trace_xfs_file_direct_read(ip, count, iocb->ki_pos); |
297 | 299 | ||
300 | if (!count) | ||
301 | return 0; /* skip atime */ | ||
302 | |||
298 | if (XFS_IS_REALTIME_INODE(ip)) | 303 | if (XFS_IS_REALTIME_INODE(ip)) |
299 | target = ip->i_mount->m_rtdev_targp; | 304 | target = ip->i_mount->m_rtdev_targp; |
300 | else | 305 | else |
@@ -303,7 +308,7 @@ xfs_file_dio_aio_read( | |||
303 | if (!IS_DAX(inode)) { | 308 | if (!IS_DAX(inode)) { |
304 | /* DIO must be aligned to device logical sector size */ | 309 | /* DIO must be aligned to device logical sector size */ |
305 | if ((iocb->ki_pos | count) & target->bt_logical_sectormask) { | 310 | if ((iocb->ki_pos | count) & target->bt_logical_sectormask) { |
306 | if (iocb->ki_pos == i_size_read(inode)) | 311 | if (iocb->ki_pos == isize) |
307 | return 0; | 312 | return 0; |
308 | return -EINVAL; | 313 | return -EINVAL; |
309 | } | 314 | } |
@@ -354,9 +359,15 @@ xfs_file_dio_aio_read( | |||
354 | xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL); | 359 | xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL); |
355 | } | 360 | } |
356 | 361 | ||
357 | ret = generic_file_read_iter(iocb, to); | 362 | data = *to; |
363 | ret = mapping->a_ops->direct_IO(iocb, &data); | ||
364 | if (ret > 0) { | ||
365 | iocb->ki_pos += ret; | ||
366 | iov_iter_advance(to, ret); | ||
367 | } | ||
358 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); | 368 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); |
359 | 369 | ||
370 | file_accessed(iocb->ki_filp); | ||
360 | return ret; | 371 | return ret; |
361 | } | 372 | } |
362 | 373 | ||