fsck.f2fs: cache all nat entries and check each of them
authorSheng Yong <shengyong1@huawei.com>
Mon, 14 Mar 2016 06:16:55 +0000 (14:16 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 22 Mar 2016 21:10:00 +0000 (14:10 -0700)
All nat entries are cached during building nat_area_bitmap, so that, in
fsck_chk_meta, we can get and check blk_addr and ino directly, to see if
they are in the valid range. Also, blk_addr is checked to see if the block
is valid in sit's valid maps.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fsck/fsck.c
fsck/fsck.h
fsck/mount.c

index 7100397..bc7655c 100644 (file)
@@ -1581,6 +1581,46 @@ int fsck_chk_meta(struct f2fs_sb_info *sbi)
                return -EINVAL;
        }
 
+       /*check nat entry with sit_area_bitmap*/
+       for (i = 0; i < fsck->nr_nat_entries; i++) {
+               u32 blk = le32_to_cpu(fsck->entries[i].block_addr);
+               nid_t ino = le32_to_cpu(fsck->entries[i].ino);
+
+               if (!blk)
+                       /*
+                        * skip entry whose ino is 0, otherwise, we will
+                        * get a negative number by BLKOFF_FROM_MAIN(sbi, blk)
+                        */
+                       continue;
+
+               if (!IS_VALID_BLK_ADDR(sbi, blk)) {
+                       MSG(0, "\tError: nat entry[ino %u block_addr 0x%x]"
+                               " is in valid\n",
+                               ino, blk);
+                       return -EINVAL;
+               }
+
+               if (!f2fs_test_sit_bitmap(sbi, blk)) {
+                       MSG(0, "\tError: nat entry[ino %u block_addr 0x%x]"
+                               " not find it in sit_area_bitmap\n",
+                               ino, blk);
+                       return -EINVAL;
+               }
+
+               if (!IS_VALID_NID(sbi, ino)) {
+                       MSG(0, "\tError: nat_entry->ino %u exceeds the range"
+                               " of nat entries %u\n",
+                               ino, fsck->nr_nat_entries);
+                       return -EINVAL;
+               }
+
+               if (!f2fs_test_bit(ino, fsck->nat_area_bitmap)) {
+                       MSG(0, "\tError: nat_entry->ino %u is not set in"
+                               " nat_area_bitmap\n", ino);
+                       return -EINVAL;
+               }
+       }
+
        return 0;
 }
 
index da4e6ad..5fc214e 100644 (file)
@@ -76,6 +76,7 @@ struct f2fs_fsck {
        u32 nr_nat_entries;
 
        u32 dentry_depth;
+       struct f2fs_nat_entry *entries;
        u32 nat_valid_inode_cnt;
 };
 
index 4f907ef..1d99375 100644 (file)
@@ -1644,6 +1644,10 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
        fsck->nat_area_bitmap = calloc(fsck->nat_area_bitmap_sz, 1);
        ASSERT(fsck->nat_area_bitmap != NULL);
 
+       fsck->entries = calloc(sizeof(struct f2fs_nat_entry),
+                                       fsck->nr_nat_entries);
+       ASSERT(fsck->entries);
+
        for (block_off = 0; block_off < nr_nat_blks; block_off++) {
 
                seg_off = block_off >> sbi->log_blocks_per_seg;
@@ -1691,6 +1695,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
                                        DBG(3, "nid[0x%x] in nat cache\n",
                                                                nid + i);
                                }
+
+                               fsck->entries[nid + i] = raw_nat;
                        } else {
                                node_info_from_raw_nat(&ni,
                                                &nat_block->entries[i]);
@@ -1708,7 +1714,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
                                         * nat_area_bitmap, fsck_verify will
                                         * nullify it
                                         */
-                                       ASSERT_MSG("Invalid nat entry[0]: blk_addr[0x%x]\n",
+                                       ASSERT_MSG("Invalid nat entry[0]: "
+                                               "blk_addr[0x%x]\n",
                                                ni.blk_addr);
                                        config.fix_on = 1;
                                        fsck->chk.valid_nat_entry_cnt--;
@@ -1718,6 +1725,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
                                        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];
                        }
                }
        }