diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-02 18:07:35 -0700 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-02 18:23:11 -0700 |
commit | 7eb6c5a03b78d8673030e89ce15345d69d5e5777 (patch) | |
tree | e3dce758045e0d9789a6cc89dd9db3db007c7757 | |
parent | a6a7ac8e9db8f834bdf517394b90f6503c412b9f (diff) | |
download | android_external_f2fs-tools-7eb6c5a03b78d8673030e89ce15345d69d5e5777.tar.gz android_external_f2fs-tools-7eb6c5a03b78d8673030e89ce15345d69d5e5777.tar.bz2 android_external_f2fs-tools-7eb6c5a03b78d8673030e89ce15345d69d5e5777.zip |
fsck.f2fs: add auto_fix feature
This patch adds an auto_fix feature which fixes inconsistency of f2fs images.
E.g.,
With this option, -a, fsck.f2fs tries to fix inconsistency only if its valid
checkpoint has CP_FSCK_FLAG, written by previous bug_on cases.
So, normally it does fix nothing, so that there is no performance regression.
But, if a sort of corruption was reported by the f2fs module, this tries to
fix potential corrupted partition.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/main.c | 26 | ||||
-rw-r--r-- | fsck/mount.c | 14 | ||||
-rw-r--r-- | include/f2fs_fs.h | 2 |
3 files changed, 31 insertions, 11 deletions
diff --git a/fsck/main.c b/fsck/main.c index 7e3bb49..e20eac2 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -40,23 +40,27 @@ void f2fs_parse_options(int argc, char *argv[]) char *prog = basename(argv[0]); if (!strcmp("fsck.f2fs", prog)) { - const char *option_string = "d:tf"; + const char *option_string = "ad:ft"; config.func = FSCK; while ((option = getopt(argc, argv, option_string)) != EOF) { switch (option) { + case 'a': + config.auto_fix = 1; + MSG(0, "Info: Fix the reported corruption.\n"); + break; case 'd': config.dbg_lv = atoi(optarg); MSG(0, "Info: Debug level = %d\n", config.dbg_lv); break; - case 't': - config.dbg_lv = -1; - break; case 'f': config.fix_on = 1; MSG(0, "Info: Force to fix corruption\n"); break; + case 't': + config.dbg_lv = -1; + break; default: MSG(0, "\tError: Unknown option %c\n", option); fsck_usage(); @@ -135,8 +139,6 @@ static void do_fsck(struct f2fs_sb_info *sbi) { u32 blk_cnt; - config.bug_on = 0; - fsck_init(sbi); fsck_chk_orphan_node(sbi); @@ -192,7 +194,12 @@ fsck_again: gfsck.sbi.fsck = &gfsck; sbi = &gfsck.sbi; - if (f2fs_do_mount(sbi) < 0) + ret = f2fs_do_mount(sbi); + if (ret == 1) { + free(sbi->ckpt); + free(sbi->raw_super); + goto out; + } else if (ret < 0) return -1; switch (config.func) { @@ -205,9 +212,9 @@ fsck_again: } f2fs_do_umount(sbi); - +out: if (config.func == FSCK && config.bug_on) { - if (config.fix_on == 0) { + if (config.fix_on == 0 && !config.auto_fix) { char ans[255] = {0}; retry: printf("Do you want to fix this partition? [Y/N] "); @@ -226,7 +233,6 @@ retry: if (config.fix_cnt > 0 && config.fix_cnt < 4) goto fsck_again; } - f2fs_finalize_device(&config); printf("\nDone.\n"); diff --git a/fsck/mount.c b/fsck/mount.c index 2bbd3c5..5a12bb1 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -1183,6 +1183,7 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi) int f2fs_do_mount(struct f2fs_sb_info *sbi) { int ret; + sbi->active_logs = NR_CURSEG_TYPE; ret = validate_super_block(sbi, 0); if (ret) { @@ -1208,6 +1209,17 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi) print_ckpt_info(sbi); + if (config.auto_fix) { + u32 flag = le32_to_cpu(sbi->ckpt->ckpt_flags); + + if (flag & CP_FSCK_FLAG) + config.fix_cnt = 1; + else + return 1; + } + + config.bug_on = 0; + sbi->total_valid_node_count = le32_to_cpu(sbi->ckpt->valid_node_count); sbi->total_valid_inode_count = le32_to_cpu(sbi->ckpt->valid_inode_count); @@ -1227,7 +1239,7 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi) return -1; } - return ret; + return 0; } void f2fs_do_umount(struct f2fs_sb_info *sbi) diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index 7242690..6467791 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -185,6 +185,7 @@ struct f2fs_configuration { int fix_on; int fix_cnt; int bug_on; + int auto_fix; } __attribute__((packed)); #ifdef CONFIG_64BIT @@ -290,6 +291,7 @@ struct f2fs_super_block { /* * For checkpoint */ +#define CP_FSCK_FLAG 0x00000010 #define CP_ERROR_FLAG 0x00000008 #define CP_COMPACT_SUM_FLAG 0x00000004 #define CP_ORPHAN_PRESENT_FLAG 0x00000002 |