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

Commit 56e73ec4 authored by David Chinner's avatar David Chinner Committed by Lachlan McIlroy
Browse files

[XFS] Can't lock inodes in radix tree preload region



When we are inside a radix tree preload region, we cannot sleep. Recently
we moved the inode locking inside the preload region for the inode radix
tree. Fix that, and fix a missed unlock in another error path in the same
code at the same time.

SGI-PV: 987246

SGI-Modid: xfs-linux-melb:xfs-kern:32385a

Signed-off-by: default avatarDavid Chinner <david@fromorbit.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
parent 2b7035fd
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -159,18 +159,19 @@ xfs_iget_cache_miss(
		goto out_destroy;
	}

	if (lock_flags)
		xfs_ilock(ip, lock_flags);

	/*
	 * Preload the radix tree so we can insert safely under the
	 * write spinlock.
	 * write spinlock. Note that we cannot sleep inside the preload
	 * region.
	 */
	if (radix_tree_preload(GFP_KERNEL)) {
		error = EAGAIN;
		goto out_destroy;
		goto out_unlock;
	}

	if (lock_flags)
		xfs_ilock(ip, lock_flags);

	mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
	first_index = agino & mask;
	write_lock(&pag->pag_ici_lock);
@@ -181,7 +182,7 @@ xfs_iget_cache_miss(
		WARN_ON(error != -EEXIST);
		XFS_STATS_INC(xs_ig_dup);
		error = EAGAIN;
		goto out_unlock;
		goto out_preload_end;
	}

	/* These values _must_ be set before releasing the radix tree lock! */
@@ -193,9 +194,12 @@ xfs_iget_cache_miss(
	*ipp = ip;
	return 0;

out_unlock:
out_preload_end:
	write_unlock(&pag->pag_ici_lock);
	radix_tree_preload_end();
out_unlock:
	if (lock_flags)
		xfs_iunlock(ip, lock_flags);
out_destroy:
	xfs_idestroy(ip);
	return error;