aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-02-04 23:03:57 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-02-17 00:58:53 -0500
commit203681f65b07055259bd475a6281136615b4e9a4 (patch)
tree81d75a7d692542c64f5bc7d724d0ebe51b98d382
parentbd859c6598dd2b73c517b3a36ecc5dd387eb1eb2 (diff)
f2fs: fix f2fs_write_meta_page at no checkpoint status
If f2fs entered errorneous checkpoint status, it should skip writing meta pages instead of redirtying the pages out. Otherwise, it cannot unmount the partition even though f2fs is under read-only status. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/checkpoint.c29
-rw-r--r--fs/f2fs/gc.c2
2 files changed, 23 insertions, 8 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 293d0486a40f..8f5dff1989a8 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -81,17 +81,18 @@ static int f2fs_write_meta_page(struct page *page,
81 struct inode *inode = page->mapping->host; 81 struct inode *inode = page->mapping->host;
82 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 82 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
83 83
84 /* Should not write any meta pages, if any IO error was occurred */ 84 if (unlikely(sbi->por_doing))
85 if (unlikely(sbi->por_doing ||
86 is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
87 goto redirty_out; 85 goto redirty_out;
88
89 if (wbc->for_reclaim) 86 if (wbc->for_reclaim)
90 goto redirty_out; 87 goto redirty_out;
91 88
92 wait_on_page_writeback(page); 89 /* Should not write any meta pages, if any IO error was occurred */
90 if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
91 goto no_write;
93 92
93 wait_on_page_writeback(page);
94 write_meta_page(sbi, page); 94 write_meta_page(sbi, page);
95no_write:
95 dec_page_count(sbi, F2FS_DIRTY_META); 96 dec_page_count(sbi, F2FS_DIRTY_META);
96 unlock_page(page); 97 unlock_page(page);
97 return 0; 98 return 0;
@@ -148,10 +149,22 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
148 149
149 for (i = 0; i < nr_pages; i++) { 150 for (i = 0; i < nr_pages; i++) {
150 struct page *page = pvec.pages[i]; 151 struct page *page = pvec.pages[i];
152
151 lock_page(page); 153 lock_page(page);
152 f2fs_bug_on(page->mapping != mapping); 154
153 f2fs_bug_on(!PageDirty(page)); 155 if (unlikely(page->mapping != mapping)) {
154 clear_page_dirty_for_io(page); 156continue_unlock:
157 unlock_page(page);
158 continue;
159 }
160 if (!PageDirty(page)) {
161 /* someone wrote it for us */
162 goto continue_unlock;
163 }
164
165 if (!clear_page_dirty_for_io(page))
166 goto continue_unlock;
167
155 if (f2fs_write_meta_page(page, &wbc)) { 168 if (f2fs_write_meta_page(page, &wbc)) {
156 unlock_page(page); 169 unlock_page(page);
157 break; 170 break;
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index ea0371e854b4..b0f57628fe55 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -701,6 +701,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
701gc_more: 701gc_more:
702 if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) 702 if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE)))
703 goto stop; 703 goto stop;
704 if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
705 goto stop;
704 706
705 if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) { 707 if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) {
706 gc_type = FG_GC; 708 gc_type = FG_GC;