[PATCH] get rid of more nameidata passing in namespace.c

Further reduction of stack footprint (sys_pivot_root());
lose useless BKL in there, while we are at it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2008-03-22 18:00:39 -04:00
parent b5266eb4c8
commit 8c3ee42e80
1 changed files with 25 additions and 28 deletions

View File

@ -1205,32 +1205,32 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
return 0; return 0;
} }
static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) static int graft_tree(struct vfsmount *mnt, struct path *path)
{ {
int err; int err;
if (mnt->mnt_sb->s_flags & MS_NOUSER) if (mnt->mnt_sb->s_flags & MS_NOUSER)
return -EINVAL; return -EINVAL;
if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != if (S_ISDIR(path->dentry->d_inode->i_mode) !=
S_ISDIR(mnt->mnt_root->d_inode->i_mode)) S_ISDIR(mnt->mnt_root->d_inode->i_mode))
return -ENOTDIR; return -ENOTDIR;
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 out_unlock; goto out_unlock;
err = security_sb_check_sb(mnt, &nd->path); err = security_sb_check_sb(mnt, path);
if (err) if (err)
goto out_unlock; goto out_unlock;
err = -ENOENT; err = -ENOENT;
if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) if (IS_ROOT(path->dentry) || !d_unhashed(path->dentry))
err = attach_recursive_mnt(mnt, &nd->path, NULL); err = attach_recursive_mnt(mnt, path, NULL);
out_unlock: out_unlock:
mutex_unlock(&nd->path.dentry->d_inode->i_mutex); mutex_unlock(&path->dentry->d_inode->i_mutex);
if (!err) if (!err)
security_sb_post_addmount(mnt, &nd->path); security_sb_post_addmount(mnt, path);
return err; return err;
} }
@ -1294,7 +1294,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
if (!mnt) if (!mnt)
goto out; goto out;
err = graft_tree(mnt, nd); err = graft_tree(mnt, &nd->path);
if (err) { if (err) {
LIST_HEAD(umount_list); LIST_HEAD(umount_list);
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
@ -1501,7 +1501,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
goto unlock; goto unlock;
newmnt->mnt_flags = mnt_flags; newmnt->mnt_flags = mnt_flags;
if ((err = graft_tree(newmnt, nd))) if ((err = graft_tree(newmnt, &nd->path)))
goto unlock; goto unlock;
if (fslist) /* add to the specified expiration list */ if (fslist) /* add to the specified expiration list */
@ -1987,15 +1987,13 @@ 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, user_nd; struct nameidata new_nd, old_nd;
struct path parent_path, root_parent; struct path parent_path, root_parent, root;
int error; int error;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
lock_kernel();
error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
&new_nd); &new_nd);
if (error) if (error)
@ -2015,7 +2013,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
} }
read_lock(&current->fs->lock); read_lock(&current->fs->lock);
user_nd.path = current->fs->root; root = current->fs->root;
path_get(&current->fs->root); path_get(&current->fs->root);
read_unlock(&current->fs->lock); read_unlock(&current->fs->lock);
down_write(&namespace_sem); down_write(&namespace_sem);
@ -2023,9 +2021,9 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
error = -EINVAL; error = -EINVAL;
if (IS_MNT_SHARED(old_nd.path.mnt) || if (IS_MNT_SHARED(old_nd.path.mnt) ||
IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) ||
IS_MNT_SHARED(user_nd.path.mnt->mnt_parent)) IS_MNT_SHARED(root.mnt->mnt_parent))
goto out2; goto out2;
if (!check_mnt(user_nd.path.mnt)) if (!check_mnt(root.mnt))
goto out2; goto out2;
error = -ENOENT; error = -ENOENT;
if (IS_DEADDIR(new_nd.path.dentry->d_inode)) if (IS_DEADDIR(new_nd.path.dentry->d_inode))
@ -2035,13 +2033,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry))
goto out2; goto out2;
error = -EBUSY; error = -EBUSY;
if (new_nd.path.mnt == user_nd.path.mnt || if (new_nd.path.mnt == root.mnt ||
old_nd.path.mnt == user_nd.path.mnt) old_nd.path.mnt == root.mnt)
goto out2; /* loop, on the same file system */ goto out2; /* loop, on the same file system */
error = -EINVAL; error = -EINVAL;
if (user_nd.path.mnt->mnt_root != user_nd.path.dentry) if (root.mnt->mnt_root != root.dentry)
goto out2; /* not a mountpoint */ goto out2; /* not a mountpoint */
if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt) if (root.mnt->mnt_parent == root.mnt)
goto out2; /* not attached */ goto out2; /* not attached */
if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) if (new_nd.path.mnt->mnt_root != new_nd.path.dentry)
goto out2; /* not a mountpoint */ goto out2; /* not a mountpoint */
@ -2063,27 +2061,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
} 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_path); detach_mnt(new_nd.path.mnt, &parent_path);
detach_mnt(user_nd.path.mnt, &root_parent); detach_mnt(root.mnt, &root_parent);
/* mount old root on put_old */ /* mount old root on put_old */
attach_mnt(user_nd.path.mnt, &old_nd.path); attach_mnt(root.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.path, &new_nd.path); chroot_fs_refs(&root, &new_nd.path);
security_sb_post_pivotroot(&user_nd.path, &new_nd.path); security_sb_post_pivotroot(&root, &new_nd.path);
error = 0; error = 0;
path_put(&root_parent); path_put(&root_parent);
path_put(&parent_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);
path_put(&user_nd.path); path_put(&root);
path_put(&old_nd.path); path_put(&old_nd.path);
out1: out1:
path_put(&new_nd.path); path_put(&new_nd.path);
out0: out0:
unlock_kernel();
return error; return error;
out3: out3:
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);