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