fs/ocfs2/dlm/dlmrecovery.c: remove duplicate declarations
[firefly-linux-kernel-4.4.55.git] / fs / dcache.c
index f09b9085f7d849e235a2b8d77c079de71c96f5d2..87bdb5329c3c90b99d67f4b5bab3ae0b347d2acf 100644 (file)
@@ -1612,6 +1612,10 @@ EXPORT_SYMBOL(d_obtain_alias);
  * If a dentry was found and moved, then it is returned.  Otherwise NULL
  * is returned.  This matches the expected return value of ->lookup.
  *
+ * Cluster filesystems may call this function with a negative, hashed dentry.
+ * In that case, we know that the inode will be a regular file, and also this
+ * will only occur during atomic_open. So we need to check for the dentry
+ * being already hashed only in the final case.
  */
 struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
 {
@@ -1636,8 +1640,11 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
                        security_d_instantiate(dentry, inode);
                        d_rehash(dentry);
                }
-       } else
-               d_add(dentry, inode);
+       } else {
+               d_instantiate(dentry, inode);
+               if (d_unhashed(dentry))
+                       d_rehash(dentry);
+       }
        return new;
 }
 EXPORT_SYMBOL(d_splice_alias);
@@ -1723,7 +1730,7 @@ EXPORT_SYMBOL(d_add_ci);
  * Do the slow-case of the dentry name compare.
  *
  * Unlike the dentry_cmp() function, we need to atomically
- * load the name, length and inode information, so that the
+ * load the name and length information, so that the
  * filesystem can rely on them, and can use the 'name' and
  * 'len' information without worrying about walking off the
  * end of memory etc.
@@ -1741,22 +1748,18 @@ enum slow_d_compare {
 
 static noinline enum slow_d_compare slow_dentry_cmp(
                const struct dentry *parent,
-               struct inode *inode,
                struct dentry *dentry,
                unsigned int seq,
                const struct qstr *name)
 {
        int tlen = dentry->d_name.len;
        const char *tname = dentry->d_name.name;
-       struct inode *i = dentry->d_inode;
 
        if (read_seqcount_retry(&dentry->d_seq, seq)) {
                cpu_relax();
                return D_COMP_SEQRETRY;
        }
-       if (parent->d_op->d_compare(parent, inode,
-                               dentry, i,
-                               tlen, tname, name))
+       if (parent->d_op->d_compare(parent, dentry, tlen, tname, name))
                return D_COMP_NOMATCH;
        return D_COMP_OK;
 }
@@ -1766,7 +1769,6 @@ static noinline enum slow_d_compare slow_dentry_cmp(
  * @parent: parent dentry
  * @name: qstr of name we wish to find
  * @seqp: returns d_seq value at the point where the dentry was found
- * @inode: returns dentry->d_inode when the inode was found valid.
  * Returns: dentry, or NULL
  *
  * __d_lookup_rcu is the dcache lookup function for rcu-walk name
@@ -1793,7 +1795,7 @@ static noinline enum slow_d_compare slow_dentry_cmp(
  */
 struct dentry *__d_lookup_rcu(const struct dentry *parent,
                                const struct qstr *name,
-                               unsigned *seqp, struct inode *inode)
+                               unsigned *seqp)
 {
        u64 hashlen = name->hash_len;
        const unsigned char *str = name->name;
@@ -1827,11 +1829,10 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent,
 seqretry:
                /*
                 * The dentry sequence count protects us from concurrent
-                * renames, and thus protects inode, parent and name fields.
+                * renames, and thus protects parent and name fields.
                 *
                 * The caller must perform a seqcount check in order
-                * to do anything useful with the returned dentry,
-                * including using the 'd_inode' pointer.
+                * to do anything useful with the returned dentry.
                 *
                 * NOTE! We do a "raw" seqcount_begin here. That means that
                 * we don't wait for the sequence count to stabilize if it
@@ -1845,12 +1846,12 @@ seqretry:
                        continue;
                if (d_unhashed(dentry))
                        continue;
-               *seqp = seq;
 
                if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
                        if (dentry->d_name.hash != hashlen_hash(hashlen))
                                continue;
-                       switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) {
+                       *seqp = seq;
+                       switch (slow_dentry_cmp(parent, dentry, seq, name)) {
                        case D_COMP_OK:
                                return dentry;
                        case D_COMP_NOMATCH:
@@ -1862,6 +1863,7 @@ seqretry:
 
                if (dentry->d_name.hash_len != hashlen)
                        continue;
+               *seqp = seq;
                if (!dentry_cmp(dentry, str, hashlen_len(hashlen)))
                        return dentry;
        }
@@ -1959,9 +1961,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name)
                if (parent->d_flags & DCACHE_OP_COMPARE) {
                        int tlen = dentry->d_name.len;
                        const char *tname = dentry->d_name.name;
-                       if (parent->d_op->d_compare(parent, parent->d_inode,
-                                               dentry, dentry->d_inode,
-                                               tlen, tname, name))
+                       if (parent->d_op->d_compare(parent, dentry, tlen, tname, name))
                                goto next;
                } else {
                        if (dentry->d_name.len != len)
@@ -1998,7 +1998,7 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
         */
        name->hash = full_name_hash(name->name, name->len);
        if (dir->d_flags & DCACHE_OP_HASH) {
-               int err = dir->d_op->d_hash(dir, dir->d_inode, name);
+               int err = dir->d_op->d_hash(dir, name);
                if (unlikely(err < 0))
                        return ERR_PTR(err);
        }
@@ -2968,34 +2968,21 @@ rename_retry:
        goto again;
 }
 
-/**
- * find_inode_number - check for dentry with name
- * @dir: directory to check
- * @name: Name to find.
- *
- * Check whether a dentry already exists for the given name,
- * and return the inode number if it has an inode. Otherwise
- * 0 is returned.
- *
- * This routine is used to post-process directory listings for
- * filesystems using synthetic inode numbers, and is necessary
- * to keep getcwd() working.
- */
-ino_t find_inode_number(struct dentry *dir, struct qstr *name)
+void d_tmpfile(struct dentry *dentry, struct inode *inode)
 {
-       struct dentry * dentry;
-       ino_t ino = 0;
-
-       dentry = d_hash_and_lookup(dir, name);
-       if (!IS_ERR_OR_NULL(dentry)) {
-               if (dentry->d_inode)
-                       ino = dentry->d_inode->i_ino;
-               dput(dentry);
-       }
-       return ino;
+       inode_dec_link_count(inode);
+       BUG_ON(dentry->d_name.name != dentry->d_iname ||
+               !hlist_unhashed(&dentry->d_alias) ||
+               !d_unlinked(dentry));
+       spin_lock(&dentry->d_parent->d_lock);
+       spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+       dentry->d_name.len = sprintf(dentry->d_iname, "#%llu",
+                               (unsigned long long)inode->i_ino);
+       spin_unlock(&dentry->d_lock);
+       spin_unlock(&dentry->d_parent->d_lock);
+       d_instantiate(dentry, inode);
 }
-EXPORT_SYMBOL(find_inode_number);
+EXPORT_SYMBOL(d_tmpfile);
 
 static __initdata unsigned long dhash_entries;
 static int __init set_dhash_entries(char *str)