diff options
Diffstat (limited to 'fs/nilfs2/recovery.c')
-rw-r--r-- | fs/nilfs2/recovery.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index bcd386d604d7..6d5412eff28f 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -798,6 +798,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
798 | struct nilfs_segsum_info ssi; | 798 | struct nilfs_segsum_info ssi; |
799 | sector_t pseg_start, pseg_end, sr_pseg_start = 0; | 799 | sector_t pseg_start, pseg_end, sr_pseg_start = 0; |
800 | 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; | ||
801 | u64 seg_seq; | 802 | u64 seg_seq; |
802 | __u64 segnum, nextnum = 0; | 803 | __u64 segnum, nextnum = 0; |
803 | __u64 cno; | 804 | __u64 cno; |
@@ -813,6 +814,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
813 | /* Calculate range of segment */ | 814 | /* Calculate range of segment */ |
814 | nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); | 815 | nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); |
815 | 816 | ||
817 | /* Read ahead segment */ | ||
818 | b = seg_start; | ||
819 | while (b <= seg_end) | ||
820 | sb_breadahead(sbi->s_super, b++); | ||
821 | |||
816 | for (;;) { | 822 | for (;;) { |
817 | /* Load segment summary */ | 823 | /* Load segment summary */ |
818 | ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); | 824 | ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); |
@@ -835,14 +841,20 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
835 | ri->ri_nextnum = nextnum; | 841 | ri->ri_nextnum = nextnum; |
836 | empty_seg = 0; | 842 | empty_seg = 0; |
837 | 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 | } | ||
838 | if (!NILFS_SEG_HAS_SR(&ssi)) { | 857 | if (!NILFS_SEG_HAS_SR(&ssi)) { |
839 | if (!scan_newer) { | ||
840 | /* This will never happen because a superblock | ||
841 | (last_segment) always points to a pseg | ||
842 | having a super root. */ | ||
843 | ret = NILFS_SEG_FAIL_CONSISTENCY; | ||
844 | goto failed; | ||
845 | } | ||
846 | if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { | 858 | if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { |
847 | ri->ri_lsegs_start = pseg_start; | 859 | ri->ri_lsegs_start = pseg_start; |
848 | ri->ri_lsegs_start_seq = seg_seq; | 860 | ri->ri_lsegs_start_seq = seg_seq; |