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; |
