aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/namei.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 6653fc35ecb7..f91002f8c017 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2299,6 +2299,45 @@ retry:
2299 return err; 2299 return err;
2300} 2300}
2301 2301
2302static 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
2310retry:
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;
2334err_drop_inode:
2335 ext4_journal_stop(handle);
2336 unlock_new_inode(inode);
2337 iput(inode);
2338 return err;
2339}
2340
2302struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, 2341struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode,
2303 struct ext4_dir_entry_2 *de, 2342 struct ext4_dir_entry_2 *de,
2304 int blocksize, int csum_size, 2343 int blocksize, int csum_size,
@@ -2906,7 +2945,7 @@ static int ext4_link(struct dentry *old_dentry,
2906retry: 2945retry:
2907 handle = ext4_journal_start(dir, EXT4_HT_DIR, 2946 handle = ext4_journal_start(dir, EXT4_HT_DIR,
2908 (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + 2947 (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
2909 EXT4_INDEX_EXTRA_TRANS_BLOCKS)); 2948 EXT4_INDEX_EXTRA_TRANS_BLOCKS) + 1);
2910 if (IS_ERR(handle)) 2949 if (IS_ERR(handle))
2911 return PTR_ERR(handle); 2950 return PTR_ERR(handle);
2912 2951
@@ -2920,6 +2959,11 @@ retry:
2920 err = ext4_add_entry(handle, dentry, inode); 2959 err = ext4_add_entry(handle, dentry, inode);
2921 if (!err) { 2960 if (!err) {
2922 ext4_mark_inode_dirty(handle, inode); 2961 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);
2923 d_instantiate(dentry, inode); 2967 d_instantiate(dentry, inode);
2924 } else { 2968 } else {
2925 drop_nlink(inode); 2969 drop_nlink(inode);
@@ -3172,6 +3216,7 @@ const struct inode_operations ext4_dir_inode_operations = {
3172 .mkdir = ext4_mkdir, 3216 .mkdir = ext4_mkdir,
3173 .rmdir = ext4_rmdir, 3217 .rmdir = ext4_rmdir,
3174 .mknod = ext4_mknod, 3218 .mknod = ext4_mknod,
3219 .tmpfile = ext4_tmpfile,
3175 .rename = ext4_rename, 3220 .rename = ext4_rename,
3176 .setattr = ext4_setattr, 3221 .setattr = ext4_setattr,
3177 .setxattr = generic_setxattr, 3222 .setxattr = generic_setxattr,