Commit 2d92ab3c authored by Al Viro's avatar Al Viro

[PATCH] finally get rid of nameidata in namespace.c

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d1811465
...@@ -1167,19 +1167,19 @@ asmlinkage long sys_oldumount(char __user * name) ...@@ -1167,19 +1167,19 @@ asmlinkage long sys_oldumount(char __user * name)
#endif #endif
static int mount_is_safe(struct nameidata *nd) static int mount_is_safe(struct path *path)
{ {
if (capable(CAP_SYS_ADMIN)) if (capable(CAP_SYS_ADMIN))
return 0; return 0;
return -EPERM; return -EPERM;
#ifdef notyet #ifdef notyet
if (S_ISLNK(nd->path.dentry->d_inode->i_mode)) if (S_ISLNK(path->dentry->d_inode->i_mode))
return -EPERM; return -EPERM;
if (nd->path.dentry->d_inode->i_mode & S_ISVTX) { if (path->dentry->d_inode->i_mode & S_ISVTX) {
if (current->uid != nd->path.dentry->d_inode->i_uid) if (current->uid != path->dentry->d_inode->i_uid)
return -EPERM; return -EPERM;
} }
if (vfs_permission(nd, MAY_WRITE)) if (inode_permission(path->dentry->d_inode, MAY_WRITE))
return -EPERM; return -EPERM;
return 0; return 0;
#endif #endif
...@@ -1427,9 +1427,9 @@ out_unlock: ...@@ -1427,9 +1427,9 @@ out_unlock:
* recursively change the type of the mountpoint. * recursively change the type of the mountpoint.
* noinline this do_mount helper to save do_mount stack space. * noinline this do_mount helper to save do_mount stack space.
*/ */
static noinline int do_change_type(struct nameidata *nd, int flag) static noinline int do_change_type(struct path *path, int flag)
{ {
struct vfsmount *m, *mnt = nd->path.mnt; struct vfsmount *m, *mnt = path->mnt;
int recurse = flag & MS_REC; int recurse = flag & MS_REC;
int type = flag & ~MS_REC; int type = flag & ~MS_REC;
int err = 0; int err = 0;
...@@ -1437,7 +1437,7 @@ static noinline int do_change_type(struct nameidata *nd, int flag) ...@@ -1437,7 +1437,7 @@ static noinline int do_change_type(struct nameidata *nd, int flag)
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (nd->path.dentry != nd->path.mnt->mnt_root) if (path->dentry != path->mnt->mnt_root)
return -EINVAL; return -EINVAL;
down_write(&namespace_sem); down_write(&namespace_sem);
...@@ -1461,38 +1461,38 @@ static noinline int do_change_type(struct nameidata *nd, int flag) ...@@ -1461,38 +1461,38 @@ static noinline int do_change_type(struct nameidata *nd, int flag)
* do loopback mount. * do loopback mount.
* noinline this do_mount helper to save do_mount stack space. * noinline this do_mount helper to save do_mount stack space.
*/ */
static noinline int do_loopback(struct nameidata *nd, char *old_name, static noinline int do_loopback(struct path *path, char *old_name,
int recurse) int recurse)
{ {
struct nameidata old_nd; struct path old_path;
struct vfsmount *mnt = NULL; struct vfsmount *mnt = NULL;
int err = mount_is_safe(nd); int err = mount_is_safe(path);
if (err) if (err)
return err; return err;
if (!old_name || !*old_name) if (!old_name || !*old_name)
return -EINVAL; return -EINVAL;
err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd); err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
if (err) if (err)
return err; return err;
down_write(&namespace_sem); down_write(&namespace_sem);
err = -EINVAL; err = -EINVAL;
if (IS_MNT_UNBINDABLE(old_nd.path.mnt)) if (IS_MNT_UNBINDABLE(old_path.mnt))
goto out; goto out;
if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
goto out; goto out;
err = -ENOMEM; err = -ENOMEM;
if (recurse) if (recurse)
mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0); mnt = copy_tree(old_path.mnt, old_path.dentry, 0);
else else
mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0); mnt = clone_mnt(old_path.mnt, old_path.dentry, 0);
if (!mnt) if (!mnt)
goto out; goto out;
err = graft_tree(mnt, &nd->path); err = graft_tree(mnt, path);
if (err) { if (err) {
LIST_HEAD(umount_list); LIST_HEAD(umount_list);
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
...@@ -1503,7 +1503,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name, ...@@ -1503,7 +1503,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
out: out:
up_write(&namespace_sem); up_write(&namespace_sem);
path_put(&old_nd.path); path_put(&old_path);
return err; return err;
} }
...@@ -1530,31 +1530,31 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags) ...@@ -1530,31 +1530,31 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
* on it - tough luck. * on it - tough luck.
* noinline this do_mount helper to save do_mount stack space. * noinline this do_mount helper to save do_mount stack space.
*/ */
static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags, static noinline int do_remount(struct path *path, int flags, int mnt_flags,
void *data) void *data)
{ {
int err; int err;
struct super_block *sb = nd->path.mnt->mnt_sb; struct super_block *sb = path->mnt->mnt_sb;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (!check_mnt(nd->path.mnt)) if (!check_mnt(path->mnt))
return -EINVAL; return -EINVAL;
if (nd->path.dentry != nd->path.mnt->mnt_root) if (path->dentry != path->mnt->mnt_root)
return -EINVAL; return -EINVAL;
down_write(&sb->s_umount); down_write(&sb->s_umount);
if (flags & MS_BIND) if (flags & MS_BIND)
err = change_mount_flags(nd->path.mnt, flags); err = change_mount_flags(path->mnt, flags);
else else
err = do_remount_sb(sb, flags, data, 0); err = do_remount_sb(sb, flags, data, 0);
if (!err) if (!err)
nd->path.mnt->mnt_flags = mnt_flags; path->mnt->mnt_flags = mnt_flags;
up_write(&sb->s_umount); up_write(&sb->s_umount);
if (!err) if (!err)
security_sb_post_remount(nd->path.mnt, flags, data); security_sb_post_remount(path->mnt, flags, data);
return err; return err;
} }
...@@ -1571,78 +1571,77 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt) ...@@ -1571,78 +1571,77 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt)
/* /*
* noinline this do_mount helper to save do_mount stack space. * noinline this do_mount helper to save do_mount stack space.
*/ */
static noinline int do_move_mount(struct nameidata *nd, char *old_name) static noinline int do_move_mount(struct path *path, char *old_name)
{ {
struct nameidata old_nd; struct path old_path, parent_path;
struct path parent_path;
struct vfsmount *p; struct vfsmount *p;
int err = 0; int err = 0;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (!old_name || !*old_name) if (!old_name || !*old_name)
return -EINVAL; return -EINVAL;
err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd); err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
if (err) if (err)
return err; return err;
down_write(&namespace_sem); down_write(&namespace_sem);
while (d_mountpoint(nd->path.dentry) && while (d_mountpoint(path->dentry) &&
follow_down(&nd->path.mnt, &nd->path.dentry)) follow_down(&path->mnt, &path->dentry))
; ;
err = -EINVAL; err = -EINVAL;
if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
goto out; goto out;
err = -ENOENT; err = -ENOENT;
mutex_lock(&nd->path.dentry->d_inode->i_mutex); mutex_lock(&path->dentry->d_inode->i_mutex);
if (IS_DEADDIR(nd->path.dentry->d_inode)) if (IS_DEADDIR(path->dentry->d_inode))
goto out1; goto out1;
if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry)) if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry))
goto out1; goto out1;
err = -EINVAL; err = -EINVAL;
if (old_nd.path.dentry != old_nd.path.mnt->mnt_root) if (old_path.dentry != old_path.mnt->mnt_root)
goto out1; goto out1;
if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent) if (old_path.mnt == old_path.mnt->mnt_parent)
goto out1; goto out1;
if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != if (S_ISDIR(path->dentry->d_inode->i_mode) !=
S_ISDIR(old_nd.path.dentry->d_inode->i_mode)) S_ISDIR(old_path.dentry->d_inode->i_mode))
goto out1; goto out1;
/* /*
* Don't move a mount residing in a shared parent. * Don't move a mount residing in a shared parent.
*/ */
if (old_nd.path.mnt->mnt_parent && if (old_path.mnt->mnt_parent &&
IS_MNT_SHARED(old_nd.path.mnt->mnt_parent)) IS_MNT_SHARED(old_path.mnt->mnt_parent))
goto out1; goto out1;
/* /*
* Don't move a mount tree containing unbindable mounts to a destination * Don't move a mount tree containing unbindable mounts to a destination
* mount which is shared. * mount which is shared.
*/ */
if (IS_MNT_SHARED(nd->path.mnt) && if (IS_MNT_SHARED(path->mnt) &&
tree_contains_unbindable(old_nd.path.mnt)) tree_contains_unbindable(old_path.mnt))
goto out1; goto out1;
err = -ELOOP; err = -ELOOP;
for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent) for (p = path->mnt; p->mnt_parent != p; p = p->mnt_parent)
if (p == old_nd.path.mnt) if (p == old_path.mnt)
goto out1; goto out1;
err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path); err = attach_recursive_mnt(old_path.mnt, path, &parent_path);
if (err) if (err)
goto out1; goto out1;
/* if the mount is moved, it should no longer be expire /* if the mount is moved, it should no longer be expire
* automatically */ * automatically */
list_del_init(&old_nd.path.mnt->mnt_expire); list_del_init(&old_path.mnt->mnt_expire);
out1: out1:
mutex_unlock(&nd->path.dentry->d_inode->i_mutex); mutex_unlock(&path->dentry->d_inode->i_mutex);
out: out:
up_write(&namespace_sem); up_write(&namespace_sem);
if (!err) if (!err)
path_put(&parent_path); path_put(&parent_path);
path_put(&old_nd.path); path_put(&old_path);
return err; return err;
} }
...@@ -1651,7 +1650,7 @@ out: ...@@ -1651,7 +1650,7 @@ out:
* namespace's tree * namespace's tree
* noinline this do_mount helper to save do_mount stack space. * noinline this do_mount helper to save do_mount stack space.
*/ */
static noinline int do_new_mount(struct nameidata *nd, char *type, int flags, static noinline int do_new_mount(struct path *path, char *type, int flags,
int mnt_flags, char *name, void *data) int mnt_flags, char *name, void *data)
{ {
struct vfsmount *mnt; struct vfsmount *mnt;
...@@ -1667,7 +1666,7 @@ static noinline int do_new_mount(struct nameidata *nd, char *type, int flags, ...@@ -1667,7 +1666,7 @@ static noinline int do_new_mount(struct nameidata *nd, char *type, int flags,
if (IS_ERR(mnt)) if (IS_ERR(mnt))
return PTR_ERR(mnt); return PTR_ERR(mnt);
return do_add_mount(mnt, &nd->path, mnt_flags, NULL); return do_add_mount(mnt, path, mnt_flags, NULL);
} }
/* /*
...@@ -1902,7 +1901,7 @@ int copy_mount_options(const void __user * data, unsigned long *where) ...@@ -1902,7 +1901,7 @@ int copy_mount_options(const void __user * data, unsigned long *where)
long do_mount(char *dev_name, char *dir_name, char *type_page, long do_mount(char *dev_name, char *dir_name, char *type_page,
unsigned long flags, void *data_page) unsigned long flags, void *data_page)
{ {
struct nameidata nd; struct path path;
int retval = 0; int retval = 0;
int mnt_flags = 0; int mnt_flags = 0;
...@@ -1940,29 +1939,29 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, ...@@ -1940,29 +1939,29 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
/* ... and get the mountpoint */ /* ... and get the mountpoint */
retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
if (retval) if (retval)
return retval; return retval;
retval = security_sb_mount(dev_name, &nd.path, retval = security_sb_mount(dev_name, &path,
type_page, flags, data_page); type_page, flags, data_page);
if (retval) if (retval)
goto dput_out; goto dput_out;
if (flags & MS_REMOUNT) if (flags & MS_REMOUNT)
retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
data_page); data_page);
else if (flags & MS_BIND) else if (flags & MS_BIND)
retval = do_loopback(&nd, dev_name, flags & MS_REC); retval = do_loopback(&path, dev_name, flags & MS_REC);
else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
retval = do_change_type(&nd, flags); retval = do_change_type(&path, flags);
else if (flags & MS_MOVE) else if (flags & MS_MOVE)
retval = do_move_mount(&nd, dev_name); retval = do_move_mount(&path, dev_name);
else else
retval = do_new_mount(&nd, type_page, flags, mnt_flags, retval = do_new_mount(&path, type_page, flags, mnt_flags,
dev_name, data_page); dev_name, data_page);
dput_out: dput_out:
path_put(&nd.path); path_put(&path);
return retval; return 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