now lock_parent() can't run into killed dentry
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 24 Feb 2018 03:07:35 +0000 (22:07 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 29 Mar 2018 19:07:42 +0000 (15:07 -0400)
all remaining callers hold either a reference or ->i_lock

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c

index af8501489af59e3f432f2f64c035f01f4d32112b..916fd57b9d18d04cd338ee930f243fc3d7eef6f5 100644 (file)
@@ -593,8 +593,6 @@ static inline struct dentry *lock_parent(struct dentry *dentry)
        struct dentry *parent = dentry->d_parent;
        if (IS_ROOT(dentry))
                return NULL;
        struct dentry *parent = dentry->d_parent;
        if (IS_ROOT(dentry))
                return NULL;
-       if (unlikely(dentry->d_lockref.count < 0))
-               return NULL;
        if (likely(spin_trylock(&parent->d_lock)))
                return parent;
        rcu_read_lock();
        if (likely(spin_trylock(&parent->d_lock)))
                return parent;
        rcu_read_lock();
@@ -614,16 +612,11 @@ again:
                spin_unlock(&parent->d_lock);
                goto again;
        }
                spin_unlock(&parent->d_lock);
                goto again;
        }
-       if (parent != dentry) {
+       rcu_read_unlock();
+       if (parent != dentry)
                spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
                spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
-               if (unlikely(dentry->d_lockref.count < 0)) {
-                       spin_unlock(&parent->d_lock);
-                       parent = NULL;
-               }
-       } else {
+       else
                parent = NULL;
                parent = NULL;
-       }
-       rcu_read_unlock();
        return parent;
 }
 
        return parent;
 }