diff options
Diffstat (limited to 'fs/xfs/xfs_iget.c')
| -rw-r--r-- | fs/xfs/xfs_iget.c | 15 | 
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e2fb6210d4c..478e587087f 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -246,9 +246,6 @@ 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. Note that we cannot sleep inside the preload @@ -256,7 +253,16 @@ xfs_iget_cache_miss(  	 */  	if (radix_tree_preload(GFP_KERNEL)) {  		error = EAGAIN; -		goto out_unlock; +		goto out_destroy; +	} + +	/* +	 * Because the inode hasn't been added to the radix-tree yet it can't +	 * be found by another thread, so we can do the non-sleeping lock here. +	 */ +	if (lock_flags) { +		if (!xfs_ilock_nowait(ip, lock_flags)) +			BUG();  	}  	mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); @@ -284,7 +290,6 @@ xfs_iget_cache_miss(  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:  |