diff mbox series

[7/8] vfs: open inside ->tmpfile()

Message ID 20220916194416.1657716-7-mszeredi@redhat.com (mailing list archive)
State New, archived
Headers show
Series [1/8] cachefiles: tmpfile error handling cleanup | expand

Commit Message

Miklos Szeredi Sept. 16, 2022, 7:44 p.m. UTC
Replace the 'struct dentry *' argument of i_op->tmpfile with
'struct file *'.

Call finish_open() as the last thing in ->tmpfile() instances (may be
omitted in the error case).

Change d_tmpfile() argument to 'struct file *' as well to make callers more
readable.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/bad_inode.c         |  2 +-
 fs/btrfs/inode.c       |  8 ++++----
 fs/dcache.c            |  4 +++-
 fs/ext2/namei.c        |  6 +++---
 fs/ext4/namei.c        |  6 +++---
 fs/f2fs/namei.c        | 13 ++++++++-----
 fs/hugetlbfs/inode.c   | 12 +++++++-----
 fs/minix/namei.c       |  6 +++---
 fs/namei.c             |  3 +--
 fs/ramfs/inode.c       |  6 +++---
 fs/ubifs/dir.c         |  7 ++++---
 fs/udf/namei.c         |  6 +++---
 fs/xfs/xfs_iops.c      | 16 +++++++++-------
 include/linux/dcache.h |  2 +-
 include/linux/fs.h     |  2 +-
 mm/shmem.c             |  6 +++---
 16 files changed, 57 insertions(+), 48 deletions(-)

Comments

kernel test robot Sept. 16, 2022, 10:04 p.m. UTC | #1
Hi Miklos,

I love your patch! Perhaps something to improve:

[auto build test WARNING on kdave/for-next]
[also build test WARNING on jaegeuk-f2fs/dev-test linus/master v6.0-rc5]
[cannot apply to viro-vfs/for-next next-20220916]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Miklos-Szeredi/cachefiles-tmpfile-error-handling-cleanup/20220917-034700
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20220917/202209170555.zV70MRNl-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/87f47d099f22ea898e5d05215f9b2c4647012001
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Miklos-Szeredi/cachefiles-tmpfile-error-handling-cleanup/20220917-034700
        git checkout 87f47d099f22ea898e5d05215f9b2c4647012001
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash fs/ext4/ fs/f2fs/ fs/minix/ fs/ramfs/ fs/ubifs/ fs/udf/ mm/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/fs.h:8,
                    from include/linux/dax.h:5,
                    from mm/filemap.c:15:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
--
   In file included from include/linux/fs.h:8,
                    from mm/shmem.c:24:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   mm/shmem.c: In function 'shmem_tmpfile':
   mm/shmem.c:2930:27: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2930 |                 d_tmpfile(file, inode);
         |                           ^~~~
         |                           |
         |                           struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/ext4/namei.c:28:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/ext4/namei.c: In function 'ext4_tmpfile':
   fs/ext4/namei.c:2874:27: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2874 |                 d_tmpfile(file, inode);
         |                           ^~~~
         |                           |
         |                           struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/f2fs/namei.c:8:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/f2fs/namei.c: In function '__f2fs_tmpfile':
   fs/f2fs/namei.c:896:35: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
     896 |                         d_tmpfile(file, inode);
         |                                   ^~~~
         |                                   |
         |                                   struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/minix/minix.h:5,
                    from fs/minix/namei.c:8:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/minix/namei.c: In function 'minix_tmpfile':
   fs/minix/namei.c:63:27: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
      63 |                 d_tmpfile(file, inode);
         |                           ^~~~
         |                           |
         |                           struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/ramfs/inode.c:26:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/ramfs/inode.c: In function 'ramfs_tmpfile':
   fs/ramfs/inode.c:156:19: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
     156 |         d_tmpfile(file, inode);
         |                   ^~~~
         |                   |
         |                   struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/ubifs/ubifs.h:16,
                    from fs/ubifs/dir.c:31:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/ubifs/dir.c: In function 'ubifs_tmpfile':
   fs/ubifs/dir.c:479:19: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
     479 |         d_tmpfile(file, inode);
         |                   ^~~~
         |                   |
         |                   struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/udf/udfdecl.h:10,
                    from fs/udf/namei.c:22:
>> include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/udf/namei.c: In function 'udf_tmpfile':
   fs/udf/namei.c:643:19: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
     643 |         d_tmpfile(file, inode);
         |                   ^~~~
         |                   |
         |                   struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +253 include/linux/dcache.h

   252	
 > 253	extern void d_tmpfile(struct file *, struct inode *);
   254
kernel test robot Sept. 17, 2022, 1:28 a.m. UTC | #2
Hi Miklos,

I love your patch! Yet something to improve:

[auto build test ERROR on kdave/for-next]
[also build test ERROR on jaegeuk-f2fs/dev-test linus/master v6.0-rc5]
[cannot apply to viro-vfs/for-next next-20220916]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Miklos-Szeredi/cachefiles-tmpfile-error-handling-cleanup/20220917-034700
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: hexagon-randconfig-r041-20220916 (https://download.01.org/0day-ci/archive/20220917/202209170929.VcScdpPu-lkp@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 791a7ae1ba3efd6bca96338e10ffde557ba83920)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/87f47d099f22ea898e5d05215f9b2c4647012001
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Miklos-Szeredi/cachefiles-tmpfile-error-handling-cleanup/20220917-034700
        git checkout 87f47d099f22ea898e5d05215f9b2c4647012001
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from mm/shmem.c:24:
   In file included from include/linux/fs.h:8:
   include/linux/dcache.h:253:30: warning: declaration of 'struct file' will not be visible outside of this function [-Wvisibility]
   extern void d_tmpfile(struct file *, struct inode *);
                                ^
>> mm/shmem.c:2930:13: error: incompatible pointer types passing 'struct file *' to parameter of type 'struct file *' [-Werror,-Wincompatible-pointer-types]
                   d_tmpfile(file, inode);
                             ^~~~
   include/linux/dcache.h:253:36: note: passing argument to parameter here
   extern void d_tmpfile(struct file *, struct inode *);
                                      ^
   1 warning and 1 error generated.
--
   In file included from fs/ext4/namei.c:28:
   In file included from include/linux/fs.h:8:
   include/linux/dcache.h:253:30: warning: declaration of 'struct file' will not be visible outside of this function [-Wvisibility]
   extern void d_tmpfile(struct file *, struct inode *);
                                ^
>> fs/ext4/namei.c:2874:13: error: incompatible pointer types passing 'struct file *' to parameter of type 'struct file *' [-Werror,-Wincompatible-pointer-types]
                   d_tmpfile(file, inode);
                             ^~~~
   include/linux/dcache.h:253:36: note: passing argument to parameter here
   extern void d_tmpfile(struct file *, struct inode *);
                                      ^
   1 warning and 1 error generated.
--
   In file included from fs/ramfs/inode.c:26:
   In file included from include/linux/fs.h:8:
   include/linux/dcache.h:253:30: warning: declaration of 'struct file' will not be visible outside of this function [-Wvisibility]
   extern void d_tmpfile(struct file *, struct inode *);
                                ^
>> fs/ramfs/inode.c:156:12: error: incompatible pointer types passing 'struct file *' to parameter of type 'struct file *' [-Werror,-Wincompatible-pointer-types]
           d_tmpfile(file, inode);
                     ^~~~
   include/linux/dcache.h:253:36: note: passing argument to parameter here
   extern void d_tmpfile(struct file *, struct inode *);
                                      ^
   1 warning and 1 error generated.
--
   In file included from fs/udf/namei.c:22:
   In file included from fs/udf/udfdecl.h:10:
   In file included from include/linux/fs.h:8:
   include/linux/dcache.h:253:30: warning: declaration of 'struct file' will not be visible outside of this function [-Wvisibility]
   extern void d_tmpfile(struct file *, struct inode *);
                                ^
>> fs/udf/namei.c:643:12: error: incompatible pointer types passing 'struct file *' to parameter of type 'struct file *' [-Werror,-Wincompatible-pointer-types]
           d_tmpfile(file, inode);
                     ^~~~
   include/linux/dcache.h:253:36: note: passing argument to parameter here
   extern void d_tmpfile(struct file *, struct inode *);
                                      ^
   1 warning and 1 error generated.


vim +2930 mm/shmem.c

  2912	
  2913	static int
  2914	shmem_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
  2915		      struct file *file, umode_t mode)
  2916	{
  2917		struct inode *inode;
  2918		int error = -ENOSPC;
  2919	
  2920		inode = shmem_get_inode(dir->i_sb, dir, mode, 0, VM_NORESERVE);
  2921		if (inode) {
  2922			error = security_inode_init_security(inode, dir,
  2923							     NULL,
  2924							     shmem_initxattrs, NULL);
  2925			if (error && error != -EOPNOTSUPP)
  2926				goto out_iput;
  2927			error = simple_acl_create(dir, inode);
  2928			if (error)
  2929				goto out_iput;
> 2930			d_tmpfile(file, inode);
  2931		}
  2932		return finish_tmpfile(file, error);
  2933	out_iput:
  2934		iput(inode);
  2935		return error;
  2936	}
  2937
kernel test robot Sept. 17, 2022, 1:49 a.m. UTC | #3
Hi Miklos,

I love your patch! Yet something to improve:

[auto build test ERROR on kdave/for-next]
[also build test ERROR on jaegeuk-f2fs/dev-test linus/master v6.0-rc5]
[cannot apply to viro-vfs/for-next next-20220916]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Miklos-Szeredi/cachefiles-tmpfile-error-handling-cleanup/20220917-034700
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: arc-randconfig-r043-20220916
compiler: arceb-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/87f47d099f22ea898e5d05215f9b2c4647012001
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Miklos-Szeredi/cachefiles-tmpfile-error-handling-cleanup/20220917-034700
        git checkout 87f47d099f22ea898e5d05215f9b2c4647012001
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from include/linux/fs.h:8,
                    from mm/shmem.c:24:
   include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   mm/shmem.c: In function 'shmem_tmpfile':
>> mm/shmem.c:2930:27: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2930 |                 d_tmpfile(file, inode);
         |                           ^~~~
         |                           |
         |                           struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   In file included from include/linux/fs.h:8,
                    from fs/ramfs/inode.c:26:
   include/linux/dcache.h:253:30: warning: 'struct file' declared inside parameter list will not be visible outside of this definition or declaration
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                              ^~~~
   fs/ramfs/inode.c: In function 'ramfs_tmpfile':
>> fs/ramfs/inode.c:156:19: error: passing argument 1 of 'd_tmpfile' from incompatible pointer type [-Werror=incompatible-pointer-types]
     156 |         d_tmpfile(file, inode);
         |                   ^~~~
         |                   |
         |                   struct file *
   include/linux/dcache.h:253:23: note: expected 'struct file *' but argument is of type 'struct file *'
     253 | extern void d_tmpfile(struct file *, struct inode *);
         |                       ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/d_tmpfile +2930 mm/shmem.c

  2912	
  2913	static int
  2914	shmem_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
  2915		      struct file *file, umode_t mode)
  2916	{
  2917		struct inode *inode;
  2918		int error = -ENOSPC;
  2919	
  2920		inode = shmem_get_inode(dir->i_sb, dir, mode, 0, VM_NORESERVE);
  2921		if (inode) {
  2922			error = security_inode_init_security(inode, dir,
  2923							     NULL,
  2924							     shmem_initxattrs, NULL);
  2925			if (error && error != -EOPNOTSUPP)
  2926				goto out_iput;
  2927			error = simple_acl_create(dir, inode);
  2928			if (error)
  2929				goto out_iput;
> 2930			d_tmpfile(file, inode);
  2931		}
  2932		return finish_tmpfile(file, error);
  2933	out_iput:
  2934		iput(inode);
  2935		return error;
  2936	}
  2937
diff mbox series

Patch

diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 12b8fdcc445b..9d1cde8066cf 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -147,7 +147,7 @@  static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry,
 }
 
 static int bad_inode_tmpfile(struct user_namespace *mnt_userns,
-			     struct inode *inode, struct dentry *dentry,
+			     struct inode *inode, struct file *file,
 			     umode_t mode)
 {
 	return -EIO;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1372210869b1..ceac5aa9a1ed 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -10168,7 +10168,7 @@  static int btrfs_permission(struct user_namespace *mnt_userns,
 }
 
 static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			 struct dentry *dentry, umode_t mode)
+			 struct file *file, umode_t mode)
 {
 	struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
 	struct btrfs_trans_handle *trans;
@@ -10176,7 +10176,7 @@  static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 	struct inode *inode;
 	struct btrfs_new_inode_args new_inode_args = {
 		.dir = dir,
-		.dentry = dentry,
+		.dentry = file->f_path.dentry,
 		.orphan = true,
 	};
 	unsigned int trans_num_items;
@@ -10213,7 +10213,7 @@  static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 	set_nlink(inode, 1);
 
 	if (!ret) {
-		d_tmpfile(dentry, inode);
+		d_tmpfile(file, inode);
 		unlock_new_inode(inode);
 		mark_inode_dirty(inode);
 	}
@@ -10225,7 +10225,7 @@  static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 out_inode:
 	if (ret)
 		iput(inode);
-	return ret;
+	return finish_tmpfile(file, ret);
 }
 
 void btrfs_set_range_writeback(struct btrfs_inode *inode, u64 start, u64 end)
diff --git a/fs/dcache.c b/fs/dcache.c
index bb0c4d0038db..89dc61389102 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -3258,8 +3258,10 @@  void d_genocide(struct dentry *parent)
 
 EXPORT_SYMBOL(d_genocide);
 
-void d_tmpfile(struct dentry *dentry, struct inode *inode)
+void d_tmpfile(struct file *file, struct inode *inode)
 {
+	struct dentry *dentry = file->f_path.dentry;
+
 	inode_dec_link_count(inode);
 	BUG_ON(dentry->d_name.name != dentry->d_iname ||
 		!hlist_unhashed(&dentry->d_u.d_alias) ||
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 5fd9a22d2b70..3f53353adb95 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -120,7 +120,7 @@  static int ext2_create (struct user_namespace * mnt_userns,
 }
 
 static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			struct dentry *dentry, umode_t mode)
+			struct file *file, umode_t mode)
 {
 	struct inode *inode = ext2_new_inode(dir, mode, NULL);
 	if (IS_ERR(inode))
@@ -128,9 +128,9 @@  static int ext2_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 
 	ext2_set_file_ops(inode);
 	mark_inode_dirty(inode);
-	d_tmpfile(dentry, inode);
+	d_tmpfile(file, inode);
 	unlock_new_inode(inode);
-	return 0;
+	return finish_tmpfile(file, 0);
 }
 
 static int ext2_mknod (struct user_namespace * mnt_userns, struct inode * dir,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 3a31b662f661..9250fa174a54 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2849,7 +2849,7 @@  static int ext4_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			struct dentry *dentry, umode_t mode)
+			struct file *file, umode_t mode)
 {
 	handle_t *handle;
 	struct inode *inode;
@@ -2871,7 +2871,7 @@  static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 		inode->i_op = &ext4_file_inode_operations;
 		inode->i_fop = &ext4_file_operations;
 		ext4_set_aops(inode);
-		d_tmpfile(dentry, inode);
+		d_tmpfile(file, inode);
 		err = ext4_orphan_add(handle, inode);
 		if (err)
 			goto err_unlock_inode;
@@ -2882,7 +2882,7 @@  static int ext4_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 		ext4_journal_stop(handle);
 	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
 		goto retry;
-	return err;
+	return finish_tmpfile(file, err);
 err_unlock_inode:
 	ext4_journal_stop(handle);
 	unlock_new_inode(inode);
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index bf00d5057abb..460a056efa82 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -845,7 +845,7 @@  static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			  struct dentry *dentry, umode_t mode, bool is_whiteout,
+			  struct file *file, umode_t mode, bool is_whiteout,
 			  struct inode **new_inode)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
@@ -892,8 +892,8 @@  static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 		inode->i_state |= I_LINKABLE;
 		spin_unlock(&inode->i_lock);
 	} else {
-		if (dentry)
-			d_tmpfile(dentry, inode);
+		if (file)
+			d_tmpfile(file, inode);
 		else
 			f2fs_i_links_write(inode, false);
 	}
@@ -915,16 +915,19 @@  static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 static int f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			struct dentry *dentry, umode_t mode)
+			struct file *file, umode_t mode)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+	int err;
 
 	if (unlikely(f2fs_cp_error(sbi)))
 		return -EIO;
 	if (!f2fs_is_checkpoint_ready(sbi))
 		return -ENOSPC;
 
-	return __f2fs_tmpfile(mnt_userns, dir, dentry, mode, false, NULL);
+	err = __f2fs_tmpfile(mnt_userns, dir, file, mode, false, NULL);
+
+	return finish_tmpfile(file, err);
 }
 
 static int f2fs_create_whiteout(struct user_namespace *mnt_userns,
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index f7a5b5124d8a..bb207560ef68 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -889,7 +889,7 @@  static int do_hugetlbfs_mknod(struct inode *dir,
 			struct dentry *dentry,
 			umode_t mode,
 			dev_t dev,
-			bool tmpfile)
+			struct file *tmpfile)
 {
 	struct inode *inode;
 	int error = -ENOSPC;
@@ -898,7 +898,7 @@  static int do_hugetlbfs_mknod(struct inode *dir,
 	if (inode) {
 		dir->i_ctime = dir->i_mtime = current_time(dir);
 		if (tmpfile) {
-			d_tmpfile(dentry, inode);
+			d_tmpfile(tmpfile, inode);
 		} else {
 			d_instantiate(dentry, inode);
 			dget(dentry);/* Extra count - pin the dentry in core */
@@ -911,7 +911,7 @@  static int do_hugetlbfs_mknod(struct inode *dir,
 static int hugetlbfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 			   struct dentry *dentry, umode_t mode, dev_t dev)
 {
-	return do_hugetlbfs_mknod(dir, dentry, mode, dev, false);
+	return do_hugetlbfs_mknod(dir, dentry, mode, dev, NULL);
 }
 
 static int hugetlbfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
@@ -932,10 +932,12 @@  static int hugetlbfs_create(struct user_namespace *mnt_userns,
 }
 
 static int hugetlbfs_tmpfile(struct user_namespace *mnt_userns,
-			     struct inode *dir, struct dentry *dentry,
+			     struct inode *dir, struct file *file,
 			     umode_t mode)
 {
-	return do_hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0, true);
+	int err = do_hugetlbfs_mknod(dir, file->f_path.dentry, mode | S_IFREG, 0, file);
+
+	return finish_tmpfile(file, err);
 }
 
 static int hugetlbfs_symlink(struct user_namespace *mnt_userns,
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 937fa5fae2b8..fc7d2a6b42d0 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -53,16 +53,16 @@  static int minix_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 static int minix_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			 struct dentry *dentry, umode_t mode)
+			 struct file *file, umode_t mode)
 {
 	int error;
 	struct inode *inode = minix_new_inode(dir, mode, &error);
 	if (inode) {
 		minix_set_inode(inode, 0);
 		mark_inode_dirty(inode);
-		d_tmpfile(dentry, inode);
+		d_tmpfile(file, inode);
 	}
-	return error;
+	return finish_tmpfile(file, error);
 }
 
 static int minix_create(struct user_namespace *mnt_userns, struct inode *dir,
diff --git a/fs/namei.c b/fs/namei.c
index 22353853651b..e7e7e1af4835 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3606,8 +3606,7 @@  static int vfs_tmpfile(struct user_namespace *mnt_userns,
 	file->f_path.mnt = parentpath->mnt;
 	file->f_path.dentry = child;
 	mode = vfs_prepare_mode(mnt_userns, dir, mode, mode, mode);
-	error = dir->i_op->tmpfile(mnt_userns, dir, child, mode);
-	error = finish_tmpfile(file, error);
+	error = dir->i_op->tmpfile(mnt_userns, dir, file, mode);
 	dput(child);
 	if (error)
 		goto out_err;
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index bc66d0173e33..dcd8c3b72d33 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -146,15 +146,15 @@  static int ramfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 static int ramfs_tmpfile(struct user_namespace *mnt_userns,
-			 struct inode *dir, struct dentry *dentry, umode_t mode)
+			 struct inode *dir, struct file *file, umode_t mode)
 {
 	struct inode *inode;
 
 	inode = ramfs_get_inode(dir->i_sb, dir, mode, 0);
 	if (!inode)
 		return -ENOSPC;
-	d_tmpfile(dentry, inode);
-	return 0;
+	d_tmpfile(file, inode);
+	return finish_tmpfile(file, 0);
 }
 
 static const struct inode_operations ramfs_dir_inode_operations = {
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 86151889548e..63473638456e 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -424,8 +424,9 @@  static void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
 }
 
 static int ubifs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-			 struct dentry *dentry, umode_t mode)
+			 struct file *file, umode_t mode)
 {
+	struct dentry *dentry = file->f_path.dentry;
 	struct inode *inode;
 	struct ubifs_info *c = dir->i_sb->s_fs_info;
 	struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
@@ -475,7 +476,7 @@  static int ubifs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 
 	mutex_lock(&ui->ui_mutex);
 	insert_inode_hash(inode);
-	d_tmpfile(dentry, inode);
+	d_tmpfile(file, inode);
 	ubifs_assert(c, ui->dirty);
 
 	instantiated = 1;
@@ -489,7 +490,7 @@  static int ubifs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 
 	ubifs_release_budget(c, &req);
 
-	return 0;
+	return finish_tmpfile(file, 0);
 
 out_cancel:
 	unlock_2_inodes(dir, inode);
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index b3d5f97f16cd..6ab0f44a7abf 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -626,7 +626,7 @@  static int udf_create(struct user_namespace *mnt_userns, struct inode *dir,
 }
 
 static int udf_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-		       struct dentry *dentry, umode_t mode)
+		       struct file *file, umode_t mode)
 {
 	struct inode *inode = udf_new_inode(dir, mode);
 
@@ -640,9 +640,9 @@  static int udf_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 	inode->i_op = &udf_file_inode_operations;
 	inode->i_fop = &udf_file_operations;
 	mark_inode_dirty(inode);
-	d_tmpfile(dentry, inode);
+	d_tmpfile(file, inode);
 	unlock_new_inode(inode);
-	return 0;
+	return finish_tmpfile(file, 0);
 }
 
 static int udf_mknod(struct user_namespace *mnt_userns, struct inode *dir,
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 45518b8c613c..8c0671a58bf2 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -167,7 +167,7 @@  xfs_generic_create(
 	struct dentry	*dentry,
 	umode_t		mode,
 	dev_t		rdev,
-	bool		tmpfile)	/* unnamed file */
+	struct file	*tmpfile)	/* unnamed file */
 {
 	struct inode	*inode;
 	struct xfs_inode *ip = NULL;
@@ -234,7 +234,7 @@  xfs_generic_create(
 		 * d_tmpfile can immediately set it back to zero.
 		 */
 		set_nlink(inode, 1);
-		d_tmpfile(dentry, inode);
+		d_tmpfile(tmpfile, inode);
 	} else
 		d_instantiate(dentry, inode);
 
@@ -261,7 +261,7 @@  xfs_vn_mknod(
 	umode_t			mode,
 	dev_t			rdev)
 {
-	return xfs_generic_create(mnt_userns, dir, dentry, mode, rdev, false);
+	return xfs_generic_create(mnt_userns, dir, dentry, mode, rdev, NULL);
 }
 
 STATIC int
@@ -272,7 +272,7 @@  xfs_vn_create(
 	umode_t			mode,
 	bool			flags)
 {
-	return xfs_generic_create(mnt_userns, dir, dentry, mode, 0, false);
+	return xfs_generic_create(mnt_userns, dir, dentry, mode, 0, NULL);
 }
 
 STATIC int
@@ -283,7 +283,7 @@  xfs_vn_mkdir(
 	umode_t			mode)
 {
 	return xfs_generic_create(mnt_userns, dir, dentry, mode | S_IFDIR, 0,
-				  false);
+				  NULL);
 }
 
 STATIC struct dentry *
@@ -1080,10 +1080,12 @@  STATIC int
 xfs_vn_tmpfile(
 	struct user_namespace	*mnt_userns,
 	struct inode		*dir,
-	struct dentry		*dentry,
+	struct file		*file,
 	umode_t			mode)
 {
-	return xfs_generic_create(mnt_userns, dir, dentry, mode, 0, true);
+	int err = xfs_generic_create(mnt_userns, dir, file->f_path.dentry, mode, 0, file);
+
+	return finish_tmpfile(file, err);
 }
 
 static const struct inode_operations xfs_inode_operations = {
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 92c78ed02b54..450b933f2bc7 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -250,7 +250,7 @@  extern struct dentry * d_make_root(struct inode *);
 /* <clickety>-<click> the ramfs-type tree */
 extern void d_genocide(struct dentry *);
 
-extern void d_tmpfile(struct dentry *, struct inode *);
+extern void d_tmpfile(struct file *, struct inode *);
 
 extern struct dentry *d_find_alias(struct inode *);
 extern void d_prune_aliases(struct inode *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8d0e11ba930c..0979b0e5b9f6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2168,7 +2168,7 @@  struct inode_operations {
 			   struct file *, unsigned open_flag,
 			   umode_t create_mode);
 	int (*tmpfile) (struct user_namespace *, struct inode *,
-			struct dentry *, umode_t);
+			struct file *, umode_t);
 	int (*set_acl)(struct user_namespace *, struct inode *,
 		       struct posix_acl *, int);
 	int (*fileattr_set)(struct user_namespace *mnt_userns,
diff --git a/mm/shmem.c b/mm/shmem.c
index 42e5888bf84d..d504fb4eaa4c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2912,7 +2912,7 @@  shmem_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 
 static int
 shmem_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
-	      struct dentry *dentry, umode_t mode)
+	      struct file *file, umode_t mode)
 {
 	struct inode *inode;
 	int error = -ENOSPC;
@@ -2927,9 +2927,9 @@  shmem_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 		error = simple_acl_create(dir, inode);
 		if (error)
 			goto out_iput;
-		d_tmpfile(dentry, inode);
+		d_tmpfile(file, inode);
 	}
-	return error;
+	return finish_tmpfile(file, error);
 out_iput:
 	iput(inode);
 	return error;