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