[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:
Родитель
2b7035fd74
Коммит
56e73ec47d
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче