diff options
Diffstat (limited to 'fs/ext4')
| -rw-r--r-- | fs/ext4/file.c | 24 | ||||
| -rw-r--r-- | fs/ext4/namei.c | 47 |
2 files changed, 48 insertions, 23 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index b19f0a457f32..6f4cc567c382 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
| @@ -494,17 +494,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) | |||
| 494 | if (dataoff > isize) | 494 | if (dataoff > isize) |
| 495 | return -ENXIO; | 495 | return -ENXIO; |
| 496 | 496 | ||
| 497 | if (dataoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 497 | return vfs_setpos(file, dataoff, maxsize); |
| 498 | return -EINVAL; | ||
| 499 | if (dataoff > maxsize) | ||
| 500 | return -EINVAL; | ||
| 501 | |||
| 502 | if (dataoff != file->f_pos) { | ||
| 503 | file->f_pos = dataoff; | ||
| 504 | file->f_version = 0; | ||
| 505 | } | ||
| 506 | |||
| 507 | return dataoff; | ||
| 508 | } | 498 | } |
| 509 | 499 | ||
| 510 | /* | 500 | /* |
| @@ -580,17 +570,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) | |||
| 580 | if (holeoff > isize) | 570 | if (holeoff > isize) |
| 581 | holeoff = isize; | 571 | holeoff = isize; |
| 582 | 572 | ||
| 583 | if (holeoff < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 573 | return vfs_setpos(file, holeoff, maxsize); |
| 584 | return -EINVAL; | ||
| 585 | if (holeoff > maxsize) | ||
| 586 | return -EINVAL; | ||
| 587 | |||
| 588 | if (holeoff != file->f_pos) { | ||
| 589 | file->f_pos = holeoff; | ||
| 590 | file->f_version = 0; | ||
| 591 | } | ||
| 592 | |||
| 593 | return holeoff; | ||
| 594 | } | 574 | } |
| 595 | 575 | ||
| 596 | /* | 576 | /* |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index ab2f6dc44b3a..234b834d5a97 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -2296,6 +2296,45 @@ retry: | |||
| 2296 | return err; | 2296 | return err; |
| 2297 | } | 2297 | } |
| 2298 | 2298 | ||
| 2299 | static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
| 2300 | { | ||
| 2301 | handle_t *handle; | ||
| 2302 | struct inode *inode; | ||
| 2303 | int err, retries = 0; | ||
| 2304 | |||
| 2305 | dquot_initialize(dir); | ||
| 2306 | |||
| 2307 | retry: | ||
| 2308 | inode = ext4_new_inode_start_handle(dir, mode, | ||
| 2309 | NULL, 0, NULL, | ||
| 2310 | EXT4_HT_DIR, | ||
| 2311 | EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + | ||
| 2312 | 4 + EXT4_XATTR_TRANS_BLOCKS); | ||
| 2313 | handle = ext4_journal_current_handle(); | ||
| 2314 | err = PTR_ERR(inode); | ||
| 2315 | if (!IS_ERR(inode)) { | ||
| 2316 | inode->i_op = &ext4_file_inode_operations; | ||
| 2317 | inode->i_fop = &ext4_file_operations; | ||
| 2318 | ext4_set_aops(inode); | ||
| 2319 | err = ext4_orphan_add(handle, inode); | ||
| 2320 | if (err) | ||
| 2321 | goto err_drop_inode; | ||
| 2322 | mark_inode_dirty(inode); | ||
| 2323 | d_tmpfile(dentry, inode); | ||
| 2324 | unlock_new_inode(inode); | ||
| 2325 | } | ||
| 2326 | if (handle) | ||
| 2327 | ext4_journal_stop(handle); | ||
| 2328 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) | ||
| 2329 | goto retry; | ||
| 2330 | return err; | ||
| 2331 | err_drop_inode: | ||
| 2332 | ext4_journal_stop(handle); | ||
| 2333 | unlock_new_inode(inode); | ||
| 2334 | iput(inode); | ||
| 2335 | return err; | ||
| 2336 | } | ||
| 2337 | |||
| 2299 | struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, | 2338 | struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, |
| 2300 | struct ext4_dir_entry_2 *de, | 2339 | struct ext4_dir_entry_2 *de, |
| 2301 | int blocksize, int csum_size, | 2340 | int blocksize, int csum_size, |
| @@ -2903,7 +2942,7 @@ static int ext4_link(struct dentry *old_dentry, | |||
| 2903 | retry: | 2942 | retry: |
| 2904 | handle = ext4_journal_start(dir, EXT4_HT_DIR, | 2943 | handle = ext4_journal_start(dir, EXT4_HT_DIR, |
| 2905 | (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + | 2944 | (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + |
| 2906 | EXT4_INDEX_EXTRA_TRANS_BLOCKS)); | 2945 | EXT4_INDEX_EXTRA_TRANS_BLOCKS) + 1); |
| 2907 | if (IS_ERR(handle)) | 2946 | if (IS_ERR(handle)) |
| 2908 | return PTR_ERR(handle); | 2947 | return PTR_ERR(handle); |
| 2909 | 2948 | ||
| @@ -2917,6 +2956,11 @@ retry: | |||
| 2917 | err = ext4_add_entry(handle, dentry, inode); | 2956 | err = ext4_add_entry(handle, dentry, inode); |
| 2918 | if (!err) { | 2957 | if (!err) { |
| 2919 | ext4_mark_inode_dirty(handle, inode); | 2958 | ext4_mark_inode_dirty(handle, inode); |
| 2959 | /* this can happen only for tmpfile being | ||
| 2960 | * linked the first time | ||
| 2961 | */ | ||
| 2962 | if (inode->i_nlink == 1) | ||
| 2963 | ext4_orphan_del(handle, inode); | ||
| 2920 | d_instantiate(dentry, inode); | 2964 | d_instantiate(dentry, inode); |
| 2921 | } else { | 2965 | } else { |
| 2922 | drop_nlink(inode); | 2966 | drop_nlink(inode); |
| @@ -3169,6 +3213,7 @@ const struct inode_operations ext4_dir_inode_operations = { | |||
| 3169 | .mkdir = ext4_mkdir, | 3213 | .mkdir = ext4_mkdir, |
| 3170 | .rmdir = ext4_rmdir, | 3214 | .rmdir = ext4_rmdir, |
| 3171 | .mknod = ext4_mknod, | 3215 | .mknod = ext4_mknod, |
| 3216 | .tmpfile = ext4_tmpfile, | ||
| 3172 | .rename = ext4_rename, | 3217 | .rename = ext4_rename, |
| 3173 | .setattr = ext4_setattr, | 3218 | .setattr = ext4_setattr, |
| 3174 | .setxattr = generic_setxattr, | 3219 | .setxattr = generic_setxattr, |
