diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c index 28d49b301d..e4f108f082 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -249,9 +249,11 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
249 | 249 | ||
250 | /* | 250 | /* |
251 | * MAY_EXEC on regular files requires special handling: We override | 251 | * MAY_EXEC on regular files requires special handling: We override |
252 | * filesystem execute permissions if the mode bits aren't set. | 252 | * filesystem execute permissions if the mode bits aren't set or |
253 | * the fs is mounted with the "noexec" flag. | ||
253 | */ | 254 | */ |
254 | if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO)) | 255 | if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) || |
256 | (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC)))) | ||
255 | return -EACCES; | 257 | return -EACCES; |
256 | 258 | ||
257 | /* Ordinary permission routines do not understand MAY_APPEND. */ | 259 | /* Ordinary permission routines do not understand MAY_APPEND. */ |
@@ -295,7 +297,7 @@ int vfs_permission(struct nameidata *nd, int mask) | |||
295 | */ | 297 | */ |
296 | int file_permission(struct file *file, int mask) | 298 | int file_permission(struct file *file, int mask) |
297 | { | 299 | { |
298 | return permission(file->f_dentry->d_inode, mask, NULL); | 300 | return permission(file->f_path.dentry->d_inode, mask, NULL); |
299 | } | 301 | } |
300 | 302 | ||
301 | /* | 303 | /* |
@@ -331,7 +333,7 @@ int get_write_access(struct inode * inode) | |||
331 | 333 | ||
332 | int deny_write_access(struct file * file) | 334 | int deny_write_access(struct file * file) |
333 | { | 335 | { |
334 | struct inode *inode = file->f_dentry->d_inode; | 336 | struct inode *inode = file->f_path.dentry->d_inode; |
335 | 337 | ||
336 | spin_lock(&inode->i_lock); | 338 | spin_lock(&inode->i_lock); |
337 | if (atomic_read(&inode->i_writecount) > 0) { | 339 | if (atomic_read(&inode->i_writecount) > 0) { |
@@ -366,7 +368,7 @@ void path_release_on_umount(struct nameidata *nd) | |||
366 | */ | 368 | */ |
367 | void release_open_intent(struct nameidata *nd) | 369 | void release_open_intent(struct nameidata *nd) |
368 | { | 370 | { |
369 | if (nd->intent.open.file->f_dentry == NULL) | 371 | if (nd->intent.open.file->f_path.dentry == NULL) |
370 | put_filp(nd->intent.open.file); | 372 | put_filp(nd->intent.open.file); |
371 | else | 373 | else |
372 | fput(nd->intent.open.file); | 374 | fput(nd->intent.open.file); |
@@ -570,11 +572,6 @@ fail: | |||
570 | return PTR_ERR(link); | 572 | return PTR_ERR(link); |
571 | } | 573 | } |
572 | 574 | ||
573 | struct path { | ||
574 | struct vfsmount *mnt; | ||
575 | struct dentry *dentry; | ||
576 | }; | ||
577 | |||
578 | static inline void dput_path(struct path *path, struct nameidata *nd) | 575 | static inline void dput_path(struct path *path, struct nameidata *nd) |
579 | { | 576 | { |
580 | dput(path->dentry); | 577 | dput(path->dentry); |
@@ -1141,7 +1138,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1141 | if (!file) | 1138 | if (!file) |
1142 | goto out_fail; | 1139 | goto out_fail; |
1143 | 1140 | ||
1144 | dentry = file->f_dentry; | 1141 | dentry = file->f_path.dentry; |
1145 | 1142 | ||
1146 | retval = -ENOTDIR; | 1143 | retval = -ENOTDIR; |
1147 | if (!S_ISDIR(dentry->d_inode->i_mode)) | 1144 | if (!S_ISDIR(dentry->d_inode->i_mode)) |
@@ -1151,7 +1148,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1151 | if (retval) | 1148 | if (retval) |
1152 | goto fput_fail; | 1149 | goto fput_fail; |
1153 | 1150 | ||
1154 | nd->mnt = mntget(file->f_vfsmnt); | 1151 | nd->mnt = mntget(file->f_path.mnt); |
1155 | nd->dentry = dget(dentry); | 1152 | nd->dentry = dget(dentry); |
1156 | 1153 | ||
1157 | fput_light(file, fput_needed); | 1154 | fput_light(file, fput_needed); |
@@ -1996,8 +1993,7 @@ asmlinkage long sys_mkdir(const char __user *pathname, int mode) | |||
1996 | void dentry_unhash(struct dentry *dentry) | 1993 | void dentry_unhash(struct dentry *dentry) |
1997 | { | 1994 | { |
1998 | dget(dentry); | 1995 | dget(dentry); |
1999 | if (atomic_read(&dentry->d_count)) | 1996 | shrink_dcache_parent(dentry); |
2000 | shrink_dcache_parent(dentry); | ||
2001 | spin_lock(&dcache_lock); | 1997 | spin_lock(&dcache_lock); |
2002 | spin_lock(&dentry->d_lock); | 1998 | spin_lock(&dentry->d_lock); |
2003 | if (atomic_read(&dentry->d_count) == 2) | 1999 | if (atomic_read(&dentry->d_count) == 2) |