aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/f2fs/checkpoint.c45
-rw-r--r--fs/f2fs/data.c11
-rw-r--r--fs/f2fs/node.c2
-rw-r--r--fs/f2fs/super.c5
4 files changed, 48 insertions, 15 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index dc29b7837687..c9c08d52ecfd 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -160,14 +160,11 @@ static int f2fs_write_meta_page(struct page *page,
160 goto redirty_out; 160 goto redirty_out;
161 if (wbc->for_reclaim) 161 if (wbc->for_reclaim)
162 goto redirty_out; 162 goto redirty_out;
163
164 /* Should not write any meta pages, if any IO error was occurred */
165 if (unlikely(f2fs_cp_error(sbi))) 163 if (unlikely(f2fs_cp_error(sbi)))
166 goto no_write; 164 goto redirty_out;
167 165
168 f2fs_wait_on_page_writeback(page, META); 166 f2fs_wait_on_page_writeback(page, META);
169 write_meta_page(sbi, page); 167 write_meta_page(sbi, page);
170no_write:
171 dec_page_count(sbi, F2FS_DIRTY_META); 168 dec_page_count(sbi, F2FS_DIRTY_META);
172 unlock_page(page); 169 unlock_page(page);
173 return 0; 170 return 0;
@@ -737,7 +734,7 @@ retry:
737/* 734/*
738 * Freeze all the FS-operations for checkpoint. 735 * Freeze all the FS-operations for checkpoint.
739 */ 736 */
740static void block_operations(struct f2fs_sb_info *sbi) 737static int block_operations(struct f2fs_sb_info *sbi)
741{ 738{
742 struct writeback_control wbc = { 739 struct writeback_control wbc = {
743 .sync_mode = WB_SYNC_ALL, 740 .sync_mode = WB_SYNC_ALL,
@@ -745,6 +742,7 @@ static void block_operations(struct f2fs_sb_info *sbi)
745 .for_reclaim = 0, 742 .for_reclaim = 0,
746 }; 743 };
747 struct blk_plug plug; 744 struct blk_plug plug;
745 int err = 0;
748 746
749 blk_start_plug(&plug); 747 blk_start_plug(&plug);
750 748
@@ -754,6 +752,10 @@ retry_flush_dents:
754 if (get_pages(sbi, F2FS_DIRTY_DENTS)) { 752 if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
755 f2fs_unlock_all(sbi); 753 f2fs_unlock_all(sbi);
756 sync_dirty_dir_inodes(sbi); 754 sync_dirty_dir_inodes(sbi);
755 if (unlikely(f2fs_cp_error(sbi))) {
756 err = -EIO;
757 goto out;
758 }
757 goto retry_flush_dents; 759 goto retry_flush_dents;
758 } 760 }
759 761
@@ -767,9 +769,16 @@ retry_flush_nodes:
767 if (get_pages(sbi, F2FS_DIRTY_NODES)) { 769 if (get_pages(sbi, F2FS_DIRTY_NODES)) {
768 up_write(&sbi->node_write); 770 up_write(&sbi->node_write);
769 sync_node_pages(sbi, 0, &wbc); 771 sync_node_pages(sbi, 0, &wbc);
772 if (unlikely(f2fs_cp_error(sbi))) {
773 f2fs_unlock_all(sbi);
774 err = -EIO;
775 goto out;
776 }
770 goto retry_flush_nodes; 777 goto retry_flush_nodes;
771 } 778 }
779out:
772 blk_finish_plug(&plug); 780 blk_finish_plug(&plug);
781 return err;
773} 782}
774 783
775static void unblock_operations(struct f2fs_sb_info *sbi) 784static void unblock_operations(struct f2fs_sb_info *sbi)
@@ -813,8 +822,11 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
813 discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); 822 discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg));
814 823
815 /* Flush all the NAT/SIT pages */ 824 /* Flush all the NAT/SIT pages */
816 while (get_pages(sbi, F2FS_DIRTY_META)) 825 while (get_pages(sbi, F2FS_DIRTY_META)) {
817 sync_meta_pages(sbi, META, LONG_MAX); 826 sync_meta_pages(sbi, META, LONG_MAX);
827 if (unlikely(f2fs_cp_error(sbi)))
828 return;
829 }
818 830
819 next_free_nid(sbi, &last_nid); 831 next_free_nid(sbi, &last_nid);
820 832
@@ -924,6 +936,9 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
924 /* wait for previous submitted node/meta pages writeback */ 936 /* wait for previous submitted node/meta pages writeback */
925 wait_on_all_pages_writeback(sbi); 937 wait_on_all_pages_writeback(sbi);
926 938
939 if (unlikely(f2fs_cp_error(sbi)))
940 return;
941
927 filemap_fdatawait_range(NODE_MAPPING(sbi), 0, LONG_MAX); 942 filemap_fdatawait_range(NODE_MAPPING(sbi), 0, LONG_MAX);
928 filemap_fdatawait_range(META_MAPPING(sbi), 0, LONG_MAX); 943 filemap_fdatawait_range(META_MAPPING(sbi), 0, LONG_MAX);
929 944
@@ -934,11 +949,13 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
934 /* Here, we only have one bio having CP pack */ 949 /* Here, we only have one bio having CP pack */
935 sync_meta_pages(sbi, META_FLUSH, LONG_MAX); 950 sync_meta_pages(sbi, META_FLUSH, LONG_MAX);
936 951
937 if (!f2fs_cp_error(sbi)) { 952 release_dirty_inode(sbi);
938 clear_prefree_segments(sbi); 953
939 release_dirty_inode(sbi); 954 if (unlikely(f2fs_cp_error(sbi)))
940 F2FS_RESET_SB_DIRT(sbi); 955 return;
941 } 956
957 clear_prefree_segments(sbi);
958 F2FS_RESET_SB_DIRT(sbi);
942} 959}
943 960
944/* 961/*
@@ -955,8 +972,10 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
955 972
956 if (!sbi->s_dirty) 973 if (!sbi->s_dirty)
957 goto out; 974 goto out;
958 975 if (unlikely(f2fs_cp_error(sbi)))
959 block_operations(sbi); 976 goto out;
977 if (block_operations(sbi))
978 goto out;
960 979
961 trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops"); 980 trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops");
962 981
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index ac3ccc25386b..6ba52a393063 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -53,7 +53,7 @@ static void f2fs_write_end_io(struct bio *bio, int err)
53 struct page *page = bvec->bv_page; 53 struct page *page = bvec->bv_page;
54 54
55 if (unlikely(err)) { 55 if (unlikely(err)) {
56 SetPageError(page); 56 set_page_dirty(page);
57 set_bit(AS_EIO, &page->mapping->flags); 57 set_bit(AS_EIO, &page->mapping->flags);
58 f2fs_stop_checkpoint(sbi); 58 f2fs_stop_checkpoint(sbi);
59 } 59 }
@@ -836,10 +836,19 @@ write:
836 836
837 /* Dentry blocks are controlled by checkpoint */ 837 /* Dentry blocks are controlled by checkpoint */
838 if (S_ISDIR(inode->i_mode)) { 838 if (S_ISDIR(inode->i_mode)) {
839 if (unlikely(f2fs_cp_error(sbi)))
840 goto redirty_out;
839 err = do_write_data_page(page, &fio); 841 err = do_write_data_page(page, &fio);
840 goto done; 842 goto done;
841 } 843 }
842 844
845 /* we should bypass data pages to proceed the kworkder jobs */
846 if (unlikely(f2fs_cp_error(sbi))) {
847 SetPageError(page);
848 unlock_page(page);
849 return 0;
850 }
851
843 if (!wbc->for_reclaim) 852 if (!wbc->for_reclaim)
844 need_balance_fs = true; 853 need_balance_fs = true;
845 else if (has_not_enough_free_secs(sbi, 0)) 854 else if (has_not_enough_free_secs(sbi, 0))
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 9f126f80813d..d2f784283425 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1215,6 +1215,8 @@ static int f2fs_write_node_page(struct page *page,
1215 1215
1216 if (unlikely(sbi->por_doing)) 1216 if (unlikely(sbi->por_doing))
1217 goto redirty_out; 1217 goto redirty_out;
1218 if (unlikely(f2fs_cp_error(sbi)))
1219 goto redirty_out;
1218 1220
1219 f2fs_wait_on_page_writeback(page, NODE); 1221 f2fs_wait_on_page_writeback(page, NODE);
1220 1222
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index e7a7b619ffd4..ddb1e9d36363 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -435,7 +435,10 @@ static void f2fs_put_super(struct super_block *sb)
435 if (sbi->s_dirty) 435 if (sbi->s_dirty)
436 write_checkpoint(sbi, true); 436 write_checkpoint(sbi, true);
437 437
438 /* normally superblock is clean, so we need to release this */ 438 /*
439 * normally superblock is clean, so we need to release this.
440 * In addition, EIO will skip do checkpoint, we need this as well.
441 */
439 release_dirty_inode(sbi); 442 release_dirty_inode(sbi);
440 443
441 iput(sbi->node_inode); 444 iput(sbi->node_inode);