diff options
author | Christoph Hellwig <hch@lst.de> | 2018-03-01 17:12:45 -0500 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-03-01 17:12:45 -0500 |
commit | ff3d8b9c4cb95180ae6ef9eed28409840525b9fa (patch) | |
tree | 14585938c73fbce45ff05877544aaab6e2c17503 /fs | |
parent | af5b5afe9ac68406892fa343fafba4ea988c3c69 (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.c | 27 |
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); |