diff options
-rw-r--r-- | fs/namei.c | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/fs/namei.c b/fs/namei.c index 808e4ea2bb94..2892e68d3a86 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -518,18 +518,20 @@ static int __emul_lookup_dentry(const char *, struct nameidata *); | |||
518 | static __always_inline int | 518 | static __always_inline int |
519 | walk_init_root(const char *name, struct nameidata *nd) | 519 | walk_init_root(const char *name, struct nameidata *nd) |
520 | { | 520 | { |
521 | read_lock(¤t->fs->lock); | 521 | struct fs_struct *fs = current->fs; |
522 | if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 522 | |
523 | nd->mnt = mntget(current->fs->altrootmnt); | 523 | read_lock(&fs->lock); |
524 | nd->dentry = dget(current->fs->altroot); | 524 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { |
525 | read_unlock(¤t->fs->lock); | 525 | nd->mnt = mntget(fs->altrootmnt); |
526 | nd->dentry = dget(fs->altroot); | ||
527 | read_unlock(&fs->lock); | ||
526 | if (__emul_lookup_dentry(name,nd)) | 528 | if (__emul_lookup_dentry(name,nd)) |
527 | return 0; | 529 | return 0; |
528 | read_lock(¤t->fs->lock); | 530 | read_lock(&fs->lock); |
529 | } | 531 | } |
530 | nd->mnt = mntget(current->fs->rootmnt); | 532 | nd->mnt = mntget(fs->rootmnt); |
531 | nd->dentry = dget(current->fs->root); | 533 | nd->dentry = dget(fs->root); |
532 | read_unlock(¤t->fs->lock); | 534 | read_unlock(&fs->lock); |
533 | return 1; | 535 | return 1; |
534 | } | 536 | } |
535 | 537 | ||
@@ -724,17 +726,19 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry) | |||
724 | 726 | ||
725 | static __always_inline void follow_dotdot(struct nameidata *nd) | 727 | static __always_inline void follow_dotdot(struct nameidata *nd) |
726 | { | 728 | { |
729 | struct fs_struct *fs = current->fs; | ||
730 | |||
727 | while(1) { | 731 | while(1) { |
728 | struct vfsmount *parent; | 732 | struct vfsmount *parent; |
729 | struct dentry *old = nd->dentry; | 733 | struct dentry *old = nd->dentry; |
730 | 734 | ||
731 | read_lock(¤t->fs->lock); | 735 | read_lock(&fs->lock); |
732 | if (nd->dentry == current->fs->root && | 736 | if (nd->dentry == fs->root && |
733 | nd->mnt == current->fs->rootmnt) { | 737 | nd->mnt == fs->rootmnt) { |
734 | read_unlock(¤t->fs->lock); | 738 | read_unlock(&fs->lock); |
735 | break; | 739 | break; |
736 | } | 740 | } |
737 | read_unlock(¤t->fs->lock); | 741 | read_unlock(&fs->lock); |
738 | spin_lock(&dcache_lock); | 742 | spin_lock(&dcache_lock); |
739 | if (nd->dentry != nd->mnt->mnt_root) { | 743 | if (nd->dentry != nd->mnt->mnt_root) { |
740 | nd->dentry = dget(nd->dentry->d_parent); | 744 | nd->dentry = dget(nd->dentry->d_parent); |
@@ -1042,15 +1046,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1042 | struct vfsmount *old_mnt = nd->mnt; | 1046 | struct vfsmount *old_mnt = nd->mnt; |
1043 | struct qstr last = nd->last; | 1047 | struct qstr last = nd->last; |
1044 | int last_type = nd->last_type; | 1048 | int last_type = nd->last_type; |
1049 | struct fs_struct *fs = current->fs; | ||
1050 | |||
1045 | /* | 1051 | /* |
1046 | * NAME was not found in alternate root or it's a directory. Try to find | 1052 | * NAME was not found in alternate root or it's a directory. |
1047 | * it in the normal root: | 1053 | * Try to find it in the normal root: |
1048 | */ | 1054 | */ |
1049 | nd->last_type = LAST_ROOT; | 1055 | nd->last_type = LAST_ROOT; |
1050 | read_lock(¤t->fs->lock); | 1056 | read_lock(&fs->lock); |
1051 | nd->mnt = mntget(current->fs->rootmnt); | 1057 | nd->mnt = mntget(fs->rootmnt); |
1052 | nd->dentry = dget(current->fs->root); | 1058 | nd->dentry = dget(fs->root); |
1053 | read_unlock(¤t->fs->lock); | 1059 | read_unlock(&fs->lock); |
1054 | if (path_walk(name, nd) == 0) { | 1060 | if (path_walk(name, nd) == 0) { |
1055 | if (nd->dentry->d_inode) { | 1061 | if (nd->dentry->d_inode) { |
1056 | dput(old_dentry); | 1062 | dput(old_dentry); |
@@ -1074,6 +1080,7 @@ void set_fs_altroot(void) | |||
1074 | struct vfsmount *mnt = NULL, *oldmnt; | 1080 | struct vfsmount *mnt = NULL, *oldmnt; |
1075 | struct dentry *dentry = NULL, *olddentry; | 1081 | struct dentry *dentry = NULL, *olddentry; |
1076 | int err; | 1082 | int err; |
1083 | struct fs_struct *fs = current->fs; | ||
1077 | 1084 | ||
1078 | if (!emul) | 1085 | if (!emul) |
1079 | goto set_it; | 1086 | goto set_it; |
@@ -1083,12 +1090,12 @@ void set_fs_altroot(void) | |||
1083 | dentry = nd.dentry; | 1090 | dentry = nd.dentry; |
1084 | } | 1091 | } |
1085 | set_it: | 1092 | set_it: |
1086 | write_lock(¤t->fs->lock); | 1093 | write_lock(&fs->lock); |
1087 | oldmnt = current->fs->altrootmnt; | 1094 | oldmnt = fs->altrootmnt; |
1088 | olddentry = current->fs->altroot; | 1095 | olddentry = fs->altroot; |
1089 | current->fs->altrootmnt = mnt; | 1096 | fs->altrootmnt = mnt; |
1090 | current->fs->altroot = dentry; | 1097 | fs->altroot = dentry; |
1091 | write_unlock(¤t->fs->lock); | 1098 | write_unlock(&fs->lock); |
1092 | if (olddentry) { | 1099 | if (olddentry) { |
1093 | dput(olddentry); | 1100 | dput(olddentry); |
1094 | mntput(oldmnt); | 1101 | mntput(oldmnt); |
@@ -1102,29 +1109,30 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1102 | int retval = 0; | 1109 | int retval = 0; |
1103 | int fput_needed; | 1110 | int fput_needed; |
1104 | struct file *file; | 1111 | struct file *file; |
1112 | struct fs_struct *fs = current->fs; | ||
1105 | 1113 | ||
1106 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 1114 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
1107 | nd->flags = flags; | 1115 | nd->flags = flags; |
1108 | nd->depth = 0; | 1116 | nd->depth = 0; |
1109 | 1117 | ||
1110 | if (*name=='/') { | 1118 | if (*name=='/') { |
1111 | read_lock(¤t->fs->lock); | 1119 | read_lock(&fs->lock); |
1112 | if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 1120 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { |
1113 | nd->mnt = mntget(current->fs->altrootmnt); | 1121 | nd->mnt = mntget(fs->altrootmnt); |
1114 | nd->dentry = dget(current->fs->altroot); | 1122 | nd->dentry = dget(fs->altroot); |
1115 | read_unlock(¤t->fs->lock); | 1123 | read_unlock(&fs->lock); |
1116 | if (__emul_lookup_dentry(name,nd)) | 1124 | if (__emul_lookup_dentry(name,nd)) |
1117 | goto out; /* found in altroot */ | 1125 | goto out; /* found in altroot */ |
1118 | read_lock(¤t->fs->lock); | 1126 | read_lock(&fs->lock); |
1119 | } | 1127 | } |
1120 | nd->mnt = mntget(current->fs->rootmnt); | 1128 | nd->mnt = mntget(fs->rootmnt); |
1121 | nd->dentry = dget(current->fs->root); | 1129 | nd->dentry = dget(fs->root); |
1122 | read_unlock(¤t->fs->lock); | 1130 | read_unlock(&fs->lock); |
1123 | } else if (dfd == AT_FDCWD) { | 1131 | } else if (dfd == AT_FDCWD) { |
1124 | read_lock(¤t->fs->lock); | 1132 | read_lock(&fs->lock); |
1125 | nd->mnt = mntget(current->fs->pwdmnt); | 1133 | nd->mnt = mntget(fs->pwdmnt); |
1126 | nd->dentry = dget(current->fs->pwd); | 1134 | nd->dentry = dget(fs->pwd); |
1127 | read_unlock(¤t->fs->lock); | 1135 | read_unlock(&fs->lock); |
1128 | } else { | 1136 | } else { |
1129 | struct dentry *dentry; | 1137 | struct dentry *dentry; |
1130 | 1138 | ||