/*
         * 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);
                __d_drop(dentry);
 
        spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_inode_lock);
 
        fsnotify_nameremove(dentry, isdir);
 }
 
        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;
 
        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);
 
        iput(inode);
        return actual;
-
-shouldnt_be_hashed:
-       spin_unlock(&dcache_inode_lock);
-       BUG();
 }
 EXPORT_SYMBOL_GPL(d_materialise_unique);