gc.c (ad2e6329666650d9cafcae9ef53fbe09ea759ae2) | gc.c (6e6093a8f144414d904575da5fdea40cf14fb63e) |
---|---|
1/* 2 * fs/f2fs/gc.c 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 64 unchanged lines hidden (view full) --- 73 74 if (has_enough_invalid_blocks(sbi)) 75 wait_ms = decrease_sleep_time(wait_ms); 76 else 77 wait_ms = increase_sleep_time(wait_ms); 78 79 sbi->bg_gc++; 80 | 1/* 2 * fs/f2fs/gc.c 3 * 4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 64 unchanged lines hidden (view full) --- 73 74 if (has_enough_invalid_blocks(sbi)) 75 wait_ms = decrease_sleep_time(wait_ms); 76 else 77 wait_ms = increase_sleep_time(wait_ms); 78 79 sbi->bg_gc++; 80 |
81 if (f2fs_gc(sbi, 1) == GC_NONE) | 81 if (f2fs_gc(sbi) == GC_NONE) |
82 wait_ms = GC_THREAD_NOGC_SLEEP_TIME; 83 else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) 84 wait_ms = GC_THREAD_MAX_SLEEP_TIME; 85 86 } while (!kthread_should_stop()); 87 return 0; 88} 89 --- 556 unchanged lines hidden (view full) --- 646 } 647 stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer))); 648 stat_inc_call_count(sbi->stat_info); 649 650 f2fs_put_page(sum_page, 0); 651 return ret; 652} 653 | 82 wait_ms = GC_THREAD_NOGC_SLEEP_TIME; 83 else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) 84 wait_ms = GC_THREAD_MAX_SLEEP_TIME; 85 86 } while (!kthread_should_stop()); 87 return 0; 88} 89 --- 556 unchanged lines hidden (view full) --- 646 } 647 stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer))); 648 stat_inc_call_count(sbi->stat_info); 649 650 f2fs_put_page(sum_page, 0); 651 return ret; 652} 653 |
654int f2fs_gc(struct f2fs_sb_info *sbi, int nGC) | 654int f2fs_gc(struct f2fs_sb_info *sbi) |
655{ | 655{ |
656 unsigned int segno; 657 int old_free_secs, cur_free_secs; 658 int gc_status, nfree; | |
659 struct list_head ilist; | 656 struct list_head ilist; |
657 unsigned int segno, i; |
|
660 int gc_type = BG_GC; | 658 int gc_type = BG_GC; |
659 int gc_status = GC_NONE; |
|
661 662 INIT_LIST_HEAD(&ilist); 663gc_more: | 660 661 INIT_LIST_HEAD(&ilist); 662gc_more: |
664 nfree = 0; 665 gc_status = GC_NONE; | 663 if (!(sbi->sb->s_flags & MS_ACTIVE)) 664 goto stop; |
666 667 if (has_not_enough_free_secs(sbi)) | 665 666 if (has_not_enough_free_secs(sbi)) |
668 old_free_secs = reserved_sections(sbi); 669 else 670 old_free_secs = free_sections(sbi); | 667 gc_type = FG_GC; |
671 | 668 |
672 while (sbi->sb->s_flags & MS_ACTIVE) { 673 int i; 674 if (has_not_enough_free_secs(sbi)) 675 gc_type = FG_GC; | 669 if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) 670 goto stop; |
676 | 671 |
677 cur_free_secs = free_sections(sbi) + nfree; 678 679 /* We got free space successfully. */ 680 if (nGC < cur_free_secs - old_free_secs) | 672 for (i = 0; i < sbi->segs_per_sec; i++) { 673 /* 674 * do_garbage_collect will give us three gc_status: 675 * GC_ERROR, GC_DONE, and GC_BLOCKED. 676 * If GC is finished uncleanly, we have to return 677 * the victim to dirty segment list. 678 */ 679 gc_status = do_garbage_collect(sbi, segno + i, &ilist, gc_type); 680 if (gc_status != GC_DONE) |
681 break; | 681 break; |
682 683 if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) 684 break; 685 686 for (i = 0; i < sbi->segs_per_sec; i++) { 687 /* 688 * do_garbage_collect will give us three gc_status: 689 * GC_ERROR, GC_DONE, and GC_BLOCKED. 690 * If GC is finished uncleanly, we have to return 691 * the victim to dirty segment list. 692 */ 693 gc_status = do_garbage_collect(sbi, segno + i, 694 &ilist, gc_type); 695 if (gc_status != GC_DONE) 696 goto stop; 697 nfree++; 698 } | |
699 } | 682 } |
700stop: 701 if (has_not_enough_free_secs(sbi) || gc_status == GC_BLOCKED) { | 683 if (has_not_enough_free_secs(sbi)) { |
702 write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); | 684 write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); |
703 if (nfree) | 685 if (has_not_enough_free_secs(sbi)) |
704 goto gc_more; 705 } | 686 goto gc_more; 687 } |
688stop: |
|
706 mutex_unlock(&sbi->gc_mutex); 707 708 put_gc_inode(&ilist); | 689 mutex_unlock(&sbi->gc_mutex); 690 691 put_gc_inode(&ilist); |
709 BUG_ON(!list_empty(&ilist)); | |
710 return gc_status; 711} 712 713void build_gc_manager(struct f2fs_sb_info *sbi) 714{ 715 DIRTY_I(sbi)->v_ops = &default_v_ops; 716} 717 | 692 return gc_status; 693} 694 695void build_gc_manager(struct f2fs_sb_info *sbi) 696{ 697 DIRTY_I(sbi)->v_ops = &default_v_ops; 698} 699 |
718int create_gc_caches(void) | 700int __init create_gc_caches(void) |
719{ 720 winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", 721 sizeof(struct inode_entry), NULL); 722 if (!winode_slab) 723 return -ENOMEM; 724 return 0; 725} 726 727void destroy_gc_caches(void) 728{ 729 kmem_cache_destroy(winode_slab); 730} | 701{ 702 winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", 703 sizeof(struct inode_entry), NULL); 704 if (!winode_slab) 705 return -ENOMEM; 706 return 0; 707} 708 709void destroy_gc_caches(void) 710{ 711 kmem_cache_destroy(winode_slab); 712} |