diff options
author | Dave Chinner <david@fromorbit.com> | 2016-01-04 16:08:47 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-01-04 16:08:47 -0500 |
commit | 4922be51ef1a95ca6a38694cf0cde5dd0308a24e (patch) | |
tree | 5a94d1298db141e63d43d9d6f42774be245d8221 /fs/xfs | |
parent | 7eeabbd4b6b69f3f6cb75730f17804b714bd853b (diff) | |
parent | a6d7636e8d0fd94fd1937db91d5b06a91fa85dde (diff) |
Merge branch 'xfs-dax-fixes-for-4.5' into for-next
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_file.c | 25 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 11 |
2 files changed, 24 insertions, 12 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( | |||
402 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 402 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
403 | return -EIO; | 403 | return -EIO; |
404 | 404 | ||
405 | xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); | ||
406 | |||
407 | trace_xfs_file_splice_read(ip, count, *ppos, ioflags); | 405 | trace_xfs_file_splice_read(ip, count, *ppos, ioflags); |
408 | 406 | ||
409 | /* for dax, we need to avoid the page cache */ | 407 | /* |
410 | if (IS_DAX(VFS_I(ip))) | 408 | * DAX inodes cannot ues the page cache for splice, so we have to push |
411 | ret = default_file_splice_read(infilp, ppos, pipe, count, flags); | 409 | * them through the VFS IO path. This means it goes through |
412 | else | 410 | * ->read_iter, which for us takes the XFS_IOLOCK_SHARED. Hence we |
413 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); | 411 | * cannot lock the splice operation at this level for DAX inodes. |
414 | if (ret > 0) | 412 | */ |
415 | XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); | 413 | if (IS_DAX(VFS_I(ip))) { |
414 | ret = default_file_splice_read(infilp, ppos, pipe, count, | ||
415 | flags); | ||
416 | goto out; | ||
417 | } | ||
416 | 418 | ||
419 | xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); | ||
420 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); | ||
417 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); | 421 | xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); |
422 | out: | ||
423 | if (ret > 0) | ||
424 | XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); | ||
418 | return ret; | 425 | return ret; |
419 | } | 426 | } |
420 | 427 | ||
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f4f5b43cf647..9ed146b96856 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -203,15 +203,20 @@ xfs_iomap_write_direct( | |||
203 | * this outside the transaction context, but if we commit and then crash | 203 | * this outside the transaction context, but if we commit and then crash |
204 | * we may not have zeroed the blocks and this will be exposed on | 204 | * we may not have zeroed the blocks and this will be exposed on |
205 | * recovery of the allocation. Hence we must zero before commit. | 205 | * recovery of the allocation. Hence we must zero before commit. |
206 | * | ||
206 | * Further, if we are mapping unwritten extents here, we need to zero | 207 | * Further, if we are mapping unwritten extents here, we need to zero |
207 | * and convert them to written so that we don't need an unwritten extent | 208 | * and convert them to written so that we don't need an unwritten extent |
208 | * callback for DAX. This also means that we need to be able to dip into | 209 | * callback for DAX. This also means that we need to be able to dip into |
209 | * the reserve block pool if there is no space left but we need to do | 210 | * the reserve block pool for bmbt block allocation if there is no space |
210 | * unwritten extent conversion. | 211 | * left but we need to do unwritten extent conversion. |
211 | */ | 212 | */ |
213 | |||
212 | if (IS_DAX(VFS_I(ip))) { | 214 | if (IS_DAX(VFS_I(ip))) { |
213 | bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; | 215 | bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; |
214 | tp->t_flags |= XFS_TRANS_RESERVE; | 216 | if (ISUNWRITTEN(imap)) { |
217 | tp->t_flags |= XFS_TRANS_RESERVE; | ||
218 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; | ||
219 | } | ||
215 | } | 220 | } |
216 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, | 221 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, |
217 | resblks, resrtextents); | 222 | resblks, resrtextents); |