linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: linux-f2fs-devel@lists.sourceforge.net
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Subject: [PATCH 1/7] fsck.f2fs: introduce -p option to check meta
Date: Wed, 23 Mar 2016 13:41:15 -0700	[thread overview]
Message-ID: <1458765681-24123-1-git-send-email-jaegeuk@kernel.org> (raw)

From: Sheng Yong <shengyong1@huawei.com>

This patch introduces a new option '-p' to do more checks on NAT/SIT areas.
'-p' has 2 levels: level 1 has the same sematics as '-a'; level 2 checks
NAT/SIT counters to see if they matches the status in SB and CP.

A new function, fsck_chk_meta, is called by '-p 1' to implement these
comparsion. If errors are detected, fix_on is set, which means fsck will
do a 'fsck -f' immediately.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c       | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fsck/fsck.h       |  7 +++++++
 fsck/main.c       | 39 +++++++++++++++++++++++++++++++++---
 fsck/mount.c      |  4 ++--
 include/f2fs_fs.h |  1 +
 5 files changed, 105 insertions(+), 5 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index c68eae7..fede8e1 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1517,6 +1517,65 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
 	free(new_blk);
 }
 
+int fsck_chk_meta(struct f2fs_sb_info *sbi)
+{
+	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+	struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+	struct seg_entry *se;
+	unsigned int sit_valid_segs = 0, sit_node_blks = 0;
+	unsigned int i;
+
+	/* 1. check sit usage with CP: curseg is lost? */
+	for (i = 0; i < TOTAL_SEGS(sbi); i++) {
+		se = get_seg_entry(sbi, i);
+		if (se->valid_blocks != 0)
+			sit_valid_segs++;
+		else if (IS_CUR_SEGNO(sbi, i, NO_CHECK_TYPE)) {
+			/* curseg has not been written back to device */
+			MSG(1, "\tInfo: curseg %u is counted in valid segs\n", i);
+			sit_valid_segs++;
+		}
+		if (IS_NODESEG(se->type))
+			sit_node_blks += se->valid_blocks;
+	}
+	if (fsck->chk.sit_free_segs + sit_valid_segs != TOTAL_SEGS(sbi)) {
+		ASSERT_MSG("SIT usage does not match: sit_free_segs %u, "
+				"sit_valid_segs %u, total_segs %u",
+			fsck->chk.sit_free_segs, sit_valid_segs,
+			TOTAL_SEGS(sbi));
+		return -EINVAL;
+	}
+
+	/* 2. check node count */
+	if (fsck->chk.valid_nat_entry_cnt != sit_node_blks) {
+		ASSERT_MSG("node count does not match: valid_nat_entry_cnt %u,"
+			" sit_node_blks %u",
+			fsck->chk.valid_nat_entry_cnt, sit_node_blks);
+		return -EINVAL;
+	}
+
+	/* 3. check SIT with CP */
+	if (fsck->chk.sit_free_segs != le32_to_cpu(cp->free_segment_count)) {
+		ASSERT_MSG("free segs does not match: sit_free_segs %u, "
+				"free_segment_count %u",
+				fsck->chk.sit_free_segs,
+				le32_to_cpu(cp->free_segment_count));
+		return -EINVAL;
+	}
+
+	/* 4. check NAT with CP */
+	if (fsck->chk.valid_nat_entry_cnt !=
+					le32_to_cpu(cp->valid_node_count)) {
+		ASSERT_MSG("valid node does not match: valid_nat_entry_cnt %u,"
+				" valid_node_count %u",
+				fsck->chk.valid_nat_entry_cnt,
+				le32_to_cpu(cp->valid_node_count));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 void fsck_init(struct f2fs_sb_info *sbi)
 {
 	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 45e4366..f03efb8 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -15,6 +15,12 @@
 
 #define FSCK_UNMATCHED_EXTENT		0x00000001
 
+enum {
+	PREEN_MODE_0,
+	PREEN_MODE_1,
+	PREEN_MODE_MAX
+};
+
 /* fsck.c */
 struct orphan_info {
 	u32 nr_inodes;
@@ -119,6 +125,7 @@ extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, u32, struct child_info *,
 		int, int);
 int fsck_chk_inline_dentries(struct f2fs_sb_info *, struct f2fs_node *,
 		struct child_info *);
+int fsck_chk_meta(struct f2fs_sb_info *sbi);
 
 void print_cp_state(u32);
 extern void print_node_info(struct f2fs_node *);
diff --git a/fsck/main.c b/fsck/main.c
index 0e23c81..93008a5 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -22,7 +22,7 @@ void fsck_usage()
 	MSG(0, "  -a check/fix potential corruption, reported by f2fs\n");
 	MSG(0, "  -d debug level [default:0]\n");
 	MSG(0, "  -f check/fix entire partition\n");
-	MSG(0, "  -p preen mode [default is same as -a]\n");
+	MSG(0, "  -p preen mode [default:0 the same as -a [0|1]]\n");
 	MSG(0, "  -t show directory tree [-d -1]\n");
 	exit(1);
 }
@@ -58,16 +58,30 @@ void f2fs_parse_options(int argc, char *argv[])
 	char *prog = basename(argv[0]);
 
 	if (!strcmp("fsck.f2fs", prog)) {
-		const char *option_string = "ad:fpt";
+		const char *option_string = "ad:fp:t";
 
 		config.func = FSCK;
 		while ((option = getopt(argc, argv, option_string)) != EOF) {
 			switch (option) {
 			case 'a':
-			case 'p':
 				config.auto_fix = 1;
 				MSG(0, "Info: Fix the reported corruption.\n");
 				break;
+			case 'p':
+				/* preen mode has different levels:
+				 *  0: default level, the same as -a
+				 *  1: check meta
+				 */
+				config.preen_mode = atoi(optarg);
+				if (config.preen_mode < 0)
+					config.preen_mode = PREEN_MODE_0;
+				else if (config.preen_mode >= PREEN_MODE_MAX)
+					config.preen_mode = PREEN_MODE_MAX - 1;
+				if (config.preen_mode == PREEN_MODE_0)
+					config.auto_fix = 1;
+				MSG(0, "Info: Fix the reported corruption in "
+					"preen mode %d\n", config.preen_mode);
+				break;
 			case 'd':
 				config.dbg_lv = atoi(optarg);
 				MSG(0, "Info: Debug level = %d\n",
@@ -213,6 +227,25 @@ static void do_fsck(struct f2fs_sb_info *sbi)
 
 	print_cp_state(flag);
 
+	if (!config.fix_on && !config.bug_on) {
+		switch (config.preen_mode) {
+		case PREEN_MODE_1:
+			if (fsck_chk_meta(sbi)) {
+				MSG(0, "[FSCK] F2FS metadata   [Fail]");
+				MSG(0, "\tError: meta does not match, "
+					"force check all\n");
+			} else {
+				MSG(0, "[FSCK] F2FS metadata   [Ok..]");
+				fsck_free(sbi);
+				return;
+			}
+
+			if (!config.ro)
+				config.fix_on = 1;
+			break;
+		}
+	}
+
 	fsck_chk_orphan_node(sbi);
 
 	/* Traverse all block recursively from root inode */
diff --git a/fsck/mount.c b/fsck/mount.c
index 153055e..af1e0c3 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1749,12 +1749,12 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
 
 	print_ckpt_info(sbi);
 
-	if (config.auto_fix) {
+	if (config.auto_fix || config.preen_mode) {
 		u32 flag = get_cp(ckpt_flags);
 
 		if (flag & CP_FSCK_FLAG)
 			config.fix_on = 1;
-		else
+		else if (!config.preen_mode)
 			return 1;
 	}
 
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 0046be6..330cbe5 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -251,6 +251,7 @@ struct f2fs_configuration {
 	int fix_on;
 	int bug_on;
 	int auto_fix;
+	int preen_mode;
 	int ro;
 	__le32 feature;			/* defined features */
 
-- 
2.6.3


------------------------------------------------------------------------------
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785351&iu=/4140

             reply	other threads:[~2016-03-23 20:41 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-23 20:41 Jaegeuk Kim [this message]
2016-03-23 20:41 ` [PATCH 2/7] fsck.f2fs: count the number of inodes during building nat_area_bitmap Jaegeuk Kim
2016-03-23 20:41 ` [PATCH 3/7] fsck.f2fs: cache all nat entries and check each of them Jaegeuk Kim
2016-03-23 20:41 ` [PATCH 4/7] fsck.f2fs: check ino in nat entry and node footer Jaegeuk Kim
2016-03-23 20:41 ` [PATCH 5/7] fsck.f2fs: set fix_on if error is detected Jaegeuk Kim
2016-03-23 20:41 ` [PATCH 6/7] fsck.f2fs: nullify the freed ckpt pointer Jaegeuk Kim
2016-03-23 20:41 ` [PATCH 7/7] fsck.f2fs: check sanity of superblock and fix any misalignment 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=1458765681-24123-1-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).