diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-03-31 00:49:18 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-04-03 04:27:50 -0400 |
commit | 4ebefc4443898f5429185ef96d85cfce0fbcc16a (patch) | |
tree | 849b232653ff2253853f97a253eca94cf8d403f8 /fs/f2fs | |
parent | 5ec4e49f9bd753e2a6857a96e01f8ae5ff00b459 (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.c | 46 |
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 | ||
485 | static void move_data_page(struct inode *inode, struct page *page, int gc_type) | 498 | static 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 | ||
601 | static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, | 623 | static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, |