|
@@ -642,7 +642,7 @@ static inline bool fast_dput(struct dentry *dentry)
|
|
|
|
|
|
/*
|
|
|
* If we have a d_op->d_delete() operation, we sould not
|
|
|
- * let the dentry count go to zero, so use "put__or_lock".
|
|
|
+ * let the dentry count go to zero, so use "put_or_lock".
|
|
|
*/
|
|
|
if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
|
|
|
return lockref_put_or_lock(&dentry->d_lockref);
|
|
@@ -697,7 +697,7 @@ static inline bool fast_dput(struct dentry *dentry)
|
|
|
*/
|
|
|
smp_rmb();
|
|
|
d_flags = ACCESS_ONCE(dentry->d_flags);
|
|
|
- d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST;
|
|
|
+ d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_DISCONNECTED;
|
|
|
|
|
|
/* Nothing to do? Dropping the reference was all we needed? */
|
|
|
if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
|
|
@@ -776,6 +776,9 @@ repeat:
|
|
|
if (unlikely(d_unhashed(dentry)))
|
|
|
goto kill_it;
|
|
|
|
|
|
+ if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED))
|
|
|
+ goto kill_it;
|
|
|
+
|
|
|
if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) {
|
|
|
if (dentry->d_op->d_delete(dentry))
|
|
|
goto kill_it;
|