Commit 9fe61450 authored by Christian Brauner's avatar Christian Brauner

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
...@@ -412,9 +412,14 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, ...@@ -412,9 +412,14 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
if (ret < 0) { if (ret < 0) {
cachefiles_io_error(cache, "Rename security error %d", ret); cachefiles_io_error(cache, "Rename security error %d", ret);
} else { } 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); trace_cachefiles_rename(object, rep, grave, why);
ret = vfs_rename(d_inode(dir), rep, ret = vfs_rename(&rd);
d_inode(cache->graveyard), grave, NULL, 0);
if (ret != 0 && ret != -ENOMEM) if (ret != 0 && ret != -ENOMEM)
cachefiles_io_error(cache, cachefiles_io_error(cache,
"Rename failed with error %d", ret); "Rename failed with error %d", ret);
......
...@@ -590,6 +590,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -590,6 +590,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct dentry *lower_new_dir_dentry; struct dentry *lower_new_dir_dentry;
struct dentry *trap; struct dentry *trap;
struct inode *target_inode; struct inode *target_inode;
struct renamedata rd = {};
if (flags) if (flags)
return -EINVAL; return -EINVAL;
...@@ -619,9 +620,12 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -619,9 +620,12 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rc = -ENOTEMPTY; rc = -ENOTEMPTY;
goto out_lock; goto out_lock;
} }
rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
d_inode(lower_new_dir_dentry), lower_new_dentry, rd.old_dir = d_inode(lower_old_dir_dentry);
NULL, 0); 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) if (rc)
goto out_lock; goto out_lock;
if (target_inode) if (target_inode)
......
...@@ -4311,12 +4311,15 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname ...@@ -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 * ->i_mutex on parents, which works but leads to some truly excessive
* locking]. * locking].
*/ */
int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, int vfs_rename(struct renamedata *rd)
struct inode *new_dir, struct dentry *new_dentry,
struct inode **delegated_inode, unsigned int flags)
{ {
int error; int error;
struct user_namespace *mnt_userns = &init_user_ns; 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); bool is_dir = d_is_dir(old_dentry);
struct inode *source = old_dentry->d_inode; struct inode *source = old_dentry->d_inode;
struct inode *target = new_dentry->d_inode; struct inode *target = new_dentry->d_inode;
...@@ -4442,6 +4445,7 @@ EXPORT_SYMBOL(vfs_rename); ...@@ -4442,6 +4445,7 @@ EXPORT_SYMBOL(vfs_rename);
int do_renameat2(int olddfd, struct filename *from, int newdfd, int do_renameat2(int olddfd, struct filename *from, int newdfd,
struct filename *to, unsigned int flags) struct filename *to, unsigned int flags)
{ {
struct renamedata rd;
struct dentry *old_dentry, *new_dentry; struct dentry *old_dentry, *new_dentry;
struct dentry *trap; struct dentry *trap;
struct path old_path, new_path; struct path old_path, new_path;
...@@ -4545,9 +4549,14 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd, ...@@ -4545,9 +4549,14 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
&new_path, new_dentry, flags); &new_path, new_dentry, flags);
if (error) if (error)
goto exit5; goto exit5;
error = vfs_rename(old_path.dentry->d_inode, old_dentry,
new_path.dentry->d_inode, new_dentry, rd.old_dir = old_path.dentry->d_inode;
&delegated_inode, flags); 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: exit5:
dput(new_dentry); dput(new_dentry);
exit4: exit4:
......
...@@ -1798,7 +1798,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, ...@@ -1798,7 +1798,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
close_cached = true; close_cached = true;
goto out_dput_old; goto out_dput_old;
} else { } 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) { if (!host_err) {
host_err = commit_metadata(tfhp); host_err = commit_metadata(tfhp);
if (!host_err) if (!host_err)
......
...@@ -214,9 +214,16 @@ static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry, ...@@ -214,9 +214,16 @@ static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry,
unsigned int flags) unsigned int flags)
{ {
int err; 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); 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) { if (err) {
pr_debug("...rename(%pd2, %pd2, ...) = %i\n", pr_debug("...rename(%pd2, %pd2, ...) = %i\n",
olddentry, newdentry, err); olddentry, newdentry, err);
......
...@@ -1775,7 +1775,17 @@ extern int vfs_symlink(struct inode *, struct dentry *, const char *); ...@@ -1775,7 +1775,17 @@ extern int vfs_symlink(struct inode *, struct dentry *, const char *);
extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **); extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **);
extern int vfs_rmdir(struct inode *, struct dentry *); extern int vfs_rmdir(struct inode *, struct dentry *);
extern int vfs_unlink(struct inode *, struct dentry *, struct inode **); extern int vfs_unlink(struct inode *, struct dentry *, struct inode **);
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int);
struct renamedata {
struct inode *old_dir;
struct dentry *old_dentry;
struct inode *new_dir;
struct dentry *new_dentry;
struct inode **delegated_inode;
unsigned int flags;
} __randomize_layout;
int vfs_rename(struct renamedata *);
static inline int vfs_whiteout(struct inode *dir, struct dentry *dentry) static inline int vfs_whiteout(struct inode *dir, struct dentry *dentry)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment