nilfs2: apply readahead for recovery on mount
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Thu, 19 Nov 2009 13:24:48 +0000 (22:24 +0900)
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Fri, 20 Nov 2009 01:05:51 +0000 (10:05 +0900)
This inserts readahead in the recovery code.  The readahead request is
issued per segment while searching the latest super root block.

This will shorten mount time after unclean unmount.  A measurement
shows the recovery time was reduced by more than 60 percent:

 e.g. real  0m11.586s -> 0m3.918s  (x 2.96)

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
fs/nilfs2/recovery.c

index bcd386d..6d5412e 100644 (file)
@@ -798,6 +798,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
        struct nilfs_segsum_info ssi;
        sector_t pseg_start, pseg_end, sr_pseg_start = 0;
        sector_t seg_start, seg_end; /* range of full segment (block number) */
+       sector_t b, end;
        u64 seg_seq;
        __u64 segnum, nextnum = 0;
        __u64 cno;
@@ -813,6 +814,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
        /* Calculate range of segment */
        nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
 
+       /* Read ahead segment */
+       b = seg_start;
+       while (b <= seg_end)
+               sb_breadahead(sbi->s_super, b++);
+
        for (;;) {
                /* Load segment summary */
                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,
                ri->ri_nextnum = nextnum;
                empty_seg = 0;
 
+               if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) {
+                       /* This will never happen because a superblock
+                          (last_segment) always points to a pseg
+                          having a super root. */
+                       ret = NILFS_SEG_FAIL_CONSISTENCY;
+                       goto failed;
+               }
+
+               if (pseg_start == seg_start) {
+                       nilfs_get_segment_range(nilfs, nextnum, &b, &end);
+                       while (b <= end)
+                               sb_breadahead(sbi->s_super, b++);
+               }
                if (!NILFS_SEG_HAS_SR(&ssi)) {
-                       if (!scan_newer) {
-                               /* This will never happen because a superblock
-                                  (last_segment) always points to a pseg
-                                  having a super root. */
-                               ret = NILFS_SEG_FAIL_CONSISTENCY;
-                               goto failed;
-                       }
                        if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
                                ri->ri_lsegs_start = pseg_start;
                                ri->ri_lsegs_start_seq = seg_seq;