aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 4acdac043b6b..faf61c35308c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -790,7 +790,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
790 790
791 inode = nd->dentry->d_inode; 791 inode = nd->dentry->d_inode;
792 if (nd->depth) 792 if (nd->depth)
793 lookup_flags = LOOKUP_FOLLOW; 793 lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
794 794
795 /* At this point we know we have a real path component. */ 795 /* At this point we know we have a real path component. */
796 for(;;) { 796 for(;;) {
@@ -885,7 +885,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
885last_with_slashes: 885last_with_slashes:
886 lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; 886 lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
887last_component: 887last_component:
888 nd->flags &= ~LOOKUP_CONTINUE; 888 /* Clear LOOKUP_CONTINUE iff it was previously unset */
889 nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
889 if (lookup_flags & LOOKUP_PARENT) 890 if (lookup_flags & LOOKUP_PARENT)
890 goto lookup_parent; 891 goto lookup_parent;
891 if (this.name[0] == '.') switch (this.len) { 892 if (this.name[0] == '.') switch (this.len) {
@@ -1069,6 +1070,8 @@ static int fastcall do_path_lookup(int dfd, const char *name,
1069 unsigned int flags, struct nameidata *nd) 1070 unsigned int flags, struct nameidata *nd)
1070{ 1071{
1071 int retval = 0; 1072 int retval = 0;
1073 int fput_needed;
1074 struct file *file;
1072 1075
1073 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1076 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1074 nd->flags = flags; 1077 nd->flags = flags;
@@ -1090,29 +1093,22 @@ static int fastcall do_path_lookup(int dfd, const char *name,
1090 nd->mnt = mntget(current->fs->pwdmnt); 1093 nd->mnt = mntget(current->fs->pwdmnt);
1091 nd->dentry = dget(current->fs->pwd); 1094 nd->dentry = dget(current->fs->pwd);
1092 } else { 1095 } else {
1093 struct file *file;
1094 int fput_needed;
1095 struct dentry *dentry; 1096 struct dentry *dentry;
1096 1097
1097 file = fget_light(dfd, &fput_needed); 1098 file = fget_light(dfd, &fput_needed);
1098 if (!file) { 1099 retval = -EBADF;
1099 retval = -EBADF; 1100 if (!file)
1100 goto out_fail; 1101 goto unlock_fail;
1101 }
1102 1102
1103 dentry = file->f_dentry; 1103 dentry = file->f_dentry;
1104 1104
1105 if (!S_ISDIR(dentry->d_inode->i_mode)) { 1105 retval = -ENOTDIR;
1106 retval = -ENOTDIR; 1106 if (!S_ISDIR(dentry->d_inode->i_mode))
1107 fput_light(file, fput_needed); 1107 goto fput_unlock_fail;
1108 goto out_fail;
1109 }
1110 1108
1111 retval = file_permission(file, MAY_EXEC); 1109 retval = file_permission(file, MAY_EXEC);
1112 if (retval) { 1110 if (retval)
1113 fput_light(file, fput_needed); 1111 goto fput_unlock_fail;
1114 goto out_fail;
1115 }
1116 1112
1117 nd->mnt = mntget(file->f_vfsmnt); 1113 nd->mnt = mntget(file->f_vfsmnt);
1118 nd->dentry = dget(dentry); 1114 nd->dentry = dget(dentry);
@@ -1126,7 +1122,12 @@ out:
1126 if (unlikely(current->audit_context 1122 if (unlikely(current->audit_context
1127 && nd && nd->dentry && nd->dentry->d_inode)) 1123 && nd && nd->dentry && nd->dentry->d_inode))
1128 audit_inode(name, nd->dentry->d_inode, flags); 1124 audit_inode(name, nd->dentry->d_inode, flags);
1129out_fail: 1125 return retval;
1126
1127fput_unlock_fail:
1128 fput_light(file, fput_needed);
1129unlock_fail:
1130 read_unlock(&current->fs->lock);
1130 return retval; 1131 return retval;
1131} 1132}
1132 1133
@@ -1161,6 +1162,7 @@ static int __path_lookup_intent_open(int dfd, const char *name,
1161 1162
1162/** 1163/**
1163 * path_lookup_open - lookup a file path with open intent 1164 * path_lookup_open - lookup a file path with open intent
1165 * @dfd: the directory to use as base, or AT_FDCWD
1164 * @name: pointer to file name 1166 * @name: pointer to file name
1165 * @lookup_flags: lookup intent flags 1167 * @lookup_flags: lookup intent flags
1166 * @nd: pointer to nameidata 1168 * @nd: pointer to nameidata
@@ -1175,6 +1177,7 @@ int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
1175 1177
1176/** 1178/**
1177 * path_lookup_create - lookup a file path with open + create intent 1179 * path_lookup_create - lookup a file path with open + create intent
1180 * @dfd: the directory to use as base, or AT_FDCWD
1178 * @name: pointer to file name 1181 * @name: pointer to file name
1179 * @lookup_flags: lookup intent flags 1182 * @lookup_flags: lookup intent flags
1180 * @nd: pointer to nameidata 1183 * @nd: pointer to nameidata