aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2016-01-04 16:08:47 -0500
committerDave Chinner <david@fromorbit.com>2016-01-04 16:08:47 -0500
commit4922be51ef1a95ca6a38694cf0cde5dd0308a24e (patch)
tree5a94d1298db141e63d43d9d6f42774be245d8221 /fs/xfs
parent7eeabbd4b6b69f3f6cb75730f17804b714bd853b (diff)
parenta6d7636e8d0fd94fd1937db91d5b06a91fa85dde (diff)
Merge branch 'xfs-dax-fixes-for-4.5' into for-next
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_file.c25
-rw-r--r--fs/xfs/xfs_iomap.c11
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);
422out:
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);