Commit 050b4142 authored by Ryusuke Konishi's avatar Ryusuke Konishi

nilfs2: apply readahead for recovery on mount

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: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent f021759d
...@@ -798,6 +798,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, ...@@ -798,6 +798,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
struct nilfs_segsum_info ssi; struct nilfs_segsum_info ssi;
sector_t pseg_start, pseg_end, sr_pseg_start = 0; sector_t pseg_start, pseg_end, sr_pseg_start = 0;
sector_t seg_start, seg_end; /* range of full segment (block number) */ sector_t seg_start, seg_end; /* range of full segment (block number) */
sector_t b, end;
u64 seg_seq; u64 seg_seq;
__u64 segnum, nextnum = 0; __u64 segnum, nextnum = 0;
__u64 cno; __u64 cno;
...@@ -813,6 +814,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, ...@@ -813,6 +814,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
/* Calculate range of segment */ /* Calculate range of segment */
nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 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 (;;) { for (;;) {
/* Load segment summary */ /* Load segment summary */
ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); 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,14 +841,20 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
ri->ri_nextnum = nextnum; ri->ri_nextnum = nextnum;
empty_seg = 0; 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 (!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)) { if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
ri->ri_lsegs_start = pseg_start; ri->ri_lsegs_start = pseg_start;
ri->ri_lsegs_start_seq = seg_seq; ri->ri_lsegs_start_seq = seg_seq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment