summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-03-01 17:12:45 -0500
committerDarrick J. Wong <darrick.wong@oracle.com>2018-03-01 17:12:45 -0500
commitff3d8b9c4cb95180ae6ef9eed28409840525b9fa (patch)
tree14585938c73fbce45ff05877544aaab6e2c17503 /fs
parentaf5b5afe9ac68406892fa343fafba4ea988c3c69 (diff)
xfs: don't block on the ilock for RWF_NOWAIT
Fix xfs_file_iomap_begin to trylock the ilock if IOMAP_NOWAIT is passed, so that we don't block io_submit callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_iomap.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index ee01859b77a5..046469fcc1b8 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -970,6 +970,15 @@ static inline bool need_excl_ilock(struct xfs_inode *ip, unsigned flags)
970 */ 970 */
971 if (xfs_is_reflink_inode(ip) && (flags & (IOMAP_WRITE | IOMAP_ZERO))) 971 if (xfs_is_reflink_inode(ip) && (flags & (IOMAP_WRITE | IOMAP_ZERO)))
972 return true; 972 return true;
973
974 /*
975 * Extents not yet cached requires exclusive access, don't block.
976 * This is an opencoded xfs_ilock_data_map_shared() to cater for the
977 * non-blocking behaviour.
978 */
979 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
980 !(ip->i_df.if_flags & XFS_IFEXTENTS))
981 return true;
973 return false; 982 return false;
974} 983}
975 984
@@ -998,16 +1007,18 @@ xfs_file_iomap_begin(
998 return xfs_file_iomap_begin_delay(inode, offset, length, iomap); 1007 return xfs_file_iomap_begin_delay(inode, offset, length, iomap);
999 } 1008 }
1000 1009
1001 if (need_excl_ilock(ip, flags)) { 1010 if (need_excl_ilock(ip, flags))
1002 lockmode = XFS_ILOCK_EXCL; 1011 lockmode = XFS_ILOCK_EXCL;
1003 xfs_ilock(ip, XFS_ILOCK_EXCL); 1012 else
1004 } else { 1013 lockmode = XFS_ILOCK_SHARED;
1005 lockmode = xfs_ilock_data_map_shared(ip);
1006 }
1007 1014
1008 if ((flags & IOMAP_NOWAIT) && !(ip->i_df.if_flags & XFS_IFEXTENTS)) { 1015 if (flags & IOMAP_NOWAIT) {
1009 error = -EAGAIN; 1016 if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
1010 goto out_unlock; 1017 return -EAGAIN;
1018 if (!xfs_ilock_nowait(ip, lockmode))
1019 return -EAGAIN;
1020 } else {
1021 xfs_ilock(ip, lockmode);
1011 } 1022 }
1012 1023
1013 ASSERT(offset <= mp->m_super->s_maxbytes); 1024 ASSERT(offset <= mp->m_super->s_maxbytes);