fix dget_parent() fastpath race
[sfrench/cifs-2.6.git] / fs / dcache.c
index e88cf0554e65907d0136595a4521fc06fd521da4..b2a7f1765f0b12192c68a4638e1edd479aa00efa 100644 (file)
@@ -903,17 +903,19 @@ struct dentry *dget_parent(struct dentry *dentry)
 {
        int gotref;
        struct dentry *ret;
+       unsigned seq;
 
        /*
         * Do optimistic parent lookup without any
         * locking.
         */
        rcu_read_lock();
+       seq = raw_seqcount_begin(&dentry->d_seq);
        ret = READ_ONCE(dentry->d_parent);
        gotref = lockref_get_not_zero(&ret->d_lockref);
        rcu_read_unlock();
        if (likely(gotref)) {
-               if (likely(ret == READ_ONCE(dentry->d_parent)))
+               if (!read_seqcount_retry(&dentry->d_seq, seq))
                        return ret;
                dput(ret);
        }