Home | History | Annotate | Download | only in fsck
      1 /**
      2  * dump.c
      3  *
      4  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
      5  *             http://www.samsung.com/
      6  *
      7  * This program is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License version 2 as
      9  * published by the Free Software Foundation.
     10  */
     11 #include "fsck.h"
     12 
     13 #define BUF_SZ	80
     14 
     15 const char *seg_type_name[SEG_TYPE_MAX] = {
     16 	"SEG_TYPE_DATA",
     17 	"SEG_TYPE_CUR_DATA",
     18 	"SEG_TYPE_NODE",
     19 	"SEG_TYPE_CUR_NODE",
     20 };
     21 
     22 void sit_dump(struct f2fs_sb_info *sbi, int start_sit, int end_sit)
     23 {
     24 	struct seg_entry *se;
     25 	int segno;
     26 	char buf[BUF_SZ];
     27 	u32 free_segs = 0;;
     28 	u64 valid_blocks = 0;
     29 	int ret;
     30 	int fd;
     31 
     32 	fd = open("dump_sit", O_CREAT|O_WRONLY|O_TRUNC, 0666);
     33 	ASSERT(fd >= 0);
     34 
     35 	for (segno = start_sit; segno < end_sit; segno++) {
     36 		se = get_seg_entry(sbi, segno);
     37 
     38 		memset(buf, 0, BUF_SZ);
     39 		snprintf(buf, BUF_SZ, "%5d %8d\n", segno, se->valid_blocks);
     40 
     41 		ret = write(fd, buf, strlen(buf));
     42 		ASSERT(ret >= 0);
     43 
     44 		DBG(4, "SIT[0x%3x] : 0x%x\n", segno, se->valid_blocks);
     45 		if (se->valid_blocks == 0x0) {
     46 			free_segs++;
     47 		} else {
     48 			ASSERT(se->valid_blocks <= 512);
     49 			valid_blocks += se->valid_blocks;
     50 		}
     51 	}
     52 
     53 	memset(buf, 0, BUF_SZ);
     54 	snprintf(buf, BUF_SZ, "valid_segs:%d\t free_segs:%d\n",
     55 			SM_I(sbi)->main_segments - free_segs, free_segs);
     56 	ret = write(fd, buf, strlen(buf));
     57 	ASSERT(ret >= 0);
     58 
     59 	close(fd);
     60 	DBG(1, "Blocks [0x%lx] Free Segs [0x%x]\n", valid_blocks, free_segs);
     61 }
     62 
     63 void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa)
     64 {
     65 	struct f2fs_summary_block sum_blk;
     66 	char buf[BUF_SZ];
     67 	int segno, i, ret;
     68 	int fd;
     69 
     70 	fd = open("dump_ssa", O_CREAT|O_WRONLY|O_TRUNC, 0666);
     71 	ASSERT(fd >= 0);
     72 
     73 	snprintf(buf, BUF_SZ, "Note: dump.f2fs -b blkaddr = 0x%x + segno * "
     74 				" 0x200 + offset\n",
     75 				sbi->sm_info->main_blkaddr);
     76 	ret = write(fd, buf, strlen(buf));
     77 	ASSERT(ret >= 0);
     78 
     79 	for (segno = start_ssa; segno < end_ssa; segno++) {
     80 		ret = get_sum_block(sbi, segno, &sum_blk);
     81 
     82 		memset(buf, 0, BUF_SZ);
     83 		switch (ret) {
     84 		case SEG_TYPE_CUR_NODE:
     85 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Current Node\n", segno);
     86 			break;
     87 		case SEG_TYPE_CUR_DATA:
     88 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Current Data\n", segno);
     89 			break;
     90 		case SEG_TYPE_NODE:
     91 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Node\n", segno);
     92 			break;
     93 		case SEG_TYPE_DATA:
     94 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Data\n", segno);
     95 			break;
     96 		}
     97 		ret = write(fd, buf, strlen(buf));
     98 		ASSERT(ret >= 0);
     99 
    100 		for (i = 0; i < ENTRIES_IN_SUM; i++) {
    101 			memset(buf, 0, BUF_SZ);
    102 			if (i % 10 == 0) {
    103 				buf[0] = '\n';
    104 				ret = write(fd, buf, strlen(buf));
    105 				ASSERT(ret >= 0);
    106 			}
    107 			snprintf(buf, BUF_SZ, "[%3d: %6x]", i,
    108 					le32_to_cpu(sum_blk.entries[i].nid));
    109 			ret = write(fd, buf, strlen(buf));
    110 			ASSERT(ret >= 0);
    111 		}
    112 	}
    113 	close(fd);
    114 }
    115 
    116 int dump_node(struct f2fs_sb_info *sbi, nid_t nid)
    117 {
    118 	struct node_info ni;
    119 	struct f2fs_node *node_blk;
    120 	int ret;
    121 
    122 	ret = get_node_info(sbi, nid, &ni);
    123 	ASSERT(ret >= 0);
    124 
    125 	node_blk = calloc(BLOCK_SZ, 1);
    126 	dev_read_block(node_blk, ni.blk_addr);
    127 
    128 	DBG(1, "Node ID               [0x%x]\n", nid);
    129 	DBG(1, "nat_entry.block_addr  [0x%x]\n", ni.blk_addr);
    130 	DBG(1, "nat_entry.version     [0x%x]\n", ni.version);
    131 	DBG(1, "nat_entry.ino         [0x%x]\n", ni.ino);
    132 
    133 	if (ni.blk_addr == 0x0) {
    134 		MSG(0, "Invalid nat entry\n\n");
    135 	}
    136 
    137 	DBG(1, "node_blk.footer.ino [0x%x]\n", le32_to_cpu(node_blk->footer.ino));
    138 	DBG(1, "node_blk.footer.nid [0x%x]\n", le32_to_cpu(node_blk->footer.nid));
    139 
    140 	if (le32_to_cpu(node_blk->footer.ino) == ni.ino &&
    141 			le32_to_cpu(node_blk->footer.nid) == ni.nid) {
    142 		print_node_info(node_blk);
    143 	} else {
    144 		MSG(0, "Invalid node block\n\n");
    145 	}
    146 
    147 	free(node_blk);
    148 	return 0;
    149 }
    150 
    151 int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
    152 {
    153 	nid_t ino, nid;
    154 	int type, ret;
    155 	struct f2fs_summary sum_entry;
    156 	struct node_info ni;
    157 	struct f2fs_node *node_blk;
    158 
    159 	type = get_sum_entry(sbi, blk_addr, &sum_entry);
    160 	nid = le32_to_cpu(sum_entry.nid);
    161 
    162 	ret = get_node_info(sbi, nid, &ni);
    163 	ASSERT(ret >= 0);
    164 
    165 	DBG(1, "Note: blkaddr = main_blkaddr + segno * 512 + offset\n");
    166 	DBG(1, "Block_addr            [0x%x]\n", blk_addr);
    167 	DBG(1, " - Segno              [0x%x]\n", GET_SEGNO(sbi, blk_addr));
    168 	DBG(1, " - Offset             [0x%x]\n", OFFSET_IN_SEG(sbi, blk_addr));
    169 	DBG(1, "SUM.nid               [0x%x]\n", nid);
    170 	DBG(1, "SUM.type              [%s]\n", seg_type_name[type]);
    171 	DBG(1, "SUM.version           [%d]\n", sum_entry.version);
    172 	DBG(1, "SUM.ofs_in_node       [%d]\n", sum_entry.ofs_in_node);
    173 	DBG(1, "NAT.blkaddr           [0x%x]\n", ni.blk_addr);
    174 	DBG(1, "NAT.ino               [0x%x]\n", ni.ino);
    175 
    176 	node_blk = calloc(BLOCK_SZ, 1);
    177 
    178 read_node_blk:
    179 	dev_read_block(node_blk, blk_addr);
    180 
    181 	ino = le32_to_cpu(node_blk->footer.ino);
    182 	nid = le32_to_cpu(node_blk->footer.nid);
    183 
    184 	if (ino == nid) {
    185 		print_node_info(node_blk);
    186 	} else {
    187 		ret = get_node_info(sbi, ino, &ni);
    188 		goto read_node_blk;
    189 	}
    190 
    191 	free(node_blk);
    192 	return ino;
    193 }
    194