summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNeilBrown <neil@brown.name>2026-09-05 07:48:11 +1000
committerChristian Brauner <brauner@kernel.org>2026-09-25 16:27:19 +0200
commitf1ac607f786f5216d40ffbbc557d0cf87e21bfd9 (patch)
tree1c8ee1e9de57e531d4c4f505c3c7275846be09a3 /include
parentf8550827bf3df4c74040d5245d019908eceba4f7 (diff)
downloadlinux-next-f1ac607f786f5216d40ffbbc557d0cf87e21bfd9.tar.gz
linux-next-f1ac607f786f5216d40ffbbc557d0cf87e21bfd9.zip
VFS: enhance d_splice_alias() to handle hashed dentries
We currently have three interfaces for attaching existing inodes to normal filesystems(*). - d_add() requires an unhashed or in-lookup dentry and doesn't handle splicing in case a directory already has dentry - d_instantiate() requires a hashed dentry, and also doesn't handle splicing. - d_splice_alias() requires unhashed or in-lookup and does handle splicing, and can return an alternate dentry. So there is no interface that supports both hashed and in-lookup, which is what ->atomic_open needs to deal with. Some filesystems check for in-lookup in their atomic_open and if found, perform a ->lookup and can subsequently use d_instantiate() if the dentry is still negative. Others d_drop() the dentry so they can use d_splice_alias(). This last will cause a problem for proposed changes to locking which require the dentry to remain hashed while an operation proceeds on it. There is also no interface which splices a directory (which might already have a dentry) to a hashed dentry. Filesystems which need to do this d_drop() first. Some filesystems (NFS) skip ->lookup processing for LOOKUP_CREATE|LOOKUP_EXCL which includes mknod, link, symlink etc. So these inode operations might get an unhashed or a hashed-negative dentry. There is no interface for instantiating these so again they need to unhash first (nfs_link) So with this patch d_splice_alias() can handle hashed, unhashed, or in-lookup dentries. This makes it suitable for ->lookup, ->atomic_open, and ->mkdir as well as others. As a side effect d_add() will also now handle hashed dentries, but I have plans to remove d_add() as there is no benefit having it as well as the others. Once updated to handle nr_dentry_negative as is required for hashed dentrties, __d_add() contains code that is identical to __d_instantiate(), so the former is changed to call the later so now: - d_add() calls __d_add() which hashes and might call __d_instantiate. - d_instantiate() calls __d_instantiate() with appropriate locks. It was suggested by Al Viro https://lore.kernel.org/all/20250813050717.GD222315@ZenIV/ that rather than allow d_splice_alias() to handle both hashed and unhashed, we should have a new d_splice_alias_hashed(). I chose not to follow this path because, as noted above, there are several cases where the filesystem has no a priori knowledge of the state of the dentry, and so would need if (d_unhashed(dentry)) alias = d_splice_alias(inode, dentry); else alias = d_splice_alias_hashed(inode, dentry); which is clumsy. Also I hope to minimise the distinction between hashed and in-lookup (they will both be hashed, just with different DCACHE_ENTRY_TYPE) and reduce the use of unhashed dentries. Unhashed dentries would only be created by d_alloc_name() and all of those are passed to d_make_persistent() (though configfs passes some to d_add(dentry, NULL) first!). So the use-case for d_splice_alias() on unhashed dentries would disappear. Note that d_make_persistent() already handles both hashed and unhashed dentries - just not in-lookup. * There is also d_make_persistent() for filesystems which are dcache-based and don't support mkdir, create etc, and d_instantiate_new() for newly created inodes that are still locked. Signed-off-by: NeilBrown <neil@brown.name> Link: https://patch.msgid.link/20260904215142.1060510-3-neilb@ownmail.net Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions