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...