diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/fs/namei.c b/fs/namei.c index a6575ca9f9d7..941c8e8228c0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -549,16 +549,16 @@ walk_init_root(const char *name, struct nameidata *nd) | |||
549 | struct fs_struct *fs = current->fs; | 549 | struct fs_struct *fs = current->fs; |
550 | 550 | ||
551 | read_lock(&fs->lock); | 551 | read_lock(&fs->lock); |
552 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 552 | if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { |
553 | nd->path.mnt = mntget(fs->altrootmnt); | 553 | nd->path = fs->altroot; |
554 | nd->path.dentry = dget(fs->altroot); | 554 | path_get(&fs->altroot); |
555 | read_unlock(&fs->lock); | 555 | read_unlock(&fs->lock); |
556 | if (__emul_lookup_dentry(name,nd)) | 556 | if (__emul_lookup_dentry(name,nd)) |
557 | return 0; | 557 | return 0; |
558 | read_lock(&fs->lock); | 558 | read_lock(&fs->lock); |
559 | } | 559 | } |
560 | nd->path.mnt = mntget(fs->rootmnt); | 560 | nd->path = fs->root; |
561 | nd->path.dentry = dget(fs->root); | 561 | path_get(&fs->root); |
562 | read_unlock(&fs->lock); | 562 | read_unlock(&fs->lock); |
563 | return 1; | 563 | return 1; |
564 | } | 564 | } |
@@ -755,8 +755,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd) | |||
755 | struct dentry *old = nd->path.dentry; | 755 | struct dentry *old = nd->path.dentry; |
756 | 756 | ||
757 | read_lock(&fs->lock); | 757 | read_lock(&fs->lock); |
758 | if (nd->path.dentry == fs->root && | 758 | if (nd->path.dentry == fs->root.dentry && |
759 | nd->path.mnt == fs->rootmnt) { | 759 | nd->path.mnt == fs->root.mnt) { |
760 | read_unlock(&fs->lock); | 760 | read_unlock(&fs->lock); |
761 | break; | 761 | break; |
762 | } | 762 | } |
@@ -1078,8 +1078,8 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1078 | */ | 1078 | */ |
1079 | nd->last_type = LAST_ROOT; | 1079 | nd->last_type = LAST_ROOT; |
1080 | read_lock(&fs->lock); | 1080 | read_lock(&fs->lock); |
1081 | nd->path.mnt = mntget(fs->rootmnt); | 1081 | nd->path = fs->root; |
1082 | nd->path.dentry = dget(fs->root); | 1082 | path_get(&fs->root); |
1083 | read_unlock(&fs->lock); | 1083 | read_unlock(&fs->lock); |
1084 | if (path_walk(name, nd) == 0) { | 1084 | if (path_walk(name, nd) == 0) { |
1085 | if (nd->path.dentry->d_inode) { | 1085 | if (nd->path.dentry->d_inode) { |
@@ -1099,29 +1099,22 @@ void set_fs_altroot(void) | |||
1099 | { | 1099 | { |
1100 | char *emul = __emul_prefix(); | 1100 | char *emul = __emul_prefix(); |
1101 | struct nameidata nd; | 1101 | struct nameidata nd; |
1102 | struct vfsmount *mnt = NULL, *oldmnt; | 1102 | struct path path = {}, old_path; |
1103 | struct dentry *dentry = NULL, *olddentry; | ||
1104 | int err; | 1103 | int err; |
1105 | struct fs_struct *fs = current->fs; | 1104 | struct fs_struct *fs = current->fs; |
1106 | 1105 | ||
1107 | if (!emul) | 1106 | if (!emul) |
1108 | goto set_it; | 1107 | goto set_it; |
1109 | err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); | 1108 | err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); |
1110 | if (!err) { | 1109 | if (!err) |
1111 | mnt = nd.path.mnt; | 1110 | path = nd.path; |
1112 | dentry = nd.path.dentry; | ||
1113 | } | ||
1114 | set_it: | 1111 | set_it: |
1115 | write_lock(&fs->lock); | 1112 | write_lock(&fs->lock); |
1116 | oldmnt = fs->altrootmnt; | 1113 | old_path = fs->altroot; |
1117 | olddentry = fs->altroot; | 1114 | fs->altroot = path; |
1118 | fs->altrootmnt = mnt; | ||
1119 | fs->altroot = dentry; | ||
1120 | write_unlock(&fs->lock); | 1115 | write_unlock(&fs->lock); |
1121 | if (olddentry) { | 1116 | if (old_path.dentry) |
1122 | dput(olddentry); | 1117 | path_put(&old_path); |
1123 | mntput(oldmnt); | ||
1124 | } | ||
1125 | } | 1118 | } |
1126 | 1119 | ||
1127 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ | 1120 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ |
@@ -1139,21 +1132,21 @@ static int do_path_lookup(int dfd, const char *name, | |||
1139 | 1132 | ||
1140 | if (*name=='/') { | 1133 | if (*name=='/') { |
1141 | read_lock(&fs->lock); | 1134 | read_lock(&fs->lock); |
1142 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 1135 | if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { |
1143 | nd->path.mnt = mntget(fs->altrootmnt); | 1136 | nd->path = fs->altroot; |
1144 | nd->path.dentry = dget(fs->altroot); | 1137 | path_get(&fs->altroot); |
1145 | read_unlock(&fs->lock); | 1138 | read_unlock(&fs->lock); |
1146 | if (__emul_lookup_dentry(name,nd)) | 1139 | if (__emul_lookup_dentry(name,nd)) |
1147 | goto out; /* found in altroot */ | 1140 | goto out; /* found in altroot */ |
1148 | read_lock(&fs->lock); | 1141 | read_lock(&fs->lock); |
1149 | } | 1142 | } |
1150 | nd->path.mnt = mntget(fs->rootmnt); | 1143 | nd->path = fs->root; |
1151 | nd->path.dentry = dget(fs->root); | 1144 | path_get(&fs->root); |
1152 | read_unlock(&fs->lock); | 1145 | read_unlock(&fs->lock); |
1153 | } else if (dfd == AT_FDCWD) { | 1146 | } else if (dfd == AT_FDCWD) { |
1154 | read_lock(&fs->lock); | 1147 | read_lock(&fs->lock); |
1155 | nd->path.mnt = mntget(fs->pwdmnt); | 1148 | nd->path = fs->pwd; |
1156 | nd->path.dentry = dget(fs->pwd); | 1149 | path_get(&fs->pwd); |
1157 | read_unlock(&fs->lock); | 1150 | read_unlock(&fs->lock); |
1158 | } else { | 1151 | } else { |
1159 | struct dentry *dentry; | 1152 | struct dentry *dentry; |