[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: David Chinner <david@fromorbit.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org>
This commit is contained in:
parent
2b7035fd74
commit
56e73ec47d
|
@ -159,18 +159,19 @@ xfs_iget_cache_miss(
|
||||||
goto out_destroy;
|
goto out_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lock_flags)
|
||||||
|
xfs_ilock(ip, lock_flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preload the radix tree so we can insert safely under the
|
* 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)) {
|
if (radix_tree_preload(GFP_KERNEL)) {
|
||||||
error = EAGAIN;
|
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);
|
mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
|
||||||
first_index = agino & mask;
|
first_index = agino & mask;
|
||||||
write_lock(&pag->pag_ici_lock);
|
write_lock(&pag->pag_ici_lock);
|
||||||
|
@ -181,7 +182,7 @@ xfs_iget_cache_miss(
|
||||||
WARN_ON(error != -EEXIST);
|
WARN_ON(error != -EEXIST);
|
||||||
XFS_STATS_INC(xs_ig_dup);
|
XFS_STATS_INC(xs_ig_dup);
|
||||||
error = EAGAIN;
|
error = EAGAIN;
|
||||||
goto out_unlock;
|
goto out_preload_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These values _must_ be set before releasing the radix tree lock! */
|
/* These values _must_ be set before releasing the radix tree lock! */
|
||||||
|
@ -193,9 +194,12 @@ xfs_iget_cache_miss(
|
||||||
*ipp = ip;
|
*ipp = ip;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_unlock:
|
out_preload_end:
|
||||||
write_unlock(&pag->pag_ici_lock);
|
write_unlock(&pag->pag_ici_lock);
|
||||||
radix_tree_preload_end();
|
radix_tree_preload_end();
|
||||||
|
out_unlock:
|
||||||
|
if (lock_flags)
|
||||||
|
xfs_iunlock(ip, lock_flags);
|
||||||
out_destroy:
|
out_destroy:
|
||||||
xfs_idestroy(ip);
|
xfs_idestroy(ip);
|
||||||
return error;
|
return error;
|
||||||
|
|
Loading…
Reference in New Issue