aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/f2fs/checkpoint.c36
-rw-r--r--fs/f2fs/f2fs.h3
-rw-r--r--fs/f2fs/segment.c8
-rw-r--r--fs/f2fs/super.c12
4 files changed, 31 insertions, 28 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index ff3c8439af87..9c1627165039 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -72,22 +72,22 @@ static int f2fs_write_meta_page(struct page *page,
72{ 72{
73 struct inode *inode = page->mapping->host; 73 struct inode *inode = page->mapping->host;
74 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 74 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
75 int err;
76 75
77 wait_on_page_writeback(page); 76 /* Should not write any meta pages, if any IO error was occurred */
78 77 if (wbc->for_reclaim ||
79 err = write_meta_page(sbi, page, wbc); 78 is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)) {
80 if (err) { 79 dec_page_count(sbi, F2FS_DIRTY_META);
81 wbc->pages_skipped++; 80 wbc->pages_skipped++;
82 set_page_dirty(page); 81 set_page_dirty(page);
82 return AOP_WRITEPAGE_ACTIVATE;
83 } 83 }
84 84
85 dec_page_count(sbi, F2FS_DIRTY_META); 85 wait_on_page_writeback(page);
86 86
87 /* In this case, we should not unlock this page */ 87 write_meta_page(sbi, page);
88 if (err != AOP_WRITEPAGE_ACTIVATE) 88 dec_page_count(sbi, F2FS_DIRTY_META);
89 unlock_page(page); 89 unlock_page(page);
90 return err; 90 return 0;
91} 91}
92 92
93static int f2fs_write_meta_pages(struct address_space *mapping, 93static int f2fs_write_meta_pages(struct address_space *mapping,
@@ -138,7 +138,10 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
138 BUG_ON(page->mapping != mapping); 138 BUG_ON(page->mapping != mapping);
139 BUG_ON(!PageDirty(page)); 139 BUG_ON(!PageDirty(page));
140 clear_page_dirty_for_io(page); 140 clear_page_dirty_for_io(page);
141 f2fs_write_meta_page(page, &wbc); 141 if (f2fs_write_meta_page(page, &wbc)) {
142 unlock_page(page);
143 break;
144 }
142 if (nwritten++ >= nr_to_write) 145 if (nwritten++ >= nr_to_write)
143 break; 146 break;
144 } 147 }
@@ -717,13 +720,12 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
717 sbi->alloc_valid_block_count = 0; 720 sbi->alloc_valid_block_count = 0;
718 721
719 /* Here, we only have one bio having CP pack */ 722 /* Here, we only have one bio having CP pack */
720 if (is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) 723 sync_meta_pages(sbi, META_FLUSH, LONG_MAX);
721 sbi->sb->s_flags |= MS_RDONLY;
722 else
723 sync_meta_pages(sbi, META_FLUSH, LONG_MAX);
724 724
725 clear_prefree_segments(sbi); 725 if (!is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) {
726 F2FS_RESET_SB_DIRT(sbi); 726 clear_prefree_segments(sbi);
727 F2FS_RESET_SB_DIRT(sbi);
728 }
727} 729}
728 730
729/* 731/*
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index c8e2d751ef9c..f4f509766465 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -929,8 +929,7 @@ void allocate_new_segments(struct f2fs_sb_info *);
929struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); 929struct page *get_sum_page(struct f2fs_sb_info *, unsigned int);
930struct bio *f2fs_bio_alloc(struct block_device *, int); 930struct bio *f2fs_bio_alloc(struct block_device *, int);
931void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync); 931void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync);
932int write_meta_page(struct f2fs_sb_info *, struct page *, 932void write_meta_page(struct f2fs_sb_info *, struct page *);
933 struct writeback_control *);
934void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int, 933void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int,
935 block_t, block_t *); 934 block_t, block_t *);
936void write_data_page(struct inode *, struct page *, struct dnode_of_data*, 935void write_data_page(struct inode *, struct page *, struct dnode_of_data*,
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4b0099066582..7aa270f3538a 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -600,6 +600,7 @@ static void f2fs_end_io_write(struct bio *bio, int err)
600 if (page->mapping) 600 if (page->mapping)
601 set_bit(AS_EIO, &page->mapping->flags); 601 set_bit(AS_EIO, &page->mapping->flags);
602 set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); 602 set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG);
603 p->sbi->sb->s_flags |= MS_RDONLY;
603 } 604 }
604 end_page_writeback(page); 605 end_page_writeback(page);
605 dec_page_count(p->sbi, F2FS_WRITEBACK); 606 dec_page_count(p->sbi, F2FS_WRITEBACK);
@@ -815,15 +816,10 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
815 mutex_unlock(&curseg->curseg_mutex); 816 mutex_unlock(&curseg->curseg_mutex);
816} 817}
817 818
818int write_meta_page(struct f2fs_sb_info *sbi, struct page *page, 819void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
819 struct writeback_control *wbc)
820{ 820{
821 if (wbc->for_reclaim)
822 return AOP_WRITEPAGE_ACTIVATE;
823
824 set_page_writeback(page); 821 set_page_writeback(page);
825 submit_write_page(sbi, page, page->index, META); 822 submit_write_page(sbi, page, page->index, META);
826 return 0;
827} 823}
828 824
829void write_node_page(struct f2fs_sb_info *sbi, struct page *page, 825void write_node_page(struct f2fs_sb_info *sbi, struct page *page,
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 37fad04c8669..117ca2a46e39 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -387,10 +387,11 @@ static int sanity_check_raw_super(struct super_block *sb,
387 return 0; 387 return 0;
388} 388}
389 389
390static int sanity_check_ckpt(struct f2fs_super_block *raw_super, 390static int sanity_check_ckpt(struct f2fs_sb_info *sbi)
391 struct f2fs_checkpoint *ckpt)
392{ 391{
393 unsigned int total, fsmeta; 392 unsigned int total, fsmeta;
393 struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
394 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
394 395
395 total = le32_to_cpu(raw_super->segment_count); 396 total = le32_to_cpu(raw_super->segment_count);
396 fsmeta = le32_to_cpu(raw_super->segment_count_ckpt); 397 fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
@@ -401,6 +402,11 @@ static int sanity_check_ckpt(struct f2fs_super_block *raw_super,
401 402
402 if (fsmeta >= total) 403 if (fsmeta >= total)
403 return 1; 404 return 1;
405
406 if (is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) {
407 f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck");
408 return 1;
409 }
404 return 0; 410 return 0;
405} 411}
406 412
@@ -525,7 +531,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
525 531
526 /* sanity checking of checkpoint */ 532 /* sanity checking of checkpoint */
527 err = -EINVAL; 533 err = -EINVAL;
528 if (sanity_check_ckpt(raw_super, sbi->ckpt)) { 534 if (sanity_check_ckpt(sbi)) {
529 f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint"); 535 f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint");
530 goto free_cp; 536 goto free_cp;
531 } 537 }