xref: /aosp_15_r20/external/f2fs-tools/fsck/inject.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker /**
2*59bfda1fSAndroid Build Coastguard Worker  * inject.c
3*59bfda1fSAndroid Build Coastguard Worker  *
4*59bfda1fSAndroid Build Coastguard Worker  * Copyright (c) 2024 OPPO Mobile Comm Corp., Ltd.
5*59bfda1fSAndroid Build Coastguard Worker  *             http://www.oppo.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 
12*59bfda1fSAndroid Build Coastguard Worker #include <getopt.h>
13*59bfda1fSAndroid Build Coastguard Worker #include "node.h"
14*59bfda1fSAndroid Build Coastguard Worker #include "inject.h"
15*59bfda1fSAndroid Build Coastguard Worker 
print_raw_nat_entry_info(struct f2fs_nat_entry * ne)16*59bfda1fSAndroid Build Coastguard Worker static void print_raw_nat_entry_info(struct f2fs_nat_entry *ne)
17*59bfda1fSAndroid Build Coastguard Worker {
18*59bfda1fSAndroid Build Coastguard Worker 	if (!c.dbg_lv)
19*59bfda1fSAndroid Build Coastguard Worker 		return;
20*59bfda1fSAndroid Build Coastguard Worker 
21*59bfda1fSAndroid Build Coastguard Worker 	DISP_u8(ne, version);
22*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(ne, ino);
23*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(ne, block_addr);
24*59bfda1fSAndroid Build Coastguard Worker }
25*59bfda1fSAndroid Build Coastguard Worker 
print_raw_sit_entry_info(struct f2fs_sit_entry * se)26*59bfda1fSAndroid Build Coastguard Worker static void print_raw_sit_entry_info(struct f2fs_sit_entry *se)
27*59bfda1fSAndroid Build Coastguard Worker {
28*59bfda1fSAndroid Build Coastguard Worker 	int i;
29*59bfda1fSAndroid Build Coastguard Worker 
30*59bfda1fSAndroid Build Coastguard Worker 	if (!c.dbg_lv)
31*59bfda1fSAndroid Build Coastguard Worker 		return;
32*59bfda1fSAndroid Build Coastguard Worker 
33*59bfda1fSAndroid Build Coastguard Worker 	DISP_u16(se, vblocks);
34*59bfda1fSAndroid Build Coastguard Worker 	if (c.layout)
35*59bfda1fSAndroid Build Coastguard Worker 		printf("%-30s ", "valid_map:");
36*59bfda1fSAndroid Build Coastguard Worker 	else
37*59bfda1fSAndroid Build Coastguard Worker 		printf("%-30s\t\t[", "valid_map");
38*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < SIT_VBLOCK_MAP_SIZE; i++)
39*59bfda1fSAndroid Build Coastguard Worker 		printf("%02x", se->valid_map[i]);
40*59bfda1fSAndroid Build Coastguard Worker 	if (c.layout)
41*59bfda1fSAndroid Build Coastguard Worker 		printf("\n");
42*59bfda1fSAndroid Build Coastguard Worker 	else
43*59bfda1fSAndroid Build Coastguard Worker 		printf("]\n");
44*59bfda1fSAndroid Build Coastguard Worker 	DISP_u64(se, mtime);
45*59bfda1fSAndroid Build Coastguard Worker }
46*59bfda1fSAndroid Build Coastguard Worker 
print_raw_sum_entry_info(struct f2fs_summary * sum)47*59bfda1fSAndroid Build Coastguard Worker static void print_raw_sum_entry_info(struct f2fs_summary *sum)
48*59bfda1fSAndroid Build Coastguard Worker {
49*59bfda1fSAndroid Build Coastguard Worker 	if (!c.dbg_lv)
50*59bfda1fSAndroid Build Coastguard Worker 		return;
51*59bfda1fSAndroid Build Coastguard Worker 
52*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(sum, nid);
53*59bfda1fSAndroid Build Coastguard Worker 	DISP_u8(sum, version);
54*59bfda1fSAndroid Build Coastguard Worker 	DISP_u16(sum, ofs_in_node);
55*59bfda1fSAndroid Build Coastguard Worker }
56*59bfda1fSAndroid Build Coastguard Worker 
print_sum_footer_info(struct summary_footer * footer)57*59bfda1fSAndroid Build Coastguard Worker static void print_sum_footer_info(struct summary_footer *footer)
58*59bfda1fSAndroid Build Coastguard Worker {
59*59bfda1fSAndroid Build Coastguard Worker 	if (!c.dbg_lv)
60*59bfda1fSAndroid Build Coastguard Worker 		return;
61*59bfda1fSAndroid Build Coastguard Worker 
62*59bfda1fSAndroid Build Coastguard Worker 	DISP_u8(footer, entry_type);
63*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(footer, check_sum);
64*59bfda1fSAndroid Build Coastguard Worker }
65*59bfda1fSAndroid Build Coastguard Worker 
print_node_footer_info(struct node_footer * footer)66*59bfda1fSAndroid Build Coastguard Worker static void print_node_footer_info(struct node_footer *footer)
67*59bfda1fSAndroid Build Coastguard Worker {
68*59bfda1fSAndroid Build Coastguard Worker 	if (!c.dbg_lv)
69*59bfda1fSAndroid Build Coastguard Worker 		return;
70*59bfda1fSAndroid Build Coastguard Worker 
71*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(footer, nid);
72*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(footer, ino);
73*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(footer, flag);
74*59bfda1fSAndroid Build Coastguard Worker 	DISP_u64(footer, cp_ver);
75*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(footer, next_blkaddr);
76*59bfda1fSAndroid Build Coastguard Worker }
77*59bfda1fSAndroid Build Coastguard Worker 
print_raw_dentry_info(struct f2fs_dir_entry * dentry)78*59bfda1fSAndroid Build Coastguard Worker static void print_raw_dentry_info(struct f2fs_dir_entry *dentry)
79*59bfda1fSAndroid Build Coastguard Worker {
80*59bfda1fSAndroid Build Coastguard Worker 	if (!c.dbg_lv)
81*59bfda1fSAndroid Build Coastguard Worker 		return;
82*59bfda1fSAndroid Build Coastguard Worker 
83*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(dentry, hash_code);
84*59bfda1fSAndroid Build Coastguard Worker 	DISP_u32(dentry, ino);
85*59bfda1fSAndroid Build Coastguard Worker 	DISP_u16(dentry, name_len);
86*59bfda1fSAndroid Build Coastguard Worker 	DISP_u8(dentry, file_type);
87*59bfda1fSAndroid Build Coastguard Worker }
88*59bfda1fSAndroid Build Coastguard Worker 
inject_usage(void)89*59bfda1fSAndroid Build Coastguard Worker void inject_usage(void)
90*59bfda1fSAndroid Build Coastguard Worker {
91*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "\nUsage: inject.f2fs [options] device\n");
92*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[options]:\n");
93*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  -d debug level [default:0]\n");
94*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  -V print the version number and exit\n");
95*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --mb <member name> which member is injected in a struct\n");
96*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --val <new value> new value to set\n");
97*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --str <new string> new string to set\n");
98*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --idx <slot index> which slot is injected in an array\n");
99*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --nid <nid> which nid is injected\n");
100*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --blk <blkaddr> which blkaddr is injected\n");
101*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --sb <0|1|2> --mb <name> [--idx <index>] --val/str <value/string> inject superblock\n");
102*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --cp <0|1|2> --mb <name> [--idx <index>] --val <value> inject checkpoint\n");
103*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --nat <0|1|2> --mb <name> --nid <nid> --val <value> inject nat entry\n");
104*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --sit <0|1|2> --mb <name> --blk <blk> [--idx <index>] --val <value> inject sit entry\n");
105*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --ssa --mb <name> --blk <blk> [--idx <index>] --val <value> inject summary entry\n");
106*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --node --mb <name> --nid <nid> [--idx <index>] --val <value> inject node\n");
107*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --dent --mb <name> --nid <ino> [--idx <index>] --val <value> inject ino's dentry\n");
108*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  --dry-run do not really inject\n");
109*59bfda1fSAndroid Build Coastguard Worker 
110*59bfda1fSAndroid Build Coastguard Worker 	exit(1);
111*59bfda1fSAndroid Build Coastguard Worker }
112*59bfda1fSAndroid Build Coastguard Worker 
inject_sb_usage(void)113*59bfda1fSAndroid Build Coastguard Worker static void inject_sb_usage(void)
114*59bfda1fSAndroid Build Coastguard Worker {
115*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --sb <0|1|2> --mb <name> [--idx <index>] --val/str <value/string>\n");
116*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[sb]:\n");
117*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  0: auto select the first super block\n");
118*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  1: select the first super block\n");
119*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  2: select the second super block\n");
120*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
121*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  magic: inject magic number\n");
122*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  s_stop_reason: inject s_stop_reason array selected by --idx <index>\n");
123*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  s_errors: inject s_errors array selected by --idx <index>\n");
124*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  devs.path: inject path in devs array selected by --idx <index> specified by --str <string>\n");
125*59bfda1fSAndroid Build Coastguard Worker }
126*59bfda1fSAndroid Build Coastguard Worker 
inject_cp_usage(void)127*59bfda1fSAndroid Build Coastguard Worker static void inject_cp_usage(void)
128*59bfda1fSAndroid Build Coastguard Worker {
129*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --cp <0|1|2> --mb <name> [--idx <index>] --val <value> inject checkpoint\n");
130*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[cp]:\n");
131*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  0: auto select the current cp pack\n");
132*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  1: select the first cp pack\n");
133*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  2: select the second cp pack\n");
134*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
135*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  checkpoint_ver: inject checkpoint_ver\n");
136*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  ckpt_flags: inject ckpt_flags\n");
137*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  cur_node_segno: inject cur_node_segno array selected by --idx <index>\n");
138*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  cur_node_blkoff: inject cur_node_blkoff array selected by --idx <index>\n");
139*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  cur_data_segno: inject cur_data_segno array selected by --idx <index>\n");
140*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  cur_data_blkoff: inject cur_data_blkoff array selected by --idx <index>\n");
141*59bfda1fSAndroid Build Coastguard Worker }
142*59bfda1fSAndroid Build Coastguard Worker 
inject_nat_usage(void)143*59bfda1fSAndroid Build Coastguard Worker static void inject_nat_usage(void)
144*59bfda1fSAndroid Build Coastguard Worker {
145*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --nat <0|1|2> --mb <name> --nid <nid> --val <value> inject nat entry\n");
146*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[nat]:\n");
147*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  0: auto select the current nat pack\n");
148*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  1: select the first nat pack\n");
149*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  2: select the second nat pack\n");
150*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
151*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  version: inject nat entry version\n");
152*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  ino: inject nat entry ino\n");
153*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  block_addr: inject nat entry block_addr\n");
154*59bfda1fSAndroid Build Coastguard Worker }
155*59bfda1fSAndroid Build Coastguard Worker 
inject_sit_usage(void)156*59bfda1fSAndroid Build Coastguard Worker static void inject_sit_usage(void)
157*59bfda1fSAndroid Build Coastguard Worker {
158*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --sit <0|1|2> --mb <name> --blk <blk> [--idx <index>] --val <value> inject sit entry\n");
159*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[sit]:\n");
160*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  0: auto select the current sit pack\n");
161*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  1: select the first sit pack\n");
162*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  2: select the second sit pack\n");
163*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
164*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  vblocks: inject sit entry vblocks\n");
165*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  valid_map: inject sit entry valid_map\n");
166*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  mtime: inject sit entry mtime\n");
167*59bfda1fSAndroid Build Coastguard Worker }
168*59bfda1fSAndroid Build Coastguard Worker 
inject_ssa_usage(void)169*59bfda1fSAndroid Build Coastguard Worker static void inject_ssa_usage(void)
170*59bfda1fSAndroid Build Coastguard Worker {
171*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --ssa --mb <name> --blk <blk> [--idx <index>] --val <value> inject summary entry\n");
172*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
173*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  entry_type: inject summary block footer entry_type\n");
174*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  check_sum: inject summary block footer check_sum\n");
175*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  nid: inject summary entry nid selected by --idx <index\n");
176*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  version: inject summary entry version selected by --idx <index\n");
177*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  ofs_in_node: inject summary entry ofs_in_node selected by --idx <index\n");
178*59bfda1fSAndroid Build Coastguard Worker }
179*59bfda1fSAndroid Build Coastguard Worker 
inject_node_usage(void)180*59bfda1fSAndroid Build Coastguard Worker static void inject_node_usage(void)
181*59bfda1fSAndroid Build Coastguard Worker {
182*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --node --mb <name> --nid <nid> [--idx <index>] --val <value> inject node\n");
183*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
184*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  nid: inject node footer nid\n");
185*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  ino: inject node footer ino\n");
186*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  flag: inject node footer flag\n");
187*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  cp_ver: inject node footer cp_ver\n");
188*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  next_blkaddr: inject node footer next_blkaddr\n");
189*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_mode: inject inode i_mode\n");
190*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_advise: inject inode i_advise\n");
191*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_inline: inject inode i_inline\n");
192*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_links: inject inode i_links\n");
193*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_size: inject inode i_size\n");
194*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_blocks: inject inode i_blocks\n");
195*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_extra_isize: inject inode i_extra_isize\n");
196*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_inode_checksum: inject inode i_inode_checksum\n");
197*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_addr: inject inode i_addr array selected by --idx <index>\n");
198*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  i_nid: inject inode i_nid array selected by --idx <index>\n");
199*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  addr: inject {in}direct node nid/addr array selected by --idx <index>\n");
200*59bfda1fSAndroid Build Coastguard Worker }
201*59bfda1fSAndroid Build Coastguard Worker 
inject_dent_usage(void)202*59bfda1fSAndroid Build Coastguard Worker static void inject_dent_usage(void)
203*59bfda1fSAndroid Build Coastguard Worker {
204*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "inject.f2fs --dent --mb <name> --nid <nid> [--idx <index>] --val <value> inject dentry\n");
205*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "[mb]:\n");
206*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  d_bitmap: inject dentry block d_bitmap of nid\n");
207*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  d_hash: inject dentry hash\n");
208*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  d_ino: inject dentry ino\n");
209*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "  d_ftype: inject dentry ftype\n");
210*59bfda1fSAndroid Build Coastguard Worker }
211*59bfda1fSAndroid Build Coastguard Worker 
inject_parse_options(int argc,char * argv[],struct inject_option * opt)212*59bfda1fSAndroid Build Coastguard Worker int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
213*59bfda1fSAndroid Build Coastguard Worker {
214*59bfda1fSAndroid Build Coastguard Worker 	int o = 0;
215*59bfda1fSAndroid Build Coastguard Worker 	const char *pack[] = {"auto", "1", "2"};
216*59bfda1fSAndroid Build Coastguard Worker 	const char *option_string = "d:Vh";
217*59bfda1fSAndroid Build Coastguard Worker 	char *endptr;
218*59bfda1fSAndroid Build Coastguard Worker 	struct option long_opt[] = {
219*59bfda1fSAndroid Build Coastguard Worker 		{"dry-run", no_argument, 0, 1},
220*59bfda1fSAndroid Build Coastguard Worker 		{"mb", required_argument, 0, 2},
221*59bfda1fSAndroid Build Coastguard Worker 		{"idx", required_argument, 0, 3},
222*59bfda1fSAndroid Build Coastguard Worker 		{"val", required_argument, 0, 4},
223*59bfda1fSAndroid Build Coastguard Worker 		{"str", required_argument, 0, 5},
224*59bfda1fSAndroid Build Coastguard Worker 		{"sb", required_argument, 0, 6},
225*59bfda1fSAndroid Build Coastguard Worker 		{"cp", required_argument, 0, 7},
226*59bfda1fSAndroid Build Coastguard Worker 		{"nat", required_argument, 0, 8},
227*59bfda1fSAndroid Build Coastguard Worker 		{"nid", required_argument, 0, 9},
228*59bfda1fSAndroid Build Coastguard Worker 		{"sit", required_argument, 0, 10},
229*59bfda1fSAndroid Build Coastguard Worker 		{"blk", required_argument, 0, 11},
230*59bfda1fSAndroid Build Coastguard Worker 		{"ssa", no_argument, 0, 12},
231*59bfda1fSAndroid Build Coastguard Worker 		{"node", no_argument, 0, 13},
232*59bfda1fSAndroid Build Coastguard Worker 		{"dent", no_argument, 0, 14},
233*59bfda1fSAndroid Build Coastguard Worker 		{0, 0, 0, 0}
234*59bfda1fSAndroid Build Coastguard Worker 	};
235*59bfda1fSAndroid Build Coastguard Worker 
236*59bfda1fSAndroid Build Coastguard Worker 	while ((o = getopt_long(argc, argv, option_string,
237*59bfda1fSAndroid Build Coastguard Worker 				long_opt, NULL)) != EOF) {
238*59bfda1fSAndroid Build Coastguard Worker 		long nid, blk;
239*59bfda1fSAndroid Build Coastguard Worker 
240*59bfda1fSAndroid Build Coastguard Worker 		switch (o) {
241*59bfda1fSAndroid Build Coastguard Worker 		case 1:
242*59bfda1fSAndroid Build Coastguard Worker 			c.dry_run = 1;
243*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: Dry run\n");
244*59bfda1fSAndroid Build Coastguard Worker 			break;
245*59bfda1fSAndroid Build Coastguard Worker 		case 2:
246*59bfda1fSAndroid Build Coastguard Worker 			opt->mb = optarg;
247*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject member %s\n", optarg);
248*59bfda1fSAndroid Build Coastguard Worker 			break;
249*59bfda1fSAndroid Build Coastguard Worker 		case 3:
250*59bfda1fSAndroid Build Coastguard Worker 			if (!is_digits(optarg))
251*59bfda1fSAndroid Build Coastguard Worker 				return EWRONG_OPT;
252*59bfda1fSAndroid Build Coastguard Worker 			opt->idx = atoi(optarg);
253*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject slot index %d\n", opt->idx);
254*59bfda1fSAndroid Build Coastguard Worker 			break;
255*59bfda1fSAndroid Build Coastguard Worker 		case 4:
256*59bfda1fSAndroid Build Coastguard Worker 			opt->val = strtoll(optarg, &endptr, 0);
257*59bfda1fSAndroid Build Coastguard Worker 			if (opt->val == LLONG_MAX || opt->val == LLONG_MIN ||
258*59bfda1fSAndroid Build Coastguard Worker 			    *endptr != '\0')
259*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
260*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject value %lld : 0x%llx\n", opt->val,
261*59bfda1fSAndroid Build Coastguard Worker 			    (unsigned long long)opt->val);
262*59bfda1fSAndroid Build Coastguard Worker 			break;
263*59bfda1fSAndroid Build Coastguard Worker 		case 5:
264*59bfda1fSAndroid Build Coastguard Worker 			opt->str = strdup(optarg);
265*59bfda1fSAndroid Build Coastguard Worker 			if (!opt->str)
266*59bfda1fSAndroid Build Coastguard Worker 				return -ENOMEM;
267*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject string %s\n", opt->str);
268*59bfda1fSAndroid Build Coastguard Worker 			break;
269*59bfda1fSAndroid Build Coastguard Worker 		case 6:
270*59bfda1fSAndroid Build Coastguard Worker 			if (!is_digits(optarg))
271*59bfda1fSAndroid Build Coastguard Worker 				return EWRONG_OPT;
272*59bfda1fSAndroid Build Coastguard Worker 			opt->sb = atoi(optarg);
273*59bfda1fSAndroid Build Coastguard Worker 			if (opt->sb < 0 || opt->sb > 2)
274*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
275*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject sb %s\n", pack[opt->sb]);
276*59bfda1fSAndroid Build Coastguard Worker 			break;
277*59bfda1fSAndroid Build Coastguard Worker 		case 7:
278*59bfda1fSAndroid Build Coastguard Worker 			if (!is_digits(optarg))
279*59bfda1fSAndroid Build Coastguard Worker 				return EWRONG_OPT;
280*59bfda1fSAndroid Build Coastguard Worker 			opt->cp = atoi(optarg);
281*59bfda1fSAndroid Build Coastguard Worker 			if (opt->cp < 0 || opt->cp > 2)
282*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
283*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject cp pack %s\n", pack[opt->cp]);
284*59bfda1fSAndroid Build Coastguard Worker 			break;
285*59bfda1fSAndroid Build Coastguard Worker 		case 8:
286*59bfda1fSAndroid Build Coastguard Worker 			if (!is_digits(optarg))
287*59bfda1fSAndroid Build Coastguard Worker 				return EWRONG_OPT;
288*59bfda1fSAndroid Build Coastguard Worker 			opt->nat = atoi(optarg);
289*59bfda1fSAndroid Build Coastguard Worker 			if (opt->nat < 0 || opt->nat > 2)
290*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
291*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject nat pack %s\n", pack[opt->nat]);
292*59bfda1fSAndroid Build Coastguard Worker 			break;
293*59bfda1fSAndroid Build Coastguard Worker 		case 9:
294*59bfda1fSAndroid Build Coastguard Worker 			nid = strtol(optarg, &endptr, 0);
295*59bfda1fSAndroid Build Coastguard Worker 			if (nid >= UINT_MAX || nid < 0 ||
296*59bfda1fSAndroid Build Coastguard Worker 			    *endptr != '\0')
297*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
298*59bfda1fSAndroid Build Coastguard Worker 			opt->nid = nid;
299*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject nid %u : 0x%x\n", opt->nid, opt->nid);
300*59bfda1fSAndroid Build Coastguard Worker 			break;
301*59bfda1fSAndroid Build Coastguard Worker 		case 10:
302*59bfda1fSAndroid Build Coastguard Worker 			if (!is_digits(optarg))
303*59bfda1fSAndroid Build Coastguard Worker 				return EWRONG_OPT;
304*59bfda1fSAndroid Build Coastguard Worker 			opt->sit = atoi(optarg);
305*59bfda1fSAndroid Build Coastguard Worker 			if (opt->sit < 0 || opt->sit > 2)
306*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
307*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject sit pack %s\n", pack[opt->sit]);
308*59bfda1fSAndroid Build Coastguard Worker 			break;
309*59bfda1fSAndroid Build Coastguard Worker 		case 11:
310*59bfda1fSAndroid Build Coastguard Worker 			blk = strtol(optarg, &endptr, 0);
311*59bfda1fSAndroid Build Coastguard Worker 			if (blk >= UINT_MAX || blk < 0 ||
312*59bfda1fSAndroid Build Coastguard Worker 			    *endptr != '\0')
313*59bfda1fSAndroid Build Coastguard Worker 				return -ERANGE;
314*59bfda1fSAndroid Build Coastguard Worker 			opt->blk = blk;
315*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject blkaddr %u : 0x%x\n", opt->blk, opt->blk);
316*59bfda1fSAndroid Build Coastguard Worker 			break;
317*59bfda1fSAndroid Build Coastguard Worker 		case 12:
318*59bfda1fSAndroid Build Coastguard Worker 			opt->ssa = true;
319*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject ssa\n");
320*59bfda1fSAndroid Build Coastguard Worker 			break;
321*59bfda1fSAndroid Build Coastguard Worker 		case 13:
322*59bfda1fSAndroid Build Coastguard Worker 			opt->node = true;
323*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject node\n");
324*59bfda1fSAndroid Build Coastguard Worker 			break;
325*59bfda1fSAndroid Build Coastguard Worker 		case 14:
326*59bfda1fSAndroid Build Coastguard Worker 			opt->dent = true;
327*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject dentry\n");
328*59bfda1fSAndroid Build Coastguard Worker 			break;
329*59bfda1fSAndroid Build Coastguard Worker 		case 'd':
330*59bfda1fSAndroid Build Coastguard Worker 			if (optarg[0] == '-' || !is_digits(optarg))
331*59bfda1fSAndroid Build Coastguard Worker 				return EWRONG_OPT;
332*59bfda1fSAndroid Build Coastguard Worker 			c.dbg_lv = atoi(optarg);
333*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: Debug level = %d\n", c.dbg_lv);
334*59bfda1fSAndroid Build Coastguard Worker 			break;
335*59bfda1fSAndroid Build Coastguard Worker 		case 'V':
336*59bfda1fSAndroid Build Coastguard Worker 			show_version("inject.f2fs");
337*59bfda1fSAndroid Build Coastguard Worker 			exit(0);
338*59bfda1fSAndroid Build Coastguard Worker 		case 'h':
339*59bfda1fSAndroid Build Coastguard Worker 		default:
340*59bfda1fSAndroid Build Coastguard Worker 			if (opt->sb >= 0) {
341*59bfda1fSAndroid Build Coastguard Worker 				inject_sb_usage();
342*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
343*59bfda1fSAndroid Build Coastguard Worker 			} else if (opt->cp >= 0) {
344*59bfda1fSAndroid Build Coastguard Worker 				inject_cp_usage();
345*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
346*59bfda1fSAndroid Build Coastguard Worker 			} else if (opt->nat >= 0) {
347*59bfda1fSAndroid Build Coastguard Worker 				inject_nat_usage();
348*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
349*59bfda1fSAndroid Build Coastguard Worker 			} else if (opt->sit >= 0) {
350*59bfda1fSAndroid Build Coastguard Worker 				inject_sit_usage();
351*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
352*59bfda1fSAndroid Build Coastguard Worker 			} else if (opt->ssa) {
353*59bfda1fSAndroid Build Coastguard Worker 				inject_ssa_usage();
354*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
355*59bfda1fSAndroid Build Coastguard Worker 			} else if (opt->node) {
356*59bfda1fSAndroid Build Coastguard Worker 				inject_node_usage();
357*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
358*59bfda1fSAndroid Build Coastguard Worker 			} else if (opt->dent) {
359*59bfda1fSAndroid Build Coastguard Worker 				inject_dent_usage();
360*59bfda1fSAndroid Build Coastguard Worker 				exit(0);
361*59bfda1fSAndroid Build Coastguard Worker 			}
362*59bfda1fSAndroid Build Coastguard Worker 			return EUNKNOWN_OPT;
363*59bfda1fSAndroid Build Coastguard Worker 		}
364*59bfda1fSAndroid Build Coastguard Worker 	}
365*59bfda1fSAndroid Build Coastguard Worker 
366*59bfda1fSAndroid Build Coastguard Worker 	return 0;
367*59bfda1fSAndroid Build Coastguard Worker }
368*59bfda1fSAndroid Build Coastguard Worker 
inject_sb(struct f2fs_sb_info * sbi,struct inject_option * opt)369*59bfda1fSAndroid Build Coastguard Worker static int inject_sb(struct f2fs_sb_info *sbi, struct inject_option *opt)
370*59bfda1fSAndroid Build Coastguard Worker {
371*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb;
372*59bfda1fSAndroid Build Coastguard Worker 	char *buf;
373*59bfda1fSAndroid Build Coastguard Worker 	int ret;
374*59bfda1fSAndroid Build Coastguard Worker 
375*59bfda1fSAndroid Build Coastguard Worker 	buf = calloc(1, F2FS_BLKSIZE);
376*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(buf != NULL);
377*59bfda1fSAndroid Build Coastguard Worker 
378*59bfda1fSAndroid Build Coastguard Worker 	if (opt->sb == 0)
379*59bfda1fSAndroid Build Coastguard Worker 		opt->sb = 1;
380*59bfda1fSAndroid Build Coastguard Worker 
381*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(buf, opt->sb == 1 ? SB0_ADDR : SB1_ADDR);
382*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
383*59bfda1fSAndroid Build Coastguard Worker 
384*59bfda1fSAndroid Build Coastguard Worker 	sb = (struct f2fs_super_block *)(buf + F2FS_SUPER_OFFSET);
385*59bfda1fSAndroid Build Coastguard Worker 
386*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "magic")) {
387*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject magic of sb %d: 0x%x -> 0x%x\n",
388*59bfda1fSAndroid Build Coastguard Worker 		    opt->sb, get_sb(magic), (u32)opt->val);
389*59bfda1fSAndroid Build Coastguard Worker 		set_sb(magic, (u32)opt->val);
390*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "s_stop_reason")) {
391*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_STOP_REASON) {
392*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of sb->s_stop_reason[]\n",
393*59bfda1fSAndroid Build Coastguard Worker 				opt->idx);
394*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
395*59bfda1fSAndroid Build Coastguard Worker 			goto out;
396*59bfda1fSAndroid Build Coastguard Worker 		}
397*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject s_stop_reason[%d] of sb %d: %d -> %d\n",
398*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->sb, sb->s_stop_reason[opt->idx],
399*59bfda1fSAndroid Build Coastguard Worker 		    (u8)opt->val);
400*59bfda1fSAndroid Build Coastguard Worker 		sb->s_stop_reason[opt->idx] = (u8)opt->val;
401*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "s_errors")) {
402*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_F2FS_ERRORS) {
403*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of sb->s_errors[]\n",
404*59bfda1fSAndroid Build Coastguard Worker 				opt->idx);
405*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
406*59bfda1fSAndroid Build Coastguard Worker 			goto out;
407*59bfda1fSAndroid Build Coastguard Worker 		}
408*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject s_errors[%d] of sb %d: %x -> %x\n",
409*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->sb, sb->s_errors[opt->idx], (u8)opt->val);
410*59bfda1fSAndroid Build Coastguard Worker 		sb->s_errors[opt->idx] = (u8)opt->val;
411*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "devs.path")) {
412*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_DEVICES) {
413*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of sb->devs[]\n", opt->idx);
414*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
415*59bfda1fSAndroid Build Coastguard Worker 			goto out;
416*59bfda1fSAndroid Build Coastguard Worker 		}
417*59bfda1fSAndroid Build Coastguard Worker 		if (strlen(opt->str) >= MAX_PATH_LEN) {
418*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid length of option str\n");
419*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
420*59bfda1fSAndroid Build Coastguard Worker 			goto out;
421*59bfda1fSAndroid Build Coastguard Worker 		}
422*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject devs[%d].path of sb %d: %s -> %s\n",
423*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->sb, (char *)sb->devs[opt->idx].path, opt->str);
424*59bfda1fSAndroid Build Coastguard Worker 		strcpy((char *)sb->devs[opt->idx].path, opt->str);
425*59bfda1fSAndroid Build Coastguard Worker 	} else {
426*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
427*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
428*59bfda1fSAndroid Build Coastguard Worker 		goto out;
429*59bfda1fSAndroid Build Coastguard Worker 	}
430*59bfda1fSAndroid Build Coastguard Worker 
431*59bfda1fSAndroid Build Coastguard Worker 	print_raw_sb_info(sb);
432*59bfda1fSAndroid Build Coastguard Worker 	update_superblock(sb, SB_MASK((u32)opt->sb - 1));
433*59bfda1fSAndroid Build Coastguard Worker 
434*59bfda1fSAndroid Build Coastguard Worker out:
435*59bfda1fSAndroid Build Coastguard Worker 	free(buf);
436*59bfda1fSAndroid Build Coastguard Worker 	free(opt->str);
437*59bfda1fSAndroid Build Coastguard Worker 	return ret;
438*59bfda1fSAndroid Build Coastguard Worker }
439*59bfda1fSAndroid Build Coastguard Worker 
inject_cp(struct f2fs_sb_info * sbi,struct inject_option * opt)440*59bfda1fSAndroid Build Coastguard Worker static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
441*59bfda1fSAndroid Build Coastguard Worker {
442*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_checkpoint *cp, *cur_cp = F2FS_CKPT(sbi);
443*59bfda1fSAndroid Build Coastguard Worker 	char *buf = NULL;
444*59bfda1fSAndroid Build Coastguard Worker 	int ret = 0;
445*59bfda1fSAndroid Build Coastguard Worker 
446*59bfda1fSAndroid Build Coastguard Worker 	if (opt->cp == 0)
447*59bfda1fSAndroid Build Coastguard Worker 		opt->cp = sbi->cur_cp;
448*59bfda1fSAndroid Build Coastguard Worker 
449*59bfda1fSAndroid Build Coastguard Worker 	if (opt->cp != sbi->cur_cp) {
450*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_super_block *sb = sbi->raw_super;
451*59bfda1fSAndroid Build Coastguard Worker 		block_t cp_addr;
452*59bfda1fSAndroid Build Coastguard Worker 
453*59bfda1fSAndroid Build Coastguard Worker 		buf = calloc(1, F2FS_BLKSIZE);
454*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(buf != NULL);
455*59bfda1fSAndroid Build Coastguard Worker 
456*59bfda1fSAndroid Build Coastguard Worker 		cp_addr = get_sb(cp_blkaddr);
457*59bfda1fSAndroid Build Coastguard Worker 		if (opt->cp == 2)
458*59bfda1fSAndroid Build Coastguard Worker 			cp_addr += 1 << get_sb(log_blocks_per_seg);
459*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_read_block(buf, cp_addr);
460*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
461*59bfda1fSAndroid Build Coastguard Worker 
462*59bfda1fSAndroid Build Coastguard Worker 		cp = (struct f2fs_checkpoint *)buf;
463*59bfda1fSAndroid Build Coastguard Worker 		sbi->ckpt = cp;
464*59bfda1fSAndroid Build Coastguard Worker 		sbi->cur_cp = opt->cp;
465*59bfda1fSAndroid Build Coastguard Worker 	} else {
466*59bfda1fSAndroid Build Coastguard Worker 		cp = cur_cp;
467*59bfda1fSAndroid Build Coastguard Worker 	}
468*59bfda1fSAndroid Build Coastguard Worker 
469*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "checkpoint_ver")) {
470*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject checkpoint_ver of cp %d: 0x%llx -> 0x%"PRIx64"\n",
471*59bfda1fSAndroid Build Coastguard Worker 		    opt->cp, get_cp(checkpoint_ver), (u64)opt->val);
472*59bfda1fSAndroid Build Coastguard Worker 		set_cp(checkpoint_ver, (u64)opt->val);
473*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "ckpt_flags")) {
474*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject ckpt_flags of cp %d: 0x%x -> 0x%x\n",
475*59bfda1fSAndroid Build Coastguard Worker 		    opt->cp, get_cp(ckpt_flags), (u32)opt->val);
476*59bfda1fSAndroid Build Coastguard Worker 		set_cp(ckpt_flags, (u32)opt->val);
477*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "cur_node_segno")) {
478*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_ACTIVE_NODE_LOGS) {
479*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of cp->cur_node_segno[]\n",
480*59bfda1fSAndroid Build Coastguard Worker 				opt->idx);
481*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
482*59bfda1fSAndroid Build Coastguard Worker 			goto out;
483*59bfda1fSAndroid Build Coastguard Worker 		}
484*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject cur_node_segno[%d] of cp %d: 0x%x -> 0x%x\n",
485*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->cp, get_cp(cur_node_segno[opt->idx]),
486*59bfda1fSAndroid Build Coastguard Worker 		    (u32)opt->val);
487*59bfda1fSAndroid Build Coastguard Worker 		set_cp(cur_node_segno[opt->idx], (u32)opt->val);
488*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "cur_node_blkoff")) {
489*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_ACTIVE_NODE_LOGS) {
490*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of cp->cur_node_blkoff[]\n",
491*59bfda1fSAndroid Build Coastguard Worker 				opt->idx);
492*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
493*59bfda1fSAndroid Build Coastguard Worker 			goto out;
494*59bfda1fSAndroid Build Coastguard Worker 		}
495*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject cur_node_blkoff[%d] of cp %d: 0x%x -> 0x%x\n",
496*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->cp, get_cp(cur_node_blkoff[opt->idx]),
497*59bfda1fSAndroid Build Coastguard Worker 		    (u16)opt->val);
498*59bfda1fSAndroid Build Coastguard Worker 		set_cp(cur_node_blkoff[opt->idx], (u16)opt->val);
499*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "cur_data_segno")) {
500*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_ACTIVE_DATA_LOGS) {
501*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of cp->cur_data_segno[]\n",
502*59bfda1fSAndroid Build Coastguard Worker 				opt->idx);
503*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
504*59bfda1fSAndroid Build Coastguard Worker 			goto out;
505*59bfda1fSAndroid Build Coastguard Worker 		}
506*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject cur_data_segno[%d] of cp %d: 0x%x -> 0x%x\n",
507*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->cp, get_cp(cur_data_segno[opt->idx]),
508*59bfda1fSAndroid Build Coastguard Worker 		    (u32)opt->val);
509*59bfda1fSAndroid Build Coastguard Worker 		set_cp(cur_data_segno[opt->idx], (u32)opt->val);
510*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "cur_data_blkoff")) {
511*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= MAX_ACTIVE_DATA_LOGS) {
512*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of cp->cur_data_blkoff[]\n",
513*59bfda1fSAndroid Build Coastguard Worker 				opt->idx);
514*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
515*59bfda1fSAndroid Build Coastguard Worker 			goto out;
516*59bfda1fSAndroid Build Coastguard Worker 		}
517*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject cur_data_blkoff[%d] of cp %d: 0x%x -> 0x%x\n",
518*59bfda1fSAndroid Build Coastguard Worker 		    opt->idx, opt->cp, get_cp(cur_data_blkoff[opt->idx]),
519*59bfda1fSAndroid Build Coastguard Worker 		    (u16)opt->val);
520*59bfda1fSAndroid Build Coastguard Worker 		set_cp(cur_data_blkoff[opt->idx], (u16)opt->val);
521*59bfda1fSAndroid Build Coastguard Worker 	} else {
522*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
523*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
524*59bfda1fSAndroid Build Coastguard Worker 		goto out;
525*59bfda1fSAndroid Build Coastguard Worker 	}
526*59bfda1fSAndroid Build Coastguard Worker 
527*59bfda1fSAndroid Build Coastguard Worker 	print_ckpt_info(sbi);
528*59bfda1fSAndroid Build Coastguard Worker 	write_raw_cp_blocks(sbi, cp, opt->cp);
529*59bfda1fSAndroid Build Coastguard Worker 
530*59bfda1fSAndroid Build Coastguard Worker out:
531*59bfda1fSAndroid Build Coastguard Worker 	free(buf);
532*59bfda1fSAndroid Build Coastguard Worker 	sbi->ckpt = cur_cp;
533*59bfda1fSAndroid Build Coastguard Worker 	return ret;
534*59bfda1fSAndroid Build Coastguard Worker }
535*59bfda1fSAndroid Build Coastguard Worker 
inject_nat(struct f2fs_sb_info * sbi,struct inject_option * opt)536*59bfda1fSAndroid Build Coastguard Worker static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
537*59bfda1fSAndroid Build Coastguard Worker {
538*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_nm_info *nm_i = NM_I(sbi);
539*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
540*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_nat_block *nat_blk;
541*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_nat_entry *ne;
542*59bfda1fSAndroid Build Coastguard Worker 	block_t blk_addr;
543*59bfda1fSAndroid Build Coastguard Worker 	unsigned int offs;
544*59bfda1fSAndroid Build Coastguard Worker 	bool is_set;
545*59bfda1fSAndroid Build Coastguard Worker 	int ret;
546*59bfda1fSAndroid Build Coastguard Worker 
547*59bfda1fSAndroid Build Coastguard Worker 	if (!IS_VALID_NID(sbi, opt->nid)) {
548*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("Invalid nid %u range [%u:%"PRIu64"]\n", opt->nid, 0,
549*59bfda1fSAndroid Build Coastguard Worker 			NAT_ENTRY_PER_BLOCK *
550*59bfda1fSAndroid Build Coastguard Worker 			((get_sb(segment_count_nat) << 1) <<
551*59bfda1fSAndroid Build Coastguard Worker 			 sbi->log_blocks_per_seg));
552*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
553*59bfda1fSAndroid Build Coastguard Worker 	}
554*59bfda1fSAndroid Build Coastguard Worker 
555*59bfda1fSAndroid Build Coastguard Worker 	nat_blk = calloc(F2FS_BLKSIZE, 1);
556*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(nat_blk);
557*59bfda1fSAndroid Build Coastguard Worker 
558*59bfda1fSAndroid Build Coastguard Worker 	/* change NAT version bitmap temporarily to select specified pack */
559*59bfda1fSAndroid Build Coastguard Worker 	is_set = f2fs_test_bit(opt->nid, nm_i->nat_bitmap);
560*59bfda1fSAndroid Build Coastguard Worker 	if (opt->nat == 0) {
561*59bfda1fSAndroid Build Coastguard Worker 		opt->nat = is_set ? 2 : 1;
562*59bfda1fSAndroid Build Coastguard Worker 	} else {
563*59bfda1fSAndroid Build Coastguard Worker 		if (opt->nat == 1)
564*59bfda1fSAndroid Build Coastguard Worker 			f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
565*59bfda1fSAndroid Build Coastguard Worker 		else
566*59bfda1fSAndroid Build Coastguard Worker 			f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
567*59bfda1fSAndroid Build Coastguard Worker 	}
568*59bfda1fSAndroid Build Coastguard Worker 
569*59bfda1fSAndroid Build Coastguard Worker 	blk_addr = current_nat_addr(sbi, opt->nid, NULL);
570*59bfda1fSAndroid Build Coastguard Worker 
571*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(nat_blk, blk_addr);
572*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
573*59bfda1fSAndroid Build Coastguard Worker 
574*59bfda1fSAndroid Build Coastguard Worker 	offs = opt->nid % NAT_ENTRY_PER_BLOCK;
575*59bfda1fSAndroid Build Coastguard Worker 	ne = &nat_blk->entries[offs];
576*59bfda1fSAndroid Build Coastguard Worker 
577*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "version")) {
578*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject nat entry version of nid %u "
579*59bfda1fSAndroid Build Coastguard Worker 		    "in pack %d: %d -> %d\n", opt->nid, opt->nat,
580*59bfda1fSAndroid Build Coastguard Worker 		    ne->version, (u8)opt->val);
581*59bfda1fSAndroid Build Coastguard Worker 		ne->version = (u8)opt->val;
582*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "ino")) {
583*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject nat entry ino of nid %u "
584*59bfda1fSAndroid Build Coastguard Worker 		    "in pack %d: %d -> %d\n", opt->nid, opt->nat,
585*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(ne->ino), (nid_t)opt->val);
586*59bfda1fSAndroid Build Coastguard Worker 		ne->ino = cpu_to_le32((nid_t)opt->val);
587*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "block_addr")) {
588*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject nat entry block_addr of nid %u "
589*59bfda1fSAndroid Build Coastguard Worker 		    "in pack %d: 0x%x -> 0x%x\n", opt->nid, opt->nat,
590*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(ne->block_addr), (block_t)opt->val);
591*59bfda1fSAndroid Build Coastguard Worker 		ne->block_addr = cpu_to_le32((block_t)opt->val);
592*59bfda1fSAndroid Build Coastguard Worker 	} else {
593*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
594*59bfda1fSAndroid Build Coastguard Worker 		free(nat_blk);
595*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
596*59bfda1fSAndroid Build Coastguard Worker 	}
597*59bfda1fSAndroid Build Coastguard Worker 	print_raw_nat_entry_info(ne);
598*59bfda1fSAndroid Build Coastguard Worker 
599*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_write_block(nat_blk, blk_addr, WRITE_LIFE_NONE);
600*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
601*59bfda1fSAndroid Build Coastguard Worker 	/* restore NAT version bitmap */
602*59bfda1fSAndroid Build Coastguard Worker 	if (is_set)
603*59bfda1fSAndroid Build Coastguard Worker 		f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
604*59bfda1fSAndroid Build Coastguard Worker 	else
605*59bfda1fSAndroid Build Coastguard Worker 		f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
606*59bfda1fSAndroid Build Coastguard Worker 
607*59bfda1fSAndroid Build Coastguard Worker 	free(nat_blk);
608*59bfda1fSAndroid Build Coastguard Worker 	return ret;
609*59bfda1fSAndroid Build Coastguard Worker }
610*59bfda1fSAndroid Build Coastguard Worker 
inject_sit(struct f2fs_sb_info * sbi,struct inject_option * opt)611*59bfda1fSAndroid Build Coastguard Worker static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
612*59bfda1fSAndroid Build Coastguard Worker {
613*59bfda1fSAndroid Build Coastguard Worker 	struct sit_info *sit_i = SIT_I(sbi);
614*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_sit_block *sit_blk;
615*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_sit_entry *sit;
616*59bfda1fSAndroid Build Coastguard Worker 	unsigned int segno, offs;
617*59bfda1fSAndroid Build Coastguard Worker 	bool is_set;
618*59bfda1fSAndroid Build Coastguard Worker 
619*59bfda1fSAndroid Build Coastguard Worker 	if (!f2fs_is_valid_blkaddr(sbi, opt->blk, DATA_GENERIC)) {
620*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("Invalid blkaddr 0x%x (valid range [0x%x:0x%lx])\n",
621*59bfda1fSAndroid Build Coastguard Worker 			opt->blk, SM_I(sbi)->main_blkaddr,
622*59bfda1fSAndroid Build Coastguard Worker 			(unsigned long)le64_to_cpu(F2FS_RAW_SUPER(sbi)->block_count));
623*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
624*59bfda1fSAndroid Build Coastguard Worker 	}
625*59bfda1fSAndroid Build Coastguard Worker 
626*59bfda1fSAndroid Build Coastguard Worker 	sit_blk = calloc(F2FS_BLKSIZE, 1);
627*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(sit_blk);
628*59bfda1fSAndroid Build Coastguard Worker 
629*59bfda1fSAndroid Build Coastguard Worker 	segno = GET_SEGNO(sbi, opt->blk);
630*59bfda1fSAndroid Build Coastguard Worker 	/* change SIT version bitmap temporarily to select specified pack */
631*59bfda1fSAndroid Build Coastguard Worker 	is_set = f2fs_test_bit(segno, sit_i->sit_bitmap);
632*59bfda1fSAndroid Build Coastguard Worker 	if (opt->sit == 0) {
633*59bfda1fSAndroid Build Coastguard Worker 		opt->sit = is_set ? 2 : 1;
634*59bfda1fSAndroid Build Coastguard Worker 	} else {
635*59bfda1fSAndroid Build Coastguard Worker 		if (opt->sit == 1)
636*59bfda1fSAndroid Build Coastguard Worker 			f2fs_clear_bit(segno, sit_i->sit_bitmap);
637*59bfda1fSAndroid Build Coastguard Worker 		else
638*59bfda1fSAndroid Build Coastguard Worker 			f2fs_set_bit(segno, sit_i->sit_bitmap);
639*59bfda1fSAndroid Build Coastguard Worker 	}
640*59bfda1fSAndroid Build Coastguard Worker 	get_current_sit_page(sbi, segno, sit_blk);
641*59bfda1fSAndroid Build Coastguard Worker 	offs = SIT_ENTRY_OFFSET(sit_i, segno);
642*59bfda1fSAndroid Build Coastguard Worker 	sit = &sit_blk->entries[offs];
643*59bfda1fSAndroid Build Coastguard Worker 
644*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "vblocks")) {
645*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject sit entry vblocks of block 0x%x "
646*59bfda1fSAndroid Build Coastguard Worker 		    "in pack %d: %u -> %u\n", opt->blk, opt->sit,
647*59bfda1fSAndroid Build Coastguard Worker 		    le16_to_cpu(sit->vblocks), (u16)opt->val);
648*59bfda1fSAndroid Build Coastguard Worker 		sit->vblocks = cpu_to_le16((u16)opt->val);
649*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "valid_map")) {
650*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx == -1) {
651*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: auto idx = %u\n", offs);
652*59bfda1fSAndroid Build Coastguard Worker 			opt->idx = offs;
653*59bfda1fSAndroid Build Coastguard Worker 		}
654*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= SIT_VBLOCK_MAP_SIZE) {
655*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid idx %u of valid_map[]\n", opt->idx);
656*59bfda1fSAndroid Build Coastguard Worker 			free(sit_blk);
657*59bfda1fSAndroid Build Coastguard Worker 			return -ERANGE;
658*59bfda1fSAndroid Build Coastguard Worker 		}
659*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject sit entry valid_map[%d] of block 0x%x "
660*59bfda1fSAndroid Build Coastguard Worker 		    "in pack %d: 0x%02x -> 0x%02x\n", opt->idx, opt->blk,
661*59bfda1fSAndroid Build Coastguard Worker 		    opt->sit, sit->valid_map[opt->idx], (u8)opt->val);
662*59bfda1fSAndroid Build Coastguard Worker 		sit->valid_map[opt->idx] = (u8)opt->val;
663*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "mtime")) {
664*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject sit entry mtime of block 0x%x "
665*59bfda1fSAndroid Build Coastguard Worker 		    "in pack %d: %"PRIu64" -> %"PRIu64"\n", opt->blk, opt->sit,
666*59bfda1fSAndroid Build Coastguard Worker 		    le64_to_cpu(sit->mtime), (u64)opt->val);
667*59bfda1fSAndroid Build Coastguard Worker 		sit->mtime = cpu_to_le64((u64)opt->val);
668*59bfda1fSAndroid Build Coastguard Worker 	} else {
669*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
670*59bfda1fSAndroid Build Coastguard Worker 		free(sit_blk);
671*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
672*59bfda1fSAndroid Build Coastguard Worker 	}
673*59bfda1fSAndroid Build Coastguard Worker 	print_raw_sit_entry_info(sit);
674*59bfda1fSAndroid Build Coastguard Worker 
675*59bfda1fSAndroid Build Coastguard Worker 	rewrite_current_sit_page(sbi, segno, sit_blk);
676*59bfda1fSAndroid Build Coastguard Worker 	/* restore SIT version bitmap */
677*59bfda1fSAndroid Build Coastguard Worker 	if (is_set)
678*59bfda1fSAndroid Build Coastguard Worker 		f2fs_set_bit(segno, sit_i->sit_bitmap);
679*59bfda1fSAndroid Build Coastguard Worker 	else
680*59bfda1fSAndroid Build Coastguard Worker 		f2fs_clear_bit(segno, sit_i->sit_bitmap);
681*59bfda1fSAndroid Build Coastguard Worker 
682*59bfda1fSAndroid Build Coastguard Worker 	free(sit_blk);
683*59bfda1fSAndroid Build Coastguard Worker 	return 0;
684*59bfda1fSAndroid Build Coastguard Worker }
685*59bfda1fSAndroid Build Coastguard Worker 
inject_ssa(struct f2fs_sb_info * sbi,struct inject_option * opt)686*59bfda1fSAndroid Build Coastguard Worker static int inject_ssa(struct f2fs_sb_info *sbi, struct inject_option *opt)
687*59bfda1fSAndroid Build Coastguard Worker {
688*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_summary_block *sum_blk;
689*59bfda1fSAndroid Build Coastguard Worker 	struct summary_footer *footer;
690*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_summary *sum;
691*59bfda1fSAndroid Build Coastguard Worker 	u32 segno, offset;
692*59bfda1fSAndroid Build Coastguard Worker 	block_t ssa_blkaddr;
693*59bfda1fSAndroid Build Coastguard Worker 	int type;
694*59bfda1fSAndroid Build Coastguard Worker 	int ret;
695*59bfda1fSAndroid Build Coastguard Worker 
696*59bfda1fSAndroid Build Coastguard Worker 	if (!f2fs_is_valid_blkaddr(sbi, opt->blk, DATA_GENERIC)) {
697*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("Invalid blkaddr %#x (valid range [%#x:%#lx])\n",
698*59bfda1fSAndroid Build Coastguard Worker 			opt->blk, SM_I(sbi)->main_blkaddr,
699*59bfda1fSAndroid Build Coastguard Worker 			(unsigned long)le64_to_cpu(F2FS_RAW_SUPER(sbi)->block_count));
700*59bfda1fSAndroid Build Coastguard Worker 		return -ERANGE;
701*59bfda1fSAndroid Build Coastguard Worker 	}
702*59bfda1fSAndroid Build Coastguard Worker 
703*59bfda1fSAndroid Build Coastguard Worker 	segno = GET_SEGNO(sbi, opt->blk);
704*59bfda1fSAndroid Build Coastguard Worker 	offset = OFFSET_IN_SEG(sbi, opt->blk);
705*59bfda1fSAndroid Build Coastguard Worker 
706*59bfda1fSAndroid Build Coastguard Worker 	sum_blk = get_sum_block(sbi, segno, &type);
707*59bfda1fSAndroid Build Coastguard Worker 	sum = &sum_blk->entries[offset];
708*59bfda1fSAndroid Build Coastguard Worker 	footer = F2FS_SUMMARY_BLOCK_FOOTER(sum_blk);
709*59bfda1fSAndroid Build Coastguard Worker 
710*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "entry_type")) {
711*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject summary block footer entry_type of "
712*59bfda1fSAndroid Build Coastguard Worker 		    "block 0x%x: %d -> %d\n", opt->blk, footer->entry_type,
713*59bfda1fSAndroid Build Coastguard Worker 		    (unsigned char)opt->val);
714*59bfda1fSAndroid Build Coastguard Worker 		footer->entry_type = (unsigned char)opt->val;
715*59bfda1fSAndroid Build Coastguard Worker 	} else 	if (!strcmp(opt->mb, "check_sum")) {
716*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject summary block footer check_sum of "
717*59bfda1fSAndroid Build Coastguard Worker 		    "block 0x%x: 0x%x -> 0x%x\n", opt->blk,
718*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(footer->check_sum), (u32)opt->val);
719*59bfda1fSAndroid Build Coastguard Worker 		footer->check_sum = cpu_to_le32((u32)opt->val);
720*59bfda1fSAndroid Build Coastguard Worker 	} else {
721*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx == -1) {
722*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: auto idx = %u\n", offset);
723*59bfda1fSAndroid Build Coastguard Worker 			opt->idx = offset;
724*59bfda1fSAndroid Build Coastguard Worker 		}
725*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= ENTRIES_IN_SUM) {
726*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid idx %u of entries[]\n", opt->idx);
727*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
728*59bfda1fSAndroid Build Coastguard Worker 			goto out;
729*59bfda1fSAndroid Build Coastguard Worker 		}
730*59bfda1fSAndroid Build Coastguard Worker 		sum = &sum_blk->entries[opt->idx];
731*59bfda1fSAndroid Build Coastguard Worker 		if (!strcmp(opt->mb, "nid")) {
732*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject summary entry nid of "
733*59bfda1fSAndroid Build Coastguard Worker 			    "block 0x%x: 0x%x -> 0x%x\n", opt->blk,
734*59bfda1fSAndroid Build Coastguard Worker 			    le32_to_cpu(sum->nid), (u32)opt->val);
735*59bfda1fSAndroid Build Coastguard Worker 			sum->nid = cpu_to_le32((u32)opt->val);
736*59bfda1fSAndroid Build Coastguard Worker 		} else if (!strcmp(opt->mb, "version")) {
737*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject summary entry version of "
738*59bfda1fSAndroid Build Coastguard Worker 			    "block 0x%x: %d -> %d\n", opt->blk,
739*59bfda1fSAndroid Build Coastguard Worker 			    sum->version, (u8)opt->val);
740*59bfda1fSAndroid Build Coastguard Worker 			sum->version = (u8)opt->val;
741*59bfda1fSAndroid Build Coastguard Worker 		} else if (!strcmp(opt->mb, "ofs_in_node")) {
742*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "Info: inject summary entry ofs_in_node of "
743*59bfda1fSAndroid Build Coastguard Worker 			    "block 0x%x: %d -> %d\n", opt->blk,
744*59bfda1fSAndroid Build Coastguard Worker 			    sum->ofs_in_node, (u16)opt->val);
745*59bfda1fSAndroid Build Coastguard Worker 			sum->ofs_in_node = cpu_to_le16((u16)opt->val);
746*59bfda1fSAndroid Build Coastguard Worker 		} else {
747*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
748*59bfda1fSAndroid Build Coastguard Worker 			ret = -EINVAL;
749*59bfda1fSAndroid Build Coastguard Worker 			goto out;
750*59bfda1fSAndroid Build Coastguard Worker 		}
751*59bfda1fSAndroid Build Coastguard Worker 
752*59bfda1fSAndroid Build Coastguard Worker 		print_raw_sum_entry_info(sum);
753*59bfda1fSAndroid Build Coastguard Worker 	}
754*59bfda1fSAndroid Build Coastguard Worker 
755*59bfda1fSAndroid Build Coastguard Worker 	print_sum_footer_info(footer);
756*59bfda1fSAndroid Build Coastguard Worker 
757*59bfda1fSAndroid Build Coastguard Worker 	ssa_blkaddr = GET_SUM_BLKADDR(sbi, segno);
758*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_write_block(sum_blk, ssa_blkaddr, WRITE_LIFE_NONE);
759*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
760*59bfda1fSAndroid Build Coastguard Worker 
761*59bfda1fSAndroid Build Coastguard Worker out:
762*59bfda1fSAndroid Build Coastguard Worker 	if (type == SEG_TYPE_NODE || type == SEG_TYPE_DATA ||
763*59bfda1fSAndroid Build Coastguard Worker 	    type == SEG_TYPE_MAX)
764*59bfda1fSAndroid Build Coastguard Worker 		free(sum_blk);
765*59bfda1fSAndroid Build Coastguard Worker 	return ret;
766*59bfda1fSAndroid Build Coastguard Worker }
767*59bfda1fSAndroid Build Coastguard Worker 
inject_inode(struct f2fs_sb_info * sbi,struct f2fs_node * node,struct inject_option * opt)768*59bfda1fSAndroid Build Coastguard Worker static int inject_inode(struct f2fs_sb_info *sbi, struct f2fs_node *node,
769*59bfda1fSAndroid Build Coastguard Worker 			struct inject_option *opt)
770*59bfda1fSAndroid Build Coastguard Worker {
771*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_inode *inode = &node->i;
772*59bfda1fSAndroid Build Coastguard Worker 
773*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "i_mode")) {
774*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_mode of nid %u: 0x%x -> 0x%x\n",
775*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le16_to_cpu(inode->i_mode), (u16)opt->val);
776*59bfda1fSAndroid Build Coastguard Worker 		inode->i_mode = cpu_to_le16((u16)opt->val);
777*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_advise")) {
778*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_advise of nid %u: 0x%x -> 0x%x\n",
779*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, inode->i_advise, (u8)opt->val);
780*59bfda1fSAndroid Build Coastguard Worker 		inode->i_advise = (u8)opt->val;
781*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_inline")) {
782*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_inline of nid %u: 0x%x -> 0x%x\n",
783*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, inode->i_inline, (u8)opt->val);
784*59bfda1fSAndroid Build Coastguard Worker 		inode->i_inline = (u8)opt->val;
785*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_links")) {
786*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_links of nid %u: %u -> %u\n",
787*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le32_to_cpu(inode->i_links), (u32)opt->val);
788*59bfda1fSAndroid Build Coastguard Worker 		inode->i_links = cpu_to_le32((u32)opt->val);
789*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_size")) {
790*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_size of nid %u: %"PRIu64" -> %"PRIu64"\n",
791*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le64_to_cpu(inode->i_size), (u64)opt->val);
792*59bfda1fSAndroid Build Coastguard Worker 		inode->i_size = cpu_to_le64((u64)opt->val);
793*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_blocks")) {
794*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_blocks of nid %u: %"PRIu64" -> %"PRIu64"\n",
795*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le64_to_cpu(inode->i_blocks), (u64)opt->val);
796*59bfda1fSAndroid Build Coastguard Worker 		inode->i_blocks = cpu_to_le64((u64)opt->val);
797*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_extra_isize")) {
798*59bfda1fSAndroid Build Coastguard Worker 		/* do not care if F2FS_EXTRA_ATTR is enabled */
799*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_extra_isize of nid %u: %d -> %d\n",
800*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le16_to_cpu(inode->i_extra_isize), (u16)opt->val);
801*59bfda1fSAndroid Build Coastguard Worker 		inode->i_extra_isize = cpu_to_le16((u16)opt->val);
802*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_inode_checksum")) {
803*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_inode_checksum of nid %u: "
804*59bfda1fSAndroid Build Coastguard Worker 		    "0x%x -> 0x%x\n", opt->nid,
805*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(inode->i_inode_checksum), (u32)opt->val);
806*59bfda1fSAndroid Build Coastguard Worker 		inode->i_inode_checksum = cpu_to_le32((u32)opt->val);
807*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_addr")) {
808*59bfda1fSAndroid Build Coastguard Worker 		/* do not care if it is inline data */
809*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= DEF_ADDRS_PER_INODE) {
810*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of i_addr[]\n", opt->idx);
811*59bfda1fSAndroid Build Coastguard Worker 			return -EINVAL;
812*59bfda1fSAndroid Build Coastguard Worker 		}
813*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_addr[%d] of nid %u: "
814*59bfda1fSAndroid Build Coastguard Worker 		    "0x%x -> 0x%x\n", opt->idx, opt->nid,
815*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(inode->i_addr[opt->idx]), (u32)opt->val);
816*59bfda1fSAndroid Build Coastguard Worker 		inode->i_addr[opt->idx] = cpu_to_le32((block_t)opt->val);
817*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "i_nid")) {
818*59bfda1fSAndroid Build Coastguard Worker 		if (opt->idx >= 5) {
819*59bfda1fSAndroid Build Coastguard Worker 			ERR_MSG("invalid index %u of i_nid[]\n", opt->idx);
820*59bfda1fSAndroid Build Coastguard Worker 			return -EINVAL;
821*59bfda1fSAndroid Build Coastguard Worker 		}
822*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject inode i_nid[%d] of nid %u: "
823*59bfda1fSAndroid Build Coastguard Worker 		    "0x%x -> 0x%x\n", opt->idx, opt->nid,
824*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(F2FS_INODE_I_NID(inode, opt->idx)),
825*59bfda1fSAndroid Build Coastguard Worker 		    (u32)opt->val);
826*59bfda1fSAndroid Build Coastguard Worker 		F2FS_INODE_I_NID(inode, opt->idx) = cpu_to_le32((nid_t)opt->val);
827*59bfda1fSAndroid Build Coastguard Worker 	} else {
828*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
829*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
830*59bfda1fSAndroid Build Coastguard Worker 	}
831*59bfda1fSAndroid Build Coastguard Worker 
832*59bfda1fSAndroid Build Coastguard Worker 	if (c.dbg_lv > 0)
833*59bfda1fSAndroid Build Coastguard Worker 		print_node_info(sbi, node, 1);
834*59bfda1fSAndroid Build Coastguard Worker 
835*59bfda1fSAndroid Build Coastguard Worker 	return 0;
836*59bfda1fSAndroid Build Coastguard Worker }
837*59bfda1fSAndroid Build Coastguard Worker 
inject_index_node(struct f2fs_sb_info * sbi,struct f2fs_node * node,struct inject_option * opt)838*59bfda1fSAndroid Build Coastguard Worker static int inject_index_node(struct f2fs_sb_info *sbi, struct f2fs_node *node,
839*59bfda1fSAndroid Build Coastguard Worker 			     struct inject_option *opt)
840*59bfda1fSAndroid Build Coastguard Worker {
841*59bfda1fSAndroid Build Coastguard Worker 	struct direct_node *dn = &node->dn;
842*59bfda1fSAndroid Build Coastguard Worker 
843*59bfda1fSAndroid Build Coastguard Worker 	if (strcmp(opt->mb, "addr")) {
844*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
845*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
846*59bfda1fSAndroid Build Coastguard Worker 	}
847*59bfda1fSAndroid Build Coastguard Worker 
848*59bfda1fSAndroid Build Coastguard Worker 	if (opt->idx >= DEF_ADDRS_PER_BLOCK) {
849*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("invalid index %u of nid/addr[]\n", opt->idx);
850*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
851*59bfda1fSAndroid Build Coastguard Worker 	}
852*59bfda1fSAndroid Build Coastguard Worker 
853*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "Info: inject node nid/addr[%d] of nid %u: 0x%x -> 0x%x\n",
854*59bfda1fSAndroid Build Coastguard Worker 	    opt->idx, opt->nid, le32_to_cpu(dn->addr[opt->idx]),
855*59bfda1fSAndroid Build Coastguard Worker 	    (block_t)opt->val);
856*59bfda1fSAndroid Build Coastguard Worker 	dn->addr[opt->idx] = cpu_to_le32((block_t)opt->val);
857*59bfda1fSAndroid Build Coastguard Worker 
858*59bfda1fSAndroid Build Coastguard Worker 	if (c.dbg_lv > 0)
859*59bfda1fSAndroid Build Coastguard Worker 		print_node_info(sbi, node, 1);
860*59bfda1fSAndroid Build Coastguard Worker 
861*59bfda1fSAndroid Build Coastguard Worker 	return 0;
862*59bfda1fSAndroid Build Coastguard Worker }
863*59bfda1fSAndroid Build Coastguard Worker 
inject_node(struct f2fs_sb_info * sbi,struct inject_option * opt)864*59bfda1fSAndroid Build Coastguard Worker static int inject_node(struct f2fs_sb_info *sbi, struct inject_option *opt)
865*59bfda1fSAndroid Build Coastguard Worker {
866*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = sbi->raw_super;
867*59bfda1fSAndroid Build Coastguard Worker 	struct node_info ni;
868*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk;
869*59bfda1fSAndroid Build Coastguard Worker 	struct node_footer *footer;
870*59bfda1fSAndroid Build Coastguard Worker 	int ret;
871*59bfda1fSAndroid Build Coastguard Worker 
872*59bfda1fSAndroid Build Coastguard Worker 	if (!IS_VALID_NID(sbi, opt->nid)) {
873*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("Invalid nid %u range [%u:%"PRIu64"]\n", opt->nid, 0,
874*59bfda1fSAndroid Build Coastguard Worker 			NAT_ENTRY_PER_BLOCK *
875*59bfda1fSAndroid Build Coastguard Worker 			((get_sb(segment_count_nat) << 1) <<
876*59bfda1fSAndroid Build Coastguard Worker 			 sbi->log_blocks_per_seg));
877*59bfda1fSAndroid Build Coastguard Worker 		return -EINVAL;
878*59bfda1fSAndroid Build Coastguard Worker 	}
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 	get_node_info(sbi, opt->nid, &ni);
884*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, ni.blk_addr);
885*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
886*59bfda1fSAndroid Build Coastguard Worker 	footer = F2FS_NODE_FOOTER(node_blk);
887*59bfda1fSAndroid Build Coastguard Worker 
888*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "nid")) {
889*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject node footer nid of nid %u: %u -> %u\n",
890*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le32_to_cpu(footer->nid), (u32)opt->val);
891*59bfda1fSAndroid Build Coastguard Worker 		footer->nid = cpu_to_le32((u32)opt->val);
892*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "ino")) {
893*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject node footer ino of nid %u: %u -> %u\n",
894*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid, le32_to_cpu(footer->ino), (u32)opt->val);
895*59bfda1fSAndroid Build Coastguard Worker 		footer->ino = cpu_to_le32((u32)opt->val);
896*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "flag")) {
897*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject node footer flag of nid %u: "
898*59bfda1fSAndroid Build Coastguard Worker 		    "0x%x -> 0x%x\n", opt->nid, le32_to_cpu(footer->flag),
899*59bfda1fSAndroid Build Coastguard Worker 		    (u32)opt->val);
900*59bfda1fSAndroid Build Coastguard Worker 		footer->flag = cpu_to_le32((u32)opt->val);
901*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "cp_ver")) {
902*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject node footer cp_ver of nid %u: "
903*59bfda1fSAndroid Build Coastguard Worker 		    "0x%"PRIx64" -> 0x%"PRIx64"\n", opt->nid, le64_to_cpu(footer->cp_ver),
904*59bfda1fSAndroid Build Coastguard Worker 		    (u64)opt->val);
905*59bfda1fSAndroid Build Coastguard Worker 		footer->cp_ver = cpu_to_le64((u64)opt->val);
906*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "next_blkaddr")) {
907*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject node footer next_blkaddr of nid %u: "
908*59bfda1fSAndroid Build Coastguard Worker 		    "0x%x -> 0x%x\n", opt->nid,
909*59bfda1fSAndroid Build Coastguard Worker 		    le32_to_cpu(footer->next_blkaddr), (u32)opt->val);
910*59bfda1fSAndroid Build Coastguard Worker 		footer->next_blkaddr = cpu_to_le32((u32)opt->val);
911*59bfda1fSAndroid Build Coastguard Worker 	} else if (ni.nid == ni.ino) {
912*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_inode(sbi, node_blk, opt);
913*59bfda1fSAndroid Build Coastguard Worker 	} else {
914*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_index_node(sbi, node_blk, opt);
915*59bfda1fSAndroid Build Coastguard Worker 	}
916*59bfda1fSAndroid Build Coastguard Worker 	if (ret)
917*59bfda1fSAndroid Build Coastguard Worker 		goto out;
918*59bfda1fSAndroid Build Coastguard Worker 
919*59bfda1fSAndroid Build Coastguard Worker 	print_node_footer_info(footer);
920*59bfda1fSAndroid Build Coastguard Worker 
921*59bfda1fSAndroid Build Coastguard Worker 	/*
922*59bfda1fSAndroid Build Coastguard Worker 	 * if i_inode_checksum is injected, should call update_block() to
923*59bfda1fSAndroid Build Coastguard Worker 	 * avoid recalculate inode checksum
924*59bfda1fSAndroid Build Coastguard Worker 	 */
925*59bfda1fSAndroid Build Coastguard Worker 	if (ni.nid == ni.ino && strcmp(opt->mb, "i_inode_checksum"))
926*59bfda1fSAndroid Build Coastguard Worker 		ret = update_inode(sbi, node_blk, &ni.blk_addr);
927*59bfda1fSAndroid Build Coastguard Worker 	else
928*59bfda1fSAndroid Build Coastguard Worker 		ret = update_block(sbi, node_blk, &ni.blk_addr, NULL);
929*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
930*59bfda1fSAndroid Build Coastguard Worker 
931*59bfda1fSAndroid Build Coastguard Worker out:
932*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
933*59bfda1fSAndroid Build Coastguard Worker 	return ret;
934*59bfda1fSAndroid Build Coastguard Worker }
935*59bfda1fSAndroid Build Coastguard Worker 
find_dir_entry(struct f2fs_dentry_ptr * d,nid_t ino)936*59bfda1fSAndroid Build Coastguard Worker static int find_dir_entry(struct f2fs_dentry_ptr *d, nid_t ino)
937*59bfda1fSAndroid Build Coastguard Worker {
938*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_dir_entry *de;
939*59bfda1fSAndroid Build Coastguard Worker 	int slot = 0;
940*59bfda1fSAndroid Build Coastguard Worker 
941*59bfda1fSAndroid Build Coastguard Worker 	while (slot < d->max) {
942*59bfda1fSAndroid Build Coastguard Worker 		if (!test_bit_le(slot, d->bitmap)) {
943*59bfda1fSAndroid Build Coastguard Worker 			slot++;
944*59bfda1fSAndroid Build Coastguard Worker 			continue;
945*59bfda1fSAndroid Build Coastguard Worker 		}
946*59bfda1fSAndroid Build Coastguard Worker 
947*59bfda1fSAndroid Build Coastguard Worker 		de = &d->dentry[slot];
948*59bfda1fSAndroid Build Coastguard Worker 		if (le32_to_cpu(de->ino) == ino && de->hash_code != 0)
949*59bfda1fSAndroid Build Coastguard Worker 			return slot;
950*59bfda1fSAndroid Build Coastguard Worker 		if (de->name_len == 0) {
951*59bfda1fSAndroid Build Coastguard Worker 			slot++;
952*59bfda1fSAndroid Build Coastguard Worker 			continue;
953*59bfda1fSAndroid Build Coastguard Worker 		}
954*59bfda1fSAndroid Build Coastguard Worker 		slot += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
955*59bfda1fSAndroid Build Coastguard Worker 	}
956*59bfda1fSAndroid Build Coastguard Worker 
957*59bfda1fSAndroid Build Coastguard Worker 	return -ENOENT;
958*59bfda1fSAndroid Build Coastguard Worker }
959*59bfda1fSAndroid Build Coastguard Worker 
inject_dentry(struct f2fs_sb_info * sbi,struct inject_option * opt)960*59bfda1fSAndroid Build Coastguard Worker static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
961*59bfda1fSAndroid Build Coastguard Worker {
962*59bfda1fSAndroid Build Coastguard Worker 	struct node_info ni;
963*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_node *node_blk = NULL;
964*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_inode *inode;
965*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_dentry_ptr d;
966*59bfda1fSAndroid Build Coastguard Worker 	void *inline_dentry;
967*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_dentry_block *dent_blk = NULL;
968*59bfda1fSAndroid Build Coastguard Worker 	block_t addr = 0;
969*59bfda1fSAndroid Build Coastguard Worker 	void *buf = NULL;
970*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_dir_entry *dent = NULL;
971*59bfda1fSAndroid Build Coastguard Worker 	struct dnode_of_data dn;
972*59bfda1fSAndroid Build Coastguard Worker 	nid_t pino;
973*59bfda1fSAndroid Build Coastguard Worker 	int slot = -ENOENT, ret;
974*59bfda1fSAndroid Build Coastguard Worker 
975*59bfda1fSAndroid Build Coastguard Worker 	node_blk = malloc(F2FS_BLKSIZE);
976*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(node_blk != NULL);
977*59bfda1fSAndroid Build Coastguard Worker 
978*59bfda1fSAndroid Build Coastguard Worker 	/* get child inode */
979*59bfda1fSAndroid Build Coastguard Worker 	get_node_info(sbi, opt->nid, &ni);
980*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, ni.blk_addr);
981*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
982*59bfda1fSAndroid Build Coastguard Worker 	pino = le32_to_cpu(node_blk->i.i_pino);
983*59bfda1fSAndroid Build Coastguard Worker 
984*59bfda1fSAndroid Build Coastguard Worker 	/* get parent inode */
985*59bfda1fSAndroid Build Coastguard Worker 	get_node_info(sbi, pino, &ni);
986*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_read_block(node_blk, ni.blk_addr);
987*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
988*59bfda1fSAndroid Build Coastguard Worker 	inode = &node_blk->i;
989*59bfda1fSAndroid Build Coastguard Worker 
990*59bfda1fSAndroid Build Coastguard Worker 	/* find child dentry */
991*59bfda1fSAndroid Build Coastguard Worker 	if (inode->i_inline & F2FS_INLINE_DENTRY) {
992*59bfda1fSAndroid Build Coastguard Worker 		inline_dentry = inline_data_addr(node_blk);
993*59bfda1fSAndroid Build Coastguard Worker 		make_dentry_ptr(&d, node_blk, inline_dentry, 2);
994*59bfda1fSAndroid Build Coastguard Worker 		addr = ni.blk_addr;
995*59bfda1fSAndroid Build Coastguard Worker 		buf = node_blk;
996*59bfda1fSAndroid Build Coastguard Worker 
997*59bfda1fSAndroid Build Coastguard Worker 		slot = find_dir_entry(&d, opt->nid);
998*59bfda1fSAndroid Build Coastguard Worker 		if (slot >= 0)
999*59bfda1fSAndroid Build Coastguard Worker 			dent = &d.dentry[slot];
1000*59bfda1fSAndroid Build Coastguard Worker 	} else {
1001*59bfda1fSAndroid Build Coastguard Worker 		unsigned int level, dirlevel, nbucket;
1002*59bfda1fSAndroid Build Coastguard Worker 		unsigned long i, end;
1003*59bfda1fSAndroid Build Coastguard Worker 
1004*59bfda1fSAndroid Build Coastguard Worker 		level = le32_to_cpu(inode->i_current_depth);
1005*59bfda1fSAndroid Build Coastguard Worker 		dirlevel = le32_to_cpu(inode->i_dir_level);
1006*59bfda1fSAndroid Build Coastguard Worker 		nbucket = dir_buckets(level, dirlevel);
1007*59bfda1fSAndroid Build Coastguard Worker 		end = dir_block_index(level, dirlevel, nbucket) +
1008*59bfda1fSAndroid Build Coastguard Worker 						bucket_blocks(level);
1009*59bfda1fSAndroid Build Coastguard Worker 
1010*59bfda1fSAndroid Build Coastguard Worker 		dent_blk = malloc(F2FS_BLKSIZE);
1011*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(dent_blk != NULL);
1012*59bfda1fSAndroid Build Coastguard Worker 
1013*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < end; i++) {
1014*59bfda1fSAndroid Build Coastguard Worker 			memset(&dn, 0, sizeof(dn));
1015*59bfda1fSAndroid Build Coastguard Worker 			set_new_dnode(&dn, node_blk, NULL, pino);
1016*59bfda1fSAndroid Build Coastguard Worker 			ret = get_dnode_of_data(sbi, &dn, i, LOOKUP_NODE);
1017*59bfda1fSAndroid Build Coastguard Worker 			if (ret < 0)
1018*59bfda1fSAndroid Build Coastguard Worker 				break;
1019*59bfda1fSAndroid Build Coastguard Worker 			addr = dn.data_blkaddr;
1020*59bfda1fSAndroid Build Coastguard Worker 			if (dn.inode_blk != dn.node_blk)
1021*59bfda1fSAndroid Build Coastguard Worker 				free(dn.node_blk);
1022*59bfda1fSAndroid Build Coastguard Worker 			if (addr == NULL_ADDR || addr == NEW_ADDR)
1023*59bfda1fSAndroid Build Coastguard Worker 				continue;
1024*59bfda1fSAndroid Build Coastguard Worker 			if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC)) {
1025*59bfda1fSAndroid Build Coastguard Worker 				MSG(0, "invalid blkaddr 0x%x at offset %lu\n",
1026*59bfda1fSAndroid Build Coastguard Worker 				    addr, i);
1027*59bfda1fSAndroid Build Coastguard Worker 				continue;
1028*59bfda1fSAndroid Build Coastguard Worker 			}
1029*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_read_block(dent_blk, addr);
1030*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
1031*59bfda1fSAndroid Build Coastguard Worker 
1032*59bfda1fSAndroid Build Coastguard Worker 			make_dentry_ptr(&d, node_blk, dent_blk, 1);
1033*59bfda1fSAndroid Build Coastguard Worker 			slot = find_dir_entry(&d, opt->nid);
1034*59bfda1fSAndroid Build Coastguard Worker 			if (slot >= 0) {
1035*59bfda1fSAndroid Build Coastguard Worker 				dent = &d.dentry[slot];
1036*59bfda1fSAndroid Build Coastguard Worker 				buf = dent_blk;
1037*59bfda1fSAndroid Build Coastguard Worker 				break;
1038*59bfda1fSAndroid Build Coastguard Worker 			}
1039*59bfda1fSAndroid Build Coastguard Worker 		}
1040*59bfda1fSAndroid Build Coastguard Worker 	}
1041*59bfda1fSAndroid Build Coastguard Worker 
1042*59bfda1fSAndroid Build Coastguard Worker 	if (slot < 0) {
1043*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("dentry of ino %u not found\n", opt->nid);
1044*59bfda1fSAndroid Build Coastguard Worker 		ret = -ENOENT;
1045*59bfda1fSAndroid Build Coastguard Worker 		goto out;
1046*59bfda1fSAndroid Build Coastguard Worker 	}
1047*59bfda1fSAndroid Build Coastguard Worker 
1048*59bfda1fSAndroid Build Coastguard Worker 	if (!strcmp(opt->mb, "d_bitmap")) {
1049*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject dentry bitmap of nid %u: 1 -> 0\n",
1050*59bfda1fSAndroid Build Coastguard Worker 		    opt->nid);
1051*59bfda1fSAndroid Build Coastguard Worker 		test_and_clear_bit_le(slot, d.bitmap);
1052*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "d_hash")) {
1053*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject dentry d_hash of nid %u: "
1054*59bfda1fSAndroid Build Coastguard Worker 		    "0x%x -> 0x%x\n", opt->nid, le32_to_cpu(dent->hash_code),
1055*59bfda1fSAndroid Build Coastguard Worker 		    (u32)opt->val);
1056*59bfda1fSAndroid Build Coastguard Worker 		dent->hash_code = cpu_to_le32((u32)opt->val);
1057*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "d_ino")) {
1058*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject dentry d_ino of nid %u: "
1059*59bfda1fSAndroid Build Coastguard Worker 		    "%u -> %u\n", opt->nid, le32_to_cpu(dent->ino),
1060*59bfda1fSAndroid Build Coastguard Worker 		    (nid_t)opt->val);
1061*59bfda1fSAndroid Build Coastguard Worker 		dent->ino = cpu_to_le32((nid_t)opt->val);
1062*59bfda1fSAndroid Build Coastguard Worker 	} else if (!strcmp(opt->mb, "d_ftype")) {
1063*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Info: inject dentry d_type of nid %u: "
1064*59bfda1fSAndroid Build Coastguard Worker 		    "%d -> %d\n", opt->nid, dent->file_type,
1065*59bfda1fSAndroid Build Coastguard Worker 		    (u8)opt->val);
1066*59bfda1fSAndroid Build Coastguard Worker 		dent->file_type = (u8)opt->val;
1067*59bfda1fSAndroid Build Coastguard Worker 	} else {
1068*59bfda1fSAndroid Build Coastguard Worker 		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
1069*59bfda1fSAndroid Build Coastguard Worker 		ret = -EINVAL;
1070*59bfda1fSAndroid Build Coastguard Worker 		goto out;
1071*59bfda1fSAndroid Build Coastguard Worker 	}
1072*59bfda1fSAndroid Build Coastguard Worker 
1073*59bfda1fSAndroid Build Coastguard Worker 	print_raw_dentry_info(dent);
1074*59bfda1fSAndroid Build Coastguard Worker 
1075*59bfda1fSAndroid Build Coastguard Worker 	if (inode->i_inline & F2FS_INLINE_DENTRY)
1076*59bfda1fSAndroid Build Coastguard Worker 		ret = update_inode(sbi, buf, &addr);
1077*59bfda1fSAndroid Build Coastguard Worker 	else
1078*59bfda1fSAndroid Build Coastguard Worker 		ret = update_block(sbi, buf, &addr, NULL);
1079*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
1080*59bfda1fSAndroid Build Coastguard Worker 
1081*59bfda1fSAndroid Build Coastguard Worker out:
1082*59bfda1fSAndroid Build Coastguard Worker 	free(node_blk);
1083*59bfda1fSAndroid Build Coastguard Worker 	free(dent_blk);
1084*59bfda1fSAndroid Build Coastguard Worker 	return ret;
1085*59bfda1fSAndroid Build Coastguard Worker }
1086*59bfda1fSAndroid Build Coastguard Worker 
do_inject(struct f2fs_sb_info * sbi)1087*59bfda1fSAndroid Build Coastguard Worker int do_inject(struct f2fs_sb_info *sbi)
1088*59bfda1fSAndroid Build Coastguard Worker {
1089*59bfda1fSAndroid Build Coastguard Worker 	struct inject_option *opt = (struct inject_option *)c.private;
1090*59bfda1fSAndroid Build Coastguard Worker 	int ret = -EINVAL;
1091*59bfda1fSAndroid Build Coastguard Worker 
1092*59bfda1fSAndroid Build Coastguard Worker 	if (opt->sb >= 0)
1093*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_sb(sbi, opt);
1094*59bfda1fSAndroid Build Coastguard Worker 	else if (opt->cp >= 0)
1095*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_cp(sbi, opt);
1096*59bfda1fSAndroid Build Coastguard Worker 	else if (opt->nat >= 0)
1097*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_nat(sbi, opt);
1098*59bfda1fSAndroid Build Coastguard Worker 	else if (opt->sit >= 0)
1099*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_sit(sbi, opt);
1100*59bfda1fSAndroid Build Coastguard Worker 	else if (opt->ssa)
1101*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_ssa(sbi, opt);
1102*59bfda1fSAndroid Build Coastguard Worker 	else if (opt->node)
1103*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_node(sbi, opt);
1104*59bfda1fSAndroid Build Coastguard Worker 	else if (opt->dent)
1105*59bfda1fSAndroid Build Coastguard Worker 		ret = inject_dentry(sbi, opt);
1106*59bfda1fSAndroid Build Coastguard Worker 
1107*59bfda1fSAndroid Build Coastguard Worker 	return ret;
1108*59bfda1fSAndroid Build Coastguard Worker }
1109