diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-07-25 18:47:25 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-07-30 17:13:35 -0400 |
commit | cf2271e781cb16e1ca22be920010c2b64d90c338 (patch) | |
tree | e5326d4d03ed5b66359faf41a00b49416d180341 /fs | |
parent | 61e0f2d0a5f2cddf7cd96fa8cb7fe53a1e5e325d (diff) |
f2fs: avoid retrying wrong recovery routine when error was occurred
This patch eliminates the propagation of recovery errors to the next mount.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/checkpoint.c | 3 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
-rw-r--r-- | fs/f2fs/recovery.c | 20 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 5 |
4 files changed, 23 insertions, 7 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 26b94bbc826c..cea20b810f44 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -796,6 +796,7 @@ static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi) | |||
796 | static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | 796 | static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) |
797 | { | 797 | { |
798 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); | 798 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); |
799 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); | ||
799 | nid_t last_nid = 0; | 800 | nid_t last_nid = 0; |
800 | block_t start_blk; | 801 | block_t start_blk; |
801 | struct page *cp_page; | 802 | struct page *cp_page; |
@@ -809,7 +810,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
809 | * This avoids to conduct wrong roll-forward operations and uses | 810 | * This avoids to conduct wrong roll-forward operations and uses |
810 | * metapages, so should be called prior to sync_meta_pages below. | 811 | * metapages, so should be called prior to sync_meta_pages below. |
811 | */ | 812 | */ |
812 | discard_next_dnode(sbi); | 813 | discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); |
813 | 814 | ||
814 | /* Flush all the NAT/SIT pages */ | 815 | /* Flush all the NAT/SIT pages */ |
815 | while (get_pages(sbi, F2FS_DIRTY_META)) | 816 | while (get_pages(sbi, F2FS_DIRTY_META)) |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 475f97ca49ae..14b9f746d5b3 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -1225,7 +1225,7 @@ void destroy_flush_cmd_control(struct f2fs_sb_info *); | |||
1225 | void invalidate_blocks(struct f2fs_sb_info *, block_t); | 1225 | void invalidate_blocks(struct f2fs_sb_info *, block_t); |
1226 | void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); | 1226 | void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); |
1227 | void clear_prefree_segments(struct f2fs_sb_info *); | 1227 | void clear_prefree_segments(struct f2fs_sb_info *); |
1228 | void discard_next_dnode(struct f2fs_sb_info *); | 1228 | void discard_next_dnode(struct f2fs_sb_info *, block_t); |
1229 | int npages_for_summary_flush(struct f2fs_sb_info *); | 1229 | int npages_for_summary_flush(struct f2fs_sb_info *); |
1230 | void allocate_new_segments(struct f2fs_sb_info *); | 1230 | void allocate_new_segments(struct f2fs_sb_info *); |
1231 | struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); | 1231 | struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); |
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index a112368a4a86..b2aa53b99f64 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
@@ -434,7 +434,9 @@ next: | |||
434 | 434 | ||
435 | int recover_fsync_data(struct f2fs_sb_info *sbi) | 435 | int recover_fsync_data(struct f2fs_sb_info *sbi) |
436 | { | 436 | { |
437 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); | ||
437 | struct list_head inode_list; | 438 | struct list_head inode_list; |
439 | block_t blkaddr; | ||
438 | int err; | 440 | int err; |
439 | bool need_writecp = false; | 441 | bool need_writecp = false; |
440 | 442 | ||
@@ -447,6 +449,9 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) | |||
447 | 449 | ||
448 | /* step #1: find fsynced inode numbers */ | 450 | /* step #1: find fsynced inode numbers */ |
449 | sbi->por_doing = true; | 451 | sbi->por_doing = true; |
452 | |||
453 | blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); | ||
454 | |||
450 | err = find_fsync_dnodes(sbi, &inode_list); | 455 | err = find_fsync_dnodes(sbi, &inode_list); |
451 | if (err) | 456 | if (err) |
452 | goto out; | 457 | goto out; |
@@ -462,8 +467,21 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) | |||
462 | out: | 467 | out: |
463 | destroy_fsync_dnodes(&inode_list); | 468 | destroy_fsync_dnodes(&inode_list); |
464 | kmem_cache_destroy(fsync_entry_slab); | 469 | kmem_cache_destroy(fsync_entry_slab); |
470 | |||
471 | if (err) { | ||
472 | truncate_inode_pages_final(NODE_MAPPING(sbi)); | ||
473 | truncate_inode_pages_final(META_MAPPING(sbi)); | ||
474 | } | ||
475 | |||
465 | sbi->por_doing = false; | 476 | sbi->por_doing = false; |
466 | if (!err && need_writecp) | 477 | if (err) { |
478 | discard_next_dnode(sbi, blkaddr); | ||
479 | |||
480 | /* Flush all the NAT/SIT pages */ | ||
481 | while (get_pages(sbi, F2FS_DIRTY_META)) | ||
482 | sync_meta_pages(sbi, META, LONG_MAX); | ||
483 | } else if (need_writecp) { | ||
467 | write_checkpoint(sbi, false); | 484 | write_checkpoint(sbi, false); |
485 | } | ||
468 | return err; | 486 | return err; |
469 | } | 487 | } |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 9fce0f47eb35..e016b97be2ac 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -379,11 +379,8 @@ static int f2fs_issue_discard(struct f2fs_sb_info *sbi, | |||
379 | return blkdev_issue_discard(sbi->sb->s_bdev, start, len, GFP_NOFS, 0); | 379 | return blkdev_issue_discard(sbi->sb->s_bdev, start, len, GFP_NOFS, 0); |
380 | } | 380 | } |
381 | 381 | ||
382 | void discard_next_dnode(struct f2fs_sb_info *sbi) | 382 | void discard_next_dnode(struct f2fs_sb_info *sbi, block_t blkaddr) |
383 | { | 383 | { |
384 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); | ||
385 | block_t blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); | ||
386 | |||
387 | if (f2fs_issue_discard(sbi, blkaddr, 1)) { | 384 | if (f2fs_issue_discard(sbi, blkaddr, 1)) { |
388 | struct page *page = grab_meta_page(sbi, blkaddr); | 385 | struct page *page = grab_meta_page(sbi, blkaddr); |
389 | /* zero-filled page */ | 386 | /* zero-filled page */ |