Skip to content

Commit af51a2a

Browse files
author
Al Viro
committed
ext4: ->tmpfile() support
very similar to ext3 counterpart... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 46a1c2c commit af51a2a

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

fs/ext4/namei.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2299,6 +2299,45 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry,
22992299
return err;
23002300
}
23012301

2302+
static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
2303+
{
2304+
handle_t *handle;
2305+
struct inode *inode;
2306+
int err, retries = 0;
2307+
2308+
dquot_initialize(dir);
2309+
2310+
retry:
2311+
inode = ext4_new_inode_start_handle(dir, mode,
2312+
NULL, 0, NULL,
2313+
EXT4_HT_DIR,
2314+
EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) +
2315+
4 + EXT4_XATTR_TRANS_BLOCKS);
2316+
handle = ext4_journal_current_handle();
2317+
err = PTR_ERR(inode);
2318+
if (!IS_ERR(inode)) {
2319+
inode->i_op = &ext4_file_inode_operations;
2320+
inode->i_fop = &ext4_file_operations;
2321+
ext4_set_aops(inode);
2322+
err = ext4_orphan_add(handle, inode);
2323+
if (err)
2324+
goto err_drop_inode;
2325+
mark_inode_dirty(inode);
2326+
d_tmpfile(dentry, inode);
2327+
unlock_new_inode(inode);
2328+
}
2329+
if (handle)
2330+
ext4_journal_stop(handle);
2331+
if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
2332+
goto retry;
2333+
return err;
2334+
err_drop_inode:
2335+
ext4_journal_stop(handle);
2336+
unlock_new_inode(inode);
2337+
iput(inode);
2338+
return err;
2339+
}
2340+
23022341
struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode,
23032342
struct ext4_dir_entry_2 *de,
23042343
int blocksize, int csum_size,
@@ -2906,7 +2945,7 @@ static int ext4_link(struct dentry *old_dentry,
29062945
retry:
29072946
handle = ext4_journal_start(dir, EXT4_HT_DIR,
29082947
(EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
2909-
EXT4_INDEX_EXTRA_TRANS_BLOCKS));
2948+
EXT4_INDEX_EXTRA_TRANS_BLOCKS) + 1);
29102949
if (IS_ERR(handle))
29112950
return PTR_ERR(handle);
29122951

@@ -2920,6 +2959,11 @@ static int ext4_link(struct dentry *old_dentry,
29202959
err = ext4_add_entry(handle, dentry, inode);
29212960
if (!err) {
29222961
ext4_mark_inode_dirty(handle, inode);
2962+
/* this can happen only for tmpfile being
2963+
* linked the first time
2964+
*/
2965+
if (inode->i_nlink == 1)
2966+
ext4_orphan_del(handle, inode);
29232967
d_instantiate(dentry, inode);
29242968
} else {
29252969
drop_nlink(inode);
@@ -3172,6 +3216,7 @@ const struct inode_operations ext4_dir_inode_operations = {
31723216
.mkdir = ext4_mkdir,
31733217
.rmdir = ext4_rmdir,
31743218
.mknod = ext4_mknod,
3219+
.tmpfile = ext4_tmpfile,
31753220
.rename = ext4_rename,
31763221
.setattr = ext4_setattr,
31773222
.setxattr = generic_setxattr,

0 commit comments

Comments
 (0)