void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
{
+ struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
+ struct f2fs_journal *journal = &curseg->sum_blk->journal;
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct f2fs_nat_block *nat_block;
+ struct node_info ni;
u32 nid, nr_nat_blks;
pgoff_t block_off;
pgoff_t block_addr;
nid = block_off * NAT_ENTRY_PER_BLOCK;
for (i = 0; i < NAT_ENTRY_PER_BLOCK; i++) {
- struct f2fs_nat_entry raw_nat;
- struct node_info ni;
ni.nid = nid + i;
if ((nid + i) == F2FS_NODE_INO(sbi) ||
continue;
}
- if (lookup_nat_in_journal(sbi, nid + i,
- &raw_nat) >= 0) {
- node_info_from_raw_nat(&ni, &raw_nat);
- if ((ni.ino == 0x0 && ni.blk_addr != 0x0))
- ASSERT_MSG("\tError: ino[0x%8x] or blk_addr[0x%16x]"
- " is invalid\n",
- ni.ino, ni.blk_addr);
- if (ni.ino == (nid + i) && ni.blk_addr != 0) {
- fsck->nat_valid_inode_cnt++;
- DBG(3, "ino[0x%8x] maybe is inode\n",
- ni.ino);
- }
- if (ni.blk_addr != 0x0) {
- f2fs_set_bit(nid + i,
- fsck->nat_area_bitmap);
- fsck->chk.valid_nat_entry_cnt++;
- DBG(3, "nid[0x%x] in nat cache\n",
- nid + i);
- }
+ node_info_from_raw_nat(&ni, &nat_block->entries[i]);
+ if (ni.blk_addr == 0x0)
+ continue;
+ if (ni.ino == 0x0) {
+ ASSERT_MSG("\tError: ino[0x%8x] or blk_addr[0x%16x]"
+ " is invalid\n", ni.ino, ni.blk_addr);
+ }
+ if (ni.ino == (nid + i)) {
+ fsck->nat_valid_inode_cnt++;
+ DBG(3, "ino[0x%8x] maybe is inode\n", ni.ino);
+ }
+ if (nid + i == 0) {
+ /*
+ * nat entry [0] must be null. If
+ * it is corrupted, set its bit in
+ * nat_area_bitmap, fsck_verify will
+ * nullify it
+ */
+ ASSERT_MSG("Invalid nat entry[0]: "
+ "blk_addr[0x%x]\n", ni.blk_addr);
+ c.fix_on = 1;
+ fsck->chk.valid_nat_entry_cnt--;
+ }
- fsck->entries[nid + i] = raw_nat;
- } else {
- node_info_from_raw_nat(&ni,
- &nat_block->entries[i]);
- if ((ni.ino == 0x0 && ni.blk_addr != 0x0))
- ASSERT_MSG("\tError: ino[0x%8x] or blk_addr[0x%16x]"
- " is invalid\n",
- ni.ino, ni.blk_addr);
- if (ni.ino == (nid + i) && ni.blk_addr != 0) {
- fsck->nat_valid_inode_cnt++;
- DBG(3, "ino[0x%8x] maybe is inode\n",
- ni.ino);
- }
- if (ni.blk_addr == 0)
- continue;
- if (nid + i == 0) {
- /*
- * nat entry [0] must be null. If
- * it is corrupted, set its bit in
- * nat_area_bitmap, fsck_verify will
- * nullify it
- */
- ASSERT_MSG("Invalid nat entry[0]: "
- "blk_addr[0x%x]\n",
- ni.blk_addr);
- c.fix_on = 1;
- fsck->chk.valid_nat_entry_cnt--;
- }
+ DBG(3, "nid[0x%8x] addr[0x%16x] ino[0x%8x]\n",
+ nid + i, ni.blk_addr, ni.ino);
+ f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
+ fsck->chk.valid_nat_entry_cnt++;
+
+ fsck->entries[nid + i] = nat_block->entries[i];
+ }
+ }
+
+ /* Traverse nat journal, update the corresponding entries */
+ for (i = 0; i < nats_in_cursum(journal); i++) {
+ struct f2fs_nat_entry raw_nat;
+ nid = le32_to_cpu(nid_in_journal(journal, i));
+ ni.nid = nid;
- DBG(3, "nid[0x%8x] addr[0x%16x] ino[0x%8x]\n",
- nid + i, ni.blk_addr, ni.ino);
- f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
- fsck->chk.valid_nat_entry_cnt++;
+ DBG(3, "==> Found nid [0x%x] in nat cache, update it\n", nid);
- fsck->entries[nid + i] = nat_block->entries[i];
+ /* Clear the original bit and count */
+ if (fsck->entries[nid].block_addr != 0x0) {
+ fsck->chk.valid_nat_entry_cnt--;
+ f2fs_clear_bit(nid, fsck->nat_area_bitmap);
+ if (fsck->entries[nid].ino == nid)
+ fsck->nat_valid_inode_cnt--;
+ }
+
+ /* Use nat entries in journal */
+ memcpy(&raw_nat, &nat_in_journal(journal, i),
+ sizeof(struct f2fs_nat_entry));
+ node_info_from_raw_nat(&ni, &raw_nat);
+ if (ni.blk_addr != 0x0) {
+ if (ni.ino == 0x0)
+ ASSERT_MSG("\tError: ino[0x%8x] or blk_addr[0x%16x]"
+ " is invalid\n", ni.ino, ni.blk_addr);
+ if (ni.ino == nid) {
+ fsck->nat_valid_inode_cnt++;
+ DBG(3, "ino[0x%8x] maybe is inode\n", ni.ino);
}
+ f2fs_set_bit(nid, fsck->nat_area_bitmap);
+ fsck->chk.valid_nat_entry_cnt++;
+ DBG(3, "nid[0x%x] in nat cache\n", nid);
}
+ fsck->entries[nid] = raw_nat;
}
free(nat_block);