summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2009-03-03 14:48:35 -0500
committerFelix Blyakher <felixb@sgi.com>2009-03-04 07:31:48 -0600
commited93ec3907f063268ced18728d0653f6199d100c (patch)
treee9e15deaec2c4609c2097da4064beef4c6341f3e
parente8fa6b483feebd23ded5eb01afd7a6e82b6078c6 (diff)
downloadlinux-ed93ec3907f063268ced18728d0653f6199d100c.tar.gz
linux-ed93ec3907f063268ced18728d0653f6199d100c.tar.bz2
linux-ed93ec3907f063268ced18728d0653f6199d100c.zip
xfs: prevent lockdep false positive in xfs_iget_cache_miss
The inode can't be locked by anyone else as we just created it a few lines above and it's not been added to any lookup data structure yet. So use a trylock that must succeed to get around the lockdep warnings. Signed-off-by: Christoph Hellwig <hch@lst.de> Reported-by: Alexander Beregalov <a.beregalov@gmail.com> Reviewed-by: Eric Sandeen <sandeen@sandeen.net> Reviewed-by: Felix Blyakher <felixb@sgi.com> Signed-off-by: Felix Blyakher <felixb@sgi.com>
-rw-r--r--fs/xfs/xfs_iget.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index e2fb6210d4c5..478e587087fe 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: