Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21c3ea18 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Dave Chinner
Browse files

xfs: unlock i_mutex in xfs_break_layouts



We want to drop all I/O path locks when recalling layouts, and that includes
i_mutex for the write path.  Without this we get stuck processe when recalls
take too long.

[dchinner: fix build with !CONFIG_PNFS]

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 66db8104
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -555,7 +555,7 @@ xfs_file_aio_write_checks(
	if (error)
		return error;

	error = xfs_break_layouts(inode, iolock);
	error = xfs_break_layouts(inode, iolock, true);
	if (error)
		return error;

@@ -842,7 +842,7 @@ xfs_file_fallocate(
		return -EOPNOTSUPP;

	xfs_ilock(ip, iolock);
	error = xfs_break_layouts(inode, &iolock);
	error = xfs_break_layouts(inode, &iolock, false);
	if (error)
		goto out_unlock;

+1 −1
Original line number Diff line number Diff line
@@ -639,7 +639,7 @@ xfs_ioc_space(
		return error;

	xfs_ilock(ip, iolock);
	error = xfs_break_layouts(inode, &iolock);
	error = xfs_break_layouts(inode, &iolock, false);
	if (error)
		goto out_unlock;

+1 −1
Original line number Diff line number Diff line
@@ -988,7 +988,7 @@ xfs_vn_setattr(
		uint		iolock = XFS_IOLOCK_EXCL;

		xfs_ilock(ip, iolock);
		error = xfs_break_layouts(dentry->d_inode, &iolock);
		error = xfs_break_layouts(dentry->d_inode, &iolock, true);
		if (!error)
			error = xfs_setattr_size(ip, iattr);
		xfs_iunlock(ip, iolock);
+6 −1
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@
int
xfs_break_layouts(
	struct inode		*inode,
	uint			*iolock)
	uint			*iolock,
	bool			with_imutex)
{
	struct xfs_inode	*ip = XFS_I(inode);
	int			error;
@@ -40,8 +41,12 @@ xfs_break_layouts(

	while ((error = break_layout(inode, false) == -EWOULDBLOCK)) {
		xfs_iunlock(ip, *iolock);
		if (with_imutex && (*iolock & XFS_IOLOCK_EXCL))
			mutex_unlock(&inode->i_mutex);
		error = break_layout(inode, true);
		*iolock = XFS_IOLOCK_EXCL;
		if (with_imutex)
			mutex_lock(&inode->i_mutex);
		xfs_ilock(ip, *iolock);
	}

+3 −2
Original line number Diff line number Diff line
@@ -8,9 +8,10 @@ int xfs_fs_map_blocks(struct inode *inode, loff_t offset, u64 length,
int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps,
		struct iattr *iattr);

int xfs_break_layouts(struct inode *inode, uint *iolock);
int xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex);
#else
static inline int xfs_break_layouts(struct inode *inode, uint *iolock)
static inline int
xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex)
{
	return 0;
}