mirror of https://gitee.com/openkylin/linux.git
[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:
parent
b5266eb4c8
commit
8c3ee42e80
|
@ -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(¤t->fs->lock);
|
read_lock(¤t->fs->lock);
|
||||||
user_nd.path = current->fs->root;
|
root = current->fs->root;
|
||||||
path_get(¤t->fs->root);
|
path_get(¤t->fs->root);
|
||||||
read_unlock(¤t->fs->lock);
|
read_unlock(¤t->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);
|
||||||
|
|
Loading…
Reference in New Issue