This patch is to dump inode which blkaddr belongs in.
Usage:
dump.f2fs /dev/sdx -b blk_addr (in 4KB)
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
#define BUF_SZ 80
+const char *seg_type_name[SEG_TYPE_MAX] = {
+ "SEG_TYPE_DATA",
+ "SEG_TYPE_CUR_DATA",
+ "SEG_TYPE_NODE",
+ "SEG_TYPE_CUR_NODE",
+};
+
void sit_dump(struct f2fs_sb_info *sbi, int start_sit, int end_sit)
{
struct seg_entry *se;
return 0;
}
-void dump_cleanup(struct f2fs_sb_info *sbi)
+int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
{
- f2fs_do_umount(sbi);
+ nid_t ino, nid;
+ int ret;
+ struct f2fs_summary sum_entry;
+ struct node_info ni;
+ struct f2fs_node *node_blk;
+
+ ret = get_sum_entry(sbi, blk_addr, &sum_entry);
+ nid = le32_to_cpu(sum_entry.nid);
+
+ DBG(1, "Node ID [0x%x]\n", nid);
+ DBG(1, "Segment Type [%s]\n", seg_type_name[ret]);
+ DBG(1, "version [%d]\n", sum_entry.version);
+ DBG(1, "ofs_in_node [%d]\n", sum_entry.ofs_in_node);
+ ret = get_node_info(sbi, nid, &ni);
+ ASSERT(ret >= 0);
+
+ node_blk = calloc(BLOCK_SZ, 1);
+
+read_node_blk:
+ dev_read_block(node_blk, ni.blk_addr);
+
+ ino = le32_to_cpu(node_blk->footer.ino);
+ nid = le32_to_cpu(node_blk->footer.nid);
+ if (ino == nid) {
+ print_inode_info(&node_blk->i);
+ } else {
+ ret = get_node_info(sbi, ino, &ni);
+ goto read_node_blk;
+ }
+
+ free(node_blk);
+ return ino;
}
void fsck_free(struct f2fs_sb_info *sbi)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
- if (fsck->main_area_bitmap)
+ if (fsck->main_area_bitmap)
free(fsck->main_area_bitmap);
if (fsck->nat_area_bitmap)
if (fsck->sit_area_bitmap)
free(fsck->sit_area_bitmap);
-
- f2fs_do_umount(sbi);
}
SEG_TYPE_CUR_DATA,
SEG_TYPE_NODE,
SEG_TYPE_CUR_NODE,
+ SEG_TYPE_MAX,
};
-
extern int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 x_nid, u32 *blk_cnt);
extern int fsck_chk_orphan_node(struct f2fs_sb_info *sbi);
int last_blk);
extern void print_node_info(struct f2fs_node *node_block);
+extern void print_inode_info(struct f2fs_inode *inode);
extern struct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi, unsigned int segno);
extern int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summary_block *sum_blk);
extern int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *sum_entry);
int end_sit;
int start_ssa;
int end_ssa;
+ u32 blk_addr;
};
extern void sit_dump(struct f2fs_sb_info *sbi, int start_sit, int end_sit);
extern void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa);
extern int dump_node(struct f2fs_sb_info *sbi, nid_t nid);
-extern void dump_cleanup(struct f2fs_sb_info *sbi);
#endif /* _FSCK_H_ */
MSG(0, " -i inode no (hex)\n");
MSG(0, " -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]\n");
MSG(0, " -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
+ MSG(0, " -b blk_addr (in 4KB)\n");
exit(1);
}
}
}
} else if (!strcmp("dump.f2fs", prog)) {
- const char *option_string = "d:i:s:a:";
+ const char *option_string = "d:i:s:a:b:";
static struct dump_option dump_opt = {
.nid = 3, /* default root ino */
.start_sit = -1,
.end_sit = -1,
.start_ssa = -1,
.end_ssa = -1,
+ .blk_addr = -1,
};
config.func = DUMP;
case 'a':
sscanf(optarg, "%d~%d", &dump_opt.start_ssa, &dump_opt.end_ssa);
break;
+ case 'b':
+ sscanf(optarg, "%d", &dump_opt.blk_addr);
+ break;
default:
MSG(0, "\tError: Unknown option %c\n", option);
dump_usage();
int do_dump(struct f2fs_sb_info *sbi)
{
struct dump_option *opt = (struct dump_option *)config.private;
+ int ret;
+
+ ret = fsck_init(sbi);
+ if (ret < 0)
+ return ret;
if (opt->end_sit == -1)
opt->end_sit = SM_I(sbi)->main_segments;
sit_dump(sbi, opt->start_sit, opt->end_sit);
if (opt->start_ssa != -1)
ssa_dump(sbi, opt->start_ssa, opt->end_ssa);
+ if (opt->blk_addr != -1) {
+ dump_inode_from_blkaddr(sbi, opt->blk_addr);
+ goto cleanup;
+ }
dump_node(sbi, opt->nid);
- dump_cleanup(sbi);
+cleanup:
+ fsck_free(sbi);
return 0;
}
break;
}
+ f2fs_do_umount(sbi);
printf("\nDone.\n");
return ret;
}
DBG(0, "Node ID [0x%x:%u] is inode\n", nid, nid);
print_inode_info(&node_block->i);
} else {
+ int i;
+ u32 *dump_blk = (u32 *)node_block;
DBG(0, "Node ID [0x%x:%u] is direct node or indirect node.\n", nid, nid);
+ for (i = 0; i <= 10; i++)
+ MSG(0, "[%d]\t\t\t[0x%8x : %d]\n", i, dump_blk[i], dump_blk[i]);
}
}
int seg_off, entry_off;
int ret;
- if (nid / NAT_ENTRY_PER_BLOCK > (fsck->nat_area_bitmap_sz * 8)) {
- DBG(0, "\n");
+ if ((nid / NAT_ENTRY_PER_BLOCK) > fsck->nr_nat_entries) {
+ DBG(0, "nid is over max nid\n");
return -EINVAL;
}
fsck->chk.sit_valid_blocks = sum_vblocks;
fsck->chk.sit_free_segs = free_segs;
- DBG(0, "Blocks [0x%x] Free Segs [0x%x]\n", sum_vblocks, free_segs);
+ DBG(0, "Blocks [0x%x] Free Segs [0x%x]\n\n", sum_vblocks, free_segs);
return 0;
}