main.c revision 2c877a862d6d22ff5324e90b726c7d6a26febfb7
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:t"; 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 case 't': 55 config.dbg_lv = -1; 56 break; 57 default: 58 MSG(0, "\tError: Unknown option %c\n",option); 59 fsck_usage(); 60 break; 61 } 62 } 63 } else if (!strcmp("dump.f2fs", prog)) { 64 const char *option_string = "d:i:s:a:b:"; 65 static struct dump_option dump_opt = { 66 .nid = 3, /* default root ino */ 67 .start_sit = -1, 68 .end_sit = -1, 69 .start_ssa = -1, 70 .end_ssa = -1, 71 .blk_addr = -1, 72 }; 73 74 config.func = DUMP; 75 while ((option = getopt(argc, argv, option_string)) != EOF) { 76 switch (option) { 77 case 'd': 78 config.dbg_lv = atoi(optarg); 79 MSG(0, "Info: Debug level = %d\n", config.dbg_lv); 80 break; 81 case 'i': 82 if (strncmp(optarg, "0x", 2)) 83 sscanf(optarg, "%d", &dump_opt.nid); 84 else 85 sscanf(optarg, "%x", &dump_opt.nid); 86 break; 87 case 's': 88 sscanf(optarg, "%d~%d", &dump_opt.start_sit, &dump_opt.end_sit); 89 break; 90 case 'a': 91 sscanf(optarg, "%d~%d", &dump_opt.start_ssa, &dump_opt.end_ssa); 92 break; 93 case 'b': 94 if (strncmp(optarg, "0x", 2)) 95 sscanf(optarg, "%d", &dump_opt.blk_addr); 96 else 97 sscanf(optarg, "%x", &dump_opt.blk_addr); 98 break; 99 default: 100 MSG(0, "\tError: Unknown option %c\n", option); 101 dump_usage(); 102 break; 103 } 104 } 105 106 config.private = &dump_opt; 107 } 108 109 if ((optind + 1) != argc) { 110 MSG(0, "\tError: Device not specified\n"); 111 if (config.func == FSCK) 112 fsck_usage(); 113 else if (config.func == DUMP) 114 dump_usage(); 115 } 116 config.device_name = argv[optind]; 117} 118 119int do_fsck(struct f2fs_sb_info *sbi) 120{ 121 u32 blk_cnt; 122 int ret; 123 124 ret = fsck_init(sbi); 125 if (ret < 0) 126 return ret; 127 128 fsck_chk_orphan_node(sbi); 129 130 /* Travses all block recursively from root inode */ 131 blk_cnt = 1; 132 ret = fsck_chk_node_blk(sbi, 133 NULL, 134 sbi->root_ino_num, 135 F2FS_FT_DIR, 136 TYPE_INODE, 137 &blk_cnt); 138 if (ret < 0) 139 goto out1; 140 141 ret = fsck_verify(sbi); 142 143out1: 144 fsck_free(sbi); 145 return ret; 146} 147 148int do_dump(struct f2fs_sb_info *sbi) 149{ 150 struct dump_option *opt = (struct dump_option *)config.private; 151 int ret; 152 153 ret = fsck_init(sbi); 154 if (ret < 0) 155 return ret; 156 157 if (opt->end_sit == -1) 158 opt->end_sit = SM_I(sbi)->main_segments; 159 if (opt->end_ssa == -1) 160 opt->end_ssa = SM_I(sbi)->main_segments; 161 if (opt->start_sit != -1) 162 sit_dump(sbi, opt->start_sit, opt->end_sit); 163 if (opt->start_ssa != -1) 164 ssa_dump(sbi, opt->start_ssa, opt->end_ssa); 165 if (opt->blk_addr != -1) { 166 dump_inode_from_blkaddr(sbi, opt->blk_addr); 167 goto cleanup; 168 } 169 170 dump_node(sbi, opt->nid); 171 172cleanup: 173 fsck_free(sbi); 174 return 0; 175} 176 177int main (int argc, char **argv) 178{ 179 struct f2fs_sb_info *sbi = &gfsck.sbi; 180 int ret = 0; 181 182 f2fs_init_configuration(&config); 183 184 f2fs_parse_options(argc, argv); 185 186 if (f2fs_dev_is_umounted(&config) < 0) 187 return -1; 188 189 /* Get device */ 190 if (f2fs_get_device_info(&config) < 0) 191 return -1; 192 193 if (f2fs_do_mount(sbi) < 0) 194 return -1; 195 196 switch (config.func) { 197 case FSCK: 198 ret = do_fsck(sbi); 199 break; 200 case DUMP: 201 ret = do_dump(sbi); 202 break; 203 } 204 205 f2fs_do_umount(sbi); 206 printf("\nDone.\n"); 207 return ret; 208} 209