aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Hsu <robinhsu@google.com>2020-06-19 17:52:12 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2020-06-29 08:48:21 -0700
commit0d0158cf23c50d130c3ce3b7b024868a029ab60e (patch)
tree3b0844ed417ec1ba99ecea602244d1930013c615
parente66e4c1f3bd589a297c2a4e78bc67ac9d3a03032 (diff)
downloadf2fs-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.c69
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)