Skip to content

Commit ff3d8b9

Browse files
Christoph Hellwigdjwong
authored andcommitted
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>
1 parent af5b5af commit ff3d8b9

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

fs/xfs/xfs_iomap.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,15 @@ static inline bool need_excl_ilock(struct xfs_inode *ip, unsigned flags)
970970
*/
971971
if (xfs_is_reflink_inode(ip) && (flags & (IOMAP_WRITE | IOMAP_ZERO)))
972972
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;
973982
return false;
974983
}
975984

@@ -998,16 +1007,18 @@ xfs_file_iomap_begin(
9981007
return xfs_file_iomap_begin_delay(inode, offset, length, iomap);
9991008
}
10001009

1001-
if (need_excl_ilock(ip, flags)) {
1010+
if (need_excl_ilock(ip, flags))
10021011
lockmode = XFS_ILOCK_EXCL;
1003-
xfs_ilock(ip, XFS_ILOCK_EXCL);
1004-
} else {
1005-
lockmode = xfs_ilock_data_map_shared(ip);
1006-
}
1012+
else
1013+
lockmode = XFS_ILOCK_SHARED;
10071014

1008-
if ((flags & IOMAP_NOWAIT) && !(ip->i_df.if_flags & XFS_IFEXTENTS)) {
1009-
error = -EAGAIN;
1010-
goto out_unlock;
1015+
if (flags & IOMAP_NOWAIT) {
1016+
if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
1017+
return -EAGAIN;
1018+
if (!xfs_ilock_nowait(ip, lockmode))
1019+
return -EAGAIN;
1020+
} else {
1021+
xfs_ilock(ip, lockmode);
10111022
}
10121023

10131024
ASSERT(offset <= mp->m_super->s_maxbytes);

0 commit comments

Comments
 (0)