Re: [PATCH v3 08/38] vfs: make vfs_mknod break delegations on parent directory

Jeff Layton <[email protected]>
Newsgroups org.kernel.vger.ecryptfs,dev.linux.lists.netfs,org.kernel.vger.linux-cifs,org.kernel.vger.linux-doc,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-nfs,org.kernel.vger.linux-trace-kernel,org.kernel.vger.linux-unionfs,org.kernel.vger.linux-xfs
Message-ID <[email protected]>
On Fri, 2025-09-26 at 17:32 +0200, Jan Kara wrote:
> On Wed 24-09-25 14:05:54, Jeff Layton wrote:
> > In order to add directory delegation support, we need to break
> > delegations on the parent whenever there is going to be a change in the
> > directory.
> > 
> > Rename vfs_mknod as __vfs_mknod, make it static, and add a new
> > delegated_inode parameter.  Make do_mknodat call __vfs_mknod and wait
> > synchronously for delegation breaks to complete. Add a new exported
> > vfs_mknod wrapper that calls __vfs_mknod with a NULL delegated_inode
> > pointer.
> > 
> > Signed-off-by: Jeff Layton <[email protected]>
> 
> Looks good. Feel free to add:
> 
> Reviewed-by: Jan Kara <[email protected]>
> 

Thanks.

FYI, I've revised this and the rmdir patches to get rid of the wrapper,
and just have the callers pass in NULL directly. I think that's more
along the lines of what Christian preferred.


> 
> > ---
> >  fs/namei.c | 57 +++++++++++++++++++++++++++++++++++----------------------
> >  1 file changed, 35 insertions(+), 22 deletions(-)
> > 
> > diff --git a/fs/namei.c b/fs/namei.c
> > index d4b8330a3eb97e205dc2e71766fed1e45503323b..7bcd898c84138061030f1f8b91273261cdf2a9b4 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -4215,24 +4215,9 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname,
> >  }
> >  EXPORT_SYMBOL(user_path_create);
> >  
> > -/**
> > - * vfs_mknod - create device node or file
> > - * @idmap:	idmap of the mount the inode was found from
> > - * @dir:	inode of the parent directory
> > - * @dentry:	dentry of the child device node
> > - * @mode:	mode of the child device node
> > - * @dev:	device number of device to create
> > - *
> > - * Create a device node or file.
> > - *
> > - * If the inode has been found through an idmapped mount the idmap of
> > - * the vfsmount must be passed through @idmap. This function will then take
> > - * care to map the inode according to @idmap before checking permissions.
> > - * On non-idmapped mounts or if permission checking is to be performed on the
> > - * raw inode simply pass @nop_mnt_idmap.
> > - */
> > -int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
> > -	      struct dentry *dentry, umode_t mode, dev_t dev)
> > +static int __vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
> > +		       struct dentry *dentry, umode_t mode, dev_t dev,
> > +		       struct inode **delegated_inode)
> >  {
> >  	bool is_whiteout = S_ISCHR(mode) && dev == WHITEOUT_DEV;
> >  	int error = may_create(idmap, dir, dentry);
> > @@ -4256,11 +4241,37 @@ int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
> >  	if (error)
> >  		return error;
> >  
> > +	error = try_break_deleg(dir, delegated_inode);
> > +	if (error)
> > +		return error;
> > +
> >  	error = dir->i_op->mknod(idmap, dir, dentry, mode, dev);
> >  	if (!error)
> >  		fsnotify_create(dir, dentry);
> >  	return error;
> >  }
> > +
> > +/**
> > + * vfs_mknod - create device node or file
> > + * @idmap:	idmap of the mount the inode was found from
> > + * @dir:	inode of the parent directory
> > + * @dentry:	dentry of the child device node
> > + * @mode:	mode of the child device node
> > + * @dev:	device number of device to create
> > + *
> > + * Create a device node or file.
> > + *
> > + * If the inode has been found through an idmapped mount the idmap of
> > + * the vfsmount must be passed through @idmap. This function will then take
> > + * care to map the inode according to @idmap before checking permissions.
> > + * On non-idmapped mounts or if permission checking is to be performed on the
> > + * raw inode simply pass @nop_mnt_idmap.
> > + */
> > +int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
> > +	      struct dentry *dentry, umode_t mode, dev_t dev)
> > +{
> > +	return __vfs_mknod(idmap, dir, dentry, mode, dev, NULL);
> > +}
> >  EXPORT_SYMBOL(vfs_mknod);
> >  
> >  static int may_mknod(umode_t mode)
> > @@ -4314,12 +4325,14 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
> >  				security_path_post_mknod(idmap, dentry);
> >  			break;
> >  		case S_IFCHR: case S_IFBLK:
> > -			error = vfs_mknod(idmap, path.dentry->d_inode,
> > -					  dentry, mode, new_decode_dev(dev));
> > +			error = __vfs_mknod(idmap, path.dentry->d_inode,
> > +					    dentry, mode, new_decode_dev(dev),
> > +					    &delegated_inode);
> >  			break;
> >  		case S_IFIFO: case S_IFSOCK:
> > -			error = vfs_mknod(idmap, path.dentry->d_inode,
> > -					  dentry, mode, 0);
> > +			error = __vfs_mknod(idmap, path.dentry->d_inode,
> > +					    dentry, mode, 0,
> > +					    &delegated_inode);
> >  			break;
> >  	}
> >  out2:
> > 
> > -- 
> > 2.51.0
> > 

-- 
Jeff Layton <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.