xref: /aosp_15_r20/external/f2fs-tools/fsck/dump.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker /**
2*59bfda1fSAndroid Build Coastguard Worker  * dump.c
3*59bfda1fSAndroid Build Coastguard Worker  *
4*59bfda1fSAndroid Build Coastguard Worker  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5*59bfda1fSAndroid Build Coastguard Worker  *             http://www.samsung.com/
6*59bfda1fSAndroid Build Coastguard Worker  *
7*59bfda1fSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify
8*59bfda1fSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License version 2 as
9*59bfda1fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
10*59bfda1fSAndroid Build Coastguard Worker  */
11*59bfda1fSAndroid Build Coastguard Worker #include <inttypes.h>
12*59bfda1fSAndroid Build Coastguard Worker 
13*59bfda1fSAndroid Build Coastguard Worker #include "node.h"
14*59bfda1fSAndroid Build Coastguard Worker #include "fsck.h"
15*59bfda1fSAndroid Build Coastguard Worker #include "xattr.h"
16*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_ATTR_XATTR_H
17*59bfda1fSAndroid Build Coastguard Worker #include <attr/xattr.h>
18*59bfda1fSAndroid Build Coastguard Worker #endif
19*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_XATTR_H
20*59bfda1fSAndroid Build Coastguard Worker #include <linux/xattr.h>
21*59bfda1fSAndroid Build Coastguard Worker #endif
22*59bfda1fSAndroid Build Coastguard Worker #include <locale.h>
23*59bfda1fSAndroid Build Coastguard Worker 
24*59bfda1fSAndroid Build Coastguard Worker #define BUF_SZ	128
25*59bfda1fSAndroid Build Coastguard Worker 
26*59bfda1fSAndroid Build Coastguard Worker /* current extent info */
27*59bfda1fSAndroid Build Coastguard Worker struct extent_info dump_extent;
28*59bfda1fSAndroid Build Coastguard Worker 
29*59bfda1fSAndroid Build Coastguard Worker const char *seg_type_name[SEG_TYPE_MAX + 1] = {
30*59bfda1fSAndroid Build Coastguard Worker 	"SEG_TYPE_DATA",
31*59bfda1fSAndroid Build Coastguard Worker 	"SEG_TYPE_CUR_DATA",
32*59bfda1fSAndroid Build Coastguard Worker 	"SEG_TYPE_NODE",
33*59bfda1fSAndroid Build Coastguard Worker 	"SEG_TYPE_CUR_NODE",
34*59bfda1fSAndroid Build Coastguard Worker 	"SEG_TYPE_NONE",
35*59bfda1fSAndroid Build Coastguard Worker };
36*59bfda1fSAndroid Build Coastguard Worker 
nat_dump(struct f2fs_sb_info * sbi,nid_t start_nat,nid_t end_nat)37*59bfda1fSAndroid Build Coastguard Worker void nat_dump(struct f2fs_sb_info *sbi, nid_t start_nat, nid_t end_nat)
38*59bfda1fSAndroid Build Coastguard Worker {
39*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_nat_block *nat_block;
40*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_block;
41*59bfda1fSAndroid Build Coastguard Worker 	struct node_footer *footer;
42*59bfda1fSAndroid Build Coastguard Worker 	nid_t nid;
43*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t block_addr;
44*59bfda1fSAndroid Build Coastguard Worker 	char buf[BUF_SZ];
45*59bfda1fSAndroid Build Coastguard Worker 	int fd, ret, pack;
46*59bfda1fSAndroid Build Coastguard Worker 
47*59bfda1fSAndroid Build Coastguard Worker 	nat_block = (struct f2fs_nat_block *)calloc(F2FS_BLKSIZE, 1);
48*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(nat_block);
49*59bfda1fSAndroid Build Coastguard Worker 	node_block = (struct f2fs_node *)calloc(F2FS_BLKSIZE, 1);
50*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_block);
51*59bfda1fSAndroid Build Coastguard Worker 	footer = F2FS_NODE_FOOTER(node_block);
52*59bfda1fSAndroid Build Coastguard Worker 
53*59bfda1fSAndroid Build Coastguard Worker 	fd = open("dump_nat", O_CREAT|O_WRONLY|O_TRUNC, 0666);
54*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(fd >= 0);
55*59bfda1fSAndroid Build Coastguard Worker 
56*59bfda1fSAndroid Build Coastguard Worker 	for (nid = start_nat; nid < end_nat; nid++) {
57*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_nat_entry raw_nat;
58*59bfda1fSAndroid Build Coastguard Worker 		struct node_info ni;
59*59bfda1fSAndroid Build Coastguard Worker 		int len;
60*59bfda1fSAndroid Build Coastguard Worker 		if(nid == 0 || nid == F2FS_NODE_INO(sbi) ||
61*59bfda1fSAndroid Build Coastguard Worker 					nid == F2FS_META_INO(sbi))
62*59bfda1fSAndroid Build Coastguard Worker 			continue;
63*59bfda1fSAndroid Build Coastguard Worker 
64*59bfda1fSAndroid Build Coastguard Worker 		ni.nid = nid;
65*59bfda1fSAndroid Build Coastguard Worker 		block_addr = current_nat_addr(sbi, nid, &pack);
66*59bfda1fSAndroid Build Coastguard Worker 
67*59bfda1fSAndroid Build Coastguard Worker 		if (lookup_nat_in_journal(sbi, nid, &raw_nat) >= 0) {
68*59bfda1fSAndroid Build Coastguard Worker 			node_info_from_raw_nat(&ni, &raw_nat);
69*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_read_block(node_block, ni.blk_addr);
70*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
71*59bfda1fSAndroid Build Coastguard Worker 			if (ni.blk_addr != 0x0) {
72*59bfda1fSAndroid Build Coastguard Worker 				len = snprintf(buf, BUF_SZ,
73*59bfda1fSAndroid Build Coastguard Worker 					"nid:%5u\tino:%5u\toffset:%5u"
74*59bfda1fSAndroid Build Coastguard Worker 					"\tblkaddr:%10u\tpack:%d"
75*59bfda1fSAndroid Build Coastguard Worker 					"\tcp_ver:0x%" PRIx64 "\n",
76*59bfda1fSAndroid Build Coastguard Worker 					ni.nid, ni.ino,
77*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(footer->flag) >> OFFSET_BIT_SHIFT,
78*59bfda1fSAndroid Build Coastguard Worker 					ni.blk_addr, pack,
79*59bfda1fSAndroid Build Coastguard Worker 					le64_to_cpu(footer->cp_ver));
80*59bfda1fSAndroid Build Coastguard Worker 				ret = write(fd, buf, len);
81*59bfda1fSAndroid Build Coastguard Worker 				ASSERT(ret >= 0);
82*59bfda1fSAndroid Build Coastguard Worker 			}
83*59bfda1fSAndroid Build Coastguard Worker 		} else {
84*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_read_block(nat_block, block_addr);
85*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
86*59bfda1fSAndroid Build Coastguard Worker 			node_info_from_raw_nat(&ni,
87*59bfda1fSAndroid Build Coastguard Worker 					&nat_block->entries[nid % NAT_ENTRY_PER_BLOCK]);
88*59bfda1fSAndroid Build Coastguard Worker 			if (ni.blk_addr == 0)
89*59bfda1fSAndroid Build Coastguard Worker 				continue;
90*59bfda1fSAndroid Build Coastguard Worker 
91*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_read_block(node_block, ni.blk_addr);
92*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
93*59bfda1fSAndroid Build Coastguard Worker 			len = snprintf(buf, BUF_SZ,
94*59bfda1fSAndroid Build Coastguard Worker 				"nid:%5u\tino:%5u\toffset:%5u"
95*59bfda1fSAndroid Build Coastguard Worker 				"\tblkaddr:%10u\tpack:%d"
96*59bfda1fSAndroid Build Coastguard Worker 				"\tcp_ver:0x%" PRIx64 "\n",
97*59bfda1fSAndroid Build Coastguard Worker 				ni.nid, ni.ino,
98*59bfda1fSAndroid Build Coastguard Worker 				le32_to_cpu(footer->flag) >> OFFSET_BIT_SHIFT,
99*59bfda1fSAndroid Build Coastguard Worker 				ni.blk_addr, pack,
100*59bfda1fSAndroid Build Coastguard Worker 				le64_to_cpu(footer->cp_ver));
101*59bfda1fSAndroid Build Coastguard Worker 			ret = write(fd, buf, len);
102*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
103*59bfda1fSAndroid Build Coastguard Worker 		}
104*59bfda1fSAndroid Build Coastguard Worker 	}
105*59bfda1fSAndroid Build Coastguard Worker 
106*59bfda1fSAndroid Build Coastguard Worker 	free(nat_block);
107*59bfda1fSAndroid Build Coastguard Worker 	free(node_block);
108*59bfda1fSAndroid Build Coastguard Worker 
109*59bfda1fSAndroid Build Coastguard Worker 	close(fd);
110*59bfda1fSAndroid Build Coastguard Worker }
111*59bfda1fSAndroid Build Coastguard Worker 
sit_dump(struct f2fs_sb_info * sbi,unsigned int start_sit,unsigned int end_sit)112*59bfda1fSAndroid Build Coastguard Worker void sit_dump(struct f2fs_sb_info *sbi, unsigned int start_sit,
113*59bfda1fSAndroid Build Coastguard Worker 					unsigned int end_sit)
114*59bfda1fSAndroid Build Coastguard Worker {
115*59bfda1fSAndroid Build Coastguard Worker 	struct seg_entry *se;
116*59bfda1fSAndroid Build Coastguard Worker 	struct sit_info *sit_i = SIT_I(sbi);
117*59bfda1fSAndroid Build Coastguard Worker 	unsigned int segno;
118*59bfda1fSAndroid Build Coastguard Worker 	char buf[BUF_SZ];
119*59bfda1fSAndroid Build Coastguard Worker 	u32 free_segs = 0;;
120*59bfda1fSAndroid Build Coastguard Worker 	u64 valid_blocks = 0;
121*59bfda1fSAndroid Build Coastguard Worker 	int ret;
122*59bfda1fSAndroid Build Coastguard Worker 	int fd, i;
123*59bfda1fSAndroid Build Coastguard Worker 	unsigned int offset;
124*59bfda1fSAndroid Build Coastguard Worker 
125*59bfda1fSAndroid Build Coastguard Worker 	fd = open("dump_sit", O_CREAT|O_WRONLY|O_TRUNC, 0666);
126*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(fd >= 0);
127*59bfda1fSAndroid Build Coastguard Worker 
128*59bfda1fSAndroid Build Coastguard Worker 	snprintf(buf, BUF_SZ, "segment_type(0:HD, 1:WD, 2:CD, "
129*59bfda1fSAndroid Build Coastguard Worker 						"3:HN, 4:WN, 5:CN)\n");
130*59bfda1fSAndroid Build Coastguard Worker 	ret = write(fd, buf, strlen(buf));
131*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
132*59bfda1fSAndroid Build Coastguard Worker 
133*59bfda1fSAndroid Build Coastguard Worker 	for (segno = start_sit; segno < end_sit; segno++) {
134*59bfda1fSAndroid Build Coastguard Worker 		se = get_seg_entry(sbi, segno);
135*59bfda1fSAndroid Build Coastguard Worker 		offset = SIT_BLOCK_OFFSET(sit_i, segno);
136*59bfda1fSAndroid Build Coastguard Worker 		memset(buf, 0, BUF_SZ);
137*59bfda1fSAndroid Build Coastguard Worker 		snprintf(buf, BUF_SZ,
138*59bfda1fSAndroid Build Coastguard Worker 		"\nsegno:%8u\tvblocks:%3u\tseg_type:%d\tsit_pack:%d\n\n",
139*59bfda1fSAndroid Build Coastguard Worker 			segno, se->valid_blocks, se->type,
140*59bfda1fSAndroid Build Coastguard Worker 			f2fs_test_bit(offset, sit_i->sit_bitmap) ? 2 : 1);
141*59bfda1fSAndroid Build Coastguard Worker 
142*59bfda1fSAndroid Build Coastguard Worker 		ret = write(fd, buf, strlen(buf));
143*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
144*59bfda1fSAndroid Build Coastguard Worker 
145*59bfda1fSAndroid Build Coastguard Worker 		if (se->valid_blocks == 0x0) {
146*59bfda1fSAndroid Build Coastguard Worker 			free_segs++;
147*59bfda1fSAndroid Build Coastguard Worker 			continue;
148*59bfda1fSAndroid Build Coastguard Worker 		}
149*59bfda1fSAndroid Build Coastguard Worker 
150*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(se->valid_blocks <= 512);
151*59bfda1fSAndroid Build Coastguard Worker 		valid_blocks += se->valid_blocks;
152*59bfda1fSAndroid Build Coastguard Worker 
153*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < 64; i++) {
154*59bfda1fSAndroid Build Coastguard Worker 			memset(buf, 0, BUF_SZ);
155*59bfda1fSAndroid Build Coastguard Worker 			snprintf(buf, BUF_SZ, "  %02x",
156*59bfda1fSAndroid Build Coastguard Worker 					*(se->cur_valid_map + i));
157*59bfda1fSAndroid Build Coastguard Worker 			ret = write(fd, buf, strlen(buf));
158*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
159*59bfda1fSAndroid Build Coastguard Worker 
160*59bfda1fSAndroid Build Coastguard Worker 			if ((i + 1) % 16 == 0) {
161*59bfda1fSAndroid Build Coastguard Worker 				snprintf(buf, BUF_SZ, "\n");
162*59bfda1fSAndroid Build Coastguard Worker 				ret = write(fd, buf, strlen(buf));
163*59bfda1fSAndroid Build Coastguard Worker 				ASSERT(ret >= 0);
164*59bfda1fSAndroid Build Coastguard Worker 			}
165*59bfda1fSAndroid Build Coastguard Worker 		}
166*59bfda1fSAndroid Build Coastguard Worker 	}
167*59bfda1fSAndroid Build Coastguard Worker 
168*59bfda1fSAndroid Build Coastguard Worker 	memset(buf, 0, BUF_SZ);
169*59bfda1fSAndroid Build Coastguard Worker 	snprintf(buf, BUF_SZ,
170*59bfda1fSAndroid Build Coastguard Worker 		"valid_blocks:[0x%" PRIx64 "]\tvalid_segs:%d\t free_segs:%d\n",
171*59bfda1fSAndroid Build Coastguard Worker 			valid_blocks,
172*59bfda1fSAndroid Build Coastguard Worker 			SM_I(sbi)->main_segments - free_segs,
173*59bfda1fSAndroid Build Coastguard Worker 			free_segs);
174*59bfda1fSAndroid Build Coastguard Worker 	ret = write(fd, buf, strlen(buf));
175*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
176*59bfda1fSAndroid Build Coastguard Worker 
177*59bfda1fSAndroid Build Coastguard Worker 	close(fd);
178*59bfda1fSAndroid Build Coastguard Worker }
179*59bfda1fSAndroid Build Coastguard Worker 
ssa_dump(struct f2fs_sb_info * sbi,int start_ssa,int end_ssa)180*59bfda1fSAndroid Build Coastguard Worker void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa)
181*59bfda1fSAndroid Build Coastguard Worker {
182*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_summary_block *sum_blk;
183*59bfda1fSAndroid Build Coastguard Worker 	char buf[BUF_SZ];
184*59bfda1fSAndroid Build Coastguard Worker 	int segno, type, i, ret;
185*59bfda1fSAndroid Build Coastguard Worker 	int fd;
186*59bfda1fSAndroid Build Coastguard Worker 
187*59bfda1fSAndroid Build Coastguard Worker 	fd = open("dump_ssa", O_CREAT|O_WRONLY|O_TRUNC, 0666);
188*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(fd >= 0);
189*59bfda1fSAndroid Build Coastguard Worker 
190*59bfda1fSAndroid Build Coastguard Worker 	snprintf(buf, BUF_SZ, "Note: dump.f2fs -b blkaddr = 0x%x + segno * "
191*59bfda1fSAndroid Build Coastguard Worker 				" 0x200 + offset\n",
192*59bfda1fSAndroid Build Coastguard Worker 				sbi->sm_info->main_blkaddr);
193*59bfda1fSAndroid Build Coastguard Worker 	ret = write(fd, buf, strlen(buf));
194*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
195*59bfda1fSAndroid Build Coastguard Worker 
196*59bfda1fSAndroid Build Coastguard Worker 	for (segno = start_ssa; segno < end_ssa; segno++) {
197*59bfda1fSAndroid Build Coastguard Worker 		sum_blk = get_sum_block(sbi, segno, &type);
198*59bfda1fSAndroid Build Coastguard Worker 
199*59bfda1fSAndroid Build Coastguard Worker 		memset(buf, 0, BUF_SZ);
200*59bfda1fSAndroid Build Coastguard Worker 		switch (type) {
201*59bfda1fSAndroid Build Coastguard Worker 		case SEG_TYPE_CUR_NODE:
202*59bfda1fSAndroid Build Coastguard Worker 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Current Node\n", segno);
203*59bfda1fSAndroid Build Coastguard Worker 			break;
204*59bfda1fSAndroid Build Coastguard Worker 		case SEG_TYPE_CUR_DATA:
205*59bfda1fSAndroid Build Coastguard Worker 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Current Data\n", segno);
206*59bfda1fSAndroid Build Coastguard Worker 			break;
207*59bfda1fSAndroid Build Coastguard Worker 		case SEG_TYPE_NODE:
208*59bfda1fSAndroid Build Coastguard Worker 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Node\n", segno);
209*59bfda1fSAndroid Build Coastguard Worker 			break;
210*59bfda1fSAndroid Build Coastguard Worker 		case SEG_TYPE_DATA:
211*59bfda1fSAndroid Build Coastguard Worker 			snprintf(buf, BUF_SZ, "\n\nsegno: %x, Data\n", segno);
212*59bfda1fSAndroid Build Coastguard Worker 			break;
213*59bfda1fSAndroid Build Coastguard Worker 		}
214*59bfda1fSAndroid Build Coastguard Worker 		ret = write(fd, buf, strlen(buf));
215*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
216*59bfda1fSAndroid Build Coastguard Worker 
217*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < ENTRIES_IN_SUM; i++) {
218*59bfda1fSAndroid Build Coastguard Worker 			memset(buf, 0, BUF_SZ);
219*59bfda1fSAndroid Build Coastguard Worker 			if (i % 10 == 0) {
220*59bfda1fSAndroid Build Coastguard Worker 				buf[0] = '\n';
221*59bfda1fSAndroid Build Coastguard Worker 				ret = write(fd, buf, strlen(buf));
222*59bfda1fSAndroid Build Coastguard Worker 				ASSERT(ret >= 0);
223*59bfda1fSAndroid Build Coastguard Worker 			}
224*59bfda1fSAndroid Build Coastguard Worker 			snprintf(buf, BUF_SZ, "[%3d: %6x]", i,
225*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(sum_blk->entries[i].nid));
226*59bfda1fSAndroid Build Coastguard Worker 			ret = write(fd, buf, strlen(buf));
227*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
228*59bfda1fSAndroid Build Coastguard Worker 		}
229*59bfda1fSAndroid Build Coastguard Worker 		if (type == SEG_TYPE_NODE || type == SEG_TYPE_DATA ||
230*59bfda1fSAndroid Build Coastguard Worker 					type == SEG_TYPE_MAX)
231*59bfda1fSAndroid Build Coastguard Worker 			free(sum_blk);
232*59bfda1fSAndroid Build Coastguard Worker 	}
233*59bfda1fSAndroid Build Coastguard Worker 	close(fd);
234*59bfda1fSAndroid Build Coastguard Worker }
235*59bfda1fSAndroid Build Coastguard Worker 
print_extent(bool last)236*59bfda1fSAndroid Build Coastguard Worker static void print_extent(bool last)
237*59bfda1fSAndroid Build Coastguard Worker {
238*59bfda1fSAndroid Build Coastguard Worker 	if (dump_extent.len == 0)
239*59bfda1fSAndroid Build Coastguard Worker 		goto out;
240*59bfda1fSAndroid Build Coastguard Worker 
241*59bfda1fSAndroid Build Coastguard Worker 	if (dump_extent.len == 1)
242*59bfda1fSAndroid Build Coastguard Worker 		printf(" %d", dump_extent.blk);
243*59bfda1fSAndroid Build Coastguard Worker 	else
244*59bfda1fSAndroid Build Coastguard Worker 		printf(" %d-%d",
245*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.blk,
246*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.blk + dump_extent.len - 1);
247*59bfda1fSAndroid Build Coastguard Worker 	dump_extent.len = 0;
248*59bfda1fSAndroid Build Coastguard Worker out:
249*59bfda1fSAndroid Build Coastguard Worker 	if (last)
250*59bfda1fSAndroid Build Coastguard Worker 		printf("\n");
251*59bfda1fSAndroid Build Coastguard Worker }
252*59bfda1fSAndroid Build Coastguard Worker 
dump_folder_contents(struct f2fs_sb_info * sbi,u8 * bitmap,struct f2fs_dir_entry * dentry,__u8 (* filenames)[F2FS_SLOT_LEN],int max)253*59bfda1fSAndroid Build Coastguard Worker static void dump_folder_contents(struct f2fs_sb_info *sbi, u8 *bitmap,
254*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_dir_entry *dentry,
255*59bfda1fSAndroid Build Coastguard Worker 				__u8 (*filenames)[F2FS_SLOT_LEN], int max)
256*59bfda1fSAndroid Build Coastguard Worker {
257*59bfda1fSAndroid Build Coastguard Worker 	int i;
258*59bfda1fSAndroid Build Coastguard Worker 	int name_len;
259*59bfda1fSAndroid Build Coastguard Worker 	char name[F2FS_NAME_LEN + 1] = {0};
260*59bfda1fSAndroid Build Coastguard Worker 
261*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < max; i++) {
262*59bfda1fSAndroid Build Coastguard Worker 		if (test_bit_le(i, bitmap) == 0)
263*59bfda1fSAndroid Build Coastguard Worker 			continue;
264*59bfda1fSAndroid Build Coastguard Worker 		name_len = le16_to_cpu(dentry[i].name_len);
265*59bfda1fSAndroid Build Coastguard Worker 		if (name_len == 0 || name_len > F2FS_NAME_LEN) {
266*59bfda1fSAndroid Build Coastguard Worker 			MSG(c.force, "Wrong name info\n\n");
267*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(name_len == 0 || name_len > F2FS_NAME_LEN);
268*59bfda1fSAndroid Build Coastguard Worker 		}
269*59bfda1fSAndroid Build Coastguard Worker 		if (name_len == 1 && filenames[i][0] == '.')
270*59bfda1fSAndroid Build Coastguard Worker 			continue;
271*59bfda1fSAndroid Build Coastguard Worker 		if (name_len == 2 && filenames[i][0] == '.' && filenames[i][1] == '.')
272*59bfda1fSAndroid Build Coastguard Worker 			continue;
273*59bfda1fSAndroid Build Coastguard Worker 		strncpy(name, (const char *)filenames[i], name_len);
274*59bfda1fSAndroid Build Coastguard Worker 		name[name_len] = 0;
275*59bfda1fSAndroid Build Coastguard Worker 		dump_node(sbi, le32_to_cpu(dentry[i].ino), 1, NULL, 0, 1, name);
276*59bfda1fSAndroid Build Coastguard Worker 	}
277*59bfda1fSAndroid Build Coastguard Worker }
278*59bfda1fSAndroid Build Coastguard Worker 
dump_data_blk(struct f2fs_sb_info * sbi,__u64 offset,u32 blkaddr,int type)279*59bfda1fSAndroid Build Coastguard Worker static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr, int type)
280*59bfda1fSAndroid Build Coastguard Worker {
281*59bfda1fSAndroid Build Coastguard Worker 	char buf[F2FS_BLKSIZE];
282*59bfda1fSAndroid Build Coastguard Worker 
283*59bfda1fSAndroid Build Coastguard Worker 	if (c.show_file_map) {
284*59bfda1fSAndroid Build Coastguard Worker 		if (c.show_file_map_max_offset < offset) {
285*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(blkaddr == NULL_ADDR);
286*59bfda1fSAndroid Build Coastguard Worker 			return;
287*59bfda1fSAndroid Build Coastguard Worker 		}
288*59bfda1fSAndroid Build Coastguard Worker 		if (!is_valid_data_blkaddr(blkaddr)) {
289*59bfda1fSAndroid Build Coastguard Worker 			print_extent(false);
290*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.blk = 0;
291*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.len = 1;
292*59bfda1fSAndroid Build Coastguard Worker 			print_extent(false);
293*59bfda1fSAndroid Build Coastguard Worker 		} else if (dump_extent.len == 0) {
294*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.blk = blkaddr;
295*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.len = 1;
296*59bfda1fSAndroid Build Coastguard Worker 		} else if (dump_extent.blk + dump_extent.len == blkaddr) {
297*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.len++;
298*59bfda1fSAndroid Build Coastguard Worker 		} else {
299*59bfda1fSAndroid Build Coastguard Worker 			print_extent(false);
300*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.blk = blkaddr;
301*59bfda1fSAndroid Build Coastguard Worker 			dump_extent.len = 1;
302*59bfda1fSAndroid Build Coastguard Worker 		}
303*59bfda1fSAndroid Build Coastguard Worker 		return;
304*59bfda1fSAndroid Build Coastguard Worker 	}
305*59bfda1fSAndroid Build Coastguard Worker 
306*59bfda1fSAndroid Build Coastguard Worker 	if (blkaddr == NULL_ADDR)
307*59bfda1fSAndroid Build Coastguard Worker 		return;
308*59bfda1fSAndroid Build Coastguard Worker 
309*59bfda1fSAndroid Build Coastguard Worker 	/* get data */
310*59bfda1fSAndroid Build Coastguard Worker 	if (blkaddr == NEW_ADDR ||
311*59bfda1fSAndroid Build Coastguard Worker 			!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
312*59bfda1fSAndroid Build Coastguard Worker 		memset(buf, 0, F2FS_BLKSIZE);
313*59bfda1fSAndroid Build Coastguard Worker 	} else {
314*59bfda1fSAndroid Build Coastguard Worker 		int ret;
315*59bfda1fSAndroid Build Coastguard Worker 
316*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_read_block(buf, blkaddr);
317*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
318*59bfda1fSAndroid Build Coastguard Worker 	}
319*59bfda1fSAndroid Build Coastguard Worker 
320*59bfda1fSAndroid Build Coastguard Worker 	if (S_ISDIR(type)) {
321*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_dentry_block *d = (struct f2fs_dentry_block *) buf;
322*59bfda1fSAndroid Build Coastguard Worker 
323*59bfda1fSAndroid Build Coastguard Worker 		dump_folder_contents(sbi, d->dentry_bitmap, F2FS_DENTRY_BLOCK_DENTRIES(d),
324*59bfda1fSAndroid Build Coastguard Worker 					F2FS_DENTRY_BLOCK_FILENAMES(d), NR_DENTRY_IN_BLOCK);
325*59bfda1fSAndroid Build Coastguard Worker #if !defined(__MINGW32__)
326*59bfda1fSAndroid Build Coastguard Worker 	} if (S_ISLNK(type)) {
327*59bfda1fSAndroid Build Coastguard Worker 		dev_write_symlink(buf, c.dump_sym_target_len);
328*59bfda1fSAndroid Build Coastguard Worker #endif
329*59bfda1fSAndroid Build Coastguard Worker 	} else {
330*59bfda1fSAndroid Build Coastguard Worker 		/* write blkaddr */
331*59bfda1fSAndroid Build Coastguard Worker 		dev_write_dump(buf, offset, F2FS_BLKSIZE);
332*59bfda1fSAndroid Build Coastguard Worker 	}
333*59bfda1fSAndroid Build Coastguard Worker }
334*59bfda1fSAndroid Build Coastguard Worker 
dump_node_blk(struct f2fs_sb_info * sbi,int ntype,u32 nid,u32 addr_per_block,u64 * ofs,int type)335*59bfda1fSAndroid Build Coastguard Worker static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype,
336*59bfda1fSAndroid Build Coastguard Worker 				u32 nid, u32 addr_per_block, u64 *ofs, int type)
337*59bfda1fSAndroid Build Coastguard Worker {
338*59bfda1fSAndroid Build Coastguard Worker 	struct node_info ni;
339*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
340*59bfda1fSAndroid Build Coastguard Worker 	u32 skip = 0;
341*59bfda1fSAndroid Build Coastguard Worker 	u32 i, idx = 0;
342*59bfda1fSAndroid Build Coastguard Worker 
343*59bfda1fSAndroid Build Coastguard Worker 	switch (ntype) {
344*59bfda1fSAndroid Build Coastguard Worker 	case TYPE_DIRECT_NODE:
345*59bfda1fSAndroid Build Coastguard Worker 		skip = idx = addr_per_block;
346*59bfda1fSAndroid Build Coastguard Worker 		break;
347*59bfda1fSAndroid Build Coastguard Worker 	case TYPE_INDIRECT_NODE:
348*59bfda1fSAndroid Build Coastguard Worker 		idx = NIDS_PER_BLOCK;
349*59bfda1fSAndroid Build Coastguard Worker 		skip = idx * addr_per_block;
350*59bfda1fSAndroid Build Coastguard Worker 		break;
351*59bfda1fSAndroid Build Coastguard Worker 	case TYPE_DOUBLE_INDIRECT_NODE:
352*59bfda1fSAndroid Build Coastguard Worker 		skip = 0;
353*59bfda1fSAndroid Build Coastguard Worker 		idx = NIDS_PER_BLOCK;
354*59bfda1fSAndroid Build Coastguard Worker 		break;
355*59bfda1fSAndroid Build Coastguard Worker 	}
356*59bfda1fSAndroid Build Coastguard Worker 
357*59bfda1fSAndroid Build Coastguard Worker 	if (nid == 0) {
358*59bfda1fSAndroid Build Coastguard Worker 		*ofs += skip;
359*59bfda1fSAndroid Build Coastguard Worker 		return;
360*59bfda1fSAndroid Build Coastguard Worker 	}
361*59bfda1fSAndroid Build Coastguard Worker 
362*59bfda1fSAndroid Build Coastguard Worker 	get_node_info(sbi, nid, &ni);
363*59bfda1fSAndroid Build Coastguard Worker 
364*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
365*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
366*59bfda1fSAndroid Build Coastguard Worker 
367*59bfda1fSAndroid Build Coastguard Worker 	dev_read_block(node_blk, ni.blk_addr);
368*59bfda1fSAndroid Build Coastguard Worker 
369*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < idx; i++) {
370*59bfda1fSAndroid Build Coastguard Worker 		switch (ntype) {
371*59bfda1fSAndroid Build Coastguard Worker 		case TYPE_DIRECT_NODE:
372*59bfda1fSAndroid Build Coastguard Worker 			dump_data_blk(sbi, *ofs * F2FS_BLKSIZE,
373*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(node_blk->dn.addr[i]), type);
374*59bfda1fSAndroid Build Coastguard Worker 			(*ofs)++;
375*59bfda1fSAndroid Build Coastguard Worker 			break;
376*59bfda1fSAndroid Build Coastguard Worker 		case TYPE_INDIRECT_NODE:
377*59bfda1fSAndroid Build Coastguard Worker 			dump_node_blk(sbi, TYPE_DIRECT_NODE,
378*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(node_blk->in.nid[i]),
379*59bfda1fSAndroid Build Coastguard Worker 					addr_per_block,
380*59bfda1fSAndroid Build Coastguard Worker 					ofs, type);
381*59bfda1fSAndroid Build Coastguard Worker 			break;
382*59bfda1fSAndroid Build Coastguard Worker 		case TYPE_DOUBLE_INDIRECT_NODE:
383*59bfda1fSAndroid Build Coastguard Worker 			dump_node_blk(sbi, TYPE_INDIRECT_NODE,
384*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(node_blk->in.nid[i]),
385*59bfda1fSAndroid Build Coastguard Worker 					addr_per_block,
386*59bfda1fSAndroid Build Coastguard Worker 					ofs, type);
387*59bfda1fSAndroid Build Coastguard Worker 			break;
388*59bfda1fSAndroid Build Coastguard Worker 		}
389*59bfda1fSAndroid Build Coastguard Worker 	}
390*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
391*59bfda1fSAndroid Build Coastguard Worker }
392*59bfda1fSAndroid Build Coastguard Worker 
393*59bfda1fSAndroid Build Coastguard Worker #ifdef HAVE_FSETXATTR
dump_xattr(struct f2fs_sb_info * sbi,struct f2fs_node * node_blk,int type)394*59bfda1fSAndroid Build Coastguard Worker static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk, int type)
395*59bfda1fSAndroid Build Coastguard Worker {
396*59bfda1fSAndroid Build Coastguard Worker 	void *xattr;
397*59bfda1fSAndroid Build Coastguard Worker 	void *last_base_addr;
398*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_xattr_entry *ent;
399*59bfda1fSAndroid Build Coastguard Worker 	char xattr_name[F2FS_NAME_LEN] = {0};
400*59bfda1fSAndroid Build Coastguard Worker 	int ret;
401*59bfda1fSAndroid Build Coastguard Worker 
402*59bfda1fSAndroid Build Coastguard Worker 	xattr = read_all_xattrs(sbi, node_blk, true);
403*59bfda1fSAndroid Build Coastguard Worker 	if (!xattr)
404*59bfda1fSAndroid Build Coastguard Worker 		return;
405*59bfda1fSAndroid Build Coastguard Worker 
406*59bfda1fSAndroid Build Coastguard Worker 	last_base_addr = (void *)xattr + XATTR_SIZE(&node_blk->i);
407*59bfda1fSAndroid Build Coastguard Worker 
408*59bfda1fSAndroid Build Coastguard Worker 	list_for_each_xattr(ent, xattr) {
409*59bfda1fSAndroid Build Coastguard Worker 		char *name = strndup(ent->e_name, ent->e_name_len);
410*59bfda1fSAndroid Build Coastguard Worker 		void *value = ent->e_name + ent->e_name_len;
411*59bfda1fSAndroid Build Coastguard Worker 
412*59bfda1fSAndroid Build Coastguard Worker 		if ((void *)(ent) + sizeof(__u32) > last_base_addr ||
413*59bfda1fSAndroid Build Coastguard Worker 			(void *)XATTR_NEXT_ENTRY(ent) > last_base_addr) {
414*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "xattr entry crosses the end of xattr space\n");
415*59bfda1fSAndroid Build Coastguard Worker 			break;
416*59bfda1fSAndroid Build Coastguard Worker 		}
417*59bfda1fSAndroid Build Coastguard Worker 
418*59bfda1fSAndroid Build Coastguard Worker 		if (!name)
419*59bfda1fSAndroid Build Coastguard Worker 			continue;
420*59bfda1fSAndroid Build Coastguard Worker 
421*59bfda1fSAndroid Build Coastguard Worker 		switch (ent->e_name_index) {
422*59bfda1fSAndroid Build Coastguard Worker 		case F2FS_XATTR_INDEX_USER:
423*59bfda1fSAndroid Build Coastguard Worker 			ret = snprintf(xattr_name, F2FS_NAME_LEN, "%s%s",
424*59bfda1fSAndroid Build Coastguard Worker 				       XATTR_USER_PREFIX, name);
425*59bfda1fSAndroid Build Coastguard Worker 			break;
426*59bfda1fSAndroid Build Coastguard Worker 
427*59bfda1fSAndroid Build Coastguard Worker 		case F2FS_XATTR_INDEX_SECURITY:
428*59bfda1fSAndroid Build Coastguard Worker 			ret = snprintf(xattr_name, F2FS_NAME_LEN, "%s%s",
429*59bfda1fSAndroid Build Coastguard Worker 				       XATTR_SECURITY_PREFIX, name);
430*59bfda1fSAndroid Build Coastguard Worker 			break;
431*59bfda1fSAndroid Build Coastguard Worker 		case F2FS_XATTR_INDEX_TRUSTED:
432*59bfda1fSAndroid Build Coastguard Worker 			ret = snprintf(xattr_name, F2FS_NAME_LEN, "%s%s",
433*59bfda1fSAndroid Build Coastguard Worker 				       XATTR_TRUSTED_PREFIX, name);
434*59bfda1fSAndroid Build Coastguard Worker 			break;
435*59bfda1fSAndroid Build Coastguard Worker 		default:
436*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Unknown xattr index 0x%x\n", ent->e_name_index);
437*59bfda1fSAndroid Build Coastguard Worker 			free(name);
438*59bfda1fSAndroid Build Coastguard Worker 			continue;
439*59bfda1fSAndroid Build Coastguard Worker 		}
440*59bfda1fSAndroid Build Coastguard Worker 		if (ret >= F2FS_NAME_LEN) {
441*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "XATTR index 0x%x name too long\n", ent->e_name_index);
442*59bfda1fSAndroid Build Coastguard Worker 			free(name);
443*59bfda1fSAndroid Build Coastguard Worker 			continue;
444*59bfda1fSAndroid Build Coastguard Worker 		}
445*59bfda1fSAndroid Build Coastguard Worker 
446*59bfda1fSAndroid Build Coastguard Worker 		DBG(1, "fd %d xattr_name %s\n", c.dump_fd, xattr_name);
447*59bfda1fSAndroid Build Coastguard Worker #if defined(__linux__)
448*59bfda1fSAndroid Build Coastguard Worker 		if (S_ISDIR(type)) {
449*59bfda1fSAndroid Build Coastguard Worker 			ret = setxattr(".", xattr_name, value,
450*59bfda1fSAndroid Build Coastguard Worker 							le16_to_cpu(ent->e_value_size), 0);
451*59bfda1fSAndroid Build Coastguard Worker 		} if (S_ISLNK(type) && c.preserve_symlinks) {
452*59bfda1fSAndroid Build Coastguard Worker 			ret = lsetxattr(c.dump_symlink, xattr_name, value,
453*59bfda1fSAndroid Build Coastguard Worker 							le16_to_cpu(ent->e_value_size), 0);
454*59bfda1fSAndroid Build Coastguard Worker 		} else {
455*59bfda1fSAndroid Build Coastguard Worker 			ret = fsetxattr(c.dump_fd, xattr_name, value,
456*59bfda1fSAndroid Build Coastguard Worker 							le16_to_cpu(ent->e_value_size), 0);
457*59bfda1fSAndroid Build Coastguard Worker 		}
458*59bfda1fSAndroid Build Coastguard Worker 
459*59bfda1fSAndroid Build Coastguard Worker #elif defined(__APPLE__)
460*59bfda1fSAndroid Build Coastguard Worker 		if (S_ISDIR(type)) {
461*59bfda1fSAndroid Build Coastguard Worker 			ret = setxattr(".", xattr_name, value,
462*59bfda1fSAndroid Build Coastguard Worker 					le16_to_cpu(ent->e_value_size), 0,
463*59bfda1fSAndroid Build Coastguard Worker 					XATTR_CREATE);
464*59bfda1fSAndroid Build Coastguard Worker 		} if (S_ISLNK(type) && c.preserve_symlinks) {
465*59bfda1fSAndroid Build Coastguard Worker 			ret = lsetxattr(c.dump_symlink, xattr_name, value,
466*59bfda1fSAndroid Build Coastguard Worker 					le16_to_cpu(ent->e_value_size), 0,
467*59bfda1fSAndroid Build Coastguard Worker 					XATTR_CREATE);
468*59bfda1fSAndroid Build Coastguard Worker 		} else {
469*59bfda1fSAndroid Build Coastguard Worker 			ret = fsetxattr(c.dump_fd, xattr_name, value,
470*59bfda1fSAndroid Build Coastguard Worker 					le16_to_cpu(ent->e_value_size), 0,
471*59bfda1fSAndroid Build Coastguard Worker 					XATTR_CREATE);
472*59bfda1fSAndroid Build Coastguard Worker 		}
473*59bfda1fSAndroid Build Coastguard Worker #endif
474*59bfda1fSAndroid Build Coastguard Worker 		if (ret)
475*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "XATTR index 0x%x set xattr failed error %d\n",
476*59bfda1fSAndroid Build Coastguard Worker 			    ent->e_name_index, errno);
477*59bfda1fSAndroid Build Coastguard Worker 
478*59bfda1fSAndroid Build Coastguard Worker 		free(name);
479*59bfda1fSAndroid Build Coastguard Worker 	}
480*59bfda1fSAndroid Build Coastguard Worker 
481*59bfda1fSAndroid Build Coastguard Worker 	free(xattr);
482*59bfda1fSAndroid Build Coastguard Worker }
483*59bfda1fSAndroid Build Coastguard Worker #else
dump_xattr(struct f2fs_sb_info * UNUSED (sbi),struct f2fs_node * UNUSED (node_blk),int UNUSED (is_dir))484*59bfda1fSAndroid Build Coastguard Worker static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi),
485*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_node *UNUSED(node_blk), int UNUSED(is_dir))
486*59bfda1fSAndroid Build Coastguard Worker {
487*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "XATTR does not support\n");
488*59bfda1fSAndroid Build Coastguard Worker }
489*59bfda1fSAndroid Build Coastguard Worker #endif
490*59bfda1fSAndroid Build Coastguard Worker 
dump_inode_blk(struct f2fs_sb_info * sbi,u32 nid,struct f2fs_node * node_blk)491*59bfda1fSAndroid Build Coastguard Worker static int dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
492*59bfda1fSAndroid Build Coastguard Worker 					struct f2fs_node *node_blk)
493*59bfda1fSAndroid Build Coastguard Worker {
494*59bfda1fSAndroid Build Coastguard Worker 	u32 i = 0;
495*59bfda1fSAndroid Build Coastguard Worker 	u64 ofs = 0;
496*59bfda1fSAndroid Build Coastguard Worker 	u32 addr_per_block;
497*59bfda1fSAndroid Build Coastguard Worker 	u16 type = le16_to_cpu(node_blk->i.i_mode);
498*59bfda1fSAndroid Build Coastguard Worker 	int ret = 0;
499*59bfda1fSAndroid Build Coastguard Worker 
500*59bfda1fSAndroid Build Coastguard Worker 	if ((node_blk->i.i_inline & F2FS_INLINE_DATA)) {
501*59bfda1fSAndroid Build Coastguard Worker 		DBG(3, "ino[0x%x] has inline data!\n", nid);
502*59bfda1fSAndroid Build Coastguard Worker 		/* recover from inline data */
503*59bfda1fSAndroid Build Coastguard Worker #if !defined(__MINGW32__)
504*59bfda1fSAndroid Build Coastguard Worker 		if (S_ISLNK(type) && c.preserve_symlinks) {
505*59bfda1fSAndroid Build Coastguard Worker 			dev_write_symlink(inline_data_addr(node_blk), c.dump_sym_target_len);
506*59bfda1fSAndroid Build Coastguard Worker 		} else
507*59bfda1fSAndroid Build Coastguard Worker #endif
508*59bfda1fSAndroid Build Coastguard Worker 		{
509*59bfda1fSAndroid Build Coastguard Worker 			dev_write_dump(inline_data_addr(node_blk),
510*59bfda1fSAndroid Build Coastguard Worker 						0, MAX_INLINE_DATA(node_blk));
511*59bfda1fSAndroid Build Coastguard Worker 		}
512*59bfda1fSAndroid Build Coastguard Worker 		ret = -1;
513*59bfda1fSAndroid Build Coastguard Worker 		goto dump_xattr;
514*59bfda1fSAndroid Build Coastguard Worker 	}
515*59bfda1fSAndroid Build Coastguard Worker 
516*59bfda1fSAndroid Build Coastguard Worker 	if ((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) {
517*59bfda1fSAndroid Build Coastguard Worker 		void *inline_dentry = inline_data_addr(node_blk);
518*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_dentry_ptr d;
519*59bfda1fSAndroid Build Coastguard Worker 
520*59bfda1fSAndroid Build Coastguard Worker 		make_dentry_ptr(&d, node_blk, inline_dentry, 2);
521*59bfda1fSAndroid Build Coastguard Worker 
522*59bfda1fSAndroid Build Coastguard Worker 		DBG(3, "ino[0x%x] has inline dentries!\n", nid);
523*59bfda1fSAndroid Build Coastguard Worker 		/* recover from inline dentry */
524*59bfda1fSAndroid Build Coastguard Worker 		dump_folder_contents(sbi, d.bitmap, d.dentry, d.filename, d.max);
525*59bfda1fSAndroid Build Coastguard Worker 		ret = -1;
526*59bfda1fSAndroid Build Coastguard Worker 		goto dump_xattr;
527*59bfda1fSAndroid Build Coastguard Worker 	}
528*59bfda1fSAndroid Build Coastguard Worker 
529*59bfda1fSAndroid Build Coastguard Worker 	c.show_file_map_max_offset = f2fs_max_file_offset(&node_blk->i);
530*59bfda1fSAndroid Build Coastguard Worker 
531*59bfda1fSAndroid Build Coastguard Worker 	if (IS_DEVICE_ALIASING(&node_blk->i)) {
532*59bfda1fSAndroid Build Coastguard Worker 		u32 blkaddr = le32_to_cpu(node_blk->i.i_ext.blk_addr);
533*59bfda1fSAndroid Build Coastguard Worker 		u32 len = le32_to_cpu(node_blk->i.i_ext.len);
534*59bfda1fSAndroid Build Coastguard Worker 		u32 idx;
535*59bfda1fSAndroid Build Coastguard Worker 
536*59bfda1fSAndroid Build Coastguard Worker 		for (idx = 0; idx < len; idx++)
537*59bfda1fSAndroid Build Coastguard Worker 			dump_data_blk(sbi, idx * F2FS_BLKSIZE, blkaddr++, type);
538*59bfda1fSAndroid Build Coastguard Worker 		print_extent(true);
539*59bfda1fSAndroid Build Coastguard Worker 
540*59bfda1fSAndroid Build Coastguard Worker 		goto dump_xattr;
541*59bfda1fSAndroid Build Coastguard Worker 	}
542*59bfda1fSAndroid Build Coastguard Worker 
543*59bfda1fSAndroid Build Coastguard Worker 	addr_per_block = ADDRS_PER_BLOCK(&node_blk->i);
544*59bfda1fSAndroid Build Coastguard Worker 
545*59bfda1fSAndroid Build Coastguard Worker 	/* check data blocks in inode */
546*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < ADDRS_PER_INODE(&node_blk->i); i++, ofs++)
547*59bfda1fSAndroid Build Coastguard Worker 		dump_data_blk(sbi, ofs * F2FS_BLKSIZE, le32_to_cpu(
548*59bfda1fSAndroid Build Coastguard Worker 			node_blk->i.i_addr[get_extra_isize(node_blk) + i]), type);
549*59bfda1fSAndroid Build Coastguard Worker 
550*59bfda1fSAndroid Build Coastguard Worker 	/* check node blocks in inode */
551*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < 5; i++) {
552*59bfda1fSAndroid Build Coastguard Worker 		if (i == 0 || i == 1)
553*59bfda1fSAndroid Build Coastguard Worker 			dump_node_blk(sbi, TYPE_DIRECT_NODE,
554*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(F2FS_INODE_I_NID(&node_blk->i, i)),
555*59bfda1fSAndroid Build Coastguard Worker 					addr_per_block,
556*59bfda1fSAndroid Build Coastguard Worker 					&ofs,
557*59bfda1fSAndroid Build Coastguard Worker 					type);
558*59bfda1fSAndroid Build Coastguard Worker 		else if (i == 2 || i == 3)
559*59bfda1fSAndroid Build Coastguard Worker 			dump_node_blk(sbi, TYPE_INDIRECT_NODE,
560*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(F2FS_INODE_I_NID(&node_blk->i, i)),
561*59bfda1fSAndroid Build Coastguard Worker 					addr_per_block,
562*59bfda1fSAndroid Build Coastguard Worker 					&ofs,
563*59bfda1fSAndroid Build Coastguard Worker 					type);
564*59bfda1fSAndroid Build Coastguard Worker 		else if (i == 4)
565*59bfda1fSAndroid Build Coastguard Worker 			dump_node_blk(sbi, TYPE_DOUBLE_INDIRECT_NODE,
566*59bfda1fSAndroid Build Coastguard Worker 					le32_to_cpu(F2FS_INODE_I_NID(&node_blk->i, i)),
567*59bfda1fSAndroid Build Coastguard Worker 					addr_per_block,
568*59bfda1fSAndroid Build Coastguard Worker 					&ofs,
569*59bfda1fSAndroid Build Coastguard Worker 					type);
570*59bfda1fSAndroid Build Coastguard Worker 		else
571*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(0);
572*59bfda1fSAndroid Build Coastguard Worker 	}
573*59bfda1fSAndroid Build Coastguard Worker 	/* last block in extent cache */
574*59bfda1fSAndroid Build Coastguard Worker 	print_extent(true);
575*59bfda1fSAndroid Build Coastguard Worker dump_xattr:
576*59bfda1fSAndroid Build Coastguard Worker 	dump_xattr(sbi, node_blk, type);
577*59bfda1fSAndroid Build Coastguard Worker 	return ret;
578*59bfda1fSAndroid Build Coastguard Worker }
579*59bfda1fSAndroid Build Coastguard Worker 
dump_file(struct f2fs_sb_info * sbi,struct node_info * ni,struct f2fs_node * node_blk,char * path)580*59bfda1fSAndroid Build Coastguard Worker static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
581*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_node *node_blk, char *path)
582*59bfda1fSAndroid Build Coastguard Worker {
583*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_inode *inode = &node_blk->i;
584*59bfda1fSAndroid Build Coastguard Worker 	int ret;
585*59bfda1fSAndroid Build Coastguard Worker 
586*59bfda1fSAndroid Build Coastguard Worker 	c.dump_fd = open(path, O_TRUNC|O_CREAT|O_RDWR, 0666);
587*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(c.dump_fd >= 0);
588*59bfda1fSAndroid Build Coastguard Worker 
589*59bfda1fSAndroid Build Coastguard Worker 	/* dump file's data */
590*59bfda1fSAndroid Build Coastguard Worker 	dump_inode_blk(sbi, ni->ino, node_blk);
591*59bfda1fSAndroid Build Coastguard Worker 
592*59bfda1fSAndroid Build Coastguard Worker 	/* adjust file size */
593*59bfda1fSAndroid Build Coastguard Worker 	ret = ftruncate(c.dump_fd, le32_to_cpu(inode->i_size));
594*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
595*59bfda1fSAndroid Build Coastguard Worker 
596*59bfda1fSAndroid Build Coastguard Worker 	close(c.dump_fd);
597*59bfda1fSAndroid Build Coastguard Worker }
598*59bfda1fSAndroid Build Coastguard Worker 
dump_link(struct f2fs_sb_info * sbi,struct node_info * ni,struct f2fs_node * node_blk,char * name)599*59bfda1fSAndroid Build Coastguard Worker static void dump_link(struct f2fs_sb_info *sbi, struct node_info *ni,
600*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_node *node_blk, char *name)
601*59bfda1fSAndroid Build Coastguard Worker {
602*59bfda1fSAndroid Build Coastguard Worker #if defined(__MINGW32__)
603*59bfda1fSAndroid Build Coastguard Worker 	dump_file(sbi, ni, node_blk, name);
604*59bfda1fSAndroid Build Coastguard Worker #else
605*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_inode *inode = &node_blk->i;
606*59bfda1fSAndroid Build Coastguard Worker 	int len = le64_to_cpu(inode->i_size);
607*59bfda1fSAndroid Build Coastguard Worker 
608*59bfda1fSAndroid Build Coastguard Worker 	if (!c.preserve_symlinks)
609*59bfda1fSAndroid Build Coastguard Worker 		return dump_file(sbi, ni, node_blk, name);
610*59bfda1fSAndroid Build Coastguard Worker 	c.dump_symlink = name;
611*59bfda1fSAndroid Build Coastguard Worker 	c.dump_sym_target_len = len + 1;
612*59bfda1fSAndroid Build Coastguard Worker 	dump_inode_blk(sbi, ni->ino, node_blk);
613*59bfda1fSAndroid Build Coastguard Worker #endif
614*59bfda1fSAndroid Build Coastguard Worker }
615*59bfda1fSAndroid Build Coastguard Worker 
dump_folder(struct f2fs_sb_info * sbi,struct node_info * ni,struct f2fs_node * node_blk,char * path,int is_root)616*59bfda1fSAndroid Build Coastguard Worker static void dump_folder(struct f2fs_sb_info *sbi, struct node_info *ni,
617*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_node *node_blk, char *path, int is_root)
618*59bfda1fSAndroid Build Coastguard Worker {
619*59bfda1fSAndroid Build Coastguard Worker 	if (!is_root) {
620*59bfda1fSAndroid Build Coastguard Worker #if defined(__MINGW32__)
621*59bfda1fSAndroid Build Coastguard Worker 		if (mkdir(path) < 0 && errno != EEXIST) {
622*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Failed to create directory %s\n", path);
623*59bfda1fSAndroid Build Coastguard Worker 			return;
624*59bfda1fSAndroid Build Coastguard Worker 		}
625*59bfda1fSAndroid Build Coastguard Worker #else
626*59bfda1fSAndroid Build Coastguard Worker 		if (mkdir(path, 0777) < 0 && errno != EEXIST) {
627*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Failed to create directory %s\n", path);
628*59bfda1fSAndroid Build Coastguard Worker 			return;
629*59bfda1fSAndroid Build Coastguard Worker 		}
630*59bfda1fSAndroid Build Coastguard Worker #endif
631*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(chdir(path) == 0);
632*59bfda1fSAndroid Build Coastguard Worker 	}
633*59bfda1fSAndroid Build Coastguard Worker 	/* dump folder data */
634*59bfda1fSAndroid Build Coastguard Worker 	dump_inode_blk(sbi, ni->ino, node_blk);
635*59bfda1fSAndroid Build Coastguard Worker 	if (!is_root)
636*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(chdir("..") == 0);
637*59bfda1fSAndroid Build Coastguard Worker }
638*59bfda1fSAndroid Build Coastguard Worker 
dump_filesystem(struct f2fs_sb_info * sbi,struct node_info * ni,struct f2fs_node * node_blk,int force,char * base_path,bool is_base,bool allow_folder,char * dirent_name)639*59bfda1fSAndroid Build Coastguard Worker static int dump_filesystem(struct f2fs_sb_info *sbi, struct node_info *ni,
640*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_node *node_blk, int force, char *base_path,
641*59bfda1fSAndroid Build Coastguard Worker 				bool is_base, bool allow_folder, char *dirent_name)
642*59bfda1fSAndroid Build Coastguard Worker {
643*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_inode *inode = &node_blk->i;
644*59bfda1fSAndroid Build Coastguard Worker 	u32 imode = le16_to_cpu(inode->i_mode);
645*59bfda1fSAndroid Build Coastguard Worker 	u32 ilinks = le32_to_cpu(inode->i_links);
646*59bfda1fSAndroid Build Coastguard Worker 	u32 i_namelen = le32_to_cpu(inode->i_namelen);
647*59bfda1fSAndroid Build Coastguard Worker 	char i_name[F2FS_NAME_LEN + 1] = {0};
648*59bfda1fSAndroid Build Coastguard Worker 	char *name = NULL;
649*59bfda1fSAndroid Build Coastguard Worker 	char path[1024] = {0};
650*59bfda1fSAndroid Build Coastguard Worker 	char ans[255] = {0};
651*59bfda1fSAndroid Build Coastguard Worker 	int is_encrypted = file_is_encrypt(inode);
652*59bfda1fSAndroid Build Coastguard Worker 	int is_root = sbi->root_ino_num == ni->nid;
653*59bfda1fSAndroid Build Coastguard Worker 	int ret;
654*59bfda1fSAndroid Build Coastguard Worker 
655*59bfda1fSAndroid Build Coastguard Worker 	if (!S_ISDIR(imode) && ilinks != 1) {
656*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "Warning: Hard link detected. Dumped files may be duplicated\n");
657*59bfda1fSAndroid Build Coastguard Worker 	}
658*59bfda1fSAndroid Build Coastguard Worker 
659*59bfda1fSAndroid Build Coastguard Worker 	if (is_encrypted) {
660*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "File is encrypted\n");
661*59bfda1fSAndroid Build Coastguard Worker 		return -1;
662*59bfda1fSAndroid Build Coastguard Worker 	}
663*59bfda1fSAndroid Build Coastguard Worker 
664*59bfda1fSAndroid Build Coastguard Worker 	if ((!S_ISREG(imode) && !S_ISLNK(imode) && !(S_ISDIR(imode) && allow_folder))) {
665*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "Not a valid file type\n\n");
666*59bfda1fSAndroid Build Coastguard Worker 		return -1;
667*59bfda1fSAndroid Build Coastguard Worker 	}
668*59bfda1fSAndroid Build Coastguard Worker 	if (!is_root && !dirent_name && (i_namelen == 0 || i_namelen > F2FS_NAME_LEN)) {
669*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "Wrong name info\n\n");
670*59bfda1fSAndroid Build Coastguard Worker 		return -1;
671*59bfda1fSAndroid Build Coastguard Worker 	}
672*59bfda1fSAndroid Build Coastguard Worker 	if (le32_to_cpu(inode->i_flags) & F2FS_NODUMP_FL) {
673*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "File has nodump flag\n\n");
674*59bfda1fSAndroid Build Coastguard Worker 		return -1;
675*59bfda1fSAndroid Build Coastguard Worker 	}
676*59bfda1fSAndroid Build Coastguard Worker 	base_path = base_path ?: "./lost_found";
677*59bfda1fSAndroid Build Coastguard Worker 	if (force)
678*59bfda1fSAndroid Build Coastguard Worker 		goto dump;
679*59bfda1fSAndroid Build Coastguard Worker 
680*59bfda1fSAndroid Build Coastguard Worker 	/* dump file's data */
681*59bfda1fSAndroid Build Coastguard Worker 	if (c.show_file_map)
682*59bfda1fSAndroid Build Coastguard Worker 		return dump_inode_blk(sbi, ni->ino, node_blk);
683*59bfda1fSAndroid Build Coastguard Worker 
684*59bfda1fSAndroid Build Coastguard Worker 	printf("Do you want to dump this %s into %s/? [Y/N] ",
685*59bfda1fSAndroid Build Coastguard Worker 			S_ISDIR(imode) ? "folder" : "file",
686*59bfda1fSAndroid Build Coastguard Worker 			base_path);
687*59bfda1fSAndroid Build Coastguard Worker 	ret = scanf("%s", ans);
688*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
689*59bfda1fSAndroid Build Coastguard Worker 
690*59bfda1fSAndroid Build Coastguard Worker 	if (!strcasecmp(ans, "y")) {
691*59bfda1fSAndroid Build Coastguard Worker dump:
692*59bfda1fSAndroid Build Coastguard Worker 		if (is_base) {
693*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(getcwd(path, sizeof(path)) != NULL);
694*59bfda1fSAndroid Build Coastguard Worker #if defined(__MINGW32__)
695*59bfda1fSAndroid Build Coastguard Worker 			ret = mkdir(base_path);
696*59bfda1fSAndroid Build Coastguard Worker #else
697*59bfda1fSAndroid Build Coastguard Worker 			ret = mkdir(base_path, 0777);
698*59bfda1fSAndroid Build Coastguard Worker #endif
699*59bfda1fSAndroid Build Coastguard Worker 
700*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret == 0 || errno == EEXIST);
701*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(chdir(base_path) == 0);
702*59bfda1fSAndroid Build Coastguard Worker 		}
703*59bfda1fSAndroid Build Coastguard Worker 
704*59bfda1fSAndroid Build Coastguard Worker 		/* make a file */
705*59bfda1fSAndroid Build Coastguard Worker 		if (!is_root) {
706*59bfda1fSAndroid Build Coastguard Worker 			/* The i_name name may be out of date. Prefer dirent_name */
707*59bfda1fSAndroid Build Coastguard Worker 			if (dirent_name) {
708*59bfda1fSAndroid Build Coastguard Worker 				name = dirent_name;
709*59bfda1fSAndroid Build Coastguard Worker 			} else  {
710*59bfda1fSAndroid Build Coastguard Worker 				strncpy(i_name, (const char *)inode->i_name, i_namelen);
711*59bfda1fSAndroid Build Coastguard Worker 				i_name[i_namelen] = 0;
712*59bfda1fSAndroid Build Coastguard Worker 				name = i_name;
713*59bfda1fSAndroid Build Coastguard Worker 			}
714*59bfda1fSAndroid Build Coastguard Worker 		}
715*59bfda1fSAndroid Build Coastguard Worker 
716*59bfda1fSAndroid Build Coastguard Worker 		if (S_ISREG(imode)) {
717*59bfda1fSAndroid Build Coastguard Worker 			dump_file(sbi, ni, node_blk, name);
718*59bfda1fSAndroid Build Coastguard Worker 		} else if (S_ISDIR(imode)) {
719*59bfda1fSAndroid Build Coastguard Worker 			dump_folder(sbi, ni, node_blk, name, is_root);
720*59bfda1fSAndroid Build Coastguard Worker 		} else {
721*59bfda1fSAndroid Build Coastguard Worker 			dump_link(sbi, ni, node_blk, name);
722*59bfda1fSAndroid Build Coastguard Worker 		}
723*59bfda1fSAndroid Build Coastguard Worker 
724*59bfda1fSAndroid Build Coastguard Worker #if !defined(__MINGW32__)
725*59bfda1fSAndroid Build Coastguard Worker 		/* fix up mode/owner */
726*59bfda1fSAndroid Build Coastguard Worker 		if (c.preserve_perms) {
727*59bfda1fSAndroid Build Coastguard Worker 			if (is_root) {
728*59bfda1fSAndroid Build Coastguard Worker 				name = i_name;
729*59bfda1fSAndroid Build Coastguard Worker 				strncpy(name, ".", 2);
730*59bfda1fSAndroid Build Coastguard Worker 			}
731*59bfda1fSAndroid Build Coastguard Worker 			if (!S_ISLNK(imode))
732*59bfda1fSAndroid Build Coastguard Worker 				ASSERT(chmod(name, imode) == 0);
733*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(lchown(name, inode->i_uid, inode->i_gid) == 0);
734*59bfda1fSAndroid Build Coastguard Worker 		}
735*59bfda1fSAndroid Build Coastguard Worker #endif
736*59bfda1fSAndroid Build Coastguard Worker 		if (is_base)
737*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(chdir(path) == 0);
738*59bfda1fSAndroid Build Coastguard Worker 	}
739*59bfda1fSAndroid Build Coastguard Worker 	return 0;
740*59bfda1fSAndroid Build Coastguard Worker }
741*59bfda1fSAndroid Build Coastguard Worker 
is_sit_bitmap_set(struct f2fs_sb_info * sbi,u32 blk_addr)742*59bfda1fSAndroid Build Coastguard Worker bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr)
743*59bfda1fSAndroid Build Coastguard Worker {
744*59bfda1fSAndroid Build Coastguard Worker 	struct seg_entry *se;
745*59bfda1fSAndroid Build Coastguard Worker 	u32 offset;
746*59bfda1fSAndroid Build Coastguard Worker 
747*59bfda1fSAndroid Build Coastguard Worker 	se = get_seg_entry(sbi, GET_SEGNO(sbi, blk_addr));
748*59bfda1fSAndroid Build Coastguard Worker 	offset = OFFSET_IN_SEG(sbi, blk_addr);
749*59bfda1fSAndroid Build Coastguard Worker 
750*59bfda1fSAndroid Build Coastguard Worker 	return f2fs_test_bit(offset,
751*59bfda1fSAndroid Build Coastguard Worker 			(const char *)se->cur_valid_map) != 0;
752*59bfda1fSAndroid Build Coastguard Worker }
753*59bfda1fSAndroid Build Coastguard Worker 
dump_node_scan_disk(struct f2fs_sb_info * sbi,nid_t nid)754*59bfda1fSAndroid Build Coastguard Worker void dump_node_scan_disk(struct f2fs_sb_info *sbi, nid_t nid)
755*59bfda1fSAndroid Build Coastguard Worker {
756*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
757*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t blkaddr;
758*59bfda1fSAndroid Build Coastguard Worker 	int ret;
759*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t start_blkaddr = SM_I(sbi)->main_blkaddr;
760*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t end_blkaddr = start_blkaddr +
761*59bfda1fSAndroid Build Coastguard Worker 		(SM_I(sbi)->main_segments << sbi->log_blocks_per_seg);
762*59bfda1fSAndroid Build Coastguard Worker 
763*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
764*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
765*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "Info: scan all nid: %u from block_addr [%lu: %lu]\n",
766*59bfda1fSAndroid Build Coastguard Worker 			nid, start_blkaddr, end_blkaddr);
767*59bfda1fSAndroid Build Coastguard Worker 
768*59bfda1fSAndroid Build Coastguard Worker 	for (blkaddr = start_blkaddr; blkaddr < end_blkaddr; blkaddr++) {
769*59bfda1fSAndroid Build Coastguard Worker 		struct seg_entry *se = get_seg_entry(sbi, GET_SEGNO(sbi, blkaddr));
770*59bfda1fSAndroid Build Coastguard Worker 		if (se->type < CURSEG_HOT_NODE)
771*59bfda1fSAndroid Build Coastguard Worker 			continue;
772*59bfda1fSAndroid Build Coastguard Worker 
773*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_read_block(node_blk, blkaddr);
774*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
775*59bfda1fSAndroid Build Coastguard Worker 		if (le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->ino) != nid ||
776*59bfda1fSAndroid Build Coastguard Worker 				le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->nid) != nid)
777*59bfda1fSAndroid Build Coastguard Worker 			continue;
778*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: nid: %u, blkaddr: %lu\n", nid, blkaddr);
779*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "node_blk.footer.flag [0x%x]\n", le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->flag));
780*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "node_blk.footer.cp_ver [%x]\n", (u32)(cpver_of_node(node_blk)));
781*59bfda1fSAndroid Build Coastguard Worker 		print_inode_info(sbi, node_blk, 0);
782*59bfda1fSAndroid Build Coastguard Worker 	}
783*59bfda1fSAndroid Build Coastguard Worker 
784*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
785*59bfda1fSAndroid Build Coastguard Worker }
786*59bfda1fSAndroid Build Coastguard Worker 
dump_node(struct f2fs_sb_info * sbi,nid_t nid,int force,char * base_path,int base,int allow_folder,char * dirent_name)787*59bfda1fSAndroid Build Coastguard Worker int dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force, char *base_path, int base, int allow_folder, char *dirent_name)
788*59bfda1fSAndroid Build Coastguard Worker {
789*59bfda1fSAndroid Build Coastguard Worker 	struct node_info ni;
790*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
791*59bfda1fSAndroid Build Coastguard Worker 	int ret = 0;
792*59bfda1fSAndroid Build Coastguard Worker 
793*59bfda1fSAndroid Build Coastguard Worker 	get_node_info(sbi, nid, &ni);
794*59bfda1fSAndroid Build Coastguard Worker 
795*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
796*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
797*59bfda1fSAndroid Build Coastguard Worker 
798*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "Node ID               [0x%x]\n", nid);
799*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "nat_entry.block_addr  [0x%x]\n", ni.blk_addr);
800*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "nat_entry.version     [0x%x]\n", ni.version);
801*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "nat_entry.ino         [0x%x]\n", ni.ino);
802*59bfda1fSAndroid Build Coastguard Worker 
803*59bfda1fSAndroid Build Coastguard Worker 	if (!f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) {
804*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "Invalid node blkaddr: %u\n\n", ni.blk_addr);
805*59bfda1fSAndroid Build Coastguard Worker 		goto out;
806*59bfda1fSAndroid Build Coastguard Worker 	}
807*59bfda1fSAndroid Build Coastguard Worker 
808*59bfda1fSAndroid Build Coastguard Worker 	dev_read_block(node_blk, ni.blk_addr);
809*59bfda1fSAndroid Build Coastguard Worker 
810*59bfda1fSAndroid Build Coastguard Worker 	if (!is_sit_bitmap_set(sbi, ni.blk_addr))
811*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "Invalid sit bitmap, %u\n\n", ni.blk_addr);
812*59bfda1fSAndroid Build Coastguard Worker 
813*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "node_blk.footer.ino [0x%x]\n", le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->ino));
814*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "node_blk.footer.nid [0x%x]\n", le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->nid));
815*59bfda1fSAndroid Build Coastguard Worker 
816*59bfda1fSAndroid Build Coastguard Worker 	if (le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->ino) == ni.ino &&
817*59bfda1fSAndroid Build Coastguard Worker 			le32_to_cpu(F2FS_NODE_FOOTER(node_blk)->nid) == ni.nid) {
818*59bfda1fSAndroid Build Coastguard Worker 		if (!c.show_file_map)
819*59bfda1fSAndroid Build Coastguard Worker 			print_node_info(sbi, node_blk, force);
820*59bfda1fSAndroid Build Coastguard Worker 
821*59bfda1fSAndroid Build Coastguard Worker 		if (ni.ino == ni.nid)
822*59bfda1fSAndroid Build Coastguard Worker 			ret = dump_filesystem(sbi, &ni, node_blk, force, base_path, base, allow_folder, dirent_name);
823*59bfda1fSAndroid Build Coastguard Worker 	} else {
824*59bfda1fSAndroid Build Coastguard Worker 		print_node_info(sbi, node_blk, force);
825*59bfda1fSAndroid Build Coastguard Worker 		MSG(force, "Invalid (i)node block\n\n");
826*59bfda1fSAndroid Build Coastguard Worker 	}
827*59bfda1fSAndroid Build Coastguard Worker out:
828*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
829*59bfda1fSAndroid Build Coastguard Worker 	return ret;
830*59bfda1fSAndroid Build Coastguard Worker }
831*59bfda1fSAndroid Build Coastguard Worker 
dump_node_from_blkaddr(struct f2fs_sb_info * sbi,u32 blk_addr)832*59bfda1fSAndroid Build Coastguard Worker static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
833*59bfda1fSAndroid Build Coastguard Worker {
834*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
835*59bfda1fSAndroid Build Coastguard Worker 	int ret;
836*59bfda1fSAndroid Build Coastguard Worker 
837*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
838*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
839*59bfda1fSAndroid Build Coastguard Worker 
840*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, blk_addr);
841*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
842*59bfda1fSAndroid Build Coastguard Worker 
843*59bfda1fSAndroid Build Coastguard Worker 	if (c.dbg_lv > 0)
844*59bfda1fSAndroid Build Coastguard Worker 		print_node_info(sbi, node_blk, 0);
845*59bfda1fSAndroid Build Coastguard Worker 	else
846*59bfda1fSAndroid Build Coastguard Worker 		print_inode_info(sbi, node_blk, 1);
847*59bfda1fSAndroid Build Coastguard Worker 
848*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
849*59bfda1fSAndroid Build Coastguard Worker }
850*59bfda1fSAndroid Build Coastguard Worker 
start_bidx_of_node(unsigned int node_ofs,struct f2fs_node * node_blk)851*59bfda1fSAndroid Build Coastguard Worker unsigned int start_bidx_of_node(unsigned int node_ofs,
852*59bfda1fSAndroid Build Coastguard Worker 					struct f2fs_node *node_blk)
853*59bfda1fSAndroid Build Coastguard Worker {
854*59bfda1fSAndroid Build Coastguard Worker 	unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4;
855*59bfda1fSAndroid Build Coastguard Worker 	unsigned int bidx;
856*59bfda1fSAndroid Build Coastguard Worker 
857*59bfda1fSAndroid Build Coastguard Worker 	if (node_ofs == 0)
858*59bfda1fSAndroid Build Coastguard Worker 		return 0;
859*59bfda1fSAndroid Build Coastguard Worker 
860*59bfda1fSAndroid Build Coastguard Worker 	if (node_ofs <= 2) {
861*59bfda1fSAndroid Build Coastguard Worker 		bidx = node_ofs - 1;
862*59bfda1fSAndroid Build Coastguard Worker 	} else if (node_ofs <= indirect_blks) {
863*59bfda1fSAndroid Build Coastguard Worker 		int dec = (node_ofs - 4) / (NIDS_PER_BLOCK + 1);
864*59bfda1fSAndroid Build Coastguard Worker 		bidx = node_ofs - 2 - dec;
865*59bfda1fSAndroid Build Coastguard Worker 	} else {
866*59bfda1fSAndroid Build Coastguard Worker 		int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1);
867*59bfda1fSAndroid Build Coastguard Worker 		bidx = node_ofs - 5 - dec;
868*59bfda1fSAndroid Build Coastguard Worker 	}
869*59bfda1fSAndroid Build Coastguard Worker 	return bidx * ADDRS_PER_BLOCK(&node_blk->i) +
870*59bfda1fSAndroid Build Coastguard Worker 				ADDRS_PER_INODE(&node_blk->i);
871*59bfda1fSAndroid Build Coastguard Worker }
872*59bfda1fSAndroid Build Coastguard Worker 
dump_data_offset(u32 blk_addr,int ofs_in_node)873*59bfda1fSAndroid Build Coastguard Worker static void dump_data_offset(u32 blk_addr, int ofs_in_node)
874*59bfda1fSAndroid Build Coastguard Worker {
875*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
876*59bfda1fSAndroid Build Coastguard Worker 	unsigned int bidx;
877*59bfda1fSAndroid Build Coastguard Worker 	unsigned int node_ofs;
878*59bfda1fSAndroid Build Coastguard Worker 	int ret;
879*59bfda1fSAndroid Build Coastguard Worker 
880*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
881*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
882*59bfda1fSAndroid Build Coastguard Worker 
883*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, blk_addr);
884*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
885*59bfda1fSAndroid Build Coastguard Worker 
886*59bfda1fSAndroid Build Coastguard Worker 	node_ofs = ofs_of_node(node_blk);
887*59bfda1fSAndroid Build Coastguard Worker 
888*59bfda1fSAndroid Build Coastguard Worker 	bidx = start_bidx_of_node(node_ofs, node_blk);
889*59bfda1fSAndroid Build Coastguard Worker 	bidx +=  ofs_in_node;
890*59bfda1fSAndroid Build Coastguard Worker 
891*59bfda1fSAndroid Build Coastguard Worker 	setlocale(LC_ALL, "");
892*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, " - Data offset       : 0x%x (BLOCK), %'u (bytes)\n",
893*59bfda1fSAndroid Build Coastguard Worker 				bidx, bidx * F2FS_BLKSIZE);
894*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
895*59bfda1fSAndroid Build Coastguard Worker }
896*59bfda1fSAndroid Build Coastguard Worker 
dump_node_offset(u32 blk_addr)897*59bfda1fSAndroid Build Coastguard Worker static void dump_node_offset(u32 blk_addr)
898*59bfda1fSAndroid Build Coastguard Worker {
899*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
900*59bfda1fSAndroid Build Coastguard Worker 	int ret;
901*59bfda1fSAndroid Build Coastguard Worker 
902*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
903*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
904*59bfda1fSAndroid Build Coastguard Worker 
905*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, blk_addr);
906*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
907*59bfda1fSAndroid Build Coastguard Worker 
908*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, " - Node offset       : 0x%x\n", ofs_of_node(node_blk));
909*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
910*59bfda1fSAndroid Build Coastguard Worker }
911*59bfda1fSAndroid Build Coastguard Worker 
has_dirent(u32 blk_addr,int is_inline,int * enc_name)912*59bfda1fSAndroid Build Coastguard Worker static int has_dirent(u32 blk_addr, int is_inline, int *enc_name)
913*59bfda1fSAndroid Build Coastguard Worker {
914*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
915*59bfda1fSAndroid Build Coastguard Worker 	int ret, is_dentry = 0;
916*59bfda1fSAndroid Build Coastguard Worker 
917*59bfda1fSAndroid Build Coastguard Worker 	node_blk = calloc(F2FS_BLKSIZE, 1);
918*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk);
919*59bfda1fSAndroid Build Coastguard Worker 
920*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, blk_addr);
921*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
922*59bfda1fSAndroid Build Coastguard Worker 
923*59bfda1fSAndroid Build Coastguard Worker 	if (IS_INODE(node_blk) && S_ISDIR(le16_to_cpu(node_blk->i.i_mode)))
924*59bfda1fSAndroid Build Coastguard Worker 		is_dentry = 1;
925*59bfda1fSAndroid Build Coastguard Worker 
926*59bfda1fSAndroid Build Coastguard Worker 	if (is_inline && !(node_blk->i.i_inline & F2FS_INLINE_DENTRY))
927*59bfda1fSAndroid Build Coastguard Worker 		is_dentry = 0;
928*59bfda1fSAndroid Build Coastguard Worker 
929*59bfda1fSAndroid Build Coastguard Worker 	*enc_name = file_is_encrypt(&node_blk->i);
930*59bfda1fSAndroid Build Coastguard Worker 
931*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
932*59bfda1fSAndroid Build Coastguard Worker 
933*59bfda1fSAndroid Build Coastguard Worker 	return is_dentry;
934*59bfda1fSAndroid Build Coastguard Worker }
935*59bfda1fSAndroid Build Coastguard Worker 
dump_dirent(u32 blk_addr,int is_inline,int enc_name)936*59bfda1fSAndroid Build Coastguard Worker static void dump_dirent(u32 blk_addr, int is_inline, int enc_name)
937*59bfda1fSAndroid Build Coastguard Worker {
938*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_dentry_ptr d;
939*59bfda1fSAndroid Build Coastguard Worker 	void *inline_dentry, *blk;
940*59bfda1fSAndroid Build Coastguard Worker 	int ret, i = 0;
941*59bfda1fSAndroid Build Coastguard Worker 
942*59bfda1fSAndroid Build Coastguard Worker 	blk = calloc(F2FS_BLKSIZE, 1);
943*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(blk);
944*59bfda1fSAndroid Build Coastguard Worker 
945*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(blk, blk_addr);
946*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
947*59bfda1fSAndroid Build Coastguard Worker 
948*59bfda1fSAndroid Build Coastguard Worker 	if (is_inline) {
949*59bfda1fSAndroid Build Coastguard Worker 		inline_dentry = inline_data_addr((struct f2fs_node *)blk);
950*59bfda1fSAndroid Build Coastguard Worker 		make_dentry_ptr(&d, blk, inline_dentry, 2);
951*59bfda1fSAndroid Build Coastguard Worker 	} else {
952*59bfda1fSAndroid Build Coastguard Worker 		make_dentry_ptr(&d, NULL, blk, 1);
953*59bfda1fSAndroid Build Coastguard Worker 	}
954*59bfda1fSAndroid Build Coastguard Worker 
955*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "%sDentry block:\n", is_inline ? "Inline " : "");
956*59bfda1fSAndroid Build Coastguard Worker 
957*59bfda1fSAndroid Build Coastguard Worker 	while (i < d.max) {
958*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_dir_entry *de;
959*59bfda1fSAndroid Build Coastguard Worker 		char en[F2FS_PRINT_NAMELEN];
960*59bfda1fSAndroid Build Coastguard Worker 		u16 name_len;
961*59bfda1fSAndroid Build Coastguard Worker 		int enc;
962*59bfda1fSAndroid Build Coastguard Worker 
963*59bfda1fSAndroid Build Coastguard Worker 		if (!test_bit_le(i, d.bitmap)) {
964*59bfda1fSAndroid Build Coastguard Worker 			i++;
965*59bfda1fSAndroid Build Coastguard Worker 			continue;
966*59bfda1fSAndroid Build Coastguard Worker 		}
967*59bfda1fSAndroid Build Coastguard Worker 
968*59bfda1fSAndroid Build Coastguard Worker 		de = &d.dentry[i];
969*59bfda1fSAndroid Build Coastguard Worker 
970*59bfda1fSAndroid Build Coastguard Worker 		if (!de->name_len) {
971*59bfda1fSAndroid Build Coastguard Worker 			i++;
972*59bfda1fSAndroid Build Coastguard Worker 			continue;
973*59bfda1fSAndroid Build Coastguard Worker 		}
974*59bfda1fSAndroid Build Coastguard Worker 
975*59bfda1fSAndroid Build Coastguard Worker 		name_len = le16_to_cpu(de->name_len);
976*59bfda1fSAndroid Build Coastguard Worker 		enc = enc_name;
977*59bfda1fSAndroid Build Coastguard Worker 
978*59bfda1fSAndroid Build Coastguard Worker 		if (de->file_type == F2FS_FT_DIR) {
979*59bfda1fSAndroid Build Coastguard Worker 			if ((d.filename[i][0] == '.' && name_len == 1) ||
980*59bfda1fSAndroid Build Coastguard Worker 				(d.filename[i][0] == '.' &&
981*59bfda1fSAndroid Build Coastguard Worker 				d.filename[i][1] == '.' && name_len == 2)) {
982*59bfda1fSAndroid Build Coastguard Worker 				enc = 0;
983*59bfda1fSAndroid Build Coastguard Worker 			}
984*59bfda1fSAndroid Build Coastguard Worker 		}
985*59bfda1fSAndroid Build Coastguard Worker 
986*59bfda1fSAndroid Build Coastguard Worker 		pretty_print_filename(d.filename[i], name_len, en, enc);
987*59bfda1fSAndroid Build Coastguard Worker 
988*59bfda1fSAndroid Build Coastguard Worker 		DBG(1, "bitmap pos[0x%x] name[%s] len[0x%x] hash[0x%x] ino[0x%x] type[0x%x]\n",
989*59bfda1fSAndroid Build Coastguard Worker 				i, en,
990*59bfda1fSAndroid Build Coastguard Worker 				name_len,
991*59bfda1fSAndroid Build Coastguard Worker 				le32_to_cpu(de->hash_code),
992*59bfda1fSAndroid Build Coastguard Worker 				le32_to_cpu(de->ino),
993*59bfda1fSAndroid Build Coastguard Worker 				de->file_type);
994*59bfda1fSAndroid Build Coastguard Worker 
995*59bfda1fSAndroid Build Coastguard Worker 		i += GET_DENTRY_SLOTS(name_len);
996*59bfda1fSAndroid Build Coastguard Worker 	}
997*59bfda1fSAndroid Build Coastguard Worker 
998*59bfda1fSAndroid Build Coastguard Worker 	free(blk);
999*59bfda1fSAndroid Build Coastguard Worker }
1000*59bfda1fSAndroid Build Coastguard Worker 
dump_info_from_blkaddr(struct f2fs_sb_info * sbi,u32 blk_addr)1001*59bfda1fSAndroid Build Coastguard Worker int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
1002*59bfda1fSAndroid Build Coastguard Worker {
1003*59bfda1fSAndroid Build Coastguard Worker 	nid_t nid;
1004*59bfda1fSAndroid Build Coastguard Worker 	int type;
1005*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_summary sum_entry;
1006*59bfda1fSAndroid Build Coastguard Worker 	struct node_info ni, ino_ni;
1007*59bfda1fSAndroid Build Coastguard Worker 	int enc_name;
1008*59bfda1fSAndroid Build Coastguard Worker 	int ret = 0;
1009*59bfda1fSAndroid Build Coastguard Worker 
1010*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "\n== Dump data from block address ==\n\n");
1011*59bfda1fSAndroid Build Coastguard Worker 
1012*59bfda1fSAndroid Build Coastguard Worker 	if (blk_addr < SM_I(sbi)->seg0_blkaddr) {
1013*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nFS Reserved Area for SEG #0: ");
1014*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1015*59bfda1fSAndroid Build Coastguard Worker 	} else if (blk_addr < SIT_I(sbi)->sit_base_addr) {
1016*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nFS Metadata Area: ");
1017*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1018*59bfda1fSAndroid Build Coastguard Worker 	} else if (blk_addr < NM_I(sbi)->nat_blkaddr) {
1019*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nFS SIT Area: ");
1020*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1021*59bfda1fSAndroid Build Coastguard Worker 	} else if (blk_addr < SM_I(sbi)->ssa_blkaddr) {
1022*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nFS NAT Area: ");
1023*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1024*59bfda1fSAndroid Build Coastguard Worker 	} else if (blk_addr < SM_I(sbi)->main_blkaddr) {
1025*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nFS SSA Area: ");
1026*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1027*59bfda1fSAndroid Build Coastguard Worker 	} else if (blk_addr > __end_block_addr(sbi)) {
1028*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nOut of address space: ");
1029*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1030*59bfda1fSAndroid Build Coastguard Worker 	}
1031*59bfda1fSAndroid Build Coastguard Worker 
1032*59bfda1fSAndroid Build Coastguard Worker 	if (ret) {
1033*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "User data is from 0x%x to 0x%x\n\n",
1034*59bfda1fSAndroid Build Coastguard Worker 			SM_I(sbi)->main_blkaddr,
1035*59bfda1fSAndroid Build Coastguard Worker 			__end_block_addr(sbi));
1036*59bfda1fSAndroid Build Coastguard Worker 		return ret;
1037*59bfda1fSAndroid Build Coastguard Worker 	}
1038*59bfda1fSAndroid Build Coastguard Worker 
1039*59bfda1fSAndroid Build Coastguard Worker 	if (!is_sit_bitmap_set(sbi, blk_addr))
1040*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\nblkaddr is not valid\n");
1041*59bfda1fSAndroid Build Coastguard Worker 
1042*59bfda1fSAndroid Build Coastguard Worker 	type = get_sum_entry(sbi, blk_addr, &sum_entry);
1043*59bfda1fSAndroid Build Coastguard Worker 	nid = le32_to_cpu(sum_entry.nid);
1044*59bfda1fSAndroid Build Coastguard Worker 
1045*59bfda1fSAndroid Build Coastguard Worker 	get_node_info(sbi, nid, &ni);
1046*59bfda1fSAndroid Build Coastguard Worker 
1047*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "Note: blkaddr = main_blkaddr + segno * 512 + offset\n");
1048*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "Block_addr            [0x%x]\n", blk_addr);
1049*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, " - Segno              [0x%x]\n", GET_SEGNO(sbi, blk_addr));
1050*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, " - Offset             [0x%x]\n", OFFSET_IN_SEG(sbi, blk_addr));
1051*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "SUM.nid               [0x%x]\n", nid);
1052*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "SUM.type              [%s]\n", type >= 0 ?
1053*59bfda1fSAndroid Build Coastguard Worker 						seg_type_name[type] :
1054*59bfda1fSAndroid Build Coastguard Worker 						"Broken");
1055*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "SUM.version           [%d]\n", sum_entry.version);
1056*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "SUM.ofs_in_node       [0x%x]\n", sum_entry.ofs_in_node);
1057*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "NAT.blkaddr           [0x%x]\n", ni.blk_addr);
1058*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "NAT.ino               [0x%x]\n", ni.ino);
1059*59bfda1fSAndroid Build Coastguard Worker 
1060*59bfda1fSAndroid Build Coastguard Worker 	get_node_info(sbi, ni.ino, &ino_ni);
1061*59bfda1fSAndroid Build Coastguard Worker 
1062*59bfda1fSAndroid Build Coastguard Worker 	/* inode block address */
1063*59bfda1fSAndroid Build Coastguard Worker 	if (ni.blk_addr == NULL_ADDR || ino_ni.blk_addr == NULL_ADDR) {
1064*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "FS Userdata Area: Obsolete block from 0x%x\n",
1065*59bfda1fSAndroid Build Coastguard Worker 			blk_addr);
1066*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
1067*59bfda1fSAndroid Build Coastguard Worker 	}
1068*59bfda1fSAndroid Build Coastguard Worker 
1069*59bfda1fSAndroid Build Coastguard Worker 	/* print inode */
1070*59bfda1fSAndroid Build Coastguard Worker 	if (c.dbg_lv > 0)
1071*59bfda1fSAndroid Build Coastguard Worker 		dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
1072*59bfda1fSAndroid Build Coastguard Worker 
1073*59bfda1fSAndroid Build Coastguard Worker 	if (type == SEG_TYPE_CUR_DATA || type == SEG_TYPE_DATA) {
1074*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "FS Userdata Area: Data block from 0x%x\n", blk_addr);
1075*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, " - Direct node block : id = 0x%x from 0x%x\n",
1076*59bfda1fSAndroid Build Coastguard Worker 					nid, ni.blk_addr);
1077*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, " - Inode block       : id = 0x%x from 0x%x\n",
1078*59bfda1fSAndroid Build Coastguard Worker 					ni.ino, ino_ni.blk_addr);
1079*59bfda1fSAndroid Build Coastguard Worker 		dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
1080*59bfda1fSAndroid Build Coastguard Worker 		dump_data_offset(ni.blk_addr,
1081*59bfda1fSAndroid Build Coastguard Worker 			le16_to_cpu(sum_entry.ofs_in_node));
1082*59bfda1fSAndroid Build Coastguard Worker 
1083*59bfda1fSAndroid Build Coastguard Worker 		if (has_dirent(ino_ni.blk_addr, 0, &enc_name))
1084*59bfda1fSAndroid Build Coastguard Worker 			dump_dirent(blk_addr, 0, enc_name);
1085*59bfda1fSAndroid Build Coastguard Worker 	} else {
1086*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "FS Userdata Area: Node block from 0x%x\n", blk_addr);
1087*59bfda1fSAndroid Build Coastguard Worker 		if (ni.ino == ni.nid) {
1088*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, " - Inode block       : id = 0x%x from 0x%x\n",
1089*59bfda1fSAndroid Build Coastguard Worker 					ni.ino, ino_ni.blk_addr);
1090*59bfda1fSAndroid Build Coastguard Worker 			dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
1091*59bfda1fSAndroid Build Coastguard Worker 
1092*59bfda1fSAndroid Build Coastguard Worker 			if (has_dirent(ino_ni.blk_addr, 1, &enc_name))
1093*59bfda1fSAndroid Build Coastguard Worker 				dump_dirent(blk_addr, 1, enc_name);
1094*59bfda1fSAndroid Build Coastguard Worker 		} else {
1095*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, " - Node block        : id = 0x%x from 0x%x\n",
1096*59bfda1fSAndroid Build Coastguard Worker 					nid, ni.blk_addr);
1097*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, " - Inode block       : id = 0x%x from 0x%x\n",
1098*59bfda1fSAndroid Build Coastguard Worker 					ni.ino, ino_ni.blk_addr);
1099*59bfda1fSAndroid Build Coastguard Worker 			dump_node_from_blkaddr(sbi, ino_ni.blk_addr);
1100*59bfda1fSAndroid Build Coastguard Worker 			dump_node_offset(ni.blk_addr);
1101*59bfda1fSAndroid Build Coastguard Worker 		}
1102*59bfda1fSAndroid Build Coastguard Worker 	}
1103*59bfda1fSAndroid Build Coastguard Worker 
1104*59bfda1fSAndroid Build Coastguard Worker 	return 0;
1105*59bfda1fSAndroid Build Coastguard Worker }
1106