On Sun, Feb 04, 2024 at 02:17:33AM +0000, Al Viro wrote: > nfs_set_verifier() relies upon dentry being pinned; if that's > the case, grabbing ->d_lock stabilizes ->d_parent and guarantees > that ->d_parent points to a positive dentry. For something > we'd run into in RCU mode that is *not* true - dentry might've > been through dentry_kill() just as we grabbed ->d_lock, with > its parent going through the same just as we get to into > nfs_set_verifier_locked(). It might get to detaching inode > (and zeroing ->d_inode) before nfs_set_verifier_locked() gets > to fetching that; we get an oops as the result. > > That can happen in nfs{,4} ->d_revalidate(); the call chain in > question is nfs_set_verifier_locked() <- nfs_set_verifier() <- > nfs_lookup_revalidate_delegated() <- nfs{,4}_do_lookup_revalidate(). > We have checked that the parent had been positive, but that's > done before we get to nfs_set_verifier() and it's possible for > memory pressure to pick our dentry as eviction candidate by that > time. If that happens, back-to-back attempts to kill dentry and > its parent are quite normal. Sure, in case of eviction we'll > fail the ->d_seq check in the caller, but we need to survive > until we return there... > > Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> > --- Acked-by: Christian Brauner <brauner@xxxxxxxxxx>