Commit 1a390689 authored by Al Viro's avatar Al Viro

[PATCH] reduce stack footprint in namespace.c

A lot of places misuse struct nameidata when they need struct path.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 3085354d
...@@ -155,15 +155,15 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns) ...@@ -155,15 +155,15 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
} }
} }
static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
{ {
old_nd->path.dentry = mnt->mnt_mountpoint; old_path->dentry = mnt->mnt_mountpoint;
old_nd->path.mnt = mnt->mnt_parent; old_path->mnt = mnt->mnt_parent;
mnt->mnt_parent = mnt; mnt->mnt_parent = mnt;
mnt->mnt_mountpoint = mnt->mnt_root; mnt->mnt_mountpoint = mnt->mnt_root;
list_del_init(&mnt->mnt_child); list_del_init(&mnt->mnt_child);
list_del_init(&mnt->mnt_hash); list_del_init(&mnt->mnt_hash);
old_nd->path.dentry->d_mounted--; old_path->dentry->d_mounted--;
} }
void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
...@@ -174,12 +174,12 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, ...@@ -174,12 +174,12 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
dentry->d_mounted++; dentry->d_mounted++;
} }
static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) static void attach_mnt(struct vfsmount *mnt, struct path *path)
{ {
mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt); mnt_set_mountpoint(path->mnt, path->dentry, mnt);
list_add_tail(&mnt->mnt_hash, mount_hashtable + list_add_tail(&mnt->mnt_hash, mount_hashtable +
hash(nd->path.mnt, nd->path.dentry)); hash(path->mnt, path->dentry));
list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); list_add_tail(&mnt->mnt_child, &path->mnt->mnt_mounts);
} }
/* /*
...@@ -744,7 +744,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, ...@@ -744,7 +744,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
int flag) int flag)
{ {
struct vfsmount *res, *p, *q, *r, *s; struct vfsmount *res, *p, *q, *r, *s;
struct nameidata nd; struct path path;
if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
return NULL; return NULL;
...@@ -769,14 +769,14 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, ...@@ -769,14 +769,14 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
q = q->mnt_parent; q = q->mnt_parent;
} }
p = s; p = s;
nd.path.mnt = q; path.mnt = q;
nd.path.dentry = p->mnt_mountpoint; path.dentry = p->mnt_mountpoint;
q = clone_mnt(p, p->mnt_root, flag); q = clone_mnt(p, p->mnt_root, flag);
if (!q) if (!q)
goto Enomem; goto Enomem;
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
list_add_tail(&q->mnt_list, &res->mnt_list); list_add_tail(&q->mnt_list, &res->mnt_list);
attach_mnt(q, &nd); attach_mnt(q, &path);
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);
} }
} }
...@@ -876,11 +876,11 @@ void drop_collected_mounts(struct vfsmount *mnt) ...@@ -876,11 +876,11 @@ void drop_collected_mounts(struct vfsmount *mnt)
* in allocations. * in allocations.
*/ */
static int attach_recursive_mnt(struct vfsmount *source_mnt, static int attach_recursive_mnt(struct vfsmount *source_mnt,
struct nameidata *nd, struct nameidata *parent_nd) struct path *path, struct path *parent_path)
{ {
LIST_HEAD(tree_list); LIST_HEAD(tree_list);
struct vfsmount *dest_mnt = nd->path.mnt; struct vfsmount *dest_mnt = path->mnt;
struct dentry *dest_dentry = nd->path.dentry; struct dentry *dest_dentry = path->dentry;
struct vfsmount *child, *p; struct vfsmount *child, *p;
if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
...@@ -892,9 +892,9 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, ...@@ -892,9 +892,9 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
} }
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
if (parent_nd) { if (parent_path) {
detach_mnt(source_mnt, parent_nd); detach_mnt(source_mnt, parent_path);
attach_mnt(source_mnt, nd); attach_mnt(source_mnt, path);
touch_mnt_namespace(current->nsproxy->mnt_ns); touch_mnt_namespace(current->nsproxy->mnt_ns);
} else { } else {
mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
...@@ -930,7 +930,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) ...@@ -930,7 +930,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
err = -ENOENT; err = -ENOENT;
if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry))
err = attach_recursive_mnt(mnt, nd, NULL); err = attach_recursive_mnt(mnt, &nd->path, NULL);
out_unlock: out_unlock:
mutex_unlock(&nd->path.dentry->d_inode->i_mutex); mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
if (!err) if (!err)
...@@ -1059,7 +1059,8 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt) ...@@ -1059,7 +1059,8 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt)
*/ */
static noinline int do_move_mount(struct nameidata *nd, char *old_name) static noinline int do_move_mount(struct nameidata *nd, char *old_name)
{ {
struct nameidata old_nd, parent_nd; struct nameidata old_nd;
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))
...@@ -1114,7 +1115,7 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name) ...@@ -1114,7 +1115,7 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
if (p == old_nd.path.mnt) if (p == old_nd.path.mnt)
goto out1; goto out1;
err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd); err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path);
if (err) if (err)
goto out1; goto out1;
...@@ -1128,7 +1129,7 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name) ...@@ -1128,7 +1129,7 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
out: out:
up_write(&namespace_sem); up_write(&namespace_sem);
if (!err) if (!err)
path_put(&parent_nd.path); path_put(&parent_path);
path_put(&old_nd.path); path_put(&old_nd.path);
return err; return err;
} }
...@@ -1683,7 +1684,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) ...@@ -1683,7 +1684,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
path_put(&old_pwd); path_put(&old_pwd);
} }
static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) static void chroot_fs_refs(struct path *old_root, struct path *new_root)
{ {
struct task_struct *g, *p; struct task_struct *g, *p;
struct fs_struct *fs; struct fs_struct *fs;
...@@ -1695,12 +1696,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) ...@@ -1695,12 +1696,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
if (fs) { if (fs) {
atomic_inc(&fs->count); atomic_inc(&fs->count);
task_unlock(p); task_unlock(p);
if (fs->root.dentry == old_nd->path.dentry if (fs->root.dentry == old_root->dentry
&& fs->root.mnt == old_nd->path.mnt) && fs->root.mnt == old_root->mnt)
set_fs_root(fs, &new_nd->path); set_fs_root(fs, new_root);
if (fs->pwd.dentry == old_nd->path.dentry if (fs->pwd.dentry == old_root->dentry
&& fs->pwd.mnt == old_nd->path.mnt) && fs->pwd.mnt == old_root->mnt)
set_fs_pwd(fs, &new_nd->path); set_fs_pwd(fs, new_root);
put_fs_struct(fs); put_fs_struct(fs);
} else } else
task_unlock(p); task_unlock(p);
...@@ -1737,7 +1738,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -1737,7 +1738,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
const char __user * put_old) const char __user * put_old)
{ {
struct vfsmount *tmp; struct vfsmount *tmp;
struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; struct nameidata new_nd, old_nd, user_nd;
struct path parent_path, root_parent;
int error; int error;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
...@@ -1811,19 +1813,19 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -1811,19 +1813,19 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
goto out3; goto out3;
} else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
goto out3; goto out3;
detach_mnt(new_nd.path.mnt, &parent_nd); detach_mnt(new_nd.path.mnt, &parent_path);
detach_mnt(user_nd.path.mnt, &root_parent); detach_mnt(user_nd.path.mnt, &root_parent);
/* mount old root on put_old */ /* mount old root on put_old */
attach_mnt(user_nd.path.mnt, &old_nd); attach_mnt(user_nd.path.mnt, &old_nd.path);
/* mount new_root on / */ /* mount new_root on / */
attach_mnt(new_nd.path.mnt, &root_parent); attach_mnt(new_nd.path.mnt, &root_parent);
touch_mnt_namespace(current->nsproxy->mnt_ns); touch_mnt_namespace(current->nsproxy->mnt_ns);
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);
chroot_fs_refs(&user_nd, &new_nd); chroot_fs_refs(&user_nd.path, &new_nd.path);
security_sb_post_pivotroot(&user_nd, &new_nd); security_sb_post_pivotroot(&user_nd, &new_nd);
error = 0; error = 0;
path_put(&root_parent.path); path_put(&root_parent);
path_put(&parent_nd.path); path_put(&parent_path);
out2: out2:
mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
up_write(&namespace_sem); up_write(&namespace_sem);
......
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