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 ---