Loading fs/xfs/xfs_file.c +16 −9 Original line number Original line Diff line number Diff line Loading @@ -402,19 +402,26 @@ xfs_file_splice_read( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; return -EIO; xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); trace_xfs_file_splice_read(ip, count, *ppos, ioflags); trace_xfs_file_splice_read(ip, count, *ppos, ioflags); /* for dax, we need to avoid the page cache */ /* if (IS_DAX(VFS_I(ip))) * DAX inodes cannot ues the page cache for splice, so we have to push ret = default_file_splice_read(infilp, ppos, pipe, count, flags); * them through the VFS IO path. This means it goes through else * ->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); ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); out: if (ret > 0) if (ret > 0) XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); return ret; return ret; } } Loading fs/xfs/xfs_iomap.c +8 −3 Original line number Original line Diff line number Diff line Loading @@ -203,15 +203,20 @@ xfs_iomap_write_direct( * this outside the transaction context, but if we commit and then crash * this outside the transaction context, but if we commit and then crash * we may not have zeroed the blocks and this will be exposed on * we may not have zeroed the blocks and this will be exposed on * recovery of the allocation. Hence we must zero before commit. * recovery of the allocation. Hence we must zero before commit. * * Further, if we are mapping unwritten extents here, we need to zero * Further, if we are mapping unwritten extents here, we need to zero * and convert them to written so that we don't need an unwritten extent * and convert them to written so that we don't need an unwritten extent * callback for DAX. This also means that we need to be able to dip into * callback for DAX. This also means that we need to be able to dip into * the reserve block pool if there is no space left but we need to do * the reserve block pool for bmbt block allocation if there is no space * unwritten extent conversion. * left but we need to do unwritten extent conversion. */ */ if (IS_DAX(VFS_I(ip))) { if (IS_DAX(VFS_I(ip))) { bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; if (ISUNWRITTEN(imap)) { tp->t_flags |= XFS_TRANS_RESERVE; tp->t_flags |= XFS_TRANS_RESERVE; resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; } } } error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, resrtextents); resblks, resrtextents); Loading Loading
fs/xfs/xfs_file.c +16 −9 Original line number Original line Diff line number Diff line Loading @@ -402,19 +402,26 @@ xfs_file_splice_read( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; return -EIO; xfs_rw_ilock(ip, XFS_IOLOCK_SHARED); trace_xfs_file_splice_read(ip, count, *ppos, ioflags); trace_xfs_file_splice_read(ip, count, *ppos, ioflags); /* for dax, we need to avoid the page cache */ /* if (IS_DAX(VFS_I(ip))) * DAX inodes cannot ues the page cache for splice, so we have to push ret = default_file_splice_read(infilp, ppos, pipe, count, flags); * them through the VFS IO path. This means it goes through else * ->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); ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); out: if (ret > 0) if (ret > 0) XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); return ret; return ret; } } Loading
fs/xfs/xfs_iomap.c +8 −3 Original line number Original line Diff line number Diff line Loading @@ -203,15 +203,20 @@ xfs_iomap_write_direct( * this outside the transaction context, but if we commit and then crash * this outside the transaction context, but if we commit and then crash * we may not have zeroed the blocks and this will be exposed on * we may not have zeroed the blocks and this will be exposed on * recovery of the allocation. Hence we must zero before commit. * recovery of the allocation. Hence we must zero before commit. * * Further, if we are mapping unwritten extents here, we need to zero * Further, if we are mapping unwritten extents here, we need to zero * and convert them to written so that we don't need an unwritten extent * and convert them to written so that we don't need an unwritten extent * callback for DAX. This also means that we need to be able to dip into * callback for DAX. This also means that we need to be able to dip into * the reserve block pool if there is no space left but we need to do * the reserve block pool for bmbt block allocation if there is no space * unwritten extent conversion. * left but we need to do unwritten extent conversion. */ */ if (IS_DAX(VFS_I(ip))) { if (IS_DAX(VFS_I(ip))) { bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; if (ISUNWRITTEN(imap)) { tp->t_flags |= XFS_TRANS_RESERVE; tp->t_flags |= XFS_TRANS_RESERVE; resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; } } } error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, resrtextents); resblks, resrtextents); Loading