Re: [PATCH 08/11] VFS: allow d_splice_alias() and d_add() to work on hashed dentries.

From: NeilBrown

Date: Wed Feb 25 2026 - 20:00:47 EST


On Wed, 13 Aug 2025, Al Viro wrote:
> On Tue, Aug 12, 2025 at 12:25:11PM +1000, NeilBrown wrote:
> > Proposed locking changes will require a dentry to remain hashed during
> > all directory operations which are currently protected by i_rwsem, or
> > for there to be a controlled transition from one hashed dentry to
> > another which maintains the lock - which will then be on the dentry.
> >
> > The current practice of dropping (unhashing) a dentry before calling
> > d_splice_alias() and d_add() defeats this need.
> >
> > This patch changes d_splice_alias() and d_add() to accept a hashed
> > dentry and to only drop it when necessary immediately before an
> > alternate dentry is hashed. These functions will, in a subsequent patch,
> > transfer the dentry locking across so that the name remains locked in
> > the directory.
>
> The problem I have with that is the loss of information. That is to
> say, "is it hashed here" is hard to deduce from code. I would rather
> add d_splice_alias_hashed() and d_add_hashed(), and then see what's
> going on in specific callers.
>
> And yes, it requires analysis of places where we have d_drop()+d_add() -
> better have it done upfront than repeat it on every code audit *for*
> *each* *single* *call* *of* d_add(), including the ones that are currently
> obviously meant to be called for unhashed dentries.
>
> I realize that it's no fun at all - in particular, I'd never been able
> to get ceph folks to explain what is and what is not possible there.
>
> I would really hate to have that expand by order of magnitude - in
> effect, you make *all* calls of d_splice_alias() and d_add() similar
> mysteries.
>

I'm picking this up at last ... only 6 months later.

d_add_hashed() would be much the same as d_instantiate(), and that
could be used for d_splice_alias() when the dentry is hashed.
There aren't any cases where d_splice_alias() is called with a directory
inode and a hashed dentry.

I think atomic_open is what makes this interesting. It can be called
with a d_in_lookup() dentry, or a negative hashed dentry. In the former
case, d_splice_alias() is appropriate. In the latter, d_instantiate()
is best.

No filesystems makes that distinction clearly.

Most which provide atomic_open check for d_in_lookup() and perform a
lookup in that case, resulting in a hashed dentry - if positive they
just return it.

The exceptions are ceph, smb/client, and nfs.

They d_drop() (if unhashed for ceph, unconditionally for smb and nfs)
and then d_splice_alias().

So I could change these to:

if (d_in_lookup(de))
d_splice_alias(de, inode);
else
d_instantiate(de, inode);

or maybe we could have a new interface, though I can't think of a good
name.

Could we enhance d_instantiate to do d_splice_alias() in the case where
the dentry is d_in_lookup()?

Thanks,
NeilBrown