main.c revision 8843554c8c43e713e2ce4e36ac3c06f9eca94b09
1/**
2 * main.c
3 *
4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5 *             http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "fsck.h"
12#include <libgen.h>
13
14struct f2fs_fsck gfsck = {
15	.sbi.fsck = &gfsck,
16};
17
18void fsck_usage()
19{
20	MSG(0, "\nUsage: fsck.f2fs [options] device\n");
21	MSG(0, "[options]:\n");
22	MSG(0, "  -d debug level [default:0]\n");
23	exit(1);
24}
25
26void dump_usage()
27{
28	MSG(0, "\nUsage: dump.f2fs [options] device\n");
29	MSG(0, "[options]:\n");
30	MSG(0, "  -d debug level [default:0]\n");
31	MSG(0, "  -i inode no (hex)\n");
32	MSG(0, "  -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]\n");
33	MSG(0, "  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
34	MSG(0, "  -b blk_addr (in 4KB)\n");
35
36	exit(1);
37}
38
39void f2fs_parse_options(int argc, char *argv[])
40{
41	int option = 0;
42	char *prog = basename(argv[0]);
43
44	if (!strcmp("fsck.f2fs", prog)) {
45		const char *option_string = "d:";
46
47		config.func = FSCK;
48		while ((option = getopt(argc, argv, option_string)) != EOF) {
49			switch (option) {
50				case 'd':
51					config.dbg_lv = atoi(optarg);
52					MSG(0, "Info: Debug level = %d\n", config.dbg_lv);
53					break;
54				default:
55					MSG(0, "\tError: Unknown option %c\n",option);
56					fsck_usage();
57					break;
58			}
59		}
60	} else if (!strcmp("dump.f2fs", prog)) {
61		const char *option_string = "d:i:s:a:b:";
62		static struct dump_option dump_opt = {
63			.nid = 3,	/* default root ino */
64			.start_sit = -1,
65			.end_sit = -1,
66			.start_ssa = -1,
67			.end_ssa = -1,
68			.blk_addr = -1,
69		};
70
71		config.func = DUMP;
72		while ((option = getopt(argc, argv, option_string)) != EOF) {
73			switch (option) {
74				case 'd':
75					config.dbg_lv = atoi(optarg);
76					MSG(0, "Info: Debug level = %d\n", config.dbg_lv);
77					break;
78				case 'i':
79					sscanf(optarg, "%x", &dump_opt.nid);
80					break;
81				case 's':
82					sscanf(optarg, "%d~%d", &dump_opt.start_sit, &dump_opt.end_sit);
83					break;
84				case 'a':
85					sscanf(optarg, "%d~%d", &dump_opt.start_ssa, &dump_opt.end_ssa);
86					break;
87				case 'b':
88					sscanf(optarg, "%d", &dump_opt.blk_addr);
89					break;
90				default:
91					MSG(0, "\tError: Unknown option %c\n", option);
92					dump_usage();
93					break;
94			}
95		}
96
97		config.private = &dump_opt;
98	}
99
100	if ((optind + 1) != argc) {
101		MSG(0, "\tError: Device not specified\n");
102		if (config.func == FSCK)
103			fsck_usage();
104		else if (config.func == DUMP)
105			dump_usage();
106	}
107	config.device_name = argv[optind];
108}
109
110int do_fsck(struct f2fs_sb_info *sbi)
111{
112	u32 blk_cnt;
113	int ret;
114
115	ret = fsck_init(sbi);
116	if (ret < 0)
117		return ret;
118
119	fsck_chk_orphan_node(sbi);
120
121	/* Travses all block recursively from root inode  */
122	blk_cnt = 1;
123	ret = fsck_chk_node_blk(sbi,
124			NULL,
125			sbi->root_ino_num,
126			F2FS_FT_DIR,
127			TYPE_INODE,
128			&blk_cnt);
129	if (ret < 0)
130		goto out1;
131
132	ret = fsck_verify(sbi);
133
134out1:
135	fsck_free(sbi);
136	return ret;
137}
138
139int do_dump(struct f2fs_sb_info *sbi)
140{
141	struct dump_option *opt = (struct dump_option *)config.private;
142	int ret;
143
144	ret = fsck_init(sbi);
145	if (ret < 0)
146		return ret;
147
148	if (opt->end_sit == -1)
149		opt->end_sit = SM_I(sbi)->main_segments;
150	if (opt->end_ssa == -1)
151		opt->end_ssa = SM_I(sbi)->main_segments;
152	if (opt->start_sit != -1)
153		sit_dump(sbi, opt->start_sit, opt->end_sit);
154	if (opt->start_ssa != -1)
155		ssa_dump(sbi, opt->start_ssa, opt->end_ssa);
156	if (opt->blk_addr != -1) {
157		dump_inode_from_blkaddr(sbi, opt->blk_addr);
158		goto cleanup;
159	}
160
161	dump_node(sbi, opt->nid);
162
163cleanup:
164	fsck_free(sbi);
165	return 0;
166}
167
168int main (int argc, char **argv)
169{
170	struct f2fs_sb_info *sbi = &gfsck.sbi;
171	int ret = 0;
172
173	f2fs_init_configuration(&config);
174
175	f2fs_parse_options(argc, argv);
176
177	if (f2fs_dev_is_mounted(&config) < 0)
178		return -1;
179
180	/* Get device */
181	if (f2fs_get_device_info(&config) < 0)
182		return -1;
183
184	if (f2fs_do_mount(sbi) < 0)
185		return -1;
186
187	switch (config.func) {
188		case FSCK:
189			ret = do_fsck(sbi);
190			break;
191		case DUMP:
192			ret = do_dump(sbi);
193			break;
194	}
195
196	f2fs_do_umount(sbi);
197	printf("\nDone.\n");
198	return ret;
199}
200