aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c72
1 files changed, 37 insertions, 35 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 7953c96a2071..6324dfc80dc6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -155,15 +155,15 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
155 } 155 }
156} 156}
157 157
158static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) 158static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
159{ 159{
160 old_nd->path.dentry = mnt->mnt_mountpoint; 160 old_path->dentry = mnt->mnt_mountpoint;
161 old_nd->path.mnt = mnt->mnt_parent; 161 old_path->mnt = mnt->mnt_parent;
162 mnt->mnt_parent = mnt; 162 mnt->mnt_parent = mnt;
163 mnt->mnt_mountpoint = mnt->mnt_root; 163 mnt->mnt_mountpoint = mnt->mnt_root;
164 list_del_init(&mnt->mnt_child); 164 list_del_init(&mnt->mnt_child);
165 list_del_init(&mnt->mnt_hash); 165 list_del_init(&mnt->mnt_hash);
166 old_nd->path.dentry->d_mounted--; 166 old_path->dentry->d_mounted--;
167} 167}
168 168
169void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, 169void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
@@ -174,12 +174,12 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
174 dentry->d_mounted++; 174 dentry->d_mounted++;
175} 175}
176 176
177static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) 177static void attach_mnt(struct vfsmount *mnt, struct path *path)
178{ 178{
179 mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt); 179 mnt_set_mountpoint(path->mnt, path->dentry, mnt);
180 list_add_tail(&mnt->mnt_hash, mount_hashtable + 180 list_add_tail(&mnt->mnt_hash, mount_hashtable +
181 hash(nd->path.mnt, nd->path.dentry)); 181 hash(path->mnt, path->dentry));
182 list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); 182 list_add_tail(&mnt->mnt_child, &path->mnt->mnt_mounts);
183} 183}
184 184
185/* 185/*
@@ -744,7 +744,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
744 int flag) 744 int flag)
745{ 745{
746 struct vfsmount *res, *p, *q, *r, *s; 746 struct vfsmount *res, *p, *q, *r, *s;
747 struct nameidata nd; 747 struct path path;
748 748
749 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) 749 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
750 return NULL; 750 return NULL;
@@ -769,14 +769,14 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
769 q = q->mnt_parent; 769 q = q->mnt_parent;
770 } 770 }
771 p = s; 771 p = s;
772 nd.path.mnt = q; 772 path.mnt = q;
773 nd.path.dentry = p->mnt_mountpoint; 773 path.dentry = p->mnt_mountpoint;
774 q = clone_mnt(p, p->mnt_root, flag); 774 q = clone_mnt(p, p->mnt_root, flag);
775 if (!q) 775 if (!q)
776 goto Enomem; 776 goto Enomem;
777 spin_lock(&vfsmount_lock); 777 spin_lock(&vfsmount_lock);
778 list_add_tail(&q->mnt_list, &res->mnt_list); 778 list_add_tail(&q->mnt_list, &res->mnt_list);
779 attach_mnt(q, &nd); 779 attach_mnt(q, &path);
780 spin_unlock(&vfsmount_lock); 780 spin_unlock(&vfsmount_lock);
781 } 781 }
782 } 782 }
@@ -876,11 +876,11 @@ void drop_collected_mounts(struct vfsmount *mnt)
876 * in allocations. 876 * in allocations.
877 */ 877 */
878static int attach_recursive_mnt(struct vfsmount *source_mnt, 878static int attach_recursive_mnt(struct vfsmount *source_mnt,
879 struct nameidata *nd, struct nameidata *parent_nd) 879 struct path *path, struct path *parent_path)
880{ 880{
881 LIST_HEAD(tree_list); 881 LIST_HEAD(tree_list);
882 struct vfsmount *dest_mnt = nd->path.mnt; 882 struct vfsmount *dest_mnt = path->mnt;
883 struct dentry *dest_dentry = nd->path.dentry; 883 struct dentry *dest_dentry = path->dentry;
884 struct vfsmount *child, *p; 884 struct vfsmount *child, *p;
885 885
886 if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) 886 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 } 892 }
893 893
894 spin_lock(&vfsmount_lock); 894 spin_lock(&vfsmount_lock);
895 if (parent_nd) { 895 if (parent_path) {
896 detach_mnt(source_mnt, parent_nd); 896 detach_mnt(source_mnt, parent_path);
897 attach_mnt(source_mnt, nd); 897 attach_mnt(source_mnt, path);
898 touch_mnt_namespace(current->nsproxy->mnt_ns); 898 touch_mnt_namespace(current->nsproxy->mnt_ns);
899 } else { 899 } else {
900 mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); 900 mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
@@ -930,7 +930,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
930 930
931 err = -ENOENT; 931 err = -ENOENT;
932 if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) 932 if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry))
933 err = attach_recursive_mnt(mnt, nd, NULL); 933 err = attach_recursive_mnt(mnt, &nd->path, NULL);
934out_unlock: 934out_unlock:
935 mutex_unlock(&nd->path.dentry->d_inode->i_mutex); 935 mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
936 if (!err) 936 if (!err)
@@ -1059,7 +1059,8 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt)
1059 */ 1059 */
1060static noinline int do_move_mount(struct nameidata *nd, char *old_name) 1060static noinline int do_move_mount(struct nameidata *nd, char *old_name)
1061{ 1061{
1062 struct nameidata old_nd, parent_nd; 1062 struct nameidata old_nd;
1063 struct path parent_path;
1063 struct vfsmount *p; 1064 struct vfsmount *p;
1064 int err = 0; 1065 int err = 0;
1065 if (!capable(CAP_SYS_ADMIN)) 1066 if (!capable(CAP_SYS_ADMIN))
@@ -1114,7 +1115,7 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
1114 if (p == old_nd.path.mnt) 1115 if (p == old_nd.path.mnt)
1115 goto out1; 1116 goto out1;
1116 1117
1117 err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd); 1118 err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path);
1118 if (err) 1119 if (err)
1119 goto out1; 1120 goto out1;
1120 1121
@@ -1128,7 +1129,7 @@ out1:
1128out: 1129out:
1129 up_write(&namespace_sem); 1130 up_write(&namespace_sem);
1130 if (!err) 1131 if (!err)
1131 path_put(&parent_nd.path); 1132 path_put(&parent_path);
1132 path_put(&old_nd.path); 1133 path_put(&old_nd.path);
1133 return err; 1134 return err;
1134} 1135}
@@ -1683,7 +1684,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
1683 path_put(&old_pwd); 1684 path_put(&old_pwd);
1684} 1685}
1685 1686
1686static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) 1687static void chroot_fs_refs(struct path *old_root, struct path *new_root)
1687{ 1688{
1688 struct task_struct *g, *p; 1689 struct task_struct *g, *p;
1689 struct fs_struct *fs; 1690 struct fs_struct *fs;
@@ -1695,12 +1696,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
1695 if (fs) { 1696 if (fs) {
1696 atomic_inc(&fs->count); 1697 atomic_inc(&fs->count);
1697 task_unlock(p); 1698 task_unlock(p);
1698 if (fs->root.dentry == old_nd->path.dentry 1699 if (fs->root.dentry == old_root->dentry
1699 && fs->root.mnt == old_nd->path.mnt) 1700 && fs->root.mnt == old_root->mnt)
1700 set_fs_root(fs, &new_nd->path); 1701 set_fs_root(fs, new_root);
1701 if (fs->pwd.dentry == old_nd->path.dentry 1702 if (fs->pwd.dentry == old_root->dentry
1702 && fs->pwd.mnt == old_nd->path.mnt) 1703 && fs->pwd.mnt == old_root->mnt)
1703 set_fs_pwd(fs, &new_nd->path); 1704 set_fs_pwd(fs, new_root);
1704 put_fs_struct(fs); 1705 put_fs_struct(fs);
1705 } else 1706 } else
1706 task_unlock(p); 1707 task_unlock(p);
@@ -1737,7 +1738,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1737 const char __user * put_old) 1738 const char __user * put_old)
1738{ 1739{
1739 struct vfsmount *tmp; 1740 struct vfsmount *tmp;
1740 struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; 1741 struct nameidata new_nd, old_nd, user_nd;
1742 struct path parent_path, root_parent;
1741 int error; 1743 int error;
1742 1744
1743 if (!capable(CAP_SYS_ADMIN)) 1745 if (!capable(CAP_SYS_ADMIN))
@@ -1811,19 +1813,19 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1811 goto out3; 1813 goto out3;
1812 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) 1814 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
1813 goto out3; 1815 goto out3;
1814 detach_mnt(new_nd.path.mnt, &parent_nd); 1816 detach_mnt(new_nd.path.mnt, &parent_path);
1815 detach_mnt(user_nd.path.mnt, &root_parent); 1817 detach_mnt(user_nd.path.mnt, &root_parent);
1816 /* mount old root on put_old */ 1818 /* mount old root on put_old */
1817 attach_mnt(user_nd.path.mnt, &old_nd); 1819 attach_mnt(user_nd.path.mnt, &old_nd.path);
1818 /* mount new_root on / */ 1820 /* mount new_root on / */
1819 attach_mnt(new_nd.path.mnt, &root_parent); 1821 attach_mnt(new_nd.path.mnt, &root_parent);
1820 touch_mnt_namespace(current->nsproxy->mnt_ns); 1822 touch_mnt_namespace(current->nsproxy->mnt_ns);
1821 spin_unlock(&vfsmount_lock); 1823 spin_unlock(&vfsmount_lock);
1822 chroot_fs_refs(&user_nd, &new_nd); 1824 chroot_fs_refs(&user_nd.path, &new_nd.path);
1823 security_sb_post_pivotroot(&user_nd, &new_nd); 1825 security_sb_post_pivotroot(&user_nd, &new_nd);
1824 error = 0; 1826 error = 0;
1825 path_put(&root_parent.path); 1827 path_put(&root_parent);
1826 path_put(&parent_nd.path); 1828 path_put(&parent_path);
1827out2: 1829out2:
1828 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); 1830 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
1829 up_write(&namespace_sem); 1831 up_write(&namespace_sem);