libceph: introduce and switch to reopen_session()
[linux-2.6-block.git] / fs / dcache.c
index 244fd2487fe99ba631cb4692498a5fdf79812506..32ceae3e611297a9e2ff99c6be92c544026c870d 100644 (file)
@@ -1745,13 +1745,11 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
        unsigned add_flags = d_flags_for_inode(inode);
 
        spin_lock(&dentry->d_lock);
-       if (inode)
-               hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
+       hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
        raw_write_seqcount_begin(&dentry->d_seq);
        __d_set_inode_and_type(dentry, inode, add_flags);
        raw_write_seqcount_end(&dentry->d_seq);
-       if (inode)
-               __fsnotify_d_instantiate(dentry);
+       __fsnotify_d_instantiate(dentry);
        spin_unlock(&dentry->d_lock);
 }
 
@@ -1773,11 +1771,11 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
 void d_instantiate(struct dentry *entry, struct inode * inode)
 {
        BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
-       if (inode)
+       if (inode) {
                spin_lock(&inode->i_lock);
-       __d_instantiate(entry, inode);
-       if (inode)
+               __d_instantiate(entry, inode);
                spin_unlock(&inode->i_lock);
+       }
        security_d_instantiate(entry, inode);
 }
 EXPORT_SYMBOL(d_instantiate);
@@ -2362,6 +2360,19 @@ void d_rehash(struct dentry * entry)
 }
 EXPORT_SYMBOL(d_rehash);
 
+
+/* inode->i_lock held if inode is non-NULL */
+
+static inline void __d_add(struct dentry *dentry, struct inode *inode)
+{
+       if (inode) {
+               __d_instantiate(dentry, inode);
+               spin_unlock(&inode->i_lock);
+       }
+       security_d_instantiate(dentry, inode);
+       d_rehash(dentry);
+}
+
 /**
  * d_add - add dentry to hash queues
  * @entry: dentry to add
@@ -2373,8 +2384,9 @@ EXPORT_SYMBOL(d_rehash);
 
 void d_add(struct dentry *entry, struct inode *inode)
 {
-       d_instantiate(entry, inode);
-       d_rehash(entry);
+       if (inode)
+               spin_lock(&inode->i_lock);
+       __d_add(entry, inode);
 }
 EXPORT_SYMBOL(d_add);
 
@@ -2764,10 +2776,9 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
 
        BUG_ON(!d_unhashed(dentry));
 
-       if (!inode) {
-               __d_instantiate(dentry, NULL);
+       if (!inode)
                goto out;
-       }
+
        spin_lock(&inode->i_lock);
        if (S_ISDIR(inode->i_mode)) {
                struct dentry *new = __d_find_any_alias(inode);
@@ -2801,12 +2812,8 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
                        return new;
                }
        }
-       /* already taking inode->i_lock, so d_add() by hand */
-       __d_instantiate(dentry, inode);
-       spin_unlock(&inode->i_lock);
 out:
-       security_d_instantiate(dentry, inode);
-       d_rehash(dentry);
+       __d_add(dentry, inode);
        return NULL;
 }
 EXPORT_SYMBOL(d_splice_alias);