aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorJan Blunck <jblunck@suse.de>2008-02-14 22:34:32 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-15 00:13:33 -0500
commit4ac9137858e08a19f29feac4e1f4df7c268b0ba5 (patch)
treef5b5d84fd12fcc2b0ba0e7ce1a79ff381ad8f5dd /fs/namespace.c
parentc5e725f33b733a77de622e91b6ba5645fcf070be (diff)
Embed a struct path into struct nameidata instead of nd->{dentry,mnt}
This is the central patch of a cleanup series. In most cases there is no good reason why someone would want to use a dentry for itself. This series reflects that fact and embeds a struct path into nameidata. Together with the other patches of this series - it enforced the correct order of getting/releasing the reference count on <dentry,vfsmount> pairs - it prepares the VFS for stacking support since it is essential to have a struct path in every place where the stack can be traversed - it reduces the overall code size: without patch series: text data bss dec hex filename 5321639 858418 715768 6895825 6938d1 vmlinux with patch series: text data bss dec hex filename 5320026 858418 715768 6894212 693284 vmlinux This patch: Switch from nd->{dentry,mnt} to nd->path.{dentry,mnt} everywhere. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: fix cifs] [akpm@linux-foundation.org: fix smack] Signed-off-by: Jan Blunck <jblunck@suse.de> Signed-off-by: Andreas Gruenbacher <agruen@suse.de> Acked-by: Christoph Hellwig <hch@lst.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c185
1 files changed, 98 insertions, 87 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 7937d30a6732..5d9fd4c6d1f5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -157,13 +157,13 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
157 157
158static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) 158static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
159{ 159{
160 old_nd->dentry = mnt->mnt_mountpoint; 160 old_nd->path.dentry = mnt->mnt_mountpoint;
161 old_nd->mnt = mnt->mnt_parent; 161 old_nd->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->dentry->d_mounted--; 166 old_nd->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,
@@ -176,10 +176,10 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
176 176
177static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) 177static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
178{ 178{
179 mnt_set_mountpoint(nd->mnt, nd->dentry, mnt); 179 mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt);
180 list_add_tail(&mnt->mnt_hash, mount_hashtable + 180 list_add_tail(&mnt->mnt_hash, mount_hashtable +
181 hash(nd->mnt, nd->dentry)); 181 hash(nd->path.mnt, nd->path.dentry));
182 list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts); 182 list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts);
183} 183}
184 184
185/* 185/*
@@ -679,20 +679,20 @@ asmlinkage long sys_umount(char __user * name, int flags)
679 if (retval) 679 if (retval)
680 goto out; 680 goto out;
681 retval = -EINVAL; 681 retval = -EINVAL;
682 if (nd.dentry != nd.mnt->mnt_root) 682 if (nd.path.dentry != nd.path.mnt->mnt_root)
683 goto dput_and_out; 683 goto dput_and_out;
684 if (!check_mnt(nd.mnt)) 684 if (!check_mnt(nd.path.mnt))
685 goto dput_and_out; 685 goto dput_and_out;
686 686
687 retval = -EPERM; 687 retval = -EPERM;
688 if (!capable(CAP_SYS_ADMIN)) 688 if (!capable(CAP_SYS_ADMIN))
689 goto dput_and_out; 689 goto dput_and_out;
690 690
691 retval = do_umount(nd.mnt, flags); 691 retval = do_umount(nd.path.mnt, flags);
692dput_and_out: 692dput_and_out:
693 /* we mustn't call path_put() as that would clear mnt_expiry_mark */ 693 /* we mustn't call path_put() as that would clear mnt_expiry_mark */
694 dput(nd.dentry); 694 dput(nd.path.dentry);
695 mntput_no_expire(nd.mnt); 695 mntput_no_expire(nd.path.mnt);
696out: 696out:
697 return retval; 697 return retval;
698} 698}
@@ -715,10 +715,10 @@ static int mount_is_safe(struct nameidata *nd)
715 return 0; 715 return 0;
716 return -EPERM; 716 return -EPERM;
717#ifdef notyet 717#ifdef notyet
718 if (S_ISLNK(nd->dentry->d_inode->i_mode)) 718 if (S_ISLNK(nd->path.dentry->d_inode->i_mode))
719 return -EPERM; 719 return -EPERM;
720 if (nd->dentry->d_inode->i_mode & S_ISVTX) { 720 if (nd->path.dentry->d_inode->i_mode & S_ISVTX) {
721 if (current->uid != nd->dentry->d_inode->i_uid) 721 if (current->uid != nd->path.dentry->d_inode->i_uid)
722 return -EPERM; 722 return -EPERM;
723 } 723 }
724 if (vfs_permission(nd, MAY_WRITE)) 724 if (vfs_permission(nd, MAY_WRITE))
@@ -767,8 +767,8 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
767 q = q->mnt_parent; 767 q = q->mnt_parent;
768 } 768 }
769 p = s; 769 p = s;
770 nd.mnt = q; 770 nd.path.mnt = q;
771 nd.dentry = p->mnt_mountpoint; 771 nd.path.dentry = p->mnt_mountpoint;
772 q = clone_mnt(p, p->mnt_root, flag); 772 q = clone_mnt(p, p->mnt_root, flag);
773 if (!q) 773 if (!q)
774 goto Enomem; 774 goto Enomem;
@@ -877,8 +877,8 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
877 struct nameidata *nd, struct nameidata *parent_nd) 877 struct nameidata *nd, struct nameidata *parent_nd)
878{ 878{
879 LIST_HEAD(tree_list); 879 LIST_HEAD(tree_list);
880 struct vfsmount *dest_mnt = nd->mnt; 880 struct vfsmount *dest_mnt = nd->path.mnt;
881 struct dentry *dest_dentry = nd->dentry; 881 struct dentry *dest_dentry = nd->path.dentry;
882 struct vfsmount *child, *p; 882 struct vfsmount *child, *p;
883 883
884 if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) 884 if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
@@ -913,13 +913,13 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
913 if (mnt->mnt_sb->s_flags & MS_NOUSER) 913 if (mnt->mnt_sb->s_flags & MS_NOUSER)
914 return -EINVAL; 914 return -EINVAL;
915 915
916 if (S_ISDIR(nd->dentry->d_inode->i_mode) != 916 if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
917 S_ISDIR(mnt->mnt_root->d_inode->i_mode)) 917 S_ISDIR(mnt->mnt_root->d_inode->i_mode))
918 return -ENOTDIR; 918 return -ENOTDIR;
919 919
920 err = -ENOENT; 920 err = -ENOENT;
921 mutex_lock(&nd->dentry->d_inode->i_mutex); 921 mutex_lock(&nd->path.dentry->d_inode->i_mutex);
922 if (IS_DEADDIR(nd->dentry->d_inode)) 922 if (IS_DEADDIR(nd->path.dentry->d_inode))
923 goto out_unlock; 923 goto out_unlock;
924 924
925 err = security_sb_check_sb(mnt, nd); 925 err = security_sb_check_sb(mnt, nd);
@@ -927,10 +927,10 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
927 goto out_unlock; 927 goto out_unlock;
928 928
929 err = -ENOENT; 929 err = -ENOENT;
930 if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) 930 if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry))
931 err = attach_recursive_mnt(mnt, nd, NULL); 931 err = attach_recursive_mnt(mnt, nd, NULL);
932out_unlock: 932out_unlock:
933 mutex_unlock(&nd->dentry->d_inode->i_mutex); 933 mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
934 if (!err) 934 if (!err)
935 security_sb_post_addmount(mnt, nd); 935 security_sb_post_addmount(mnt, nd);
936 return err; 936 return err;
@@ -942,14 +942,14 @@ out_unlock:
942 */ 942 */
943static noinline int do_change_type(struct nameidata *nd, int flag) 943static noinline int do_change_type(struct nameidata *nd, int flag)
944{ 944{
945 struct vfsmount *m, *mnt = nd->mnt; 945 struct vfsmount *m, *mnt = nd->path.mnt;
946 int recurse = flag & MS_REC; 946 int recurse = flag & MS_REC;
947 int type = flag & ~MS_REC; 947 int type = flag & ~MS_REC;
948 948
949 if (!capable(CAP_SYS_ADMIN)) 949 if (!capable(CAP_SYS_ADMIN))
950 return -EPERM; 950 return -EPERM;
951 951
952 if (nd->dentry != nd->mnt->mnt_root) 952 if (nd->path.dentry != nd->path.mnt->mnt_root)
953 return -EINVAL; 953 return -EINVAL;
954 954
955 down_write(&namespace_sem); 955 down_write(&namespace_sem);
@@ -981,17 +981,17 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
981 981
982 down_write(&namespace_sem); 982 down_write(&namespace_sem);
983 err = -EINVAL; 983 err = -EINVAL;
984 if (IS_MNT_UNBINDABLE(old_nd.mnt)) 984 if (IS_MNT_UNBINDABLE(old_nd.path.mnt))
985 goto out; 985 goto out;
986 986
987 if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) 987 if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
988 goto out; 988 goto out;
989 989
990 err = -ENOMEM; 990 err = -ENOMEM;
991 if (recurse) 991 if (recurse)
992 mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0); 992 mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0);
993 else 993 else
994 mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0); 994 mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0);
995 995
996 if (!mnt) 996 if (!mnt)
997 goto out; 997 goto out;
@@ -1021,24 +1021,24 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
1021 void *data) 1021 void *data)
1022{ 1022{
1023 int err; 1023 int err;
1024 struct super_block *sb = nd->mnt->mnt_sb; 1024 struct super_block *sb = nd->path.mnt->mnt_sb;
1025 1025
1026 if (!capable(CAP_SYS_ADMIN)) 1026 if (!capable(CAP_SYS_ADMIN))
1027 return -EPERM; 1027 return -EPERM;
1028 1028
1029 if (!check_mnt(nd->mnt)) 1029 if (!check_mnt(nd->path.mnt))
1030 return -EINVAL; 1030 return -EINVAL;
1031 1031
1032 if (nd->dentry != nd->mnt->mnt_root) 1032 if (nd->path.dentry != nd->path.mnt->mnt_root)
1033 return -EINVAL; 1033 return -EINVAL;
1034 1034
1035 down_write(&sb->s_umount); 1035 down_write(&sb->s_umount);
1036 err = do_remount_sb(sb, flags, data, 0); 1036 err = do_remount_sb(sb, flags, data, 0);
1037 if (!err) 1037 if (!err)
1038 nd->mnt->mnt_flags = mnt_flags; 1038 nd->path.mnt->mnt_flags = mnt_flags;
1039 up_write(&sb->s_umount); 1039 up_write(&sb->s_umount);
1040 if (!err) 1040 if (!err)
1041 security_sb_post_remount(nd->mnt, flags, data); 1041 security_sb_post_remount(nd->path.mnt, flags, data);
1042 return err; 1042 return err;
1043} 1043}
1044 1044
@@ -1069,56 +1069,60 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
1069 return err; 1069 return err;
1070 1070
1071 down_write(&namespace_sem); 1071 down_write(&namespace_sem);
1072 while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) 1072 while (d_mountpoint(nd->path.dentry) &&
1073 follow_down(&nd->path.mnt, &nd->path.dentry))
1073 ; 1074 ;
1074 err = -EINVAL; 1075 err = -EINVAL;
1075 if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) 1076 if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
1076 goto out; 1077 goto out;
1077 1078
1078 err = -ENOENT; 1079 err = -ENOENT;
1079 mutex_lock(&nd->dentry->d_inode->i_mutex); 1080 mutex_lock(&nd->path.dentry->d_inode->i_mutex);
1080 if (IS_DEADDIR(nd->dentry->d_inode)) 1081 if (IS_DEADDIR(nd->path.dentry->d_inode))
1081 goto out1; 1082 goto out1;
1082 1083
1083 if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry)) 1084 if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry))
1084 goto out1; 1085 goto out1;
1085 1086
1086 err = -EINVAL; 1087 err = -EINVAL;
1087 if (old_nd.dentry != old_nd.mnt->mnt_root) 1088 if (old_nd.path.dentry != old_nd.path.mnt->mnt_root)
1088 goto out1; 1089 goto out1;
1089 1090
1090 if (old_nd.mnt == old_nd.mnt->mnt_parent) 1091 if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent)
1091 goto out1; 1092 goto out1;
1092 1093
1093 if (S_ISDIR(nd->dentry->d_inode->i_mode) != 1094 if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
1094 S_ISDIR(old_nd.dentry->d_inode->i_mode)) 1095 S_ISDIR(old_nd.path.dentry->d_inode->i_mode))
1095 goto out1; 1096 goto out1;
1096 /* 1097 /*
1097 * Don't move a mount residing in a shared parent. 1098 * Don't move a mount residing in a shared parent.
1098 */ 1099 */
1099 if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent)) 1100 if (old_nd.path.mnt->mnt_parent &&
1101 IS_MNT_SHARED(old_nd.path.mnt->mnt_parent))
1100 goto out1; 1102 goto out1;
1101 /* 1103 /*
1102 * Don't move a mount tree containing unbindable mounts to a destination 1104 * Don't move a mount tree containing unbindable mounts to a destination
1103 * mount which is shared. 1105 * mount which is shared.
1104 */ 1106 */
1105 if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt)) 1107 if (IS_MNT_SHARED(nd->path.mnt) &&
1108 tree_contains_unbindable(old_nd.path.mnt))
1106 goto out1; 1109 goto out1;
1107 err = -ELOOP; 1110 err = -ELOOP;
1108 for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent) 1111 for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent)
1109 if (p == old_nd.mnt) 1112 if (p == old_nd.path.mnt)
1110 goto out1; 1113 goto out1;
1111 1114
1112 if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd))) 1115 err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd);
1116 if (err)
1113 goto out1; 1117 goto out1;
1114 1118
1115 spin_lock(&vfsmount_lock); 1119 spin_lock(&vfsmount_lock);
1116 /* if the mount is moved, it should no longer be expire 1120 /* if the mount is moved, it should no longer be expire
1117 * automatically */ 1121 * automatically */
1118 list_del_init(&old_nd.mnt->mnt_expire); 1122 list_del_init(&old_nd.path.mnt->mnt_expire);
1119 spin_unlock(&vfsmount_lock); 1123 spin_unlock(&vfsmount_lock);
1120out1: 1124out1:
1121 mutex_unlock(&nd->dentry->d_inode->i_mutex); 1125 mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
1122out: 1126out:
1123 up_write(&namespace_sem); 1127 up_write(&namespace_sem);
1124 if (!err) 1128 if (!err)
@@ -1162,16 +1166,17 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
1162 1166
1163 down_write(&namespace_sem); 1167 down_write(&namespace_sem);
1164 /* Something was mounted here while we slept */ 1168 /* Something was mounted here while we slept */
1165 while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) 1169 while (d_mountpoint(nd->path.dentry) &&
1170 follow_down(&nd->path.mnt, &nd->path.dentry))
1166 ; 1171 ;
1167 err = -EINVAL; 1172 err = -EINVAL;
1168 if (!check_mnt(nd->mnt)) 1173 if (!check_mnt(nd->path.mnt))
1169 goto unlock; 1174 goto unlock;
1170 1175
1171 /* Refuse the same filesystem on the same mount point */ 1176 /* Refuse the same filesystem on the same mount point */
1172 err = -EBUSY; 1177 err = -EBUSY;
1173 if (nd->mnt->mnt_sb == newmnt->mnt_sb && 1178 if (nd->path.mnt->mnt_sb == newmnt->mnt_sb &&
1174 nd->mnt->mnt_root == nd->dentry) 1179 nd->path.mnt->mnt_root == nd->path.dentry)
1175 goto unlock; 1180 goto unlock;
1176 1181
1177 err = -EINVAL; 1182 err = -EINVAL;
@@ -1697,12 +1702,14 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
1697 if (fs) { 1702 if (fs) {
1698 atomic_inc(&fs->count); 1703 atomic_inc(&fs->count);
1699 task_unlock(p); 1704 task_unlock(p);
1700 if (fs->root == old_nd->dentry 1705 if (fs->root == old_nd->path.dentry
1701 && fs->rootmnt == old_nd->mnt) 1706 && fs->rootmnt == old_nd->path.mnt)
1702 set_fs_root(fs, new_nd->mnt, new_nd->dentry); 1707 set_fs_root(fs, new_nd->path.mnt,
1703 if (fs->pwd == old_nd->dentry 1708 new_nd->path.dentry);
1704 && fs->pwdmnt == old_nd->mnt) 1709 if (fs->pwd == old_nd->path.dentry
1705 set_fs_pwd(fs, new_nd->mnt, new_nd->dentry); 1710 && fs->pwdmnt == old_nd->path.mnt)
1711 set_fs_pwd(fs, new_nd->path.mnt,
1712 new_nd->path.dentry);
1706 put_fs_struct(fs); 1713 put_fs_struct(fs);
1707 } else 1714 } else
1708 task_unlock(p); 1715 task_unlock(p);
@@ -1752,7 +1759,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1752 if (error) 1759 if (error)
1753 goto out0; 1760 goto out0;
1754 error = -EINVAL; 1761 error = -EINVAL;
1755 if (!check_mnt(new_nd.mnt)) 1762 if (!check_mnt(new_nd.path.mnt))
1756 goto out1; 1763 goto out1;
1757 1764
1758 error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); 1765 error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd);
@@ -1766,55 +1773,59 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1766 } 1773 }
1767 1774
1768 read_lock(&current->fs->lock); 1775 read_lock(&current->fs->lock);
1769 user_nd.mnt = mntget(current->fs->rootmnt); 1776 user_nd.path.mnt = mntget(current->fs->rootmnt);
1770 user_nd.dentry = dget(current->fs->root); 1777 user_nd.path.dentry = dget(current->fs->root);
1771 read_unlock(&current->fs->lock); 1778 read_unlock(&current->fs->lock);
1772 down_write(&namespace_sem); 1779 down_write(&namespace_sem);
1773 mutex_lock(&old_nd.dentry->d_inode->i_mutex); 1780 mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
1774 error = -EINVAL; 1781 error = -EINVAL;
1775 if (IS_MNT_SHARED(old_nd.mnt) || 1782 if (IS_MNT_SHARED(old_nd.path.mnt) ||
1776 IS_MNT_SHARED(new_nd.mnt->mnt_parent) || 1783 IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) ||
1777 IS_MNT_SHARED(user_nd.mnt->mnt_parent)) 1784 IS_MNT_SHARED(user_nd.path.mnt->mnt_parent))
1778 goto out2; 1785 goto out2;
1779 if (!check_mnt(user_nd.mnt)) 1786 if (!check_mnt(user_nd.path.mnt))
1780 goto out2; 1787 goto out2;
1781 error = -ENOENT; 1788 error = -ENOENT;
1782 if (IS_DEADDIR(new_nd.dentry->d_inode)) 1789 if (IS_DEADDIR(new_nd.path.dentry->d_inode))
1783 goto out2; 1790 goto out2;
1784 if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry)) 1791 if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry))
1785 goto out2; 1792 goto out2;
1786 if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry)) 1793 if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry))
1787 goto out2; 1794 goto out2;
1788 error = -EBUSY; 1795 error = -EBUSY;
1789 if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt) 1796 if (new_nd.path.mnt == user_nd.path.mnt ||
1797 old_nd.path.mnt == user_nd.path.mnt)
1790 goto out2; /* loop, on the same file system */ 1798 goto out2; /* loop, on the same file system */
1791 error = -EINVAL; 1799 error = -EINVAL;
1792 if (user_nd.mnt->mnt_root != user_nd.dentry) 1800 if (user_nd.path.mnt->mnt_root != user_nd.path.dentry)
1793 goto out2; /* not a mountpoint */ 1801 goto out2; /* not a mountpoint */
1794 if (user_nd.mnt->mnt_parent == user_nd.mnt) 1802 if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt)
1795 goto out2; /* not attached */ 1803 goto out2; /* not attached */
1796 if (new_nd.mnt->mnt_root != new_nd.dentry) 1804 if (new_nd.path.mnt->mnt_root != new_nd.path.dentry)
1797 goto out2; /* not a mountpoint */ 1805 goto out2; /* not a mountpoint */
1798 if (new_nd.mnt->mnt_parent == new_nd.mnt) 1806 if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt)
1799 goto out2; /* not attached */ 1807 goto out2; /* not attached */
1800 tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */ 1808 /* make sure we can reach put_old from new_root */
1809 tmp = old_nd.path.mnt;
1801 spin_lock(&vfsmount_lock); 1810 spin_lock(&vfsmount_lock);
1802 if (tmp != new_nd.mnt) { 1811 if (tmp != new_nd.path.mnt) {
1803 for (;;) { 1812 for (;;) {
1804 if (tmp->mnt_parent == tmp) 1813 if (tmp->mnt_parent == tmp)
1805 goto out3; /* already mounted on put_old */ 1814 goto out3; /* already mounted on put_old */
1806 if (tmp->mnt_parent == new_nd.mnt) 1815 if (tmp->mnt_parent == new_nd.path.mnt)
1807 break; 1816 break;
1808 tmp = tmp->mnt_parent; 1817 tmp = tmp->mnt_parent;
1809 } 1818 }
1810 if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry)) 1819 if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry))
1811 goto out3; 1820 goto out3;
1812 } else if (!is_subdir(old_nd.dentry, new_nd.dentry)) 1821 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
1813 goto out3; 1822 goto out3;
1814 detach_mnt(new_nd.mnt, &parent_nd); 1823 detach_mnt(new_nd.path.mnt, &parent_nd);
1815 detach_mnt(user_nd.mnt, &root_parent); 1824 detach_mnt(user_nd.path.mnt, &root_parent);
1816 attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */ 1825 /* mount old root on put_old */
1817 attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */ 1826 attach_mnt(user_nd.path.mnt, &old_nd);
1827 /* mount new_root on / */
1828 attach_mnt(new_nd.path.mnt, &root_parent);
1818 touch_mnt_namespace(current->nsproxy->mnt_ns); 1829 touch_mnt_namespace(current->nsproxy->mnt_ns);
1819 spin_unlock(&vfsmount_lock); 1830 spin_unlock(&vfsmount_lock);
1820 chroot_fs_refs(&user_nd, &new_nd); 1831 chroot_fs_refs(&user_nd, &new_nd);
@@ -1823,7 +1834,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1823 path_release(&root_parent); 1834 path_release(&root_parent);
1824 path_release(&parent_nd); 1835 path_release(&parent_nd);
1825out2: 1836out2:
1826 mutex_unlock(&old_nd.dentry->d_inode->i_mutex); 1837 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
1827 up_write(&namespace_sem); 1838 up_write(&namespace_sem);
1828 path_release(&user_nd); 1839 path_release(&user_nd);
1829 path_release(&old_nd); 1840 path_release(&old_nd);