aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-03-31 00:49:18 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-04-03 04:27:50 -0400
commit4ebefc4443898f5429185ef96d85cfce0fbcc16a (patch)
tree849b232653ff2253853f97a253eca94cf8d403f8 /fs/f2fs
parent5ec4e49f9bd753e2a6857a96e01f8ae5ff00b459 (diff)
f2fs: check completion of foreground GC
The foreground GCs are triggered under not enough free sections. So, we should not skip moving valid blocks in the victim segments. Reviewed-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/gc.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 09b8a907400b..136c0f7a670b 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -131,7 +131,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
131{ 131{
132 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 132 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
133 133
134 if (p->alloc_mode) { 134 if (p->alloc_mode == SSR) {
135 p->gc_mode = GC_GREEDY; 135 p->gc_mode = GC_GREEDY;
136 p->dirty_segmap = dirty_i->dirty_segmap[type]; 136 p->dirty_segmap = dirty_i->dirty_segmap[type];
137 p->ofs_unit = 1; 137 p->ofs_unit = 1;
@@ -404,8 +404,14 @@ next_step:
404 continue; 404 continue;
405 405
406 /* set page dirty and write it */ 406 /* set page dirty and write it */
407 if (!PageWriteback(node_page)) 407 if (gc_type == FG_GC) {
408 f2fs_submit_bio(sbi, NODE, true);
409 wait_on_page_writeback(node_page);
408 set_page_dirty(node_page); 410 set_page_dirty(node_page);
411 } else {
412 if (!PageWriteback(node_page))
413 set_page_dirty(node_page);
414 }
409 f2fs_put_page(node_page, 1); 415 f2fs_put_page(node_page, 1);
410 stat_inc_node_blk_count(sbi, 1); 416 stat_inc_node_blk_count(sbi, 1);
411 } 417 }
@@ -421,6 +427,13 @@ next_step:
421 .for_reclaim = 0, 427 .for_reclaim = 0,
422 }; 428 };
423 sync_node_pages(sbi, 0, &wbc); 429 sync_node_pages(sbi, 0, &wbc);
430
431 /*
432 * In the case of FG_GC, it'd be better to reclaim this victim
433 * completely.
434 */
435 if (get_valid_blocks(sbi, segno, 1) != 0)
436 goto next_step;
424 } 437 }
425} 438}
426 439
@@ -484,20 +497,19 @@ static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
484 497
485static void move_data_page(struct inode *inode, struct page *page, int gc_type) 498static void move_data_page(struct inode *inode, struct page *page, int gc_type)
486{ 499{
487 if (page->mapping != inode->i_mapping)
488 goto out;
489
490 if (inode != page->mapping->host)
491 goto out;
492
493 if (PageWriteback(page))
494 goto out;
495
496 if (gc_type == BG_GC) { 500 if (gc_type == BG_GC) {
501 if (PageWriteback(page))
502 goto out;
497 set_page_dirty(page); 503 set_page_dirty(page);
498 set_cold_data(page); 504 set_cold_data(page);
499 } else { 505 } else {
500 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 506 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
507
508 if (PageWriteback(page)) {
509 f2fs_submit_bio(sbi, DATA, true);
510 wait_on_page_writeback(page);
511 }
512
501 mutex_lock_op(sbi, DATA_WRITE); 513 mutex_lock_op(sbi, DATA_WRITE);
502 if (clear_page_dirty_for_io(page) && 514 if (clear_page_dirty_for_io(page) &&
503 S_ISDIR(inode->i_mode)) { 515 S_ISDIR(inode->i_mode)) {
@@ -594,8 +606,18 @@ next_iput:
594 if (++phase < 4) 606 if (++phase < 4)
595 goto next_step; 607 goto next_step;
596 608
597 if (gc_type == FG_GC) 609 if (gc_type == FG_GC) {
598 f2fs_submit_bio(sbi, DATA, true); 610 f2fs_submit_bio(sbi, DATA, true);
611
612 /*
613 * In the case of FG_GC, it'd be better to reclaim this victim
614 * completely.
615 */
616 if (get_valid_blocks(sbi, segno, 1) != 0) {
617 phase = 2;
618 goto next_step;
619 }
620 }
599} 621}
600 622
601static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, 623static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim,