On Wed, Apr 14, 2021 at 03:41:10AM +0000, Al Viro wrote: > > + if (!d_is_tail_negative(dentry)) { > > + parent = lock_parent(dentry); > > + if (!parent) > > + return; > > Wait a minute. It's not a good environment for calling lock_parent(). > Who said that dentry won't get freed right under it? [snip] FWIW, in that state (dentry->d_lock held) we have * stable ->d_flags * stable ->d_count * stable ->d_inode IOW, we can bloody well check ->d_count *before* bothering with lock_parent(). It does not get rid of the problems with lifetimes, though. We could do something along the lines of rcu_read_lock() if retain_dentry() parent = NULL if that dentry might need to be moved in list parent = lock_parent() // if reached __dentry_kill(), d_count() will be -128, // so the check below will exclude those if that dentry does need to be moved move it to the end of list unlock dentry and parent (if any) rcu_read_unlock() return here, but your other uses of lock_parent() also need attention. And recursive call of dput() in trim_negative() (#6/6) is really asking for trouble.