diff options
author | Dave Chinner <david@fromorbit.com> | 2016-01-05 08:08:47 +1100 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-01-05 08:08:47 +1100 |
commit | 4922be51ef1a95ca6a38694cf0cde5dd0308a24e (patch) | |
tree | 5a94d1298db141e63d43d9d6f42774be245d8221 /fs/xfs/xfs_file.c | |
parent | 7eeabbd4b6b69f3f6cb75730f17804b714bd853b (diff) | |
parent | a6d7636e8d0fd94fd1937db91d5b06a91fa85dde (diff) | |
download | talos-obmc-linux-4922be51ef1a95ca6a38694cf0cde5dd0308a24e.tar.gz talos-obmc-linux-4922be51ef1a95ca6a38694cf0cde5dd0308a24e.zip |
Merge branch 'xfs-dax-fixes-for-4.5' into for-next
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r-- | fs/xfs/xfs_file.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f5392ab2def1..ebe9b8290a70 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -402,19 +402,26 @@ xfs_file_splice_read( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; - xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); - trace_xfs_file_splice_read(ip, count, *ppos, ioflags); - /* for dax, we need to avoid the page cache */ - if (IS_DAX(VFS_I(ip))) - ret = default_file_splice_read(infilp, ppos, pipe, count, flags); - else - ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); - if (ret > 0) - XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); + /* + * DAX inodes cannot ues the page cache for splice, so we have to push + * them through the VFS IO path. This means it goes through + * ->read_iter, which for us takes the XFS_IOLOCK_SHARED. Hence we + * cannot lock the splice operation at this level for DAX inodes. + */ + if (IS_DAX(VFS_I(ip))) { + ret = default_file_splice_read(infilp, ppos, pipe, count, + flags); + goto out; + } + xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); + ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); +out: + if (ret > 0) + XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); return ret; } |