aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/recovery.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-05-23 06:46:44 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-07-22 21:02:09 -0400
commit85655484f896d078d310221475b90ea27f76e5f2 (patch)
tree007cab199f81b4b461dd7a05fd90e84381a8ccd6 /fs/nilfs2/recovery.c
parent354fa8be280ce81c88b6b236d62d23ebcade2d3f (diff)
nilfs2: do not use nilfs_segsum_info structure in recovery code
This will get rid of nilfs_segsum_info use from recovery functions for simplicity. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/recovery.c')
-rw-r--r--fs/nilfs2/recovery.c91
1 files changed, 37 insertions, 54 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 35506b1704d1..f5d9c3f954ae 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -91,24 +91,6 @@ static int nilfs_warn_segment_error(int err)
91 return -EINVAL; 91 return -EINVAL;
92} 92}
93 93
94static void store_segsum_info(struct nilfs_segsum_info *ssi,
95 struct nilfs_segment_summary *sum,
96 unsigned int blocksize)
97{
98 ssi->flags = le16_to_cpu(sum->ss_flags);
99 ssi->seg_seq = le64_to_cpu(sum->ss_seq);
100 ssi->ctime = le64_to_cpu(sum->ss_create);
101 ssi->next = le64_to_cpu(sum->ss_next);
102 ssi->nblocks = le32_to_cpu(sum->ss_nblocks);
103 ssi->nfinfo = le32_to_cpu(sum->ss_nfinfo);
104 ssi->sumbytes = le32_to_cpu(sum->ss_sumbytes);
105
106 ssi->nsumblk = DIV_ROUND_UP(ssi->sumbytes, blocksize);
107 ssi->nfileblk = ssi->nblocks - ssi->nsumblk - !!NILFS_SEG_HAS_SR(ssi);
108
109 /* need to verify ->ss_bytes field if read ->ss_cno */
110}
111
112/** 94/**
113 * nilfs_compute_checksum - compute checksum of blocks continuously 95 * nilfs_compute_checksum - compute checksum of blocks continuously
114 * @nilfs: nilfs object 96 * @nilfs: nilfs object
@@ -328,29 +310,31 @@ static void nilfs_skip_summary_info(struct the_nilfs *nilfs,
328 * nilfs_scan_dsync_log - get block information of a log written for data sync 310 * nilfs_scan_dsync_log - get block information of a log written for data sync
329 * @nilfs: nilfs object 311 * @nilfs: nilfs object
330 * @start_blocknr: start block number of the log 312 * @start_blocknr: start block number of the log
331 * @ssi: log summary information 313 * @sum: log summary information
332 * @head: list head to add nilfs_recovery_block struct 314 * @head: list head to add nilfs_recovery_block struct
333 */ 315 */
334static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr, 316static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr,
335 struct nilfs_segsum_info *ssi, 317 struct nilfs_segment_summary *sum,
336 struct list_head *head) 318 struct list_head *head)
337{ 319{
338 struct buffer_head *bh; 320 struct buffer_head *bh;
339 unsigned int offset; 321 unsigned int offset;
340 unsigned long nfinfo = ssi->nfinfo; 322 u32 nfinfo, sumbytes;
341 sector_t blocknr = start_blocknr + ssi->nsumblk; 323 sector_t blocknr;
342 ino_t ino; 324 ino_t ino;
343 int err = -EIO; 325 int err = -EIO;
344 326
327 nfinfo = le32_to_cpu(sum->ss_nfinfo);
345 if (!nfinfo) 328 if (!nfinfo)
346 return 0; 329 return 0;
347 330
331 sumbytes = le32_to_cpu(sum->ss_sumbytes);
332 blocknr = start_blocknr + DIV_ROUND_UP(sumbytes, nilfs->ns_blocksize);
348 bh = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); 333 bh = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize);
349 if (unlikely(!bh)) 334 if (unlikely(!bh))
350 goto out; 335 goto out;
351 336
352 offset = le16_to_cpu( 337 offset = le16_to_cpu(sum->ss_bytes);
353 ((struct nilfs_segment_summary *)bh->b_data)->ss_bytes);
354 for (;;) { 338 for (;;) {
355 unsigned long nblocks, ndatablk, nnodeblk; 339 unsigned long nblocks, ndatablk, nnodeblk;
356 struct nilfs_finfo *finfo; 340 struct nilfs_finfo *finfo;
@@ -593,12 +577,12 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
593 struct nilfs_sb_info *sbi, 577 struct nilfs_sb_info *sbi,
594 struct nilfs_recovery_info *ri) 578 struct nilfs_recovery_info *ri)
595{ 579{
596 struct nilfs_segsum_info ssi;
597 struct buffer_head *bh_sum = NULL; 580 struct buffer_head *bh_sum = NULL;
598 struct nilfs_segment_summary *sum; 581 struct nilfs_segment_summary *sum;
599 sector_t pseg_start; 582 sector_t pseg_start;
600 sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */ 583 sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */
601 unsigned long nsalvaged_blocks = 0; 584 unsigned long nsalvaged_blocks = 0;
585 unsigned int flags;
602 u64 seg_seq; 586 u64 seg_seq;
603 __u64 segnum, nextnum = 0; 587 __u64 segnum, nextnum = 0;
604 int empty_seg = 0; 588 int empty_seg = 0;
@@ -633,32 +617,34 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
633 goto strayed; 617 goto strayed;
634 } 618 }
635 619
636 store_segsum_info(&ssi, sum, nilfs->ns_blocksize); 620 flags = le16_to_cpu(sum->ss_flags);
637 if (unlikely(NILFS_SEG_HAS_SR(&ssi))) 621 if (flags & NILFS_SS_SR)
638 goto confused; 622 goto confused;
639 623
640 /* Found a valid partial segment; do recovery actions */ 624 /* Found a valid partial segment; do recovery actions */
641 nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next); 625 nextnum = nilfs_get_segnum_of_block(nilfs,
626 le64_to_cpu(sum->ss_next));
642 empty_seg = 0; 627 empty_seg = 0;
643 nilfs->ns_ctime = ssi.ctime; 628 nilfs->ns_ctime = le64_to_cpu(sum->ss_create);
644 if (!(ssi.flags & NILFS_SS_GC)) 629 if (!(flags & NILFS_SS_GC))
645 nilfs->ns_nongc_ctime = ssi.ctime; 630 nilfs->ns_nongc_ctime = nilfs->ns_ctime;
646 631
647 switch (state) { 632 switch (state) {
648 case RF_INIT_ST: 633 case RF_INIT_ST:
649 if (!NILFS_SEG_LOGBGN(&ssi) || !NILFS_SEG_DSYNC(&ssi)) 634 if (!(flags & NILFS_SS_LOGBGN) ||
635 !(flags & NILFS_SS_SYNDT))
650 goto try_next_pseg; 636 goto try_next_pseg;
651 state = RF_DSYNC_ST; 637 state = RF_DSYNC_ST;
652 /* Fall through */ 638 /* Fall through */
653 case RF_DSYNC_ST: 639 case RF_DSYNC_ST:
654 if (!NILFS_SEG_DSYNC(&ssi)) 640 if (!(flags & NILFS_SS_SYNDT))
655 goto confused; 641 goto confused;
656 642
657 err = nilfs_scan_dsync_log(nilfs, pseg_start, &ssi, 643 err = nilfs_scan_dsync_log(nilfs, pseg_start, sum,
658 &dsync_blocks); 644 &dsync_blocks);
659 if (unlikely(err)) 645 if (unlikely(err))
660 goto failed; 646 goto failed;
661 if (NILFS_SEG_LOGEND(&ssi)) { 647 if (flags & NILFS_SS_LOGEND) {
662 err = nilfs_recover_dsync_blocks( 648 err = nilfs_recover_dsync_blocks(
663 nilfs, sbi, &dsync_blocks, 649 nilfs, sbi, &dsync_blocks,
664 &nsalvaged_blocks); 650 &nsalvaged_blocks);
@@ -672,7 +658,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
672 try_next_pseg: 658 try_next_pseg:
673 if (pseg_start == ri->ri_lsegs_end) 659 if (pseg_start == ri->ri_lsegs_end)
674 break; 660 break;
675 pseg_start += ssi.nblocks; 661 pseg_start += le32_to_cpu(sum->ss_nblocks);
676 if (pseg_start < seg_end) 662 if (pseg_start < seg_end)
677 continue; 663 continue;
678 goto feed_segment; 664 goto feed_segment;
@@ -822,12 +808,13 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
822int nilfs_search_super_root(struct the_nilfs *nilfs, 808int nilfs_search_super_root(struct the_nilfs *nilfs,
823 struct nilfs_recovery_info *ri) 809 struct nilfs_recovery_info *ri)
824{ 810{
825 struct nilfs_segsum_info ssi;
826 struct buffer_head *bh_sum = NULL; 811 struct buffer_head *bh_sum = NULL;
827 struct nilfs_segment_summary *sum; 812 struct nilfs_segment_summary *sum;
828 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 813 sector_t pseg_start, pseg_end, sr_pseg_start = 0;
829 sector_t seg_start, seg_end; /* range of full segment (block number) */ 814 sector_t seg_start, seg_end; /* range of full segment (block number) */
830 sector_t b, end; 815 sector_t b, end;
816 unsigned long nblocks;
817 unsigned int flags;
831 u64 seg_seq; 818 u64 seg_seq;
832 __u64 segnum, nextnum = 0; 819 __u64 segnum, nextnum = 0;
833 __u64 cno; 820 __u64 cno;
@@ -862,8 +849,8 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
862 goto strayed; 849 goto strayed;
863 } 850 }
864 851
865 store_segsum_info(&ssi, sum, nilfs->ns_blocksize); 852 nblocks = le32_to_cpu(sum->ss_nblocks);
866 pseg_end = pseg_start + ssi.nblocks - 1; 853 pseg_end = pseg_start + nblocks - 1;
867 if (unlikely(pseg_end > seg_end)) { 854 if (unlikely(pseg_end > seg_end)) {
868 ret = NILFS_SEG_FAIL_CONSISTENCY; 855 ret = NILFS_SEG_FAIL_CONSISTENCY;
869 goto strayed; 856 goto strayed;
@@ -873,11 +860,13 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
873 ri->ri_pseg_start = pseg_start; 860 ri->ri_pseg_start = pseg_start;
874 ri->ri_seq = seg_seq; 861 ri->ri_seq = seg_seq;
875 ri->ri_segnum = segnum; 862 ri->ri_segnum = segnum;
876 nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next); 863 nextnum = nilfs_get_segnum_of_block(nilfs,
864 le64_to_cpu(sum->ss_next));
877 ri->ri_nextnum = nextnum; 865 ri->ri_nextnum = nextnum;
878 empty_seg = 0; 866 empty_seg = 0;
879 867
880 if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) { 868 flags = le16_to_cpu(sum->ss_flags);
869 if (!(flags & NILFS_SS_SR) && !scan_newer) {
881 /* This will never happen because a superblock 870 /* This will never happen because a superblock
882 (last_segment) always points to a pseg 871 (last_segment) always points to a pseg
883 having a super root. */ 872 having a super root. */
@@ -891,12 +880,12 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
891 __breadahead(nilfs->ns_bdev, b++, 880 __breadahead(nilfs->ns_bdev, b++,
892 nilfs->ns_blocksize); 881 nilfs->ns_blocksize);
893 } 882 }
894 if (!NILFS_SEG_HAS_SR(&ssi)) { 883 if (!(flags & NILFS_SS_SR)) {
895 if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { 884 if (!ri->ri_lsegs_start && (flags & NILFS_SS_LOGBGN)) {
896 ri->ri_lsegs_start = pseg_start; 885 ri->ri_lsegs_start = pseg_start;
897 ri->ri_lsegs_start_seq = seg_seq; 886 ri->ri_lsegs_start_seq = seg_seq;
898 } 887 }
899 if (NILFS_SEG_LOGEND(&ssi)) 888 if (flags & NILFS_SS_LOGEND)
900 ri->ri_lsegs_end = pseg_start; 889 ri->ri_lsegs_end = pseg_start;
901 goto try_next_pseg; 890 goto try_next_pseg;
902 } 891 }
@@ -907,12 +896,12 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
907 ri->ri_lsegs_start = ri->ri_lsegs_end = 0; 896 ri->ri_lsegs_start = ri->ri_lsegs_end = 0;
908 897
909 nilfs_dispose_segment_list(&segments); 898 nilfs_dispose_segment_list(&segments);
910 nilfs->ns_pseg_offset = (sr_pseg_start = pseg_start) 899 sr_pseg_start = pseg_start;
911 + ssi.nblocks - seg_start; 900 nilfs->ns_pseg_offset = pseg_start + nblocks - seg_start;
912 nilfs->ns_seg_seq = seg_seq; 901 nilfs->ns_seg_seq = seg_seq;
913 nilfs->ns_segnum = segnum; 902 nilfs->ns_segnum = segnum;
914 nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */ 903 nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */
915 nilfs->ns_ctime = ssi.ctime; 904 nilfs->ns_ctime = le64_to_cpu(sum->ss_create);
916 nilfs->ns_nextnum = nextnum; 905 nilfs->ns_nextnum = nextnum;
917 906
918 if (scan_newer) 907 if (scan_newer)
@@ -923,15 +912,9 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
923 scan_newer = 1; 912 scan_newer = 1;
924 } 913 }
925 914
926 /* reset region for roll-forward */
927 pseg_start += ssi.nblocks;
928 if (pseg_start < seg_end)
929 continue;
930 goto feed_segment;
931
932 try_next_pseg: 915 try_next_pseg:
933 /* Standing on a course, or met an inconsistent state */ 916 /* Standing on a course, or met an inconsistent state */
934 pseg_start += ssi.nblocks; 917 pseg_start += nblocks;
935 if (pseg_start < seg_end) 918 if (pseg_start < seg_end)
936 continue; 919 continue;
937 goto feed_segment; 920 goto feed_segment;