Skip to content

Commit 4922be5

Browse files
committed
Merge branch 'xfs-dax-fixes-for-4.5' into for-next
2 parents 7eeabbd + a6d7636 commit 4922be5

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

fs/xfs/xfs_file.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -402,19 +402,26 @@ xfs_file_splice_read(
402402
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
403403
return -EIO;
404404

405-
xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
406-
407405
trace_xfs_file_splice_read(ip, count, *ppos, ioflags);
408406

409-
/* for dax, we need to avoid the page cache */
410-
if (IS_DAX(VFS_I(ip)))
411-
ret = default_file_splice_read(infilp, ppos, pipe, count, flags);
412-
else
413-
ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
414-
if (ret > 0)
415-
XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret);
407+
/*
408+
* DAX inodes cannot ues the page cache for splice, so we have to push
409+
* them through the VFS IO path. This means it goes through
410+
* ->read_iter, which for us takes the XFS_IOLOCK_SHARED. Hence we
411+
* cannot lock the splice operation at this level for DAX inodes.
412+
*/
413+
if (IS_DAX(VFS_I(ip))) {
414+
ret = default_file_splice_read(infilp, ppos, pipe, count,
415+
flags);
416+
goto out;
417+
}
416418

419+
xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
420+
ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
417421
xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
422+
out:
423+
if (ret > 0)
424+
XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret);
418425
return ret;
419426
}
420427

fs/xfs/xfs_iomap.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,20 @@ xfs_iomap_write_direct(
203203
* this outside the transaction context, but if we commit and then crash
204204
* we may not have zeroed the blocks and this will be exposed on
205205
* recovery of the allocation. Hence we must zero before commit.
206+
*
206207
* Further, if we are mapping unwritten extents here, we need to zero
207208
* and convert them to written so that we don't need an unwritten extent
208209
* 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-
* unwritten extent conversion.
210+
* the reserve block pool for bmbt block allocation if there is no space
211+
* left but we need to do unwritten extent conversion.
211212
*/
213+
212214
if (IS_DAX(VFS_I(ip))) {
213215
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+
}
215220
}
216221
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
217222
resblks, resrtextents);

0 commit comments

Comments
 (0)