pass ->f_flags value to alloc_empty_file()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 11 Jul 2018 19:00:04 +0000 (15:00 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 12 Jul 2018 14:04:13 +0000 (10:04 -0400)
... and have it set the f_flags-derived part of ->f_mode.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/file_table.c
fs/internal.h
fs/namei.c
fs/open.c

index 76cfa4c43e1326fb08b46f8746dbb58687ae1ddd..705f486f7007127a270decbaaeb1af65e8c4a9da 100644 (file)
@@ -101,7 +101,7 @@ int proc_nr_files(struct ctl_table *table, int write,
  * done, you will imbalance int the mount's writer count
  * and a warning at __fput() time.
  */
-struct file *alloc_empty_file(const struct cred *cred)
+struct file *alloc_empty_file(int flags, const struct cred *cred)
 {
        static long old_max;
        struct file *f;
@@ -135,6 +135,8 @@ struct file *alloc_empty_file(const struct cred *cred)
        spin_lock_init(&f->f_lock);
        mutex_init(&f->f_pos_lock);
        eventpoll_init_file(f);
+       f->f_flags = flags;
+       f->f_mode = OPEN_FMODE(flags);
        /* f->f_version: 0 */
        percpu_counter_inc(&nr_files);
        return f;
@@ -160,12 +162,10 @@ struct file *alloc_file(const struct path *path, int flags,
 {
        struct file *file;
 
-       file = alloc_empty_file(current_cred());
+       file = alloc_empty_file(flags, current_cred());
        if (IS_ERR(file))
                return file;
 
-       file->f_mode = OPEN_FMODE(flags);
-       file->f_flags = flags;
        file->f_path = *path;
        file->f_inode = path->dentry->d_inode;
        file->f_mapping = path->dentry->d_inode->i_mapping;
index 66473bf388e4f2cca07ac25f9432e74d09844172..661c314aba30a68b6220c0cf638b074157f326f4 100644 (file)
@@ -93,7 +93,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
 /*
  * file_table.c
  */
-extern struct file *alloc_empty_file(const struct cred *);
+extern struct file *alloc_empty_file(int, const struct cred *);
 
 /*
  * super.c
index af2ec1803f573d46df2a18bcc371812ed56fb27a..223925e30adb55469ecf2e2f9eed1c0aeac580c6 100644 (file)
@@ -3513,12 +3513,10 @@ static struct file *path_openat(struct nameidata *nd,
        int opened = 0;
        int error;
 
-       file = alloc_empty_file(current_cred());
+       file = alloc_empty_file(op->open_flag, current_cred());
        if (IS_ERR(file))
                return file;
 
-       file->f_flags = op->open_flag;
-
        if (unlikely(file->f_flags & __O_TMPFILE)) {
                error = do_tmpfile(nd, flags, op, file, &opened);
                goto out2;
index 0061f9ea044d0946e476d64d69ad9778d4482350..15d2c3ab91ff00656b4f3c418e754d758c4116c3 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -742,9 +742,6 @@ static int do_dentry_open(struct file *f,
        static const struct file_operations empty_fops = {};
        int error;
 
-       f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
-                               FMODE_PREAD | FMODE_PWRITE;
-
        path_get(&f->f_path);
        f->f_inode = inode;
        f->f_mapping = inode->i_mapping;
@@ -788,6 +785,8 @@ static int do_dentry_open(struct file *f,
        if (error)
                goto cleanup_all;
 
+       /* normally all 3 are set; ->open() can clear them if needed */
+       f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
        if (!open)
                open = f->f_op->open;
        if (open) {
@@ -921,9 +920,8 @@ struct file *dentry_open(const struct path *path, int flags,
        /* We must always pass in a valid mount pointer. */
        BUG_ON(!path->mnt);
 
-       f = alloc_empty_file(cred);
+       f = alloc_empty_file(flags, cred);
        if (!IS_ERR(f)) {
-               f->f_flags = flags;
                error = vfs_open(path, f, cred);
                if (!error) {
                        /* from now on we need fput() to dispose of f */