Unverified Commit e8960c1b authored by Jeff Layton's avatar Jeff Layton Committed by Christian Brauner
Browse files

vfs: make vfs_mknod break delegations on parent directory



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.

Add a new delegated_inode pointer to vfs_mknod() and have the
appropriate callers wait when there is an outstanding delegation. All
other callers just set the pointer to NULL.

Reviewed-by: default avatarJan Kara <jack@suse.cz>
Reviewed-by: default avatarNeilBrown <neil@brown.name>
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20251111-dir-deleg-ro-v6-11-52f3feebb2f2@kernel.org


Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent c826229c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -231,7 +231,7 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
		return PTR_ERR(dentry);

	err = vfs_mknod(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode,
			dev->devt);
			dev->devt, NULL);
	if (!err) {
		struct iattr newattrs;

+1 −1
Original line number Diff line number Diff line
@@ -564,7 +564,7 @@ ecryptfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
	rc = lock_parent(dentry, &lower_dentry, &lower_dir);
	if (!rc)
		rc = vfs_mknod(&nop_mnt_idmap, lower_dir,
			       lower_dentry, mode, dev);
			       lower_dentry, mode, dev, NULL);
	if (rc || d_really_is_negative(lower_dentry))
		goto out;
	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ int __init init_mknod(const char *filename, umode_t mode, unsigned int dev)
	error = security_path_mknod(&path, dentry, mode, dev);
	if (!error)
		error = vfs_mknod(mnt_idmap(path.mnt), path.dentry->d_inode,
				  dentry, mode, new_decode_dev(dev));
				  dentry, mode, new_decode_dev(dev), NULL);
	end_creating_path(&path, dentry);
	return error;
}
+15 −8
Original line number Diff line number Diff line
@@ -4295,6 +4295,7 @@ inline struct dentry *start_creating_user_path(
}
EXPORT_SYMBOL(start_creating_user_path);


/**
 * vfs_mknod - create device node or file
 * @idmap:		idmap of the mount the inode was found from
@@ -4302,6 +4303,7 @@ EXPORT_SYMBOL(start_creating_user_path);
 * @dentry:		dentry of the child device node
 * @mode:		mode of the child device node
 * @dev:		device number of device to create
 * @delegated_inode:	returns parent inode, if the inode is delegated.
 *
 * Create a device node or file.
 *
@@ -4312,7 +4314,8 @@ EXPORT_SYMBOL(start_creating_user_path);
 * 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)
	      struct dentry *dentry, umode_t mode, dev_t dev,
	      struct delegated_inode *delegated_inode)
{
	bool is_whiteout = S_ISCHR(mode) && dev == WHITEOUT_DEV;
	int error = may_create(idmap, dir, dentry);
@@ -4336,6 +4339,10 @@ 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);
@@ -4393,11 +4400,11 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
			break;
		case S_IFCHR: case S_IFBLK:
			error = vfs_mknod(idmap, path.dentry->d_inode,
					  dentry, mode, new_decode_dev(dev));
					  dentry, mode, new_decode_dev(dev), &di);
			break;
		case S_IFIFO: case S_IFSOCK:
			error = vfs_mknod(idmap, path.dentry->d_inode,
					  dentry, mode, 0);
					  dentry, mode, 0, &di);
			break;
	}
out2:
+1 −1
Original line number Diff line number Diff line
@@ -1573,7 +1573,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
	case S_IFIFO:
	case S_IFSOCK:
		host_err = vfs_mknod(&nop_mnt_idmap, dirp, dchild,
				     iap->ia_mode, rdev);
				     iap->ia_mode, rdev, NULL);
		break;
	default:
		printk(KERN_WARNING "nfsd: bad file type %o in nfsd_create\n",
Loading