diff options
author | Robin Hsu <robinhsu@google.com> | 2020-06-19 17:52:12 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2020-06-29 08:48:21 -0700 |
commit | 0d0158cf23c50d130c3ce3b7b024868a029ab60e (patch) | |
tree | 3b0844ed417ec1ba99ecea602244d1930013c615 | |
parent | e66e4c1f3bd589a297c2a4e78bc67ac9d3a03032 (diff) | |
download | f2fs-tools-0d0158cf23c50d130c3ce3b7b024868a029ab60e.tar.gz |
fsck.f2fs: Fix slow fsck in auto-fix mode
Split f2fs_init_nid_bitmap() into two disjoint parts:
f2fs_early_init_nid_bitmap(), and
f2fs_late_init_nid_bitmap(),
where f2fs_late_init_nid_bitmap() won't be called in auto-fix mode, when
no errors were found.
f2fs_late_init_nid_bitmap() contains the loop to create NID bitmap from
NAT. which is the main reason for slow fsck.
Signed-off-by: Robin Hsu <robinhsu@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/mount.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/fsck/mount.c b/fsck/mount.c index fb45941..d0f2eab 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -1288,15 +1288,14 @@ pgoff_t current_nat_addr(struct f2fs_sb_info *sbi, nid_t start, int *pack) return block_addr; } -static int f2fs_init_nid_bitmap(struct f2fs_sb_info *sbi) +/* will not init nid_bitmap from nat */ +static int f2fs_early_init_nid_bitmap(struct f2fs_sb_info *sbi) { struct f2fs_nm_info *nm_i = NM_I(sbi); int nid_bitmap_size = (nm_i->max_nid + BITS_PER_BYTE - 1) / BITS_PER_BYTE; struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); struct f2fs_summary_block *sum = curseg->sum_blk; struct f2fs_journal *journal = &sum->journal; - struct f2fs_nat_block *nat_block; - block_t start_blk; nid_t nid; int i; @@ -1310,28 +1309,6 @@ static int f2fs_init_nid_bitmap(struct f2fs_sb_info *sbi) /* arbitrarily set 0 bit */ f2fs_set_bit(0, nm_i->nid_bitmap); - nat_block = malloc(F2FS_BLKSIZE); - if (!nat_block) { - free(nm_i->nid_bitmap); - return -ENOMEM; - } - - f2fs_ra_meta_pages(sbi, 0, NAT_BLOCK_OFFSET(nm_i->max_nid), - META_NAT); - - for (nid = 0; nid < nm_i->max_nid; nid++) { - if (!(nid % NAT_ENTRY_PER_BLOCK)) { - int ret; - - start_blk = current_nat_addr(sbi, nid, NULL); - ret = dev_read_block(nat_block, start_blk); - ASSERT(ret >= 0); - } - - if (nat_block->entries[nid % NAT_ENTRY_PER_BLOCK].block_addr) - f2fs_set_bit(nid, nm_i->nid_bitmap); - } - if (nats_in_cursum(journal) > NAT_JOURNAL_ENTRIES) { MSG(0, "\tError: f2fs_init_nid_bitmap truncate n_nats(%u) to " "NAT_JOURNAL_ENTRIES(%lu)\n", @@ -1361,6 +1338,41 @@ static int f2fs_init_nid_bitmap(struct f2fs_sb_info *sbi) if (addr != NULL_ADDR) f2fs_set_bit(nid, nm_i->nid_bitmap); } + return 0; +} + +/* will init nid_bitmap from nat */ +static int f2fs_late_init_nid_bitmap(struct f2fs_sb_info *sbi) +{ + struct f2fs_nm_info *nm_i = NM_I(sbi); + struct f2fs_nat_block *nat_block; + block_t start_blk; + nid_t nid; + + if (!(c.func == SLOAD || c.func == FSCK)) + return 0; + + nat_block = malloc(F2FS_BLKSIZE); + if (!nat_block) { + free(nm_i->nid_bitmap); + return -ENOMEM; + } + + f2fs_ra_meta_pages(sbi, 0, NAT_BLOCK_OFFSET(nm_i->max_nid), + META_NAT); + for (nid = 0; nid < nm_i->max_nid; nid++) { + if (!(nid % NAT_ENTRY_PER_BLOCK)) { + int ret; + + start_blk = current_nat_addr(sbi, nid, NULL); + ret = dev_read_block(nat_block, start_blk); + ASSERT(ret >= 0); + } + + if (nat_block->entries[nid % NAT_ENTRY_PER_BLOCK].block_addr) + f2fs_set_bit(nid, nm_i->nid_bitmap); + } + free(nat_block); return 0; } @@ -1565,7 +1577,7 @@ int init_node_manager(struct f2fs_sb_info *sbi) /* copy version bitmap */ memcpy(nm_i->nat_bitmap, version_bitmap, nm_i->bitmap_size); - return f2fs_init_nid_bitmap(sbi); + return f2fs_early_init_nid_bitmap(sbi); } int build_node_manager(struct f2fs_sb_info *sbi) @@ -3463,6 +3475,11 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi) if (!f2fs_should_proceed(sb, get_cp(ckpt_flags))) return 1; + if (f2fs_late_init_nid_bitmap(sbi)) { + ERR_MSG("f2fs_late_init_nid_bitmap failed\n"); + return -1; + } + /* Check nat_bits */ if (c.func == FSCK && is_set_ckpt_flags(cp, CP_NAT_BITS_FLAG)) { if (check_nat_bits(sbi, sb, cp) && c.fix_on) |