fs: dcache reduce dcache_inode_lock
Nick Piggin [Fri, 7 Jan 2011 06:49:42 +0000 (17:49 +1100)]
dcache_inode_lock can be avoided in d_delete() and d_materialise_unique()
in cases where it is not required.

Signed-off-by: Nick Piggin <npiggin@kernel.dk>

fs/dcache.c

index ccdc5c2..01f0167 100644 (file)
@@ -1828,10 +1828,15 @@ void d_delete(struct dentry * dentry)
        /*
         * Are we the only user?
         */
-       spin_lock(&dcache_inode_lock);
+again:
        spin_lock(&dentry->d_lock);
        isdir = S_ISDIR(dentry->d_inode->i_mode);
        if (dentry->d_count == 1) {
+               if (!spin_trylock(&dcache_inode_lock)) {
+                       spin_unlock(&dentry->d_lock);
+                       cpu_relax();
+                       goto again;
+               }
                dentry->d_flags &= ~DCACHE_CANT_MOUNT;
                dentry_iput(dentry);
                fsnotify_nameremove(dentry, isdir);
@@ -1842,7 +1847,6 @@ void d_delete(struct dentry * dentry)
                __d_drop(dentry);
 
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_inode_lock);
 
        fsnotify_nameremove(dentry, isdir);
 }
@@ -2164,14 +2168,15 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 
        BUG_ON(!d_unhashed(dentry));
 
-       spin_lock(&dcache_inode_lock);
-
        if (!inode) {
                actual = dentry;
                __d_instantiate(dentry, NULL);
-               goto found_lock;
+               d_rehash(actual);
+               goto out_nolock;
        }
 
+       spin_lock(&dcache_inode_lock);
+
        if (S_ISDIR(inode->i_mode)) {
                struct dentry *alias;
 
@@ -2198,10 +2203,9 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
        actual = __d_instantiate_unique(dentry, inode);
        if (!actual)
                actual = dentry;
-       else if (unlikely(!d_unhashed(actual)))
-               goto shouldnt_be_hashed;
+       else
+               BUG_ON(!d_unhashed(actual));
 
-found_lock:
        spin_lock(&actual->d_lock);
 found:
        spin_lock(&dcache_hash_lock);
@@ -2217,10 +2221,6 @@ out_nolock:
 
        iput(inode);
        return actual;
-
-shouldnt_be_hashed:
-       spin_unlock(&dcache_inode_lock);
-       BUG();
 }
 EXPORT_SYMBOL_GPL(d_materialise_unique);