• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
sit_dump(struct f2fs_sb_info * sbi,int start_sit,int end_sit)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 
ssa_dump(struct f2fs_sb_info * sbi,int start_ssa,int end_ssa)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 
dump_node(struct f2fs_sb_info * sbi,nid_t nid)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 
dump_inode_from_blkaddr(struct f2fs_sb_info * sbi,u32 blk_addr)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