diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 00:01:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 00:01:44 -0500 |
commit | f9a03ae123c92c1f45cd2ca88d0f6edd787be78c (patch) | |
tree | c15c8b9b5732eb36b591bf570de63f3c30d252e1 /fs/f2fs/file.c | |
parent | 1289ace5b4f70f1e68ce785735b82c7e483de863 (diff) | |
parent | 447135a86659c646017b8e707c1243c186bf2dff (diff) |
Merge tag 'for-f2fs-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim:
"This series adds two ioctls to control cached data and fragmented
files. Most of the rest fixes missing error cases and bugs that we
have not covered so far. Summary:
Enhancements:
- support an ioctl to execute online file defragmentation
- support an ioctl to flush cached data
- speed up shrinking of extent_cache entries
- handle broken superblock
- refector dirty inode management infra
- revisit f2fs_map_blocks to handle more cases
- reduce global lock coverage
- add detecting user's idle time
Major bug fixes:
- fix data race condition on cached nat entries
- fix error cases of volatile and atomic writes"
* tag 'for-f2fs-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (87 commits)
f2fs: should unset atomic flag after successful commit
f2fs: fix wrong memory condition check
f2fs: monitor the number of background checkpoint
f2fs: detect idle time depending on user behavior
f2fs: introduce time and interval facility
f2fs: skip releasing nodes in chindless extent tree
f2fs: use atomic type for node count in extent tree
f2fs: recognize encrypted data in f2fs_fiemap
f2fs: clean up f2fs_balance_fs
f2fs: remove redundant calls
f2fs: avoid unnecessary f2fs_balance_fs calls
f2fs: check the page status filled from disk
f2fs: introduce __get_node_page to reuse common code
f2fs: check node id earily when readaheading node page
f2fs: read isize while holding i_mutex in fiemap
Revert "f2fs: check the node block address of newly allocated nid"
f2fs: cover more area with nat_tree_lock
f2fs: introduce max_file_blocks in sbi
f2fs crypto: check CONFIG_F2FS_FS_XATTR for encrypted symlink
f2fs: introduce zombie list for fast shrinking extent trees
...
Diffstat (limited to 'fs/f2fs/file.c')
-rw-r--r-- | fs/f2fs/file.c | 344 |
1 files changed, 274 insertions, 70 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index a197215ad52b..18ddb1e5182a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -40,8 +40,6 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, | |||
40 | struct dnode_of_data dn; | 40 | struct dnode_of_data dn; |
41 | int err; | 41 | int err; |
42 | 42 | ||
43 | f2fs_balance_fs(sbi); | ||
44 | |||
45 | sb_start_pagefault(inode->i_sb); | 43 | sb_start_pagefault(inode->i_sb); |
46 | 44 | ||
47 | f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); | 45 | f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); |
@@ -57,6 +55,8 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, | |||
57 | f2fs_put_dnode(&dn); | 55 | f2fs_put_dnode(&dn); |
58 | f2fs_unlock_op(sbi); | 56 | f2fs_unlock_op(sbi); |
59 | 57 | ||
58 | f2fs_balance_fs(sbi, dn.node_changed); | ||
59 | |||
60 | file_update_time(vma->vm_file); | 60 | file_update_time(vma->vm_file); |
61 | lock_page(page); | 61 | lock_page(page); |
62 | if (unlikely(page->mapping != inode->i_mapping || | 62 | if (unlikely(page->mapping != inode->i_mapping || |
@@ -96,6 +96,7 @@ mapped: | |||
96 | clear_cold_data(page); | 96 | clear_cold_data(page); |
97 | out: | 97 | out: |
98 | sb_end_pagefault(inode->i_sb); | 98 | sb_end_pagefault(inode->i_sb); |
99 | f2fs_update_time(sbi, REQ_TIME); | ||
99 | return block_page_mkwrite_return(err); | 100 | return block_page_mkwrite_return(err); |
100 | } | 101 | } |
101 | 102 | ||
@@ -201,7 +202,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
201 | trace_f2fs_sync_file_enter(inode); | 202 | trace_f2fs_sync_file_enter(inode); |
202 | 203 | ||
203 | /* if fdatasync is triggered, let's do in-place-update */ | 204 | /* if fdatasync is triggered, let's do in-place-update */ |
204 | if (get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) | 205 | if (datasync || get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) |
205 | set_inode_flag(fi, FI_NEED_IPU); | 206 | set_inode_flag(fi, FI_NEED_IPU); |
206 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 207 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
207 | clear_inode_flag(fi, FI_NEED_IPU); | 208 | clear_inode_flag(fi, FI_NEED_IPU); |
@@ -233,9 +234,6 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
233 | goto out; | 234 | goto out; |
234 | } | 235 | } |
235 | go_write: | 236 | go_write: |
236 | /* guarantee free sections for fsync */ | ||
237 | f2fs_balance_fs(sbi); | ||
238 | |||
239 | /* | 237 | /* |
240 | * Both of fdatasync() and fsync() are able to be recovered from | 238 | * Both of fdatasync() and fsync() are able to be recovered from |
241 | * sudden-power-off. | 239 | * sudden-power-off. |
@@ -261,8 +259,10 @@ sync_nodes: | |||
261 | sync_node_pages(sbi, ino, &wbc); | 259 | sync_node_pages(sbi, ino, &wbc); |
262 | 260 | ||
263 | /* if cp_error was enabled, we should avoid infinite loop */ | 261 | /* if cp_error was enabled, we should avoid infinite loop */ |
264 | if (unlikely(f2fs_cp_error(sbi))) | 262 | if (unlikely(f2fs_cp_error(sbi))) { |
263 | ret = -EIO; | ||
265 | goto out; | 264 | goto out; |
265 | } | ||
266 | 266 | ||
267 | if (need_inode_block_update(sbi, ino)) { | 267 | if (need_inode_block_update(sbi, ino)) { |
268 | mark_inode_dirty_sync(inode); | 268 | mark_inode_dirty_sync(inode); |
@@ -275,12 +275,13 @@ sync_nodes: | |||
275 | goto out; | 275 | goto out; |
276 | 276 | ||
277 | /* once recovery info is written, don't need to tack this */ | 277 | /* once recovery info is written, don't need to tack this */ |
278 | remove_dirty_inode(sbi, ino, APPEND_INO); | 278 | remove_ino_entry(sbi, ino, APPEND_INO); |
279 | clear_inode_flag(fi, FI_APPEND_WRITE); | 279 | clear_inode_flag(fi, FI_APPEND_WRITE); |
280 | flush_out: | 280 | flush_out: |
281 | remove_dirty_inode(sbi, ino, UPDATE_INO); | 281 | remove_ino_entry(sbi, ino, UPDATE_INO); |
282 | clear_inode_flag(fi, FI_UPDATE_WRITE); | 282 | clear_inode_flag(fi, FI_UPDATE_WRITE); |
283 | ret = f2fs_issue_flush(sbi); | 283 | ret = f2fs_issue_flush(sbi); |
284 | f2fs_update_time(sbi, REQ_TIME); | ||
284 | out: | 285 | out: |
285 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); | 286 | trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); |
286 | f2fs_trace_ios(NULL, 1); | 287 | f2fs_trace_ios(NULL, 1); |
@@ -418,19 +419,18 @@ static loff_t f2fs_llseek(struct file *file, loff_t offset, int whence) | |||
418 | static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) | 419 | static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) |
419 | { | 420 | { |
420 | struct inode *inode = file_inode(file); | 421 | struct inode *inode = file_inode(file); |
422 | int err; | ||
421 | 423 | ||
422 | if (f2fs_encrypted_inode(inode)) { | 424 | if (f2fs_encrypted_inode(inode)) { |
423 | int err = f2fs_get_encryption_info(inode); | 425 | err = f2fs_get_encryption_info(inode); |
424 | if (err) | 426 | if (err) |
425 | return 0; | 427 | return 0; |
426 | } | 428 | } |
427 | 429 | ||
428 | /* we don't need to use inline_data strictly */ | 430 | /* we don't need to use inline_data strictly */ |
429 | if (f2fs_has_inline_data(inode)) { | 431 | err = f2fs_convert_inline_inode(inode); |
430 | int err = f2fs_convert_inline_inode(inode); | 432 | if (err) |
431 | if (err) | 433 | return err; |
432 | return err; | ||
433 | } | ||
434 | 434 | ||
435 | file_accessed(file); | 435 | file_accessed(file); |
436 | vma->vm_ops = &f2fs_file_vm_ops; | 436 | vma->vm_ops = &f2fs_file_vm_ops; |
@@ -483,11 +483,11 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count) | |||
483 | F2FS_I(dn->inode)) + ofs; | 483 | F2FS_I(dn->inode)) + ofs; |
484 | f2fs_update_extent_cache_range(dn, fofs, 0, len); | 484 | f2fs_update_extent_cache_range(dn, fofs, 0, len); |
485 | dec_valid_block_count(sbi, dn->inode, nr_free); | 485 | dec_valid_block_count(sbi, dn->inode, nr_free); |
486 | set_page_dirty(dn->node_page); | ||
487 | sync_inode_page(dn); | 486 | sync_inode_page(dn); |
488 | } | 487 | } |
489 | dn->ofs_in_node = ofs; | 488 | dn->ofs_in_node = ofs; |
490 | 489 | ||
490 | f2fs_update_time(sbi, REQ_TIME); | ||
491 | trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid, | 491 | trace_f2fs_truncate_data_blocks_range(dn->inode, dn->nid, |
492 | dn->ofs_in_node, nr_free); | 492 | dn->ofs_in_node, nr_free); |
493 | return nr_free; | 493 | return nr_free; |
@@ -604,7 +604,7 @@ int f2fs_truncate(struct inode *inode, bool lock) | |||
604 | trace_f2fs_truncate(inode); | 604 | trace_f2fs_truncate(inode); |
605 | 605 | ||
606 | /* we should check inline_data size */ | 606 | /* we should check inline_data size */ |
607 | if (f2fs_has_inline_data(inode) && !f2fs_may_inline_data(inode)) { | 607 | if (!f2fs_may_inline_data(inode)) { |
608 | err = f2fs_convert_inline_inode(inode); | 608 | err = f2fs_convert_inline_inode(inode); |
609 | if (err) | 609 | if (err) |
610 | return err; | 610 | return err; |
@@ -679,13 +679,20 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) | |||
679 | err = f2fs_truncate(inode, true); | 679 | err = f2fs_truncate(inode, true); |
680 | if (err) | 680 | if (err) |
681 | return err; | 681 | return err; |
682 | f2fs_balance_fs(F2FS_I_SB(inode)); | 682 | f2fs_balance_fs(F2FS_I_SB(inode), true); |
683 | } else { | 683 | } else { |
684 | /* | 684 | /* |
685 | * do not trim all blocks after i_size if target size is | 685 | * do not trim all blocks after i_size if target size is |
686 | * larger than i_size. | 686 | * larger than i_size. |
687 | */ | 687 | */ |
688 | truncate_setsize(inode, attr->ia_size); | 688 | truncate_setsize(inode, attr->ia_size); |
689 | |||
690 | /* should convert inline inode here */ | ||
691 | if (!f2fs_may_inline_data(inode)) { | ||
692 | err = f2fs_convert_inline_inode(inode); | ||
693 | if (err) | ||
694 | return err; | ||
695 | } | ||
689 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 696 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
690 | } | 697 | } |
691 | } | 698 | } |
@@ -727,7 +734,7 @@ static int fill_zero(struct inode *inode, pgoff_t index, | |||
727 | if (!len) | 734 | if (!len) |
728 | return 0; | 735 | return 0; |
729 | 736 | ||
730 | f2fs_balance_fs(sbi); | 737 | f2fs_balance_fs(sbi, true); |
731 | 738 | ||
732 | f2fs_lock_op(sbi); | 739 | f2fs_lock_op(sbi); |
733 | page = get_new_data_page(inode, NULL, index, false); | 740 | page = get_new_data_page(inode, NULL, index, false); |
@@ -778,13 +785,11 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
778 | { | 785 | { |
779 | pgoff_t pg_start, pg_end; | 786 | pgoff_t pg_start, pg_end; |
780 | loff_t off_start, off_end; | 787 | loff_t off_start, off_end; |
781 | int ret = 0; | 788 | int ret; |
782 | 789 | ||
783 | if (f2fs_has_inline_data(inode)) { | 790 | ret = f2fs_convert_inline_inode(inode); |
784 | ret = f2fs_convert_inline_inode(inode); | 791 | if (ret) |
785 | if (ret) | 792 | return ret; |
786 | return ret; | ||
787 | } | ||
788 | 793 | ||
789 | pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; | 794 | pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; |
790 | pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; | 795 | pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; |
@@ -815,7 +820,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
815 | loff_t blk_start, blk_end; | 820 | loff_t blk_start, blk_end; |
816 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 821 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
817 | 822 | ||
818 | f2fs_balance_fs(sbi); | 823 | f2fs_balance_fs(sbi, true); |
819 | 824 | ||
820 | blk_start = (loff_t)pg_start << PAGE_CACHE_SHIFT; | 825 | blk_start = (loff_t)pg_start << PAGE_CACHE_SHIFT; |
821 | blk_end = (loff_t)pg_end << PAGE_CACHE_SHIFT; | 826 | blk_end = (loff_t)pg_end << PAGE_CACHE_SHIFT; |
@@ -918,7 +923,7 @@ static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end) | |||
918 | int ret = 0; | 923 | int ret = 0; |
919 | 924 | ||
920 | for (; end < nrpages; start++, end++) { | 925 | for (; end < nrpages; start++, end++) { |
921 | f2fs_balance_fs(sbi); | 926 | f2fs_balance_fs(sbi, true); |
922 | f2fs_lock_op(sbi); | 927 | f2fs_lock_op(sbi); |
923 | ret = __exchange_data_block(inode, end, start, true); | 928 | ret = __exchange_data_block(inode, end, start, true); |
924 | f2fs_unlock_op(sbi); | 929 | f2fs_unlock_op(sbi); |
@@ -941,13 +946,9 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
941 | if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1)) | 946 | if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1)) |
942 | return -EINVAL; | 947 | return -EINVAL; |
943 | 948 | ||
944 | f2fs_balance_fs(F2FS_I_SB(inode)); | 949 | ret = f2fs_convert_inline_inode(inode); |
945 | 950 | if (ret) | |
946 | if (f2fs_has_inline_data(inode)) { | 951 | return ret; |
947 | ret = f2fs_convert_inline_inode(inode); | ||
948 | if (ret) | ||
949 | return ret; | ||
950 | } | ||
951 | 952 | ||
952 | pg_start = offset >> PAGE_CACHE_SHIFT; | 953 | pg_start = offset >> PAGE_CACHE_SHIFT; |
953 | pg_end = (offset + len) >> PAGE_CACHE_SHIFT; | 954 | pg_end = (offset + len) >> PAGE_CACHE_SHIFT; |
@@ -991,13 +992,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, | |||
991 | if (ret) | 992 | if (ret) |
992 | return ret; | 993 | return ret; |
993 | 994 | ||
994 | f2fs_balance_fs(sbi); | 995 | ret = f2fs_convert_inline_inode(inode); |
995 | 996 | if (ret) | |
996 | if (f2fs_has_inline_data(inode)) { | 997 | return ret; |
997 | ret = f2fs_convert_inline_inode(inode); | ||
998 | if (ret) | ||
999 | return ret; | ||
1000 | } | ||
1001 | 998 | ||
1002 | ret = filemap_write_and_wait_range(mapping, offset, offset + len - 1); | 999 | ret = filemap_write_and_wait_range(mapping, offset, offset + len - 1); |
1003 | if (ret) | 1000 | if (ret) |
@@ -1104,13 +1101,11 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) | |||
1104 | if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1)) | 1101 | if (offset & (F2FS_BLKSIZE - 1) || len & (F2FS_BLKSIZE - 1)) |
1105 | return -EINVAL; | 1102 | return -EINVAL; |
1106 | 1103 | ||
1107 | f2fs_balance_fs(sbi); | 1104 | ret = f2fs_convert_inline_inode(inode); |
1105 | if (ret) | ||
1106 | return ret; | ||
1108 | 1107 | ||
1109 | if (f2fs_has_inline_data(inode)) { | 1108 | f2fs_balance_fs(sbi, true); |
1110 | ret = f2fs_convert_inline_inode(inode); | ||
1111 | if (ret) | ||
1112 | return ret; | ||
1113 | } | ||
1114 | 1109 | ||
1115 | ret = truncate_blocks(inode, i_size_read(inode), true); | 1110 | ret = truncate_blocks(inode, i_size_read(inode), true); |
1116 | if (ret) | 1111 | if (ret) |
@@ -1154,17 +1149,15 @@ static int expand_inode_data(struct inode *inode, loff_t offset, | |||
1154 | loff_t off_start, off_end; | 1149 | loff_t off_start, off_end; |
1155 | int ret = 0; | 1150 | int ret = 0; |
1156 | 1151 | ||
1157 | f2fs_balance_fs(sbi); | ||
1158 | |||
1159 | ret = inode_newsize_ok(inode, (len + offset)); | 1152 | ret = inode_newsize_ok(inode, (len + offset)); |
1160 | if (ret) | 1153 | if (ret) |
1161 | return ret; | 1154 | return ret; |
1162 | 1155 | ||
1163 | if (f2fs_has_inline_data(inode)) { | 1156 | ret = f2fs_convert_inline_inode(inode); |
1164 | ret = f2fs_convert_inline_inode(inode); | 1157 | if (ret) |
1165 | if (ret) | 1158 | return ret; |
1166 | return ret; | 1159 | |
1167 | } | 1160 | f2fs_balance_fs(sbi, true); |
1168 | 1161 | ||
1169 | pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; | 1162 | pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; |
1170 | pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; | 1163 | pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; |
@@ -1246,6 +1239,7 @@ static long f2fs_fallocate(struct file *file, int mode, | |||
1246 | if (!ret) { | 1239 | if (!ret) { |
1247 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 1240 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
1248 | mark_inode_dirty(inode); | 1241 | mark_inode_dirty(inode); |
1242 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | ||
1249 | } | 1243 | } |
1250 | 1244 | ||
1251 | out: | 1245 | out: |
@@ -1353,8 +1347,6 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) | |||
1353 | if (!inode_owner_or_capable(inode)) | 1347 | if (!inode_owner_or_capable(inode)) |
1354 | return -EACCES; | 1348 | return -EACCES; |
1355 | 1349 | ||
1356 | f2fs_balance_fs(F2FS_I_SB(inode)); | ||
1357 | |||
1358 | if (f2fs_is_atomic_file(inode)) | 1350 | if (f2fs_is_atomic_file(inode)) |
1359 | return 0; | 1351 | return 0; |
1360 | 1352 | ||
@@ -1363,6 +1355,8 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) | |||
1363 | return ret; | 1355 | return ret; |
1364 | 1356 | ||
1365 | set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | 1357 | set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); |
1358 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | ||
1359 | |||
1366 | return 0; | 1360 | return 0; |
1367 | } | 1361 | } |
1368 | 1362 | ||
@@ -1384,8 +1378,10 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) | |||
1384 | if (f2fs_is_atomic_file(inode)) { | 1378 | if (f2fs_is_atomic_file(inode)) { |
1385 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | 1379 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); |
1386 | ret = commit_inmem_pages(inode, false); | 1380 | ret = commit_inmem_pages(inode, false); |
1387 | if (ret) | 1381 | if (ret) { |
1382 | set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | ||
1388 | goto err_out; | 1383 | goto err_out; |
1384 | } | ||
1389 | } | 1385 | } |
1390 | 1386 | ||
1391 | ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0); | 1387 | ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0); |
@@ -1410,6 +1406,7 @@ static int f2fs_ioc_start_volatile_write(struct file *filp) | |||
1410 | return ret; | 1406 | return ret; |
1411 | 1407 | ||
1412 | set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | 1408 | set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); |
1409 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | ||
1413 | return 0; | 1410 | return 0; |
1414 | } | 1411 | } |
1415 | 1412 | ||
@@ -1441,13 +1438,17 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp) | |||
1441 | if (ret) | 1438 | if (ret) |
1442 | return ret; | 1439 | return ret; |
1443 | 1440 | ||
1444 | f2fs_balance_fs(F2FS_I_SB(inode)); | 1441 | if (f2fs_is_atomic_file(inode)) { |
1445 | 1442 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | |
1446 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | 1443 | commit_inmem_pages(inode, true); |
1447 | clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | 1444 | } |
1448 | commit_inmem_pages(inode, true); | 1445 | if (f2fs_is_volatile_file(inode)) { |
1446 | clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | ||
1447 | ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0); | ||
1448 | } | ||
1449 | 1449 | ||
1450 | mnt_drop_write_file(filp); | 1450 | mnt_drop_write_file(filp); |
1451 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | ||
1451 | return ret; | 1452 | return ret; |
1452 | } | 1453 | } |
1453 | 1454 | ||
@@ -1487,6 +1488,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) | |||
1487 | default: | 1488 | default: |
1488 | return -EINVAL; | 1489 | return -EINVAL; |
1489 | } | 1490 | } |
1491 | f2fs_update_time(sbi, REQ_TIME); | ||
1490 | return 0; | 1492 | return 0; |
1491 | } | 1493 | } |
1492 | 1494 | ||
@@ -1517,6 +1519,7 @@ static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) | |||
1517 | if (copy_to_user((struct fstrim_range __user *)arg, &range, | 1519 | if (copy_to_user((struct fstrim_range __user *)arg, &range, |
1518 | sizeof(range))) | 1520 | sizeof(range))) |
1519 | return -EFAULT; | 1521 | return -EFAULT; |
1522 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | ||
1520 | return 0; | 1523 | return 0; |
1521 | } | 1524 | } |
1522 | 1525 | ||
@@ -1540,6 +1543,7 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) | |||
1540 | sizeof(policy))) | 1543 | sizeof(policy))) |
1541 | return -EFAULT; | 1544 | return -EFAULT; |
1542 | 1545 | ||
1546 | f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); | ||
1543 | return f2fs_process_policy(&policy, inode); | 1547 | return f2fs_process_policy(&policy, inode); |
1544 | #else | 1548 | #else |
1545 | return -EOPNOTSUPP; | 1549 | return -EOPNOTSUPP; |
@@ -1586,13 +1590,13 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg) | |||
1586 | generate_random_uuid(sbi->raw_super->encrypt_pw_salt); | 1590 | generate_random_uuid(sbi->raw_super->encrypt_pw_salt); |
1587 | 1591 | ||
1588 | err = f2fs_commit_super(sbi, false); | 1592 | err = f2fs_commit_super(sbi, false); |
1589 | |||
1590 | mnt_drop_write_file(filp); | ||
1591 | if (err) { | 1593 | if (err) { |
1592 | /* undo new data */ | 1594 | /* undo new data */ |
1593 | memset(sbi->raw_super->encrypt_pw_salt, 0, 16); | 1595 | memset(sbi->raw_super->encrypt_pw_salt, 0, 16); |
1596 | mnt_drop_write_file(filp); | ||
1594 | return err; | 1597 | return err; |
1595 | } | 1598 | } |
1599 | mnt_drop_write_file(filp); | ||
1596 | got_it: | 1600 | got_it: |
1597 | if (copy_to_user((__u8 __user *)arg, sbi->raw_super->encrypt_pw_salt, | 1601 | if (copy_to_user((__u8 __user *)arg, sbi->raw_super->encrypt_pw_salt, |
1598 | 16)) | 1602 | 16)) |
@@ -1629,7 +1633,6 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) | |||
1629 | { | 1633 | { |
1630 | struct inode *inode = file_inode(filp); | 1634 | struct inode *inode = file_inode(filp); |
1631 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 1635 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
1632 | struct cp_control cpc; | ||
1633 | 1636 | ||
1634 | if (!capable(CAP_SYS_ADMIN)) | 1637 | if (!capable(CAP_SYS_ADMIN)) |
1635 | return -EPERM; | 1638 | return -EPERM; |
@@ -1637,13 +1640,196 @@ static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) | |||
1637 | if (f2fs_readonly(sbi->sb)) | 1640 | if (f2fs_readonly(sbi->sb)) |
1638 | return -EROFS; | 1641 | return -EROFS; |
1639 | 1642 | ||
1640 | cpc.reason = __get_cp_reason(sbi); | 1643 | return f2fs_sync_fs(sbi->sb, 1); |
1644 | } | ||
1641 | 1645 | ||
1642 | mutex_lock(&sbi->gc_mutex); | 1646 | static int f2fs_defragment_range(struct f2fs_sb_info *sbi, |
1643 | write_checkpoint(sbi, &cpc); | 1647 | struct file *filp, |
1644 | mutex_unlock(&sbi->gc_mutex); | 1648 | struct f2fs_defragment *range) |
1649 | { | ||
1650 | struct inode *inode = file_inode(filp); | ||
1651 | struct f2fs_map_blocks map; | ||
1652 | struct extent_info ei; | ||
1653 | pgoff_t pg_start, pg_end; | ||
1654 | unsigned int blk_per_seg = sbi->blocks_per_seg; | ||
1655 | unsigned int total = 0, sec_num; | ||
1656 | unsigned int pages_per_sec = sbi->segs_per_sec * blk_per_seg; | ||
1657 | block_t blk_end = 0; | ||
1658 | bool fragmented = false; | ||
1659 | int err; | ||
1645 | 1660 | ||
1646 | return 0; | 1661 | /* if in-place-update policy is enabled, don't waste time here */ |
1662 | if (need_inplace_update(inode)) | ||
1663 | return -EINVAL; | ||
1664 | |||
1665 | pg_start = range->start >> PAGE_CACHE_SHIFT; | ||
1666 | pg_end = (range->start + range->len) >> PAGE_CACHE_SHIFT; | ||
1667 | |||
1668 | f2fs_balance_fs(sbi, true); | ||
1669 | |||
1670 | mutex_lock(&inode->i_mutex); | ||
1671 | |||
1672 | /* writeback all dirty pages in the range */ | ||
1673 | err = filemap_write_and_wait_range(inode->i_mapping, range->start, | ||
1674 | range->start + range->len - 1); | ||
1675 | if (err) | ||
1676 | goto out; | ||
1677 | |||
1678 | /* | ||
1679 | * lookup mapping info in extent cache, skip defragmenting if physical | ||
1680 | * block addresses are continuous. | ||
1681 | */ | ||
1682 | if (f2fs_lookup_extent_cache(inode, pg_start, &ei)) { | ||
1683 | if (ei.fofs + ei.len >= pg_end) | ||
1684 | goto out; | ||
1685 | } | ||
1686 | |||
1687 | map.m_lblk = pg_start; | ||
1688 | |||
1689 | /* | ||
1690 | * lookup mapping info in dnode page cache, skip defragmenting if all | ||
1691 | * physical block addresses are continuous even if there are hole(s) | ||
1692 | * in logical blocks. | ||
1693 | */ | ||
1694 | while (map.m_lblk < pg_end) { | ||
1695 | map.m_len = pg_end - map.m_lblk; | ||
1696 | err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); | ||
1697 | if (err) | ||
1698 | goto out; | ||
1699 | |||
1700 | if (!(map.m_flags & F2FS_MAP_FLAGS)) { | ||
1701 | map.m_lblk++; | ||
1702 | continue; | ||
1703 | } | ||
1704 | |||
1705 | if (blk_end && blk_end != map.m_pblk) { | ||
1706 | fragmented = true; | ||
1707 | break; | ||
1708 | } | ||
1709 | blk_end = map.m_pblk + map.m_len; | ||
1710 | |||
1711 | map.m_lblk += map.m_len; | ||
1712 | } | ||
1713 | |||
1714 | if (!fragmented) | ||
1715 | goto out; | ||
1716 | |||
1717 | map.m_lblk = pg_start; | ||
1718 | map.m_len = pg_end - pg_start; | ||
1719 | |||
1720 | sec_num = (map.m_len + pages_per_sec - 1) / pages_per_sec; | ||
1721 | |||
1722 | /* | ||
1723 | * make sure there are enough free section for LFS allocation, this can | ||
1724 | * avoid defragment running in SSR mode when free section are allocated | ||
1725 | * intensively | ||
1726 | */ | ||
1727 | if (has_not_enough_free_secs(sbi, sec_num)) { | ||
1728 | err = -EAGAIN; | ||
1729 | goto out; | ||
1730 | } | ||
1731 | |||
1732 | while (map.m_lblk < pg_end) { | ||
1733 | pgoff_t idx; | ||
1734 | int cnt = 0; | ||
1735 | |||
1736 | do_map: | ||
1737 | map.m_len = pg_end - map.m_lblk; | ||
1738 | err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_READ); | ||
1739 | if (err) | ||
1740 | goto clear_out; | ||
1741 | |||
1742 | if (!(map.m_flags & F2FS_MAP_FLAGS)) { | ||
1743 | map.m_lblk++; | ||
1744 | continue; | ||
1745 | } | ||
1746 | |||
1747 | set_inode_flag(F2FS_I(inode), FI_DO_DEFRAG); | ||
1748 | |||
1749 | idx = map.m_lblk; | ||
1750 | while (idx < map.m_lblk + map.m_len && cnt < blk_per_seg) { | ||
1751 | struct page *page; | ||
1752 | |||
1753 | page = get_lock_data_page(inode, idx, true); | ||
1754 | if (IS_ERR(page)) { | ||
1755 | err = PTR_ERR(page); | ||
1756 | goto clear_out; | ||
1757 | } | ||
1758 | |||
1759 | set_page_dirty(page); | ||
1760 | f2fs_put_page(page, 1); | ||
1761 | |||
1762 | idx++; | ||
1763 | cnt++; | ||
1764 | total++; | ||
1765 | } | ||
1766 | |||
1767 | map.m_lblk = idx; | ||
1768 | |||
1769 | if (idx < pg_end && cnt < blk_per_seg) | ||
1770 | goto do_map; | ||
1771 | |||
1772 | clear_inode_flag(F2FS_I(inode), FI_DO_DEFRAG); | ||
1773 | |||
1774 | err = filemap_fdatawrite(inode->i_mapping); | ||
1775 | if (err) | ||
1776 | goto out; | ||
1777 | } | ||
1778 | clear_out: | ||
1779 | clear_inode_flag(F2FS_I(inode), FI_DO_DEFRAG); | ||
1780 | out: | ||
1781 | mutex_unlock(&inode->i_mutex); | ||
1782 | if (!err) | ||
1783 | range->len = (u64)total << PAGE_CACHE_SHIFT; | ||
1784 | return err; | ||
1785 | } | ||
1786 | |||
1787 | static int f2fs_ioc_defragment(struct file *filp, unsigned long arg) | ||
1788 | { | ||
1789 | struct inode *inode = file_inode(filp); | ||
1790 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
1791 | struct f2fs_defragment range; | ||
1792 | int err; | ||
1793 | |||
1794 | if (!capable(CAP_SYS_ADMIN)) | ||
1795 | return -EPERM; | ||
1796 | |||
1797 | if (!S_ISREG(inode->i_mode)) | ||
1798 | return -EINVAL; | ||
1799 | |||
1800 | err = mnt_want_write_file(filp); | ||
1801 | if (err) | ||
1802 | return err; | ||
1803 | |||
1804 | if (f2fs_readonly(sbi->sb)) { | ||
1805 | err = -EROFS; | ||
1806 | goto out; | ||
1807 | } | ||
1808 | |||
1809 | if (copy_from_user(&range, (struct f2fs_defragment __user *)arg, | ||
1810 | sizeof(range))) { | ||
1811 | err = -EFAULT; | ||
1812 | goto out; | ||
1813 | } | ||
1814 | |||
1815 | /* verify alignment of offset & size */ | ||
1816 | if (range.start & (F2FS_BLKSIZE - 1) || | ||
1817 | range.len & (F2FS_BLKSIZE - 1)) { | ||
1818 | err = -EINVAL; | ||
1819 | goto out; | ||
1820 | } | ||
1821 | |||
1822 | err = f2fs_defragment_range(sbi, filp, &range); | ||
1823 | f2fs_update_time(sbi, REQ_TIME); | ||
1824 | if (err < 0) | ||
1825 | goto out; | ||
1826 | |||
1827 | if (copy_to_user((struct f2fs_defragment __user *)arg, &range, | ||
1828 | sizeof(range))) | ||
1829 | err = -EFAULT; | ||
1830 | out: | ||
1831 | mnt_drop_write_file(filp); | ||
1832 | return err; | ||
1647 | } | 1833 | } |
1648 | 1834 | ||
1649 | long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 1835 | long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
@@ -1679,6 +1865,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1679 | return f2fs_ioc_gc(filp, arg); | 1865 | return f2fs_ioc_gc(filp, arg); |
1680 | case F2FS_IOC_WRITE_CHECKPOINT: | 1866 | case F2FS_IOC_WRITE_CHECKPOINT: |
1681 | return f2fs_ioc_write_checkpoint(filp, arg); | 1867 | return f2fs_ioc_write_checkpoint(filp, arg); |
1868 | case F2FS_IOC_DEFRAGMENT: | ||
1869 | return f2fs_ioc_defragment(filp, arg); | ||
1682 | default: | 1870 | default: |
1683 | return -ENOTTY; | 1871 | return -ENOTTY; |
1684 | } | 1872 | } |
@@ -1706,6 +1894,22 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1706 | case F2FS_IOC32_SETFLAGS: | 1894 | case F2FS_IOC32_SETFLAGS: |
1707 | cmd = F2FS_IOC_SETFLAGS; | 1895 | cmd = F2FS_IOC_SETFLAGS; |
1708 | break; | 1896 | break; |
1897 | case F2FS_IOC32_GETVERSION: | ||
1898 | cmd = F2FS_IOC_GETVERSION; | ||
1899 | break; | ||
1900 | case F2FS_IOC_START_ATOMIC_WRITE: | ||
1901 | case F2FS_IOC_COMMIT_ATOMIC_WRITE: | ||
1902 | case F2FS_IOC_START_VOLATILE_WRITE: | ||
1903 | case F2FS_IOC_RELEASE_VOLATILE_WRITE: | ||
1904 | case F2FS_IOC_ABORT_VOLATILE_WRITE: | ||
1905 | case F2FS_IOC_SHUTDOWN: | ||
1906 | case F2FS_IOC_SET_ENCRYPTION_POLICY: | ||
1907 | case F2FS_IOC_GET_ENCRYPTION_PWSALT: | ||
1908 | case F2FS_IOC_GET_ENCRYPTION_POLICY: | ||
1909 | case F2FS_IOC_GARBAGE_COLLECT: | ||
1910 | case F2FS_IOC_WRITE_CHECKPOINT: | ||
1911 | case F2FS_IOC_DEFRAGMENT: | ||
1912 | break; | ||
1709 | default: | 1913 | default: |
1710 | return -ENOIOCTLCMD; | 1914 | return -ENOIOCTLCMD; |
1711 | } | 1915 | } |