aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/gc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-25 15:34:27 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-25 15:34:27 -0500
commit74790147fb4e9b71083a62a525ab283a275d63b7 (patch)
tree2805293e7f1806ce2fd804255f868ab94edeae88 /fs/f2fs/gc.c
parentf6dcf8e747a0723ace5275334bacfcd88ab39333 (diff)
parent949db153b6466c6f7cad5a427ecea94985927311 (diff)
Merge 3.8-rc5 into char-misc-next
This pulls in all of the 3.8-rc5 fixes into this branch so we can test easier. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/f2fs/gc.c')
-rw-r--r--fs/f2fs/gc.c68
1 files changed, 27 insertions, 41 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index b0ec721e984a..c386910dacc5 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -78,7 +78,7 @@ static int gc_thread_func(void *data)
78 78
79 sbi->bg_gc++; 79 sbi->bg_gc++;
80 80
81 if (f2fs_gc(sbi, 1) == GC_NONE) 81 if (f2fs_gc(sbi) == GC_NONE)
82 wait_ms = GC_THREAD_NOGC_SLEEP_TIME; 82 wait_ms = GC_THREAD_NOGC_SLEEP_TIME;
83 else if (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; 84 wait_ms = GC_THREAD_MAX_SLEEP_TIME;
@@ -424,7 +424,11 @@ next_step:
424} 424}
425 425
426/* 426/*
427 * Calculate start block index that this node page contains 427 * Calculate start block index indicating the given node offset.
428 * Be careful, caller should give this node offset only indicating direct node
429 * blocks. If any node offsets, which point the other types of node blocks such
430 * as indirect or double indirect node blocks, are given, it must be a caller's
431 * bug.
428 */ 432 */
429block_t start_bidx_of_node(unsigned int node_ofs) 433block_t start_bidx_of_node(unsigned int node_ofs)
430{ 434{
@@ -651,62 +655,44 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno,
651 return ret; 655 return ret;
652} 656}
653 657
654int f2fs_gc(struct f2fs_sb_info *sbi, int nGC) 658int f2fs_gc(struct f2fs_sb_info *sbi)
655{ 659{
656 unsigned int segno;
657 int old_free_secs, cur_free_secs;
658 int gc_status, nfree;
659 struct list_head ilist; 660 struct list_head ilist;
661 unsigned int segno, i;
660 int gc_type = BG_GC; 662 int gc_type = BG_GC;
663 int gc_status = GC_NONE;
661 664
662 INIT_LIST_HEAD(&ilist); 665 INIT_LIST_HEAD(&ilist);
663gc_more: 666gc_more:
664 nfree = 0; 667 if (!(sbi->sb->s_flags & MS_ACTIVE))
665 gc_status = GC_NONE; 668 goto stop;
666 669
667 if (has_not_enough_free_secs(sbi)) 670 if (has_not_enough_free_secs(sbi))
668 old_free_secs = reserved_sections(sbi); 671 gc_type = FG_GC;
669 else
670 old_free_secs = free_sections(sbi);
671
672 while (sbi->sb->s_flags & MS_ACTIVE) {
673 int i;
674 if (has_not_enough_free_secs(sbi))
675 gc_type = FG_GC;
676 672
677 cur_free_secs = free_sections(sbi) + nfree; 673 if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE))
674 goto stop;
678 675
679 /* We got free space successfully. */ 676 for (i = 0; i < sbi->segs_per_sec; i++) {
680 if (nGC < cur_free_secs - old_free_secs) 677 /*
681 break; 678 * do_garbage_collect will give us three gc_status:
682 679 * GC_ERROR, GC_DONE, and GC_BLOCKED.
683 if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) 680 * If GC is finished uncleanly, we have to return
681 * the victim to dirty segment list.
682 */
683 gc_status = do_garbage_collect(sbi, segno + i, &ilist, gc_type);
684 if (gc_status != GC_DONE)
684 break; 685 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 } 686 }
700stop: 687 if (has_not_enough_free_secs(sbi)) {
701 if (has_not_enough_free_secs(sbi) || gc_status == GC_BLOCKED) {
702 write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); 688 write_checkpoint(sbi, (gc_status == GC_BLOCKED), false);
703 if (nfree) 689 if (has_not_enough_free_secs(sbi))
704 goto gc_more; 690 goto gc_more;
705 } 691 }
692stop:
706 mutex_unlock(&sbi->gc_mutex); 693 mutex_unlock(&sbi->gc_mutex);
707 694
708 put_gc_inode(&ilist); 695 put_gc_inode(&ilist);
709 BUG_ON(!list_empty(&ilist));
710 return gc_status; 696 return gc_status;
711} 697}
712 698
@@ -715,7 +701,7 @@ void build_gc_manager(struct f2fs_sb_info *sbi)
715 DIRTY_I(sbi)->v_ops = &default_v_ops; 701 DIRTY_I(sbi)->v_ops = &default_v_ops;
716} 702}
717 703
718int create_gc_caches(void) 704int __init create_gc_caches(void)
719{ 705{
720 winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", 706 winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes",
721 sizeof(struct inode_entry), NULL); 707 sizeof(struct inode_entry), NULL);