Commit 20fb1936 authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 1ce41cd8 62b2ce96
...@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, ...@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
struct fuse_entry_out outentry; struct fuse_entry_out outentry;
struct fuse_file *ff; struct fuse_file *ff;
/* Userspace expects S_IFREG in create mode */
BUG_ON((mode & S_IFMT) != S_IFREG);
forget = fuse_alloc_forget(); forget = fuse_alloc_forget();
err = -ENOMEM; err = -ENOMEM;
if (!forget) if (!forget)
......
...@@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, ...@@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
goto out; goto out;
} }
mode = op->mode & S_IALLUGO; mode = op->mode;
if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
mode &= ~current_umask(); mode &= ~current_umask();
...@@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, ...@@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
} }
if (open_flag & O_CREAT) { if (open_flag & O_CREAT) {
error = may_o_create(&nd->path, dentry, op->mode); error = may_o_create(&nd->path, dentry, mode);
if (error) { if (error) {
create_error = error; create_error = error;
if (open_flag & O_EXCL) if (open_flag & O_EXCL)
...@@ -2489,6 +2489,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, ...@@ -2489,6 +2489,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
dput(dentry); dput(dentry);
dentry = file->f_path.dentry; dentry = file->f_path.dentry;
} }
if (create_error && dentry->d_inode == NULL) {
error = create_error;
goto out;
}
goto looked_up; goto looked_up;
} }
......
...@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o ...@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
int lookup_flags = 0; int lookup_flags = 0;
int acc_mode; int acc_mode;
if (!(flags & O_CREAT)) if (flags & O_CREAT)
mode = 0; op->mode = (mode & S_IALLUGO) | S_IFREG;
op->mode = mode; else
op->mode = 0;
/* Must never be set by userspace */ /* Must never be set by userspace */
flags &= ~FMODE_NONOTIFY; flags &= ~FMODE_NONOTIFY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment