xfs
[Top] [All Lists]

[PATCH 1/3] xfs: prevent lockdep false positive in xfs_iget_cache_miss

To: xfs@xxxxxxxxxxx
Subject: [PATCH 1/3] xfs: prevent lockdep false positive in xfs_iget_cache_miss
From: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Date: Tue, 03 Mar 2009 14:48:35 -0500
References: <20090303194834.264998000@xxxxxxxxxxxxxxxxxxxxxx>
User-agent: quilt/0.47-1
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@xxxxxx>
Reported-by: Alexander Beregalov <a.beregalov@xxxxxxxxx>
Reviewed-by: Eric Sandeen <sandeen@xxxxxxxxxxx>
Reviewed-by: Felix Blyakher <felixb@xxxxxxx>

Index: xfs/fs/xfs/xfs_iget.c
===================================================================
--- xfs.orig/fs/xfs/xfs_iget.c  2009-03-03 18:02:56.262853671 +0100
+++ xfs/fs/xfs/xfs_iget.c       2009-03-03 18:08:44.681880431 +0100
@@ -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:

<Prev in Thread] Current Thread [Next in Thread>