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