aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-07-10 23:08:14 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-07-10 23:08:14 +0000
commita4774aad9cbcfef232b65f521e940068e9633e5d (patch)
tree965a63827bed6d5df7fbd1b2db1498d1f22f0ae8
parent95042ab4ba4c39a75fd55f223f5ed4cc1f911fa6 (diff)
parent75ec64039d6af9b04906b018c67342a6d2a09f1c (diff)
downloadf2fs-tools-android11-qpr1-d-release.tar.gz
Change-Id: Iab3e9fedaba0d22917ac28d0cceb80c99b95dbd1
-rw-r--r--fsck/f2fs.h3
-rw-r--r--fsck/mount.c102
2 files changed, 75 insertions, 30 deletions
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 2a00d35..76e8272 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -273,6 +273,9 @@ struct f2fs_sb_info {
u32 free_segments;
int cp_backuped; /* backup valid checkpoint */
+
+ /* true if late_build_segment_manger() is called */
+ bool seg_manager_done;
};
static inline struct f2fs_super_block *F2FS_RAW_SUPER(struct f2fs_sb_info *sbi)
diff --git a/fsck/mount.c b/fsck/mount.c
index fb45941..6d467c8 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)
@@ -2272,7 +2284,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi)
return 0;
}
-static int build_segment_manager(struct f2fs_sb_info *sbi)
+static int early_build_segment_manager(struct f2fs_sb_info *sbi)
{
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
@@ -2294,7 +2306,7 @@ static int build_segment_manager(struct f2fs_sb_info *sbi)
sm_info->main_segments = get_sb(segment_count_main);
sm_info->ssa_blkaddr = get_sb(ssa_blkaddr);
- if (build_sit_info(sbi) || build_curseg(sbi) || build_sit_entries(sbi)) {
+ if (build_sit_info(sbi) || build_curseg(sbi)) {
free(sm_info);
return -ENOMEM;
}
@@ -2302,6 +2314,20 @@ static int build_segment_manager(struct f2fs_sb_info *sbi)
return 0;
}
+static int late_build_segment_manager(struct f2fs_sb_info *sbi)
+{
+ if (sbi->seg_manager_done)
+ return 1; /* this function was already called */
+
+ sbi->seg_manager_done = true;
+ if (build_sit_entries(sbi)) {
+ free (sbi->sm_info);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
void build_sit_area_bitmap(struct f2fs_sb_info *sbi)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -3375,6 +3401,12 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
if (ret)
goto out;
+ ret = late_build_segment_manager(sbi);
+ if (ret < 0) {
+ ERR_MSG("late_build_segment_manager failed\n");
+ goto out;
+ }
+
ret = traverse_dnodes(sbi, &inode_list);
out:
destroy_fsync_dnodes(&inode_list);
@@ -3445,8 +3477,8 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
sbi->last_valid_block_count = sbi->total_valid_block_count;
sbi->alloc_valid_block_count = 0;
- if (build_segment_manager(sbi)) {
- ERR_MSG("build_segment_manager failed\n");
+ if (early_build_segment_manager(sbi)) {
+ ERR_MSG("early_build_segment_manager failed\n");
return -1;
}
@@ -3463,6 +3495,16 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
if (!f2fs_should_proceed(sb, get_cp(ckpt_flags)))
return 1;
+ if (late_build_segment_manager(sbi) < 0) {
+ ERR_MSG("late_build_segment_manager failed\n");
+ 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)