@@ -10382,14 +10382,6 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
if (ret)
goto out;
- /*
- * We set number of links to 0 in btrfs_new_inode(), and here we set
- * it to 1 because d_tmpfile() will issue a warning if the count is 0,
- * through:
- *
- * d_tmpfile() -> inode_dec_link_count() -> drop_nlink()
- */
- set_nlink(inode, 1);
d_tmpfile(dentry, inode);
unlock_new_inode(inode);
mark_inode_dirty(inode);
@@ -3042,12 +3042,14 @@ void d_genocide(struct dentry *parent)
EXPORT_SYMBOL(d_genocide);
+/*
+ * Instantiate an inode in the dentry cache as a temporary file. Callers must
+ * ensure that @inode has a zero link count.
+ */
void d_tmpfile(struct dentry *dentry, struct inode *inode)
{
- inode_dec_link_count(inode);
- BUG_ON(dentry->d_name.name != dentry->d_iname ||
- !hlist_unhashed(&dentry->d_u.d_alias) ||
- !d_unlinked(dentry));
+ WARN_ON(dentry->d_name.name != dentry->d_iname ||
+ !d_unlinked(dentry) || inode->i_nlink != 0);
spin_lock(&dentry->d_parent->d_lock);
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
dentry->d_name.len = sprintf(dentry->d_iname, "#%llu",
@@ -117,7 +117,7 @@ static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
return PTR_ERR(inode);
ext2_set_file_ops(inode);
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
unlock_new_inode(inode);
return 0;
@@ -2517,6 +2517,7 @@ static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
inode->i_op = &ext4_file_inode_operations;
inode->i_fop = &ext4_file_operations;
ext4_set_aops(inode);
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
err = ext4_orphan_add(handle, inode);
if (err)
@@ -780,6 +780,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
f2fs_i_links_write(inode, false);
*whiteout = inode;
} else {
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
}
/* link_count was changed by d_tmpfile as well. */
@@ -57,7 +57,7 @@ static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
struct inode *inode = minix_new_inode(dir, mode, &error);
if (inode) {
minix_set_inode(inode, 0);
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
}
return error;
@@ -419,6 +419,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
drop_nlink(inode);
*whiteout = inode;
} else {
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
}
ubifs_assert(c, ui->dirty);
@@ -652,7 +652,7 @@ static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
inode->i_data.a_ops = &udf_aops;
inode->i_op = &udf_file_inode_operations;
inode->i_fop = &udf_file_operations;
- mark_inode_dirty(inode);
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
unlock_new_inode(inode);
return 0;
@@ -191,18 +191,9 @@ xfs_generic_create(
xfs_setup_iops(ip);
- if (tmpfile) {
- /*
- * The VFS requires that any inode fed to d_tmpfile must have
- * nlink == 1 so that it can decrement the nlink in d_tmpfile.
- * However, we created the temp file with nlink == 0 because
- * we're not allowed to put an inode with nlink > 0 on the
- * unlinked list. Therefore we have to set nlink to 1 so that
- * d_tmpfile can immediately set it back to zero.
- */
- set_nlink(inode, 1);
+ if (tmpfile)
d_tmpfile(dentry, inode);
- } else
+ else
d_instantiate(dentry, inode);
xfs_finish_inode_setup(ip);
@@ -2818,6 +2818,7 @@ shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
error = simple_acl_create(dir, inode);
if (error)
goto out_iput;
+ inode_dec_link_count(inode);
d_tmpfile(dentry, inode);
}
return error;