Browse Source

pass ->f_flags value to alloc_empty_file()

... and have it set the f_flags-derived part of ->f_mode.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 7 years ago
parent
commit
ea73ea7279
4 changed files with 9 additions and 13 deletions
  1. 4 4
      fs/file_table.c
  2. 1 1
      fs/internal.h
  3. 1 3
      fs/namei.c
  4. 3 5
      fs/open.c

+ 4 - 4
fs/file_table.c

@@ -101,7 +101,7 @@ int proc_nr_files(struct ctl_table *table, int write,
  * done, you will imbalance int the mount's writer count
  * done, you will imbalance int the mount's writer count
  * and a warning at __fput() time.
  * 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;
 	static long old_max;
 	struct file *f;
 	struct file *f;
@@ -135,6 +135,8 @@ struct file *alloc_empty_file(const struct cred *cred)
 	spin_lock_init(&f->f_lock);
 	spin_lock_init(&f->f_lock);
 	mutex_init(&f->f_pos_lock);
 	mutex_init(&f->f_pos_lock);
 	eventpoll_init_file(f);
 	eventpoll_init_file(f);
+	f->f_flags = flags;
+	f->f_mode = OPEN_FMODE(flags);
 	/* f->f_version: 0 */
 	/* f->f_version: 0 */
 	percpu_counter_inc(&nr_files);
 	percpu_counter_inc(&nr_files);
 	return f;
 	return f;
@@ -160,12 +162,10 @@ struct file *alloc_file(const struct path *path, int flags,
 {
 {
 	struct file *file;
 	struct file *file;
 
 
-	file = alloc_empty_file(current_cred());
+	file = alloc_empty_file(flags, current_cred());
 	if (IS_ERR(file))
 	if (IS_ERR(file))
 		return file;
 		return file;
 
 
-	file->f_mode = OPEN_FMODE(flags);
-	file->f_flags = flags;
 	file->f_path = *path;
 	file->f_path = *path;
 	file->f_inode = path->dentry->d_inode;
 	file->f_inode = path->dentry->d_inode;
 	file->f_mapping = path->dentry->d_inode->i_mapping;
 	file->f_mapping = path->dentry->d_inode->i_mapping;

+ 1 - 1
fs/internal.h

@@ -93,7 +93,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
 /*
 /*
  * file_table.c
  * file_table.c
  */
  */
-extern struct file *alloc_empty_file(const struct cred *);
+extern struct file *alloc_empty_file(int, const struct cred *);
 
 
 /*
 /*
  * super.c
  * super.c

+ 1 - 3
fs/namei.c

@@ -3513,12 +3513,10 @@ static struct file *path_openat(struct nameidata *nd,
 	int opened = 0;
 	int opened = 0;
 	int error;
 	int error;
 
 
-	file = alloc_empty_file(current_cred());
+	file = alloc_empty_file(op->open_flag, current_cred());
 	if (IS_ERR(file))
 	if (IS_ERR(file))
 		return file;
 		return file;
 
 
-	file->f_flags = op->open_flag;
-
 	if (unlikely(file->f_flags & __O_TMPFILE)) {
 	if (unlikely(file->f_flags & __O_TMPFILE)) {
 		error = do_tmpfile(nd, flags, op, file, &opened);
 		error = do_tmpfile(nd, flags, op, file, &opened);
 		goto out2;
 		goto out2;

+ 3 - 5
fs/open.c

@@ -742,9 +742,6 @@ static int do_dentry_open(struct file *f,
 	static const struct file_operations empty_fops = {};
 	static const struct file_operations empty_fops = {};
 	int error;
 	int error;
 
 
-	f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
-				FMODE_PREAD | FMODE_PWRITE;
-
 	path_get(&f->f_path);
 	path_get(&f->f_path);
 	f->f_inode = inode;
 	f->f_inode = inode;
 	f->f_mapping = inode->i_mapping;
 	f->f_mapping = inode->i_mapping;
@@ -788,6 +785,8 @@ static int do_dentry_open(struct file *f,
 	if (error)
 	if (error)
 		goto cleanup_all;
 		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)
 	if (!open)
 		open = f->f_op->open;
 		open = f->f_op->open;
 	if (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. */
 	/* We must always pass in a valid mount pointer. */
 	BUG_ON(!path->mnt);
 	BUG_ON(!path->mnt);
 
 
-	f = alloc_empty_file(cred);
+	f = alloc_empty_file(flags, cred);
 	if (!IS_ERR(f)) {
 	if (!IS_ERR(f)) {
-		f->f_flags = flags;
 		error = vfs_open(path, f, cred);
 		error = vfs_open(path, f, cred);
 		if (!error) {
 		if (!error) {
 			/* from now on we need fput() to dispose of f */
 			/* from now on we need fput() to dispose of f */