diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 05:23:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-07-03 08:23:28 -0400 |
commit | af51a2ac36d1f96bee30438ec95a51e4635d1e33 (patch) | |
tree | 51aaa115bd9678153c425c0fb4b98472bcf666e5 /fs/ext4 | |
parent | 46a1c2c7ae53de2a5676754b54a73c591a3951d2 (diff) |
ext4: ->tmpfile() support
very similar to ext3 counterpart...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/namei.c | 47 |
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 | ||
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 | |||
2302 | struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, | 2341 | struct 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, | |||
2906 | retry: | 2945 | retry: |
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, |