linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] fsck.f2fs: introduce -p option to check meta
@ 2016-03-23 20:41 Jaegeuk Kim
  2016-03-23 20:41 ` [PATCH 2/7] fsck.f2fs: count the number of inodes during building nat_area_bitmap Jaegeuk Kim
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/7] fsck.f2fs: count the number of inodes during building nat_area_bitmap
  2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
@ 2016-03-23 20:41 ` Jaegeuk Kim
  2016-03-23 20:41 ` [PATCH 3/7] fsck.f2fs: cache all nat entries and check each of them Jaegeuk Kim
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

From: Sheng Yong <shengyong1@huawei.com>

The nid and ino of an inode are the same. So during building
nat_area_bitmap, we can know which nat entry represents an
inode, thus, we can count the number of inodes.

Then in fsck_chk_meta, the amount of inodes can be compared
with that recorded in CP.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c  |  8 ++++++++
 fsck/fsck.h  |  1 +
 fsck/mount.c | 10 ++++++++++
 3 files changed, 19 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index fede8e1..7100397 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1573,6 +1573,14 @@ int fsck_chk_meta(struct f2fs_sb_info *sbi)
 		return -EINVAL;
 	}
 
+	if (fsck->nat_valid_inode_cnt != le32_to_cpu(cp->valid_inode_count)) {
+		ASSERT_MSG("valid inode does not match: nat_valid_inode_cnt %u,"
+				" valid_inode_count %u",
+				fsck->nat_valid_inode_cnt,
+				le32_to_cpu(cp->valid_inode_count));
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
diff --git a/fsck/fsck.h b/fsck/fsck.h
index f03efb8..da4e6ad 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -76,6 +76,7 @@ struct f2fs_fsck {
 	u32 nr_nat_entries;
 
 	u32 dentry_depth;
+	u32 nat_valid_inode_cnt;
 };
 
 #define BLOCK_SZ		4096
diff --git a/fsck/mount.c b/fsck/mount.c
index af1e0c3..4f907ef 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1679,6 +1679,11 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 			if (lookup_nat_in_journal(sbi, nid + i,
 							&raw_nat) >= 0) {
 				node_info_from_raw_nat(&ni, &raw_nat);
+				if (ni.ino == (nid + i) && ni.blk_addr != 0) {
+					fsck->nat_valid_inode_cnt++;
+					DBG(3, "ino[0x%8x] maybe is inode\n",
+								ni.ino);
+				}
 				if (ni.blk_addr != 0x0) {
 					f2fs_set_bit(nid + i,
 							fsck->nat_area_bitmap);
@@ -1689,6 +1694,11 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 			} else {
 				node_info_from_raw_nat(&ni,
 						&nat_block->entries[i]);
+				if (ni.ino == (nid + i) && ni.blk_addr != 0) {
+					fsck->nat_valid_inode_cnt++;
+					DBG(3, "ino[0x%8x] maybe is inode\n",
+								ni.ino);
+				}
 				if (ni.blk_addr == 0)
 					continue;
 				if (nid + i == 0) {
-- 
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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/7] fsck.f2fs: cache all nat entries and check each of them
  2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
  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 ` Jaegeuk Kim
  2016-03-23 20:41 ` [PATCH 4/7] fsck.f2fs: check ino in nat entry and node footer Jaegeuk Kim
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

From: Sheng Yong <shengyong1@huawei.com>

All nat entries are cached during building nat_area_bitmap, so that, in
fsck_chk_meta, we can get and check blk_addr and ino directly, to see if
they are in the valid range. Also, blk_addr is checked to see if the block
is valid in sit's valid maps.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/fsck.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 fsck/fsck.h  |  1 +
 fsck/mount.c | 11 ++++++++++-
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 7100397..bc7655c 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1581,6 +1581,46 @@ int fsck_chk_meta(struct f2fs_sb_info *sbi)
 		return -EINVAL;
 	}
 
+	/*check nat entry with sit_area_bitmap*/
+	for (i = 0; i < fsck->nr_nat_entries; i++) {
+		u32 blk = le32_to_cpu(fsck->entries[i].block_addr);
+		nid_t ino = le32_to_cpu(fsck->entries[i].ino);
+
+		if (!blk)
+			/*
+			 * skip entry whose ino is 0, otherwise, we will
+			 * get a negative number by BLKOFF_FROM_MAIN(sbi, blk)
+			 */
+			continue;
+
+		if (!IS_VALID_BLK_ADDR(sbi, blk)) {
+			MSG(0, "\tError: nat entry[ino %u block_addr 0x%x]"
+				" is in valid\n",
+				ino, blk);
+			return -EINVAL;
+		}
+
+		if (!f2fs_test_sit_bitmap(sbi, blk)) {
+			MSG(0, "\tError: nat entry[ino %u block_addr 0x%x]"
+				" not find it in sit_area_bitmap\n",
+				ino, blk);
+			return -EINVAL;
+		}
+
+		if (!IS_VALID_NID(sbi, ino)) {
+			MSG(0, "\tError: nat_entry->ino %u exceeds the range"
+				" of nat entries %u\n",
+				ino, fsck->nr_nat_entries);
+			return -EINVAL;
+		}
+
+		if (!f2fs_test_bit(ino, fsck->nat_area_bitmap)) {
+			MSG(0, "\tError: nat_entry->ino %u is not set in"
+				" nat_area_bitmap\n", ino);
+			return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/fsck/fsck.h b/fsck/fsck.h
index da4e6ad..5fc214e 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -76,6 +76,7 @@ struct f2fs_fsck {
 	u32 nr_nat_entries;
 
 	u32 dentry_depth;
+	struct f2fs_nat_entry *entries;
 	u32 nat_valid_inode_cnt;
 };
 
diff --git a/fsck/mount.c b/fsck/mount.c
index 4f907ef..1d99375 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1644,6 +1644,10 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 	fsck->nat_area_bitmap = calloc(fsck->nat_area_bitmap_sz, 1);
 	ASSERT(fsck->nat_area_bitmap != NULL);
 
+	fsck->entries = calloc(sizeof(struct f2fs_nat_entry),
+					fsck->nr_nat_entries);
+	ASSERT(fsck->entries);
+
 	for (block_off = 0; block_off < nr_nat_blks; block_off++) {
 
 		seg_off = block_off >> sbi->log_blocks_per_seg;
@@ -1691,6 +1695,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 					DBG(3, "nid[0x%x] in nat cache\n",
 								nid + i);
 				}
+
+				fsck->entries[nid + i] = raw_nat;
 			} else {
 				node_info_from_raw_nat(&ni,
 						&nat_block->entries[i]);
@@ -1708,7 +1714,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 					 * nat_area_bitmap, fsck_verify will
 					 * nullify it
 					 */
-					ASSERT_MSG("Invalid nat entry[0]: blk_addr[0x%x]\n",
+					ASSERT_MSG("Invalid nat entry[0]: "
+						"blk_addr[0x%x]\n",
 						ni.blk_addr);
 					config.fix_on = 1;
 					fsck->chk.valid_nat_entry_cnt--;
@@ -1718,6 +1725,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 					nid + i, ni.blk_addr, ni.ino);
 				f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
 				fsck->chk.valid_nat_entry_cnt++;
+
+				fsck->entries[nid + i] = nat_block->entries[i];
 			}
 		}
 	}
-- 
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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/7] fsck.f2fs: check ino in nat entry and node footer
  2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
  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 ` Jaegeuk Kim
  2016-03-23 20:41 ` [PATCH 5/7] fsck.f2fs: set fix_on if error is detected Jaegeuk Kim
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

From: Sheng Yong <shengyong1@huawei.com>

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/mount.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fsck/mount.c b/fsck/mount.c
index 1d99375..51d50ec 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1683,6 +1683,10 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 			if (lookup_nat_in_journal(sbi, nid + i,
 							&raw_nat) >= 0) {
 				node_info_from_raw_nat(&ni, &raw_nat);
+				if ((ni.ino == 0x0 && ni.blk_addr != 0x0))
+					ASSERT_MSG("\tError: ino[0x%8x] or blk_addr[0x%16x]"
+						" is invalid\n",
+						ni.ino, ni.blk_addr);
 				if (ni.ino == (nid + i) && ni.blk_addr != 0) {
 					fsck->nat_valid_inode_cnt++;
 					DBG(3, "ino[0x%8x] maybe is inode\n",
@@ -1700,6 +1704,10 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
 			} else {
 				node_info_from_raw_nat(&ni,
 						&nat_block->entries[i]);
+				if ((ni.ino == 0x0 && ni.blk_addr != 0x0))
+					ASSERT_MSG("\tError: ino[0x%8x] or blk_addr[0x%16x]"
+						" is invalid\n",
+						ni.ino, ni.blk_addr);
 				if (ni.ino == (nid + i) && ni.blk_addr != 0) {
 					fsck->nat_valid_inode_cnt++;
 					DBG(3, "ino[0x%8x] maybe is inode\n",
-- 
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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/7] fsck.f2fs: set fix_on if error is detected
  2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
                   ` (2 preceding siblings ...)
  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 ` 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
  5 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

From: Sheng Yong <shengyong1@huawei.com>

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/main.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/fsck/main.c b/fsck/main.c
index 93008a5..6058c4d 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -244,6 +244,18 @@ static void do_fsck(struct f2fs_sb_info *sbi)
 				config.fix_on = 1;
 			break;
 		}
+	} else {
+		/*
+		 * we can hit this in 3 situations:
+		 *  1. fsck -f, fix_on has already been set to 1 when
+		 *     parsing options;
+		 *  2. fsck -a && CP_FSCK_FLAG is set, fix_on has already
+		 *     been set to 1 when checking CP_FSCK_FLAG;
+		 *  3. fsck -p 1 && error is detected, then bug_on is set,
+		 *     we set fix_on = 1 here, so that fsck can fix errors
+		 *     automatically
+		*/
+		config.fix_on = 1;
 	}
 
 	fsck_chk_orphan_node(sbi);
-- 
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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/7] fsck.f2fs: nullify the freed ckpt pointer
  2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
                   ` (3 preceding siblings ...)
  2016-03-23 20:41 ` [PATCH 5/7] fsck.f2fs: set fix_on if error is detected Jaegeuk Kim
@ 2016-03-23 20:41 ` Jaegeuk Kim
  2016-03-23 20:41 ` [PATCH 7/7] fsck.f2fs: check sanity of superblock and fix any misalignment Jaegeuk Kim
  5 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

Otherwise, we get a double free error by:

In fsck/main.c,

545 out_err:
546         if (sbi->ckpt)
547                 free(sbi->ckpt);

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/mount.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fsck/mount.c b/fsck/mount.c
index 51d50ec..37a0025 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -502,6 +502,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
 
 fail_no_cp:
 	free(sbi->ckpt);
+	sbi->ckpt = NULL;
 	return -EINVAL;
 }
 
-- 
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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 7/7] fsck.f2fs: check sanity of superblock and fix any misalignment
  2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
                   ` (4 preceding siblings ...)
  2016-03-23 20:41 ` [PATCH 6/7] fsck.f2fs: nullify the freed ckpt pointer Jaegeuk Kim
@ 2016-03-23 20:41 ` Jaegeuk Kim
  5 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2016-03-23 20:41 UTC (permalink / raw)
  To: linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch detects any corrupted superblock and fix misalignment when it finds,
which is synced with the f2fs kernel module.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fsck/mount.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 2 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 37a0025..67c681e 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -265,7 +265,90 @@ void print_sb_state(struct f2fs_super_block *sb)
 	MSG(0, "\n");
 }
 
-int sanity_check_raw_super(struct f2fs_super_block *sb)
+static inline int sanity_check_area_boundary(struct f2fs_super_block *sb,
+							u64 offset)
+{
+	u32 segment0_blkaddr = get_sb(segment0_blkaddr);
+	u32 cp_blkaddr = get_sb(cp_blkaddr);
+	u32 sit_blkaddr = get_sb(sit_blkaddr);
+	u32 nat_blkaddr = get_sb(nat_blkaddr);
+	u32 ssa_blkaddr = get_sb(ssa_blkaddr);
+	u32 main_blkaddr = get_sb(main_blkaddr);
+	u32 segment_count_ckpt = get_sb(segment_count_ckpt);
+	u32 segment_count_sit = get_sb(segment_count_sit);
+	u32 segment_count_nat = get_sb(segment_count_nat);
+	u32 segment_count_ssa = get_sb(segment_count_ssa);
+	u32 segment_count_main = get_sb(segment_count_main);
+	u32 segment_count = get_sb(segment_count);
+	u32 log_blocks_per_seg = get_sb(log_blocks_per_seg);
+	u64 main_end_blkaddr = main_blkaddr +
+				(segment_count_main << log_blocks_per_seg);
+	u64 seg_end_blkaddr = segment0_blkaddr +
+				(segment_count << log_blocks_per_seg);
+
+	if (segment0_blkaddr != cp_blkaddr) {
+		MSG(0, "\tMismatch segment0(%u) cp_blkaddr(%u)\n",
+				segment0_blkaddr, cp_blkaddr);
+		return -1;
+	}
+
+	if (cp_blkaddr + (segment_count_ckpt << log_blocks_per_seg) !=
+							sit_blkaddr) {
+		MSG(0, "\tWrong CP boundary, start(%u) end(%u) blocks(%u)\n",
+			cp_blkaddr, sit_blkaddr,
+			segment_count_ckpt << log_blocks_per_seg);
+		return -1;
+	}
+
+	if (sit_blkaddr + (segment_count_sit << log_blocks_per_seg) !=
+							nat_blkaddr) {
+		MSG(0, "\tWrong SIT boundary, start(%u) end(%u) blocks(%u)\n",
+			sit_blkaddr, nat_blkaddr,
+			segment_count_sit << log_blocks_per_seg);
+		return -1;
+	}
+
+	if (nat_blkaddr + (segment_count_nat << log_blocks_per_seg) !=
+							ssa_blkaddr) {
+		MSG(0, "\tWrong NAT boundary, start(%u) end(%u) blocks(%u)\n",
+			nat_blkaddr, ssa_blkaddr,
+			segment_count_nat << log_blocks_per_seg);
+		return -1;
+	}
+
+	if (ssa_blkaddr + (segment_count_ssa << log_blocks_per_seg) !=
+							main_blkaddr) {
+		MSG(0, "\tWrong SSA boundary, start(%u) end(%u) blocks(%u)\n",
+			ssa_blkaddr, main_blkaddr,
+			segment_count_ssa << log_blocks_per_seg);
+		return -1;
+	}
+
+	if (main_end_blkaddr > seg_end_blkaddr) {
+		MSG(0, "\tWrong MAIN_AREA, start(%u) end(%u) block(%u)\n",
+			main_blkaddr,
+			segment0_blkaddr +
+				(segment_count << log_blocks_per_seg),
+			segment_count_main << log_blocks_per_seg);
+		return -1;
+	} else if (main_end_blkaddr < seg_end_blkaddr) {
+		int err;
+
+		set_sb(segment_count, (main_end_blkaddr -
+				segment0_blkaddr) >> log_blocks_per_seg);
+
+		err = dev_write(sb, offset, sizeof(struct f2fs_super_block));
+		MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n",
+			err ? "failed": "done",
+			main_blkaddr,
+			segment0_blkaddr +
+				(segment_count << log_blocks_per_seg),
+			segment_count_main << log_blocks_per_seg);
+	}
+	return 0;
+}
+
+int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset)
 {
 	unsigned int blocksize;
 
@@ -279,6 +362,15 @@ int sanity_check_raw_super(struct f2fs_super_block *sb)
 	if (F2FS_BLKSIZE != blocksize)
 		return -1;
 
+	/* check log blocks per segment */
+	if (get_sb(log_blocks_per_seg) != 9)
+		return -1;
+
+	if (get_sb(log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE ||
+			get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE)
+		return -1;
+
+	/* Currently, support 512/1024/2048/4096 bytes sector size */
 	if (get_sb(log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE ||
 			get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE)
 		return -1;
@@ -287,6 +379,13 @@ int sanity_check_raw_super(struct f2fs_super_block *sb)
 						F2FS_MAX_LOG_SECTOR_SIZE)
 		return -1;
 
+	/* check reserved ino info */
+	if (get_sb(node_ino) != 1 || get_sb(meta_ino) != 2 ||
+					get_sb(root_ino) != 3)
+		return -1;
+
+	if (sanity_check_area_boundary(sb, offset))
+		return -1;
 	return 0;
 }
 
@@ -304,7 +403,7 @@ int validate_super_block(struct f2fs_sb_info *sbi, int block)
 	if (dev_read(sbi->raw_super, offset, sizeof(struct f2fs_super_block)))
 		return -1;
 
-	if (!sanity_check_raw_super(sbi->raw_super)) {
+	if (!sanity_check_raw_super(sbi->raw_super, offset)) {
 		/* get kernel version */
 		if (config.kd >= 0) {
 			dev_read_version(config.version, 0, VERSION_LEN);
-- 
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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-03-23 20:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-23 20:41 [PATCH 1/7] fsck.f2fs: introduce -p option to check meta Jaegeuk Kim
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

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).