Commit e41f7d4e authored by Al Viro's avatar Al Viro

merge path_init and path_init_rcu

Actual dependency on whether we want RCU or not is in 3 small areas
(as it ought to be) and everything around those is the same in both
versions.  Since each function has only one caller and those callers
are on two sides of if (flags & LOOKUP_RCU), it's easier and cleaner
to merge them and pull the checks inside.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ee0827cd
...@@ -1520,33 +1520,30 @@ static int link_path_walk(const char *name, struct nameidata *nd) ...@@ -1520,33 +1520,30 @@ static int link_path_walk(const char *name, struct nameidata *nd)
return err; return err;
} }
static int path_init_rcu(int dfd, const char *name, unsigned int flags, struct nameidata *nd) static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
{ {
int retval = 0; int retval = 0;
int fput_needed; int fput_needed;
struct file *file; struct file *file;
nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags | LOOKUP_RCU; nd->flags = flags;
nd->depth = 0; nd->depth = 0;
nd->root.mnt = NULL; nd->root.mnt = NULL;
nd->file = NULL; nd->file = NULL;
if (*name=='/') { if (*name=='/') {
struct fs_struct *fs = current->fs; if (flags & LOOKUP_RCU) {
unsigned seq;
br_read_lock(vfsmount_lock); br_read_lock(vfsmount_lock);
rcu_read_lock(); rcu_read_lock();
set_root_rcu(nd);
do { } else {
seq = read_seqcount_begin(&fs->seq); set_root(nd);
nd->root = fs->root; path_get(&nd->root);
}
nd->path = nd->root; nd->path = nd->root;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
} while (read_seqcount_retry(&fs->seq, seq));
} else if (dfd == AT_FDCWD) { } else if (dfd == AT_FDCWD) {
if (flags & LOOKUP_RCU) {
struct fs_struct *fs = current->fs; struct fs_struct *fs = current->fs;
unsigned seq; unsigned seq;
...@@ -1558,7 +1555,9 @@ static int path_init_rcu(int dfd, const char *name, unsigned int flags, struct n ...@@ -1558,7 +1555,9 @@ static int path_init_rcu(int dfd, const char *name, unsigned int flags, struct n
nd->path = fs->pwd; nd->path = fs->pwd;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
} while (read_seqcount_retry(&fs->seq, seq)); } while (read_seqcount_retry(&fs->seq, seq));
} else {
get_fs_pwd(current->fs, &nd->path);
}
} else { } else {
struct dentry *dentry; struct dentry *dentry;
...@@ -1578,62 +1577,18 @@ static int path_init_rcu(int dfd, const char *name, unsigned int flags, struct n ...@@ -1578,62 +1577,18 @@ static int path_init_rcu(int dfd, const char *name, unsigned int flags, struct n
goto fput_fail; goto fput_fail;
nd->path = file->f_path; nd->path = file->f_path;
if (flags & LOOKUP_RCU) {
if (fput_needed) if (fput_needed)
nd->file = file; nd->file = file;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
br_read_lock(vfsmount_lock); br_read_lock(vfsmount_lock);
rcu_read_lock(); rcu_read_lock();
}
nd->inode = nd->path.dentry->d_inode;
return 0;
fput_fail:
fput_light(file, fput_needed);
out_fail:
return retval;
}
static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
{
int retval = 0;
int fput_needed;
struct file *file;
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
nd->depth = 0;
nd->root.mnt = NULL;
if (*name=='/') {
set_root(nd);
nd->path = nd->root;
path_get(&nd->root);
} else if (dfd == AT_FDCWD) {
get_fs_pwd(current->fs, &nd->path);
} else { } else {
struct dentry *dentry;
file = fget_light(dfd, &fput_needed);
retval = -EBADF;
if (!file)
goto out_fail;
dentry = file->f_path.dentry;
retval = -ENOTDIR;
if (!S_ISDIR(dentry->d_inode->i_mode))
goto fput_fail;
retval = file_permission(file, MAY_EXEC);
if (retval)
goto fput_fail;
nd->path = file->f_path;
path_get(&file->f_path); path_get(&file->f_path);
fput_light(file, fput_needed); fput_light(file, fput_needed);
} }
}
nd->inode = nd->path.dentry->d_inode; nd->inode = nd->path.dentry->d_inode;
return 0; return 0;
...@@ -1663,9 +1618,6 @@ static int path_lookupat(int dfd, const char *name, ...@@ -1663,9 +1618,6 @@ static int path_lookupat(int dfd, const char *name,
* be handled by restarting a traditional ref-walk (which will always * be handled by restarting a traditional ref-walk (which will always
* be able to complete). * be able to complete).
*/ */
if (flags & LOOKUP_RCU)
retval = path_init_rcu(dfd, name, flags, nd);
else
retval = path_init(dfd, name, flags, nd); retval = path_init(dfd, name, flags, nd);
if (unlikely(retval)) if (unlikely(retval))
......
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