aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/checkpoint.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-08-11 21:37:46 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-08-21 16:55:05 -0400
commitcf779cab14d50a84b61399f758da269654b863db (patch)
treec11a1da5ea17f3e3f86e5cdad7cc57b97427e7fa /fs/f2fs/checkpoint.c
parent8501017e50fb7586ba522a2913ce664d6c2024f6 (diff)
f2fs: handle EIO not to break fs consistency
There are two rules when EIO is occurred. 1. don't write any checkpoint data to preserve the previous checkpoint 2. don't lose the cached dentry/node/meta pages So, at first, this patch adds set_page_dirty in f2fs_write_end_io's failure. Then, writing checkpoint/dentry/node blocks is not allowed. Note that, for the data pages, we can't just throw away by redirtying them. Otherwise, kworker can fall into infinite loop to flush them. (Ref. xfstests/019) Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r--fs/f2fs/checkpoint.c45
1 files changed, 32 insertions, 13 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