]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
VFS: Change vfs_mkdir() to return the dentry.
authorNeilBrown <neilb@suse.de>
Thu, 27 Feb 2025 01:32:58 +0000 (12:32 +1100)
committerChristian Brauner <brauner@kernel.org>
Wed, 5 Mar 2025 10:52:50 +0000 (11:52 +0100)
commitc54b386969a58151765a9ffaaa0438e7b580283f
treea3b7bfc30caa76f4c92d92ef270cc5baa2536209
parent8376583b84a1937196514dbe380917d61af29978
VFS: Change vfs_mkdir() to return the dentry.

vfs_mkdir() does not guarantee to leave the child dentry hashed or make
it positive on success, and in many such cases the filesystem had to use
a different dentry which it can now return.

This patch changes vfs_mkdir() to return the dentry provided by the
filesystems which is hashed and positive when provided.  This reduces
the number of cases where the resulting dentry is not positive to a
handful which don't deserve extra efforts.

The only callers of vfs_mkdir() which are interested in the resulting
inode are in-kernel filesystem clients: cachefiles, nfsd, smb/server.
The only filesystems that don't reliably provide the inode are:
- kernfs, tracefs which these clients are unlikely to be interested in
- cifs in some configurations would need to do a lookup to find the
  created inode, but doesn't.  cifs cannot be exported via NFS, is
  unlikely to be used by cachefiles, and smb/server only has a soft
  requirement for the inode, so this is unlikely to be a problem in
  practice.
- hostfs, nfs, cifs may need to do a lookup (rarely for NFS) and it is
  possible for a race to make that lookup fail.  Actual failure
  is unlikely and providing callers handle negative dentries graceful
  they will fail-safe.

So this patch removes the lookup code in nfsd and smb/server and adjusts
them to fail safe if a negative dentry is provided:
- cache-files already fails safe by restarting the task from the
  top - it still does with this change, though it no longer calls
  cachefiles_put_directory() as that will crash if the dentry is
  negative.
- nfsd reports "Server-fault" which it what it used to do if the lookup
  failed. This will never happen on any file-systems that it can actually
  export, so this is of no consequence.  I removed the fh_update()
  call as that is not needed and out-of-place.  A subsequent
  nfsd_create_setattr() call will call fh_update() when needed.
- smb/server only wants the inode to call ksmbd_smb_inherit_owner()
  which updates ->i_uid (without calling notify_change() or similar)
  which can be safely skipping on cifs (I hope).

If a different dentry is returned, the first one is put.  If necessary
the fact that it is new can be determined by comparing pointers.  A new
dentry will certainly have a new pointer (as the old is put after the
new is obtained).
Similarly if an error is returned (via ERR_PTR()) the original dentry is
put.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: NeilBrown <neilb@suse.de>
Link: https://lore.kernel.org/r/20250227013949.536172-7-neilb@suse.de
Signed-off-by: Christian Brauner <brauner@kernel.org>
13 files changed:
drivers/base/devtmpfs.c
fs/cachefiles/namei.c
fs/ecryptfs/inode.c
fs/init.c
fs/namei.c
fs/nfsd/nfs4recover.c
fs/nfsd/vfs.c
fs/overlayfs/dir.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c
fs/smb/server/vfs.c
fs/xfs/scrub/orphanage.c
include/linux/fs.h