segment.c (29583dfcd2dd72c766422bd05c16f06c6b1fb356) | segment.c (41e8f85a75fc60e1543e4903428a1b481b672a17) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/f2fs/segment.c 4 * 5 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 6 * http://www.samsung.com/ 7 */ 8#include <linux/fs.h> --- 178 unchanged lines hidden (view full) --- 187 188void f2fs_abort_atomic_write(struct inode *inode, bool clean) 189{ 190 struct f2fs_inode_info *fi = F2FS_I(inode); 191 192 if (!f2fs_is_atomic_file(inode)) 193 return; 194 | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/f2fs/segment.c 4 * 5 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 6 * http://www.samsung.com/ 7 */ 8#include <linux/fs.h> --- 178 unchanged lines hidden (view full) --- 187 188void f2fs_abort_atomic_write(struct inode *inode, bool clean) 189{ 190 struct f2fs_inode_info *fi = F2FS_I(inode); 191 192 if (!f2fs_is_atomic_file(inode)) 193 return; 194 |
195 if (clean) 196 truncate_inode_pages_final(inode->i_mapping); | |
197 clear_inode_flag(fi->cow_inode, FI_COW_FILE); 198 iput(fi->cow_inode); 199 fi->cow_inode = NULL; 200 release_atomic_write_cnt(inode); | 195 clear_inode_flag(fi->cow_inode, FI_COW_FILE); 196 iput(fi->cow_inode); 197 fi->cow_inode = NULL; 198 release_atomic_write_cnt(inode); |
199 clear_inode_flag(inode, FI_ATOMIC_COMMITTED); 200 clear_inode_flag(inode, FI_ATOMIC_REPLACE); |
|
201 clear_inode_flag(inode, FI_ATOMIC_FILE); 202 stat_dec_atomic_inode(inode); | 201 clear_inode_flag(inode, FI_ATOMIC_FILE); 202 stat_dec_atomic_inode(inode); |
203 204 if (clean) { 205 truncate_inode_pages_final(inode->i_mapping); 206 f2fs_i_size_write(inode, fi->original_i_size); 207 } |
|
203} 204 205static int __replace_atomic_write_block(struct inode *inode, pgoff_t index, 206 block_t new_addr, block_t *old_addr, bool recover) 207{ 208 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 209 struct dnode_of_data dn; 210 struct node_info ni; --- 41 unchanged lines hidden (view full) --- 252 f2fs_put_dnode(&dn); 253 return 0; 254} 255 256static void __complete_revoke_list(struct inode *inode, struct list_head *head, 257 bool revoke) 258{ 259 struct revoke_entry *cur, *tmp; | 208} 209 210static int __replace_atomic_write_block(struct inode *inode, pgoff_t index, 211 block_t new_addr, block_t *old_addr, bool recover) 212{ 213 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 214 struct dnode_of_data dn; 215 struct node_info ni; --- 41 unchanged lines hidden (view full) --- 257 f2fs_put_dnode(&dn); 258 return 0; 259} 260 261static void __complete_revoke_list(struct inode *inode, struct list_head *head, 262 bool revoke) 263{ 264 struct revoke_entry *cur, *tmp; |
265 pgoff_t start_index = 0; 266 bool truncate = is_inode_flag_set(inode, FI_ATOMIC_REPLACE); |
|
260 261 list_for_each_entry_safe(cur, tmp, head, list) { | 267 268 list_for_each_entry_safe(cur, tmp, head, list) { |
262 if (revoke) | 269 if (revoke) { |
263 __replace_atomic_write_block(inode, cur->index, 264 cur->old_addr, NULL, true); | 270 __replace_atomic_write_block(inode, cur->index, 271 cur->old_addr, NULL, true); |
272 } else if (truncate) { 273 f2fs_truncate_hole(inode, start_index, cur->index); 274 start_index = cur->index + 1; 275 } 276 |
|
265 list_del(&cur->list); 266 kmem_cache_free(revoke_entry_slab, cur); 267 } | 277 list_del(&cur->list); 278 kmem_cache_free(revoke_entry_slab, cur); 279 } |
280 281 if (!revoke && truncate) 282 f2fs_do_truncate_blocks(inode, start_index * PAGE_SIZE, false); |
|
268} 269 270static int __f2fs_commit_atomic_write(struct inode *inode) 271{ 272 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 273 struct f2fs_inode_info *fi = F2FS_I(inode); 274 struct inode *cow_inode = fi->cow_inode; 275 struct revoke_entry *new; --- 54 unchanged lines hidden (view full) --- 330 } 331 f2fs_put_dnode(&dn); 332next: 333 off += blen; 334 len -= blen; 335 } 336 337out: | 283} 284 285static int __f2fs_commit_atomic_write(struct inode *inode) 286{ 287 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 288 struct f2fs_inode_info *fi = F2FS_I(inode); 289 struct inode *cow_inode = fi->cow_inode; 290 struct revoke_entry *new; --- 54 unchanged lines hidden (view full) --- 345 } 346 f2fs_put_dnode(&dn); 347next: 348 off += blen; 349 len -= blen; 350 } 351 352out: |
338 if (ret) | 353 if (ret) { |
339 sbi->revoked_atomic_block += fi->atomic_write_cnt; | 354 sbi->revoked_atomic_block += fi->atomic_write_cnt; |
340 else | 355 } else { |
341 sbi->committed_atomic_block += fi->atomic_write_cnt; | 356 sbi->committed_atomic_block += fi->atomic_write_cnt; |
357 set_inode_flag(inode, FI_ATOMIC_COMMITTED); 358 } |
|
342 343 __complete_revoke_list(inode, &revoke_list, ret ? true : false); 344 345 return ret; 346} 347 348int f2fs_commit_atomic_write(struct inode *inode) 349{ --- 265 unchanged lines hidden (view full) --- 615 616 return cmd.ret; 617} 618 619int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi) 620{ 621 dev_t dev = sbi->sb->s_bdev->bd_dev; 622 struct flush_cmd_control *fcc; | 359 360 __complete_revoke_list(inode, &revoke_list, ret ? true : false); 361 362 return ret; 363} 364 365int f2fs_commit_atomic_write(struct inode *inode) 366{ --- 265 unchanged lines hidden (view full) --- 632 633 return cmd.ret; 634} 635 636int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi) 637{ 638 dev_t dev = sbi->sb->s_bdev->bd_dev; 639 struct flush_cmd_control *fcc; |
623 int err = 0; | |
624 625 if (SM_I(sbi)->fcc_info) { 626 fcc = SM_I(sbi)->fcc_info; 627 if (fcc->f2fs_issue_flush) | 640 641 if (SM_I(sbi)->fcc_info) { 642 fcc = SM_I(sbi)->fcc_info; 643 if (fcc->f2fs_issue_flush) |
628 return err; | 644 return 0; |
629 goto init_thread; 630 } 631 632 fcc = f2fs_kzalloc(sbi, sizeof(struct flush_cmd_control), GFP_KERNEL); 633 if (!fcc) 634 return -ENOMEM; 635 atomic_set(&fcc->issued_flush, 0); 636 atomic_set(&fcc->queued_flush, 0); 637 init_waitqueue_head(&fcc->flush_wait_queue); 638 init_llist_head(&fcc->issue_list); 639 SM_I(sbi)->fcc_info = fcc; 640 if (!test_opt(sbi, FLUSH_MERGE)) | 645 goto init_thread; 646 } 647 648 fcc = f2fs_kzalloc(sbi, sizeof(struct flush_cmd_control), GFP_KERNEL); 649 if (!fcc) 650 return -ENOMEM; 651 atomic_set(&fcc->issued_flush, 0); 652 atomic_set(&fcc->queued_flush, 0); 653 init_waitqueue_head(&fcc->flush_wait_queue); 654 init_llist_head(&fcc->issue_list); 655 SM_I(sbi)->fcc_info = fcc; 656 if (!test_opt(sbi, FLUSH_MERGE)) |
641 return err; | 657 return 0; |
642 643init_thread: 644 fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, 645 "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); 646 if (IS_ERR(fcc->f2fs_issue_flush)) { | 658 659init_thread: 660 fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, 661 "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); 662 if (IS_ERR(fcc->f2fs_issue_flush)) { |
647 err = PTR_ERR(fcc->f2fs_issue_flush); | 663 int err = PTR_ERR(fcc->f2fs_issue_flush); 664 |
648 kfree(fcc); 649 SM_I(sbi)->fcc_info = NULL; 650 return err; 651 } 652 | 665 kfree(fcc); 666 SM_I(sbi)->fcc_info = NULL; 667 return err; 668 } 669 |
653 return err; | 670 return 0; |
654} 655 656void f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free) 657{ 658 struct flush_cmd_control *fcc = SM_I(sbi)->fcc_info; 659 660 if (fcc && fcc->f2fs_issue_flush) { 661 struct task_struct *flush_thread = fcc->f2fs_issue_flush; --- 189 unchanged lines hidden (view full) --- 851 holes[NODE] += f2fs_usable_blks_in_seg(sbi, segno) - 852 se->valid_blocks; 853 else 854 holes[DATA] += f2fs_usable_blks_in_seg(sbi, segno) - 855 se->valid_blocks; 856 } 857 mutex_unlock(&dirty_i->seglist_lock); 858 | 671} 672 673void f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free) 674{ 675 struct flush_cmd_control *fcc = SM_I(sbi)->fcc_info; 676 677 if (fcc && fcc->f2fs_issue_flush) { 678 struct task_struct *flush_thread = fcc->f2fs_issue_flush; --- 189 unchanged lines hidden (view full) --- 868 holes[NODE] += f2fs_usable_blks_in_seg(sbi, segno) - 869 se->valid_blocks; 870 else 871 holes[DATA] += f2fs_usable_blks_in_seg(sbi, segno) - 872 se->valid_blocks; 873 } 874 mutex_unlock(&dirty_i->seglist_lock); 875 |
859 unusable = holes[DATA] > holes[NODE] ? holes[DATA] : holes[NODE]; | 876 unusable = max(holes[DATA], holes[NODE]); |
860 if (unusable > ovp_holes) 861 return unusable - ovp_holes; 862 return 0; 863} 864 865int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable) 866{ 867 int ovp_hole_segs = --- 575 unchanged lines hidden (view full) --- 1443 for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { 1444 if (dpolicy->timeout && 1445 f2fs_time_over(sbi, UMOUNT_DISCARD_TIMEOUT)) 1446 break; 1447 1448 if (i + 1 < dpolicy->granularity) 1449 break; 1450 | 877 if (unusable > ovp_holes) 878 return unusable - ovp_holes; 879 return 0; 880} 881 882int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable) 883{ 884 int ovp_hole_segs = --- 575 unchanged lines hidden (view full) --- 1460 for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { 1461 if (dpolicy->timeout && 1462 f2fs_time_over(sbi, UMOUNT_DISCARD_TIMEOUT)) 1463 break; 1464 1465 if (i + 1 < dpolicy->granularity) 1466 break; 1467 |
1451 if (i < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered) | 1468 if (i + 1 < dcc->max_ordered_discard && dpolicy->ordered) |
1452 return __issue_discard_cmd_orderly(sbi, dpolicy); 1453 1454 pend_list = &dcc->pend_list[i]; 1455 1456 mutex_lock(&dcc->cmd_lock); 1457 if (list_empty(pend_list)) 1458 goto next; 1459 if (unlikely(dcc->rbtree_check)) --- 560 unchanged lines hidden (view full) --- 2020 struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; 2021 int err = 0; 2022 2023 if (!f2fs_realtime_discard_enable(sbi)) 2024 return 0; 2025 2026 dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi, 2027 "f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev)); | 1469 return __issue_discard_cmd_orderly(sbi, dpolicy); 1470 1471 pend_list = &dcc->pend_list[i]; 1472 1473 mutex_lock(&dcc->cmd_lock); 1474 if (list_empty(pend_list)) 1475 goto next; 1476 if (unlikely(dcc->rbtree_check)) --- 560 unchanged lines hidden (view full) --- 2037 struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; 2038 int err = 0; 2039 2040 if (!f2fs_realtime_discard_enable(sbi)) 2041 return 0; 2042 2043 dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi, 2044 "f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev)); |
2028 if (IS_ERR(dcc->f2fs_issue_discard)) | 2045 if (IS_ERR(dcc->f2fs_issue_discard)) { |
2029 err = PTR_ERR(dcc->f2fs_issue_discard); | 2046 err = PTR_ERR(dcc->f2fs_issue_discard); |
2047 dcc->f2fs_issue_discard = NULL; 2048 } |
|
2030 2031 return err; 2032} 2033 2034static int create_discard_cmd_control(struct f2fs_sb_info *sbi) 2035{ 2036 struct discard_cmd_control *dcc; 2037 int err = 0, i; 2038 2039 if (SM_I(sbi)->dcc_info) { 2040 dcc = SM_I(sbi)->dcc_info; 2041 goto init_thread; 2042 } 2043 2044 dcc = f2fs_kzalloc(sbi, sizeof(struct discard_cmd_control), GFP_KERNEL); 2045 if (!dcc) 2046 return -ENOMEM; 2047 2048 dcc->discard_granularity = DEFAULT_DISCARD_GRANULARITY; | 2049 2050 return err; 2051} 2052 2053static int create_discard_cmd_control(struct f2fs_sb_info *sbi) 2054{ 2055 struct discard_cmd_control *dcc; 2056 int err = 0, i; 2057 2058 if (SM_I(sbi)->dcc_info) { 2059 dcc = SM_I(sbi)->dcc_info; 2060 goto init_thread; 2061 } 2062 2063 dcc = f2fs_kzalloc(sbi, sizeof(struct discard_cmd_control), GFP_KERNEL); 2064 if (!dcc) 2065 return -ENOMEM; 2066 2067 dcc->discard_granularity = DEFAULT_DISCARD_GRANULARITY; |
2068 dcc->max_ordered_discard = DEFAULT_MAX_ORDERED_DISCARD_GRANULARITY; |
|
2049 if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SEGMENT) 2050 dcc->discard_granularity = sbi->blocks_per_seg; 2051 else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION) 2052 dcc->discard_granularity = BLKS_PER_SEC(sbi); 2053 2054 INIT_LIST_HEAD(&dcc->entry_list); 2055 for (i = 0; i < MAX_PLIST_NUM; i++) 2056 INIT_LIST_HEAD(&dcc->pend_list[i]); --- 3232 unchanged lines hidden --- | 2069 if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SEGMENT) 2070 dcc->discard_granularity = sbi->blocks_per_seg; 2071 else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION) 2072 dcc->discard_granularity = BLKS_PER_SEC(sbi); 2073 2074 INIT_LIST_HEAD(&dcc->entry_list); 2075 for (i = 0; i < MAX_PLIST_NUM; i++) 2076 INIT_LIST_HEAD(&dcc->pend_list[i]); --- 3232 unchanged lines hidden --- |