diff options
Diffstat (limited to 'fs/nilfs2/recovery.c')
-rw-r--r-- | fs/nilfs2/recovery.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index 6dc83591d118..c9c96c7825dc 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -770,14 +770,8 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs, | |||
770 | nilfs_finish_roll_forward(nilfs, sbi, ri); | 770 | nilfs_finish_roll_forward(nilfs, sbi, ri); |
771 | } | 771 | } |
772 | 772 | ||
773 | nilfs_detach_checkpoint(sbi); | ||
774 | return 0; | ||
775 | |||
776 | failed: | 773 | failed: |
777 | nilfs_detach_checkpoint(sbi); | 774 | nilfs_detach_checkpoint(sbi); |
778 | nilfs_mdt_clear(nilfs->ns_cpfile); | ||
779 | nilfs_mdt_clear(nilfs->ns_sufile); | ||
780 | nilfs_mdt_clear(nilfs->ns_dat); | ||
781 | return err; | 775 | return err; |
782 | } | 776 | } |
783 | 777 | ||
@@ -804,6 +798,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
804 | struct nilfs_segsum_info ssi; | 798 | struct nilfs_segsum_info ssi; |
805 | sector_t pseg_start, pseg_end, sr_pseg_start = 0; | 799 | sector_t pseg_start, pseg_end, sr_pseg_start = 0; |
806 | sector_t seg_start, seg_end; /* range of full segment (block number) */ | 800 | sector_t seg_start, seg_end; /* range of full segment (block number) */ |
801 | sector_t b, end; | ||
807 | u64 seg_seq; | 802 | u64 seg_seq; |
808 | __u64 segnum, nextnum = 0; | 803 | __u64 segnum, nextnum = 0; |
809 | __u64 cno; | 804 | __u64 cno; |
@@ -819,6 +814,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
819 | /* Calculate range of segment */ | 814 | /* Calculate range of segment */ |
820 | nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); | 815 | nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); |
821 | 816 | ||
817 | /* Read ahead segment */ | ||
818 | b = seg_start; | ||
819 | while (b <= seg_end) | ||
820 | sb_breadahead(sbi->s_super, b++); | ||
821 | |||
822 | for (;;) { | 822 | for (;;) { |
823 | /* Load segment summary */ | 823 | /* Load segment summary */ |
824 | ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); | 824 | ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); |
@@ -841,14 +841,20 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
841 | ri->ri_nextnum = nextnum; | 841 | ri->ri_nextnum = nextnum; |
842 | empty_seg = 0; | 842 | empty_seg = 0; |
843 | 843 | ||
844 | if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) { | ||
845 | /* This will never happen because a superblock | ||
846 | (last_segment) always points to a pseg | ||
847 | having a super root. */ | ||
848 | ret = NILFS_SEG_FAIL_CONSISTENCY; | ||
849 | goto failed; | ||
850 | } | ||
851 | |||
852 | if (pseg_start == seg_start) { | ||
853 | nilfs_get_segment_range(nilfs, nextnum, &b, &end); | ||
854 | while (b <= end) | ||
855 | sb_breadahead(sbi->s_super, b++); | ||
856 | } | ||
844 | if (!NILFS_SEG_HAS_SR(&ssi)) { | 857 | if (!NILFS_SEG_HAS_SR(&ssi)) { |
845 | if (!scan_newer) { | ||
846 | /* This will never happen because a superblock | ||
847 | (last_segment) always points to a pseg | ||
848 | having a super root. */ | ||
849 | ret = NILFS_SEG_FAIL_CONSISTENCY; | ||
850 | goto failed; | ||
851 | } | ||
852 | if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { | 858 | if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { |
853 | ri->ri_lsegs_start = pseg_start; | 859 | ri->ri_lsegs_start = pseg_start; |
854 | ri->ri_lsegs_start_seq = seg_seq; | 860 | ri->ri_lsegs_start_seq = seg_seq; |
@@ -919,7 +925,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
919 | 925 | ||
920 | super_root_found: | 926 | super_root_found: |
921 | /* Updating pointers relating to the latest checkpoint */ | 927 | /* Updating pointers relating to the latest checkpoint */ |
922 | list_splice(&segments, ri->ri_used_segments.prev); | 928 | list_splice_tail(&segments, &ri->ri_used_segments); |
923 | nilfs->ns_last_pseg = sr_pseg_start; | 929 | nilfs->ns_last_pseg = sr_pseg_start; |
924 | nilfs->ns_last_seq = nilfs->ns_seg_seq; | 930 | nilfs->ns_last_seq = nilfs->ns_seg_seq; |
925 | nilfs->ns_last_cno = ri->ri_cno; | 931 | nilfs->ns_last_cno = ri->ri_cno; |