diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-18 13:02:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-18 13:02:17 -0400 |
commit | 20fb1936dee63fe397236d4ff3fd253a62b7b0b8 (patch) | |
tree | bbabde4f08ec8388549083df426fdcc6ffd2f82a | |
parent | 1ce41cd849d476f45b2dccaf40b39fe6c4f8d793 (diff) | |
parent | 62b2ce964bb901f00a480104bd35a2e1f8d2cf58 (diff) |
Merge branch 'vfs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull vfs fixes from Miklos Szeredi.
This mainly fixes some confusion about whether the open 'mode' variable
passed around should contain the full file type (S_IFREG etc)
information or just the permission mode. In particular, the lack of
proper file type information had confused fuse.
* 'vfs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
vfs: fix propagation of atomic_open create error on negative dentry
fuse: check create mode in atomic open
vfs: pass right create mode to may_o_create()
vfs: atomic_open(): fix create mode usage
vfs: canonicalize create mode in build_open_flags()
-rw-r--r-- | fs/fuse/dir.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 8 | ||||
-rw-r--r-- | fs/open.c | 7 |
3 files changed, 13 insertions, 5 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8964cf3999b2..324bc0850534 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
383 | struct fuse_entry_out outentry; | 383 | struct fuse_entry_out outentry; |
384 | struct fuse_file *ff; | 384 | struct fuse_file *ff; |
385 | 385 | ||
386 | /* Userspace expects S_IFREG in create mode */ | ||
387 | BUG_ON((mode & S_IFMT) != S_IFREG); | ||
388 | |||
386 | forget = fuse_alloc_forget(); | 389 | forget = fuse_alloc_forget(); |
387 | err = -ENOMEM; | 390 | err = -ENOMEM; |
388 | if (!forget) | 391 | if (!forget) |
diff --git a/fs/namei.c b/fs/namei.c index 1b464390dde8..db76b866a097 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2414 | goto out; | 2414 | goto out; |
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | mode = op->mode & S_IALLUGO; | 2417 | mode = op->mode; |
2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) | 2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) |
2419 | mode &= ~current_umask(); | 2419 | mode &= ~current_umask(); |
2420 | 2420 | ||
@@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2452 | } | 2452 | } |
2453 | 2453 | ||
2454 | if (open_flag & O_CREAT) { | 2454 | if (open_flag & O_CREAT) { |
2455 | error = may_o_create(&nd->path, dentry, op->mode); | 2455 | error = may_o_create(&nd->path, dentry, mode); |
2456 | if (error) { | 2456 | if (error) { |
2457 | create_error = error; | 2457 | create_error = error; |
2458 | if (open_flag & O_EXCL) | 2458 | if (open_flag & O_EXCL) |
@@ -2489,6 +2489,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2489 | dput(dentry); | 2489 | dput(dentry); |
2490 | dentry = file->f_path.dentry; | 2490 | dentry = file->f_path.dentry; |
2491 | } | 2491 | } |
2492 | if (create_error && dentry->d_inode == NULL) { | ||
2493 | error = create_error; | ||
2494 | goto out; | ||
2495 | } | ||
2492 | goto looked_up; | 2496 | goto looked_up; |
2493 | } | 2497 | } |
2494 | 2498 | ||
@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
852 | int lookup_flags = 0; | 852 | int lookup_flags = 0; |
853 | int acc_mode; | 853 | int acc_mode; |
854 | 854 | ||
855 | if (!(flags & O_CREAT)) | 855 | if (flags & O_CREAT) |
856 | mode = 0; | 856 | op->mode = (mode & S_IALLUGO) | S_IFREG; |
857 | op->mode = mode; | 857 | else |
858 | op->mode = 0; | ||
858 | 859 | ||
859 | /* Must never be set by userspace */ | 860 | /* Must never be set by userspace */ |
860 | flags &= ~FMODE_NONOTIFY; | 861 | flags &= ~FMODE_NONOTIFY; |