aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-18 13:02:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-18 13:02:17 -0400
commit20fb1936dee63fe397236d4ff3fd253a62b7b0b8 (patch)
treebbabde4f08ec8388549083df426fdcc6ffd2f82a
parent1ce41cd849d476f45b2dccaf40b39fe6c4f8d793 (diff)
parent62b2ce964bb901f00a480104bd35a2e1f8d2cf58 (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.c3
-rw-r--r--fs/namei.c8
-rw-r--r--fs/open.c7
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
diff --git a/fs/open.c b/fs/open.c
index bc132e167d2d..e1f2cdb91a4d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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;