On Fri, Apr 19, 2019 at 04:48:10PM +0800, Hou Tao wrote:

> The root cause is the inconsistency between d_flags & d_inode
> during the REF-walk in lookup_fast(): d_is_negative(dentry)
> returns false, but d_backing_inode() still returns a NULL pointer.
> 
> The RCU-walk path in lookup_fast() uses d_seq to ensure d_flags & d_inode
> are consistent, and lookup_slow() use inode lock to ensure that, so only
> the REF-walk path in lookup_fast() is problematic.
> 
> Fixing it by adding a paired smp_rmb/smp_wmb between the reading/writing
> of d_inode & d_flags to ensure the consistency.

The problem is real, but I'm not sure I like the proposed fix ;-/
We could simply use d_really_is_negative() there, avoiding all that
mess.  If and when we get around to whiteouts-in-dcache (i.e. if
unionfs series gets resurrected), we can revisit that...

Reply via email to