Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af51a2ac authored by Al Viro's avatar Al Viro
Browse files

ext4: ->tmpfile() support



very similar to ext3 counterpart...

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 46a1c2c7
Loading
Loading
Loading
Loading
+46 −1
Original line number Diff line number Diff line
@@ -2299,6 +2299,45 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry,
	return err;
}

static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	handle_t *handle;
	struct inode *inode;
	int err, retries = 0;

	dquot_initialize(dir);

retry:
	inode = ext4_new_inode_start_handle(dir, mode,
					    NULL, 0, NULL,
					    EXT4_HT_DIR,
			EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) +
			  4 + EXT4_XATTR_TRANS_BLOCKS);
	handle = ext4_journal_current_handle();
	err = PTR_ERR(inode);
	if (!IS_ERR(inode)) {
		inode->i_op = &ext4_file_inode_operations;
		inode->i_fop = &ext4_file_operations;
		ext4_set_aops(inode);
		err = ext4_orphan_add(handle, inode);
		if (err)
			goto err_drop_inode;
		mark_inode_dirty(inode);
		d_tmpfile(dentry, inode);
		unlock_new_inode(inode);
	}
	if (handle)
		ext4_journal_stop(handle);
	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
		goto retry;
	return err;
err_drop_inode:
	ext4_journal_stop(handle);
	unlock_new_inode(inode);
	iput(inode);
	return err;
}

struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode,
			  struct ext4_dir_entry_2 *de,
			  int blocksize, int csum_size,
@@ -2906,7 +2945,7 @@ static int ext4_link(struct dentry *old_dentry,
retry:
	handle = ext4_journal_start(dir, EXT4_HT_DIR,
		(EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
		 EXT4_INDEX_EXTRA_TRANS_BLOCKS));
		 EXT4_INDEX_EXTRA_TRANS_BLOCKS) + 1);
	if (IS_ERR(handle))
		return PTR_ERR(handle);

@@ -2920,6 +2959,11 @@ static int ext4_link(struct dentry *old_dentry,
	err = ext4_add_entry(handle, dentry, inode);
	if (!err) {
		ext4_mark_inode_dirty(handle, inode);
		/* this can happen only for tmpfile being
		 * linked the first time
		 */
		if (inode->i_nlink == 1)
			ext4_orphan_del(handle, inode);
		d_instantiate(dentry, inode);
	} else {
		drop_nlink(inode);
@@ -3172,6 +3216,7 @@ const struct inode_operations ext4_dir_inode_operations = {
	.mkdir		= ext4_mkdir,
	.rmdir		= ext4_rmdir,
	.mknod		= ext4_mknod,
	.tmpfile	= ext4_tmpfile,
	.rename		= ext4_rename,
	.setattr	= ext4_setattr,
	.setxattr	= generic_setxattr,