From: Jaegeuk Kim <jaegeuk@kernel.org>
To: linux-f2fs-devel@lists.sourceforge.net
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Subject: [PATCH 02/17] fsck.f2fs: retry to fix corrupted image
Date: Fri, 29 Aug 2014 17:28:49 -0700 [thread overview]
Message-ID: <1409358544-54740-2-git-send-email-jaegeuk@kernel.org> (raw)
In-Reply-To: <1409358544-54740-1-git-send-email-jaegeuk@kernel.org>
This patch adds a facility to retry conducting fsck.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 9 +++-
fsck/main.c | 141 +++++++++++++++++++++++++++++++++++-------------------
include/f2fs_fs.h | 5 ++
3 files changed, 104 insertions(+), 51 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 303ba8d..9a4c26c 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -761,6 +761,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
node->nid, node->links);
node = node->next;
}
+ config.bug_on = 1;
}
printf("[FSCK] Unreachable nat entries ");
@@ -769,6 +770,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf(" [Fail] [0x%x]\n", nr_unref_nid);
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
printf("[FSCK] SIT valid block bitmap checking ");
@@ -777,6 +779,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf("[Fail]\n");
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
printf("[FSCK] Hard link checking for regular file ");
@@ -785,6 +788,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf(" [Fail] [0x%x]\n", fsck->chk.multi_hard_link_files);
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
printf("[FSCK] valid_block_count matching with CP ");
@@ -793,6 +797,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf(" [Fail] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt);
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
printf("[FSCK] valid_node_count matcing with CP (de lookup) ");
@@ -801,6 +806,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf(" [Fail] [0x%x]\n", fsck->chk.valid_node_cnt);
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
printf("[FSCK] valid_node_count matcing with CP (nat lookup) ");
@@ -809,6 +815,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf(" [Fail] [0x%x]\n", fsck->chk.valid_nat_entry_cnt);
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
printf("[FSCK] valid_inode_count matched with CP ");
@@ -817,8 +824,8 @@ int fsck_verify(struct f2fs_sb_info *sbi)
} else {
printf(" [Fail] [0x%x]\n", fsck->chk.valid_inode_cnt);
ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
}
-
return ret;
}
diff --git a/fsck/main.c b/fsck/main.c
index 46f5d04..266e9b5 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -11,9 +11,7 @@
#include "fsck.h"
#include <libgen.h>
-struct f2fs_fsck gfsck = {
- .sbi = { .fsck = &gfsck, },
-};
+struct f2fs_fsck gfsck;
void fsck_usage()
{
@@ -42,22 +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:t";
+ const char *option_string = "d:tf";
config.func = FSCK;
while ((option = getopt(argc, argv, option_string)) != EOF) {
switch (option) {
- 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;
- default:
- MSG(0, "\tError: Unknown option %c\n",option);
- fsck_usage();
- 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;
+ default:
+ MSG(0, "\tError: Unknown option %c\n", option);
+ fsck_usage();
+ break;
}
}
} else if (!strcmp("dump.f2fs", prog)) {
@@ -73,34 +76,46 @@ void f2fs_parse_options(int argc, char *argv[])
config.func = DUMP;
while ((option = getopt(argc, argv, option_string)) != EOF) {
+ int ret = 0;
+
switch (option) {
- case 'd':
- config.dbg_lv = atoi(optarg);
- MSG(0, "Info: Debug level = %d\n", config.dbg_lv);
- break;
- case 'i':
- if (strncmp(optarg, "0x", 2))
- sscanf(optarg, "%d", &dump_opt.nid);
- else
- sscanf(optarg, "%x", &dump_opt.nid);
- break;
- case 's':
- sscanf(optarg, "%d~%d", &dump_opt.start_sit, &dump_opt.end_sit);
- break;
- case 'a':
- sscanf(optarg, "%d~%d", &dump_opt.start_ssa, &dump_opt.end_ssa);
- break;
- case 'b':
- if (strncmp(optarg, "0x", 2))
- sscanf(optarg, "%d", &dump_opt.blk_addr);
- else
- sscanf(optarg, "%x", &dump_opt.blk_addr);
- break;
- default:
- MSG(0, "\tError: Unknown option %c\n", option);
- dump_usage();
- break;
+ case 'd':
+ config.dbg_lv = atoi(optarg);
+ MSG(0, "Info: Debug level = %d\n",
+ config.dbg_lv);
+ break;
+ case 'i':
+ if (strncmp(optarg, "0x", 2))
+ ret = sscanf(optarg, "%d",
+ &dump_opt.nid);
+ else
+ ret = sscanf(optarg, "%x",
+ &dump_opt.nid);
+ break;
+ case 's':
+ ret = sscanf(optarg, "%d~%d",
+ &dump_opt.start_sit,
+ &dump_opt.end_sit);
+ break;
+ case 'a':
+ ret = sscanf(optarg, "%d~%d",
+ &dump_opt.start_ssa,
+ &dump_opt.end_ssa);
+ break;
+ case 'b':
+ if (strncmp(optarg, "0x", 2))
+ ret = sscanf(optarg, "%d",
+ &dump_opt.blk_addr);
+ else
+ ret = sscanf(optarg, "%x",
+ &dump_opt.blk_addr);
+ break;
+ default:
+ MSG(0, "\tError: Unknown option %c\n", option);
+ dump_usage();
+ break;
}
+ ASSERT(ret >= 0);
}
config.private = &dump_opt;
@@ -121,13 +136,15 @@ int do_fsck(struct f2fs_sb_info *sbi)
u32 blk_cnt;
int ret;
+ config.bug_on = 0;
+
ret = fsck_init(sbi);
if (ret < 0)
return ret;
fsck_chk_orphan_node(sbi);
- /* Travses all block recursively from root inode */
+ /* Traverse all block recursively from root inode */
blk_cnt = 1;
ret = fsck_chk_node_blk(sbi,
NULL,
@@ -139,7 +156,6 @@ int do_fsck(struct f2fs_sb_info *sbi)
goto out1;
ret = fsck_verify(sbi);
-
out1:
fsck_free(sbi);
return ret;
@@ -176,7 +192,7 @@ cleanup:
int main (int argc, char **argv)
{
- struct f2fs_sb_info *sbi = &gfsck.sbi;
+ struct f2fs_sb_info *sbi;
int ret = 0;
f2fs_init_configuration(&config);
@@ -189,21 +205,46 @@ int main (int argc, char **argv)
/* Get device */
if (f2fs_get_device_info(&config) < 0)
return -1;
+fsck_again:
+ memset(&gfsck, 0, sizeof(gfsck));
+ gfsck.sbi.fsck = &gfsck;
+ sbi = &gfsck.sbi;
if (f2fs_do_mount(sbi) < 0)
return -1;
switch (config.func) {
- case FSCK:
- ret = do_fsck(sbi);
- break;
- case DUMP:
- ret = do_dump(sbi);
- break;
+ case FSCK:
+ ret = do_fsck(sbi);
+ break;
+ case DUMP:
+ ret = do_dump(sbi);
+ break;
}
f2fs_do_umount(sbi);
+ if (config.func == FSCK && config.bug_on) {
+ if (config.fix_on == 0) {
+ char ans[255] = {0};
+retry:
+ printf("Do you want to fix this partition? [Y/N] ");
+ ret = scanf("%s", ans);
+ ASSERT(ret >= 0);
+ if (!strcasecmp(ans, "y"))
+ config.fix_cnt++;
+ else if (!strcasecmp(ans, "n"))
+ config.fix_cnt = 0;
+ else
+ goto retry;
+ } else {
+ config.fix_cnt++;
+ }
+ /* avoid infinite trials */
+ if (config.fix_cnt > 0 && config.fix_cnt < 4)
+ goto fsck_again;
+ }
+
f2fs_finalize_device(&config);
printf("\nDone.\n");
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index aebb1d2..49911a0 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -60,6 +60,7 @@ typedef unsigned long pgoff_t;
printf("\nAssertion failed!\n"); \
printf("[%s:%4d] " #exp, __func__, __LINE__); \
printf("\n --> "fmt, ##__VA_ARGS__); \
+ config.bug_on = 1; \
exit(-1); \
} \
} while (0);
@@ -69,6 +70,7 @@ typedef unsigned long pgoff_t;
if (!(exp)) { \
printf("\nAssertion failed!\n"); \
printf("[%s:%4d] " #exp"\n", __func__, __LINE__);\
+ config.bug_on = 1; \
exit(-1); \
} \
} while (0);
@@ -180,6 +182,9 @@ struct f2fs_configuration {
int trim;
int func;
void *private;
+ int fix_on;
+ int fix_cnt;
+ int bug_on;
} __attribute__((packed));
#ifdef CONFIG_64BIT
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
next prev parent reply other threads:[~2014-08-30 0:29 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
2014-08-30 0:28 ` Jaegeuk Kim [this message]
2014-08-30 0:28 ` [PATCH 03/17] fsck.f2fs: clean up codes Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 04/17] fsck.f2fs: handle IS_VALID_BLK_ADDR Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 05/17] fsck.f2fs: remove return value of get_node_info Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 06/17] fsck.f2fs: handle error cases Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 07/17] fsck.f2fs: cleanup mount.c Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 08/17] fsck.f2fs: give a chance to recover sit entries Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 09/17] fsck.f2fs: fix inode block inconsistency Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 10/17] fsck.f2fs: add fixing messeages Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 11/17] fsck.f2fs: remove dentry if its inode block is corrupted Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 12/17] fsck.f2fs: corrupted orphan inode will be removed Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 13/17] fsck.f2fs: remove corrupted xattr block Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 14/17] fsck.f2fs: handle correctly segment summary entries Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 15/17] fsck.f2fs: fix checkpoint Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 16/17] fsck.f2fs: check next block is free or not Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 17/17] fsck.f2fs: remove list.h Jaegeuk Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1409358544-54740-2-git-send-email-jaegeuk@kernel.org \
--to=jaegeuk@kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).