Unverified Commit 9fe61450 authored by Christian Brauner's avatar Christian Brauner
Browse files

namei: introduce struct renamedata

In order to handle idmapped mounts we will extend the vfs rename helper
to take two new arguments in follow up patches. Since this operations
already takes a bunch of arguments add a simple struct renamedata and
make the current helper use it before we extend it.

Link: https://lore.kernel.org/r/20210121131959.646623-14-christian.brauner@ubuntu.com


Cc: Christoph Hellwig <hch@lst.de>
Cc: David Howells <dhowells@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
parent ba73d987
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -412,9 +412,14 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
	if (ret < 0) {
		cachefiles_io_error(cache, "Rename security error %d", ret);
	} else {
		struct renamedata rd = {
			.old_dir	= d_inode(dir),
			.old_dentry	= rep,
			.new_dir	= d_inode(cache->graveyard),
			.new_dentry	= grave,
		};
		trace_cachefiles_rename(object, rep, grave, why);
		ret = vfs_rename(d_inode(dir), rep,
				 d_inode(cache->graveyard), grave, NULL, 0);
		ret = vfs_rename(&rd);
		if (ret != 0 && ret != -ENOMEM)
			cachefiles_io_error(cache,
					    "Rename failed with error %d", ret);
+7 −3
Original line number Diff line number Diff line
@@ -590,6 +590,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	struct dentry *lower_new_dir_dentry;
	struct dentry *trap;
	struct inode *target_inode;
	struct renamedata rd = {};

	if (flags)
		return -EINVAL;
@@ -619,9 +620,12 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
		rc = -ENOTEMPTY;
		goto out_lock;
	}
	rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
			d_inode(lower_new_dir_dentry), lower_new_dentry,
			NULL, 0);

	rd.old_dir	= d_inode(lower_old_dir_dentry);
	rd.old_dentry	= lower_old_dentry;
	rd.new_dir	= d_inode(lower_new_dir_dentry);
	rd.new_dentry	= lower_new_dentry;
	rc = vfs_rename(&rd);
	if (rc)
		goto out_lock;
	if (target_inode)
+15 −6
Original line number Diff line number Diff line
@@ -4311,12 +4311,15 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
 *	   ->i_mutex on parents, which works but leads to some truly excessive
 *	   locking].
 */
int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	       struct inode *new_dir, struct dentry *new_dentry,
	       struct inode **delegated_inode, unsigned int flags)
int vfs_rename(struct renamedata *rd)
{
	int error;
	struct user_namespace *mnt_userns = &init_user_ns;
	struct inode *old_dir = rd->old_dir, *new_dir = rd->new_dir;
	struct dentry *old_dentry = rd->old_dentry;
	struct dentry *new_dentry = rd->new_dentry;
	struct inode **delegated_inode = rd->delegated_inode;
	unsigned int flags = rd->flags;
	bool is_dir = d_is_dir(old_dentry);
	struct inode *source = old_dentry->d_inode;
	struct inode *target = new_dentry->d_inode;
@@ -4442,6 +4445,7 @@ EXPORT_SYMBOL(vfs_rename);
int do_renameat2(int olddfd, struct filename *from, int newdfd,
		 struct filename *to, unsigned int flags)
{
	struct renamedata rd;
	struct dentry *old_dentry, *new_dentry;
	struct dentry *trap;
	struct path old_path, new_path;
@@ -4545,9 +4549,14 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
				     &new_path, new_dentry, flags);
	if (error)
		goto exit5;
	error = vfs_rename(old_path.dentry->d_inode, old_dentry,
			   new_path.dentry->d_inode, new_dentry,
			   &delegated_inode, flags);

	rd.old_dir	   = old_path.dentry->d_inode;
	rd.old_dentry	   = old_dentry;
	rd.new_dir	   = new_path.dentry->d_inode;
	rd.new_dentry	   = new_dentry;
	rd.delegated_inode = &delegated_inode;
	rd.flags	   = flags;
	error = vfs_rename(&rd);
exit5:
	dput(new_dentry);
exit4:
+7 −1
Original line number Diff line number Diff line
@@ -1798,7 +1798,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
		close_cached = true;
		goto out_dput_old;
	} else {
		host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL, 0);
		struct renamedata rd = {
			.old_dir	= fdir,
			.old_dentry	= odentry,
			.new_dir	= tdir,
			.new_dentry	= ndentry,
		};
		host_err = vfs_rename(&rd);
		if (!host_err) {
			host_err = commit_metadata(tfhp);
			if (!host_err)
+8 −1
Original line number Diff line number Diff line
@@ -214,9 +214,16 @@ static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry,
				unsigned int flags)
{
	int err;
	struct renamedata rd = {
		.old_dir 	= olddir,
		.old_dentry 	= olddentry,
		.new_dir 	= newdir,
		.new_dentry 	= newdentry,
		.flags 		= flags,
	};

	pr_debug("rename(%pd2, %pd2, 0x%x)\n", olddentry, newdentry, flags);
	err = vfs_rename(olddir, olddentry, newdir, newdentry, NULL, flags);
	err = vfs_rename(&rd);
	if (err) {
		pr_debug("...rename(%pd2, %pd2, ...) = %i\n",
			 olddentry, newdentry, err);
Loading