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