Revert "fs: use RCU read side protection in d_validate"
authorNick Piggin <npiggin@kernel.dk>
Wed, 5 Jan 2011 09:01:21 +0000 (20:01 +1100)
committerNick Piggin <npiggin@kernel.dk>
Wed, 5 Jan 2011 09:01:21 +0000 (20:01 +1100)
This reverts commit 3825bdb7ed920845961f32f364454bee5f469abb.

You cannot dget() a dentry without having a reference, or holding
a lock that guarantees it remains valid.

Signed-off-by: Nick Piggin <npiggin@kernel.dk>
fs/dcache.c

index 23702a9d4e6d130b6ef226d1157f1a484f93a282..cc2b938021796c0a8d4492030043309f087f790e 100644 (file)
@@ -1491,26 +1491,33 @@ out:
  * This is used by ncpfs in its readdir implementation.
  * Zero is returned in the dentry is invalid.
  */
-int d_validate(struct dentry *dentry, struct dentry *parent)
+int d_validate(struct dentry *dentry, struct dentry *dparent)
 {
-       struct hlist_head *head = d_hash(parent, dentry->d_name.hash);
-       struct hlist_node *node;
-       struct dentry *d;
+       struct hlist_head *base;
+       struct hlist_node *lhp;
 
        /* Check whether the ptr might be valid at all.. */
        if (!kmem_ptr_validate(dentry_cache, dentry))
-               return 0;
-       if (dentry->d_parent != parent)
-               return 0;
+               goto out;
 
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(d, node, head, d_hash) {
-               if (d == dentry) {
-                       dget(dentry);
+       if (dentry->d_parent != dparent)
+               goto out;
+
+       spin_lock(&dcache_lock);
+       base = d_hash(dparent, dentry->d_name.hash);
+       hlist_for_each(lhp,base) { 
+               /* hlist_for_each_entry_rcu() not required for d_hash list
+                * as it is parsed under dcache_lock
+                */
+               if (dentry == hlist_entry(lhp, struct dentry, d_hash)) {
+                       __dget_locked(dentry);
+                       spin_unlock(&dcache_lock);
                        return 1;
                }
        }
-       rcu_read_unlock();
+       spin_unlock(&dcache_lock);
+out:
        return 0;
 }
 EXPORT_SYMBOL(d_validate);