aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Hsu <robinhsu@google.com>2020-07-10 06:54:29 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-07-10 06:54:29 +0000
commita90c93387fa29554bc177b51ff9920d42663522c (patch)
tree167366fbfc5df31c219b707abd2e58f8ea6a88c3
parent15936d35f5038f98a994eb72f603fb99e6f2659f (diff)
parent3973c080af58ca7af1f251a3b188986de1982e03 (diff)
downloadf2fs-tools-a90c93387fa29554bc177b51ff9920d42663522c.tar.gz
fsck.f2fs: Fix slow fsck in auto-fix mode am: 3973c080af
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/f2fs-tools/+/11910345 Change-Id: Idee92a750c23506c403d906c2a1357a2f1c2351d
-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)