* [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char
@ 2014-08-30 0:28 Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 02/17] fsck.f2fs: retry to fix corrupted image Jaegeuk Kim
` (15 more replies)
0 siblings, 16 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
This can hurt when calculating hash value, resulting in false alarm.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 5 +++--
include/f2fs_fs.h | 2 +-
lib/libf2fs.c | 31 ++++++++++++-------------------
3 files changed, 16 insertions(+), 22 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 2d8dffb..303ba8d 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -542,11 +542,12 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi,
continue;
}
- name_len = le32_to_cpu(de_blk->dentry[i].name_len);
+ name_len = le16_to_cpu(de_blk->dentry[i].name_len);
name = calloc(name_len + 1, 1);
memcpy(name, de_blk->filename[i], name_len);
+ hash_code = f2fs_dentry_hash((const unsigned char *)name,
+ name_len);
- hash_code = f2fs_dentry_hash((const char *)name, name_len);
ASSERT(le32_to_cpu(de_blk->dentry[i].hash_code) == hash_code);
ftype = de_blk->dentry[i].file_type;
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 9ade334..aebb1d2 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -679,7 +679,7 @@ extern int dev_fill(void *, __u64, size_t);
extern int dev_read_block(void *, __u64);
extern int dev_read_blocks(void *, __u64, __u32 );
-f2fs_hash_t f2fs_dentry_hash(const char *, int);
+f2fs_hash_t f2fs_dentry_hash(const unsigned char *, int);
extern struct f2fs_configuration config;
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 6168c5c..01ef4e9 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -235,7 +235,8 @@ static void TEA_transform(unsigned int buf[4], unsigned int const in[])
}
-static void str2hashbuf(const char *msg, int len, unsigned int *buf, int num)
+static void str2hashbuf(const unsigned char *msg, int len,
+ unsigned int *buf, int num)
{
unsigned pad, val;
int i;
@@ -269,24 +270,17 @@ static void str2hashbuf(const char *msg, int len, unsigned int *buf, int num)
* @param len name lenth
* @return return on success hash value, errno on failure
*/
-f2fs_hash_t f2fs_dentry_hash(const char *name, int len)
+f2fs_hash_t f2fs_dentry_hash(const unsigned char *name, int len)
{
__u32 hash;
f2fs_hash_t f2fs_hash;
- const char *p;
+ const unsigned char *p;
__u32 in[8], buf[4];
/* special hash codes for special dentries */
- if (name[0] == '.') {
- if (name[1] == '\0') {
- f2fs_hash = F2FS_DOT_HASH;
- goto exit;
- }
- if (name[1] == '.' && name[2] == '\0') {
- f2fs_hash = F2FS_DDOT_HASH;
- goto exit;
- }
- }
+ if ((len <= 2) && (name[0] == '.') &&
+ (name[1] == '.' || name[1] == '\0'))
+ return 0;
/* Initialize the default seed for the hash checksum functions */
buf[0] = 0x67452301;
@@ -295,18 +289,17 @@ f2fs_hash_t f2fs_dentry_hash(const char *name, int len)
buf[3] = 0x10325476;
p = name;
- while (len > 0) {
+ while (1) {
str2hashbuf(p, len, in, 4);
TEA_transform(buf, in);
- len -= 16;
p += 16;
+ if (len <= 16)
+ break;
+ len -= 16;
}
hash = buf[0];
- f2fs_hash = hash;
-exit:
- f2fs_hash &= ~F2FS_HASH_COL_BIT;
-
+ f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
return f2fs_hash;
}
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/17] fsck.f2fs: retry to fix corrupted image
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
2014-08-30 0:28 ` [PATCH 03/17] fsck.f2fs: clean up codes Jaegeuk Kim
` (14 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
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/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/17] fsck.f2fs: clean up codes
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 ` [PATCH 02/17] fsck.f2fs: retry to fix corrupted image Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 04/17] fsck.f2fs: handle IS_VALID_BLK_ADDR Jaegeuk Kim
` (13 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Fix wrong coding style.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/dump.c | 2 +-
fsck/f2fs.h | 12 +--
fsck/fsck.c | 294 +++++++++++++++++++++++++-----------------------------
fsck/fsck.h | 105 +++++++------------
include/f2fs_fs.h | 83 ++++++++-------
5 files changed, 217 insertions(+), 279 deletions(-)
diff --git a/fsck/dump.c b/fsck/dump.c
index 44d4105..e14a190 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -141,7 +141,7 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype,
struct node_info ni;
struct f2fs_node *node_blk;
int i, ret;
- u32 idx, skip;
+ u32 idx, skip = 0;
switch (ntype) {
case TYPE_DIRECT_NODE:
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 427a733..aa43cdc 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -301,12 +301,12 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type)
(segno / SIT_ENTRY_PER_BLOCK)
#define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments)
-#define IS_VALID_NID(sbi, nid) \
- do { \
- ASSERT(nid <= (NAT_ENTRY_PER_BLOCK * \
- F2FS_RAW_SUPER(sbi)->segment_count_nat \
- << (sbi->log_blocks_per_seg - 1))); \
- } while (0);
+static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid)
+{
+ return (nid <= (NAT_ENTRY_PER_BLOCK *
+ F2FS_RAW_SUPER(sbi)->segment_count_nat
+ << (sbi->log_blocks_per_seg - 1)));
+}
#define IS_VALID_BLK_ADDR(sbi, addr) \
do { \
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 9a4c26c..5c99385 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -13,7 +13,30 @@
char *tree_mark;
uint32_t tree_mark_size = 256;
-static int add_into_hard_link_list(struct f2fs_sb_info *sbi, u32 nid, u32 link_cnt)
+static inline int f2fs_set_main_bitmap(struct f2fs_sb_info *sbi, u32 blk)
+{
+ struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+ return f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, blk), fsck->main_area_bitmap);
+}
+
+static inline int f2fs_test_main_bitmap(struct f2fs_sb_info *sbi, u32 blk)
+{
+ struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+ return f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk),
+ fsck->main_area_bitmap);
+}
+
+static inline int f2fs_test_sit_bitmap(struct f2fs_sb_info *sbi, u32 blk)
+{
+ struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+
+ return f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk), fsck->sit_area_bitmap);
+}
+
+static int add_into_hard_link_list(struct f2fs_sb_info *sbi,
+ u32 nid, u32 link_cnt)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct hard_link_node *node = NULL, *tmp = NULL, *prev = NULL;
@@ -90,7 +113,8 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
}
-static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid, u32 blk_addr)
+static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid,
+ u32 blk_addr)
{
int ret = 0;
struct f2fs_summary sum_entry;
@@ -99,23 +123,26 @@ static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid, u32 blk_addr
ASSERT(ret >= 0);
if (ret == SEG_TYPE_DATA || ret == SEG_TYPE_CUR_DATA) {
- ASSERT_MSG(0, "Summary footer is not a node segment summary\n");;
+ ASSERT_MSG("Summary footer is not for node segment\n");
} else if (ret == SEG_TYPE_NODE) {
if (le32_to_cpu(sum_entry.nid) != nid) {
DBG(0, "nid [0x%x]\n", nid);
DBG(0, "target blk_addr [0x%x]\n", blk_addr);
DBG(0, "summary blk_addr [0x%x]\n",
- GET_SUM_BLKADDR(sbi, GET_SEGNO(sbi, blk_addr)));
+ GET_SUM_BLKADDR(sbi,
+ GET_SEGNO(sbi, blk_addr)));
DBG(0, "seg no / offset [0x%x / 0x%x]\n",
- GET_SEGNO(sbi, blk_addr), OFFSET_IN_SEG(sbi, blk_addr));
- DBG(0, "summary_entry.nid [0x%x]\n", le32_to_cpu(sum_entry.nid));
+ GET_SEGNO(sbi, blk_addr),
+ OFFSET_IN_SEG(sbi, blk_addr));
+ DBG(0, "summary_entry.nid [0x%x]\n",
+ le32_to_cpu(sum_entry.nid));
DBG(0, "--> node block's nid [0x%x]\n", nid);
- ASSERT_MSG(0, "Invalid node seg summary\n");
+ ASSERT_MSG("Invalid node seg summary\n");
}
} else if (ret == SEG_TYPE_CUR_NODE) {
/* current node segment has no ssa */
} else {
- ASSERT_MSG(0, "Invalid return value of 'get_sum_entry'");
+ ASSERT_MSG("Invalid return value of 'get_sum_entry'");
}
return 1;
@@ -134,18 +161,19 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
sum_entry.version != version ||
le16_to_cpu(sum_entry.ofs_in_node) != idx_in_node) {
- DBG(0, "summary_entry.nid [0x%x]\n", le32_to_cpu(sum_entry.nid));
- DBG(0, "summary_entry.version [0x%x]\n", sum_entry.version);
- DBG(0, "summary_entry.ofs_in_node [0x%x]\n", le16_to_cpu(sum_entry.ofs_in_node));
-
+ DBG(0, "summary_entry.nid [0x%x]\n",
+ le32_to_cpu(sum_entry.nid));
+ DBG(0, "summary_entry.version [0x%x]\n",
+ sum_entry.version);
+ DBG(0, "summary_entry.ofs_in_node [0x%x]\n",
+ le16_to_cpu(sum_entry.ofs_in_node));
DBG(0, "parent nid [0x%x]\n", parent_nid);
DBG(0, "version from nat [0x%x]\n", version);
DBG(0, "idx in parent node [0x%x]\n", idx_in_node);
DBG(0, "Target data block addr [0x%x]\n", blk_addr);
- ASSERT_MSG(0, "Invalid data seg summary\n");
+ ASSERT_MSG("Invalid data seg summary\n");
}
-
return 1;
}
@@ -161,13 +189,14 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
struct f2fs_node *node_blk = NULL;
int ret = 0;
- IS_VALID_NID(sbi, nid);
+ if (!IS_VALID_NID(sbi, nid))
+ ASSERT_MSG("nid is not valid. [0x%x]", nid);
if (ftype != F2FS_FT_ORPHAN ||
f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0x0)
f2fs_clear_bit(nid, fsck->nat_area_bitmap);
else
- ASSERT_MSG(0, "nid duplicated [0x%x]\n", nid);
+ ASSERT_MSG("nid duplicated [0x%x]\n", nid);
ret = get_node_info(sbi, nid, &ni);
ASSERT(ret >= 0);
@@ -188,12 +217,10 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
is_valid_ssa_node_blk(sbi, nid, ni.blk_addr);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->sit_area_bitmap) == 0x0) {
- DBG(0, "SIT bitmap is 0x0. blk_addr[0x%x]\n", ni.blk_addr);
- ASSERT(0);
- }
+ if (f2fs_test_sit_bitmap(sbi, ni.blk_addr) == 0)
+ ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", ni.blk_addr);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap) == 0x0) {
+ if (f2fs_test_main_bitmap(sbi, ni.blk_addr) == 0) {
fsck->chk.valid_blk_cnt++;
fsck->chk.valid_node_cnt++;
}
@@ -204,8 +231,8 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
ret = dev_read_block(node_blk, ni.blk_addr);
ASSERT(ret >= 0);
- ASSERT_MSG(nid == le32_to_cpu(node_blk->footer.nid),
- "nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]\n",
+ if (nid != le32_to_cpu(node_blk->footer.nid))
+ ASSERT_MSG("nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]",
nid, ni.blk_addr, le32_to_cpu(node_blk->footer.nid));
if (ntype == TYPE_INODE) {
@@ -219,34 +246,23 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
/* it's not inode */
ASSERT(node_blk->footer.nid != node_blk->footer.ino);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap) != 0) {
- DBG(0, "Duplicated node block. ino[0x%x][0x%x]\n", nid, ni.blk_addr);
- ASSERT(0);
- }
- f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap);
+ if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0)
+ ASSERT_MSG("Duplicated node blk. nid[0x%x][0x%x]\n",
+ nid, ni.blk_addr);
+
+ f2fs_set_main_bitmap(sbi, ni.blk_addr);
switch (ntype) {
case TYPE_DIRECT_NODE:
- ret = fsck_chk_dnode_blk(sbi,
- inode,
- nid,
- ftype,
- node_blk,
- blk_cnt,
- &ni);
+ ret = fsck_chk_dnode_blk(sbi, inode, nid, ftype,
+ node_blk, blk_cnt, &ni);
break;
case TYPE_INDIRECT_NODE:
- ret = fsck_chk_idnode_blk(sbi,
- inode,
- ftype,
- node_blk,
+ ret = fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
blk_cnt);
break;
case TYPE_DOUBLE_INDIRECT_NODE:
- ret = fsck_chk_didnode_blk(sbi,
- inode,
- ftype,
- node_blk,
+ ret = fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
blk_cnt);
break;
default:
@@ -277,7 +293,7 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
ASSERT(node_blk->footer.nid == node_blk->footer.ino);
ASSERT(le32_to_cpu(node_blk->footer.nid) == nid);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap) == 0x0)
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0)
fsck->chk.valid_inode_cnt++;
/* Orphan node. i_links should be 0 */
@@ -290,16 +306,16 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
if (ftype == F2FS_FT_DIR) {
/* not included '.' & '..' */
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap) != 0) {
- DBG(0, "Duplicated inode blk. ino[0x%x][0x%x]\n", nid, ni->blk_addr);
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) != 0) {
+ DBG(0, "Duplicated inode blk. ino[0x%x][0x%x]\n",
+ nid, ni->blk_addr);
ASSERT(0);
}
- f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap);
+ f2fs_set_main_bitmap(sbi, ni->blk_addr);
} else {
-
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap) == 0x0) {
- f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap);
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
+ f2fs_set_main_bitmap(sbi, ni->blk_addr);
if (i_links > 1) {
/* First time. Create new hard link node */
add_into_hard_link_list(sbi, nid, i_links);
@@ -308,13 +324,14 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
} else {
if (i_links <= 1) {
DBG(0, "Error. Node ID [0x%x]."
- " There are one more hard links."
- " But i_links is [0x%x]\n",
+ " There are one more hard links."
+ " But i_links is [0x%x]\n",
nid, i_links);
ASSERT(0);
}
- DBG(3, "ino[0x%x] has hard links [0x%x]\n", nid, i_links);
+ DBG(3, "ino[0x%x] has hard links [0x%x]\n",
+ nid, i_links);
ret = find_and_dec_hard_link_list(sbi, nid);
ASSERT(ret >= 0);
@@ -323,7 +340,8 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
}
}
- fsck_chk_xattr_blk(sbi, nid, le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt);
+ fsck_chk_xattr_blk(sbi, nid,
+ le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt);
if (ftype == F2FS_FT_CHRDEV || ftype == F2FS_FT_BLKDEV ||
ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK)
@@ -339,13 +357,9 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
*blk_cnt = *blk_cnt + 1;
ret = fsck_chk_data_blk(sbi,
le32_to_cpu(node_blk->i.i_addr[idx]),
- &child_cnt,
- &child_files,
+ &child_cnt, &child_files,
(i_blocks == *blk_cnt),
- ftype,
- nid,
- idx,
- ni->version);
+ ftype, nid, idx, ni->version);
ASSERT(ret >= 0);
}
}
@@ -363,23 +377,23 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) {
*blk_cnt = *blk_cnt + 1;
- ret = fsck_chk_node_blk(sbi,
- &node_blk->i,
+ ret = fsck_chk_node_blk(sbi, &node_blk->i,
le32_to_cpu(node_blk->i.i_nid[idx]),
- ftype,
- ntype,
- blk_cnt);
+ ftype, ntype, blk_cnt);
ASSERT(ret >= 0);
}
}
check:
if (ftype == F2FS_FT_DIR)
- DBG(1, "Directory Inode: ino: %x name: %s depth: %d child files: %d\n\n",
- le32_to_cpu(node_blk->footer.ino), node_blk->i.i_name,
- le32_to_cpu(node_blk->i.i_current_depth), child_files);
+ DBG(1, "Directory Inode: 0x%x [%s] depth: %d has %d files\n\n",
+ le32_to_cpu(node_blk->footer.ino),
+ node_blk->i.i_name,
+ le32_to_cpu(node_blk->i.i_current_depth),
+ child_files);
if (ftype == F2FS_FT_ORPHAN)
- DBG(1, "Orphan Inode: ino: %x name: %s i_blocks: %u\n\n",
- le32_to_cpu(node_blk->footer.ino), node_blk->i.i_name,
+ DBG(1, "Orphan Inode: 0x%x [%s] i_blocks: %u\n\n",
+ le32_to_cpu(node_blk->footer.ino),
+ node_blk->i.i_name,
(u32)i_blocks);
if ((ftype == F2FS_FT_DIR && i_links != child_cnt) ||
(i_blocks != *blk_cnt)) {
@@ -395,13 +409,9 @@ out:
return 0;
}
-int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- u32 nid,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt,
- struct node_info *ni)
+int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
+ u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk,
+ u32 *blk_cnt, struct node_info *ni)
{
int idx;
u32 child_cnt = 0, child_files = 0;
@@ -411,24 +421,16 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi,
continue;
*blk_cnt = *blk_cnt + 1;
fsck_chk_data_blk(sbi,
- le32_to_cpu(node_blk->dn.addr[idx]),
- &child_cnt,
- &child_files,
- le64_to_cpu(inode->i_blocks) == *blk_cnt,
- ftype,
- nid,
- idx,
- ni->version);
+ le32_to_cpu(node_blk->dn.addr[idx]),
+ &child_cnt, &child_files,
+ le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype,
+ nid, idx, ni->version);
}
-
return 0;
}
-int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt)
+int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
+ enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt)
{
int i = 0;
@@ -436,22 +438,14 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi,
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
continue;
*blk_cnt = *blk_cnt + 1;
- fsck_chk_node_blk(sbi,
- inode,
- le32_to_cpu(node_blk->in.nid[i]),
- ftype,
- TYPE_DIRECT_NODE,
- blk_cnt);
+ fsck_chk_node_blk(sbi, inode, le32_to_cpu(node_blk->in.nid[i]),
+ ftype, TYPE_DIRECT_NODE, blk_cnt);
}
-
return 0;
}
-int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt)
+int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
+ enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt)
{
int i = 0;
@@ -459,14 +453,10 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi,
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
continue;
*blk_cnt = *blk_cnt + 1;
- fsck_chk_node_blk(sbi,
- inode,
+ fsck_chk_node_blk(sbi, inode,
le32_to_cpu(node_blk->in.nid[i]),
- ftype,
- TYPE_INDIRECT_NODE,
- blk_cnt);
+ ftype, TYPE_INDIRECT_NODE, blk_cnt);
}
-
return 0;
}
@@ -510,11 +500,8 @@ static void print_dentry(__u32 depth, __u8 *name,
name, le32_to_cpu(de_blk->dentry[idx].ino));
}
-int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi,
- u32 blk_addr,
- u32 *child_cnt,
- u32 *child_files,
- int last_blk)
+int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
+ u32 *child_cnt, u32 *child_files, int last_blk)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
int i;
@@ -537,7 +524,7 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi,
fsck->dentry_depth++;
for (i = 0; i < NR_DENTRY_IN_BLOCK;) {
- if (test_bit(i, (unsigned long *)de_blk->dentry_bitmap) == 0x0) {
+ if (test_bit(i, (unsigned long *)de_blk->dentry_bitmap) == 0) {
i++;
continue;
}
@@ -555,15 +542,16 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi,
/* Becareful. 'dentry.file_type' is not imode. */
if (ftype == F2FS_FT_DIR) {
*child_cnt = *child_cnt + 1;
- if ((name[0] == '.' && name[1] == '.' && name_len == 2) ||
- (name[0] == '.' && name_len == 1)) {
+ if ((name[0] == '.' && name_len == 1) ||
+ (name[0] == '.' && name[1] == '.' &&
+ name_len == 2)) {
i++;
free(name);
continue;
}
}
- DBG(1, "[%3u] - no[0x%x] name[%s] len[0x%x] ino[0x%x] type[0x%x]\n",
+ DBG(1, "[%3u]-[0x%x] name[%s] len[0x%x] ino[0x%x] type[0x%x]\n",
fsck->dentry_depth, i, name, name_len,
le32_to_cpu(de_blk->dentry[i].ino),
de_blk->dentry[i].file_type);
@@ -586,23 +574,19 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi,
free(name);
}
- DBG(1, "[%3d] Dentry Block [0x%x] Done : dentries:%d in %d slots (len:%d)\n\n",
- fsck->dentry_depth, blk_addr, dentries, NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN);
+ DBG(1, "[%3d] Dentry Block [0x%x] Done : "
+ "dentries:%d in %d slots (len:%d)\n\n",
+ fsck->dentry_depth, blk_addr, dentries,
+ NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN);
fsck->dentry_depth--;
free(de_blk);
return 0;
}
-int fsck_chk_data_blk(struct f2fs_sb_info *sbi,
- u32 blk_addr,
- u32 *child_cnt,
- u32 *child_files,
- int last_blk,
- enum FILE_TYPE ftype,
- u32 parent_nid,
- u16 idx_in_node,
- u8 ver)
+int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
+ u32 *child_cnt, u32 *child_files, int last_blk,
+ enum FILE_TYPE ftype, u32 parent_nid, u16 idx_in_node, u8 ver)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -616,24 +600,20 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi,
is_valid_ssa_data_blk(sbi, blk_addr, parent_nid, idx_in_node, ver);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk_addr), fsck->sit_area_bitmap) == 0x0) {
- ASSERT_MSG(0, "SIT bitmap is 0x0. blk_addr[0x%x]\n", blk_addr);
- }
+ if (f2fs_test_sit_bitmap(sbi, blk_addr) == 0)
+ ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]\n", blk_addr);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk_addr), fsck->main_area_bitmap) != 0) {
- ASSERT_MSG(0, "Duplicated data block. pnid[0x%x] idx[0x%x] blk_addr[0x%x]\n",
- parent_nid, idx_in_node, blk_addr);
- }
- f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, blk_addr), fsck->main_area_bitmap);
+ if (f2fs_test_main_bitmap(sbi, blk_addr) != 0)
+ ASSERT_MSG("Duplicated data [0x%x]. pnid[0x%x] idx[0x%x]",
+ blk_addr, parent_nid, idx_in_node);
+
+ f2fs_set_main_bitmap(sbi, blk_addr);
fsck->chk.valid_blk_cnt++;
if (ftype == F2FS_FT_DIR) {
- fsck_chk_dentry_blk(sbi,
- blk_addr,
- child_cnt,
- child_files,
- last_blk);
+ fsck_chk_dentry_blk(sbi, blk_addr, child_cnt,
+ child_files, last_blk);
}
return 0;
@@ -665,23 +645,18 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
DBG(1, "[%3d] ino [0x%x]\n", i, ino);
blk_cnt = 1;
- ret = fsck_chk_node_blk(sbi,
- NULL,
- ino,
- F2FS_FT_ORPHAN,
- TYPE_INODE,
- &blk_cnt);
+ ret = fsck_chk_node_blk(sbi, NULL, ino,
+ F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
ASSERT(ret >= 0);
}
memset(orphan_blk, 0, BLOCK_SZ);
}
free(orphan_blk);
-
-
return 0;
}
-int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, u32 x_nid, u32 *blk_cnt)
+int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
+ u32 x_nid, u32 *blk_cnt)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct node_info ni;
@@ -692,7 +667,7 @@ int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, u32 x_nid, u32 *blk_cn
if (f2fs_test_bit(x_nid, fsck->nat_area_bitmap) != 0x0) {
f2fs_clear_bit(x_nid, fsck->nat_area_bitmap);
} else {
- ASSERT_MSG(0, "xattr_nid duplicated [0x%x]\n", x_nid);
+ ASSERT_MSG("xattr_nid duplicated [0x%x]\n", x_nid);
}
*blk_cnt = *blk_cnt + 1;
@@ -701,12 +676,12 @@ int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, u32 x_nid, u32 *blk_cn
ASSERT(get_node_info(sbi, x_nid, &ni) >= 0);
- if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap) != 0) {
- ASSERT_MSG(0, "Duplicated node block for x_attr. "
+ if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0) {
+ ASSERT_MSG("Duplicated node block for x_attr. "
"x_nid[0x%x] block addr[0x%x]\n",
x_nid, ni.blk_addr);
}
- f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap);
+ f2fs_set_main_bitmap(sbi, ni.blk_addr);
DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid);
return 0;
@@ -718,8 +693,10 @@ int fsck_init(struct f2fs_sb_info *sbi)
struct f2fs_sm_info *sm_i = SM_I(sbi);
/*
- * We build three bitmap for main/sit/nat so that may check consistency of filesystem.
- * 1. main_area_bitmap will be used to check whether all blocks of main area is used or not.
+ * We build three bitmap for main/sit/nat so that may check consistency
+ * of filesystem.
+ * 1. main_area_bitmap will be used to check whether all blocks of main
+ * area is used or not.
* 2. nat_area_bitmap has bitmap information of used nid in NAT.
* 3. sit_area_bitmap has bitmap information of used main block.
* At Last sequence, we compare main_area_bitmap with sit_area_bitmap.
@@ -774,7 +751,8 @@ int fsck_verify(struct f2fs_sb_info *sbi)
}
printf("[FSCK] SIT valid block bitmap checking ");
- if (memcmp(fsck->sit_area_bitmap, fsck->main_area_bitmap, fsck->sit_area_bitmap_sz) == 0x0) {
+ if (memcmp(fsck->sit_area_bitmap, fsck->main_area_bitmap,
+ fsck->sit_area_bitmap_sz) == 0x0) {
printf("[Ok..]\n");
} else {
printf("[Fail]\n");
diff --git a/fsck/fsck.h b/fsck/fsck.h
index e5a3841..dcb6656 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -76,72 +76,37 @@ enum seg_type {
SEG_TYPE_MAX,
};
-extern int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, u32 x_nid, u32 *blk_cnt);
-extern int fsck_chk_orphan_node(struct f2fs_sb_info *sbi);
-
-extern int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- u32 nid,
- enum FILE_TYPE ftype,
- enum NODE_TYPE ntype,
- u32 *blk_cnt);
-
-extern int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
- u32 nid,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt,
- struct node_info *ni);
-
-extern int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- u32 nid,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt,
- struct node_info *ni);
-
-extern int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt);
-
-extern int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt);
-
-extern int fsck_chk_data_blk(struct f2fs_sb_info *sbi,
- u32 blk_addr,
- u32 *child_cnt,
- u32 *child_files,
- int last_blk,
- enum FILE_TYPE ftype,
- u32 parent_nid,
- u16 idx_in_node,
- u8 ver);
-
-extern int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi,
- u32 blk_addr,
- u32 *child_cnt,
- u32 *child_files,
- int last_blk);
-
-extern void print_node_info(struct f2fs_node *node_block);
-extern void print_inode_info(struct f2fs_inode *inode);
-extern struct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi, unsigned int segno);
-extern int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summary_block *sum_blk);
-extern int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *sum_entry);
-extern int get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni);
-extern void build_nat_area_bitmap(struct f2fs_sb_info *sbi);
-extern int build_sit_area_bitmap(struct f2fs_sb_info *sbi);
-extern int fsck_init(struct f2fs_sb_info *sbi);
-extern int fsck_verify(struct f2fs_sb_info *sbi);
-extern void fsck_free(struct f2fs_sb_info *sbi);
-extern int f2fs_do_mount(struct f2fs_sb_info *sbi);
-extern void f2fs_do_umount(struct f2fs_sb_info *sbi);
+extern int fsck_chk_xattr_blk(struct f2fs_sb_info *, u32, u32, u32 *);
+extern int fsck_chk_orphan_node(struct f2fs_sb_info *);
+extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
+ enum FILE_TYPE, enum NODE_TYPE, u32 *);
+extern int fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
+ struct f2fs_node *, u32 *, struct node_info *);
+extern int fsck_chk_dnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
+ u32, enum FILE_TYPE, struct f2fs_node *, u32 *,
+ struct node_info *);
+extern int fsck_chk_idnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
+ enum FILE_TYPE, struct f2fs_node *, u32 *);
+extern int fsck_chk_didnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
+ enum FILE_TYPE, struct f2fs_node *, u32 *);
+extern int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32, u32 *, u32 *,
+ int, enum FILE_TYPE, u32, u16, u8);
+extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, u32, u32 *, u32 *, int);
+
+extern void print_node_info(struct f2fs_node *);
+extern void print_inode_info(struct f2fs_inode *);
+extern struct seg_entry *get_seg_entry(struct f2fs_sb_info *, unsigned int);
+extern int get_sum_block(struct f2fs_sb_info *, unsigned int,
+ struct f2fs_summary_block *);
+extern int get_sum_entry(struct f2fs_sb_info *, u32, struct f2fs_summary *);
+extern int get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
+extern void build_nat_area_bitmap(struct f2fs_sb_info *);
+extern int build_sit_area_bitmap(struct f2fs_sb_info *);
+extern int fsck_init(struct f2fs_sb_info *);
+extern int fsck_verify(struct f2fs_sb_info *);
+extern void fsck_free(struct f2fs_sb_info *);
+extern int f2fs_do_mount(struct f2fs_sb_info *);
+extern void f2fs_do_umount(struct f2fs_sb_info *);
/* dump.c */
struct dump_option {
@@ -153,9 +118,9 @@ struct dump_option {
int32_t blk_addr;
};
-extern void sit_dump(struct f2fs_sb_info *sbi, int start_sit, int end_sit);
-extern void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa);
-extern int dump_node(struct f2fs_sb_info *sbi, nid_t nid);
-extern int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr);
+extern void sit_dump(struct f2fs_sb_info *, int, int);
+extern void ssa_dump(struct f2fs_sb_info *, int, int);
+extern int dump_node(struct f2fs_sb_info *, nid_t);
+extern int dump_inode_from_blkaddr(struct f2fs_sb_info *, u32);
#endif /* _FSCK_H_ */
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 49911a0..dace9aa 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -54,39 +54,33 @@ typedef unsigned long pgoff_t;
/*
* Debugging interfaces
*/
-#define ASSERT_MSG(exp, fmt, ...) \
+#define ASSERT_MSG(fmt, ...) \
do { \
- if (!(exp)) { \
- printf("\nAssertion failed!\n"); \
- printf("[%s:%4d] " #exp, __func__, __LINE__); \
- printf("\n --> "fmt, ##__VA_ARGS__); \
- config.bug_on = 1; \
- exit(-1); \
- } \
- } while (0);
+ printf("[ASSERT] (%s:%4d) ", __func__, __LINE__); \
+ printf(" --> "fmt"\n", ##__VA_ARGS__); \
+ config.bug_on = 1; \
+ } while (0)
#define ASSERT(exp) \
do { \
if (!(exp)) { \
- printf("\nAssertion failed!\n"); \
- printf("[%s:%4d] " #exp"\n", __func__, __LINE__);\
- config.bug_on = 1; \
+ printf("[ASSERT] (%s:%4d) " #exp"\n", \
+ __func__, __LINE__); \
exit(-1); \
} \
- } while (0);
+ } while (0)
#define ERR_MSG(fmt, ...) \
do { \
- printf("[%s:%d] " fmt, __func__, __LINE__, ##__VA_ARGS__); \
- } while (0);
-
+ printf("[%s:%d] " fmt, __func__, __LINE__, ##__VA_ARGS__); \
+ } while (0)
#define MSG(n, fmt, ...) \
do { \
if (config.dbg_lv >= n) { \
printf(fmt, ##__VA_ARGS__); \
} \
- } while (0);
+ } while (0)
#define DBG(n, fmt, ...) \
do { \
@@ -94,52 +88,52 @@ typedef unsigned long pgoff_t;
printf("[%s:%4d] " fmt, \
__func__, __LINE__, ##__VA_ARGS__); \
} \
- } while (0);
+ } while (0)
/* Display on console */
#define DISP(fmt, ptr, member) \
do { \
printf("%-30s" fmt, #member, ((ptr)->member)); \
- } while (0);
+ } while (0)
#define DISP_u32(ptr, member) \
do { \
assert(sizeof((ptr)->member) <= 4); \
printf("%-30s" "\t\t[0x%8x : %u]\n", \
- #member, ((ptr)->member), ((ptr)->member) ); \
- } while (0);
+ #member, ((ptr)->member), ((ptr)->member)); \
+ } while (0)
#define DISP_u64(ptr, member) \
do { \
assert(sizeof((ptr)->member) == 8); \
printf("%-30s" "\t\t[0x%8llx : %llu]\n", \
- #member, ((ptr)->member), ((ptr)->member) ); \
- } while (0);
+ #member, ((ptr)->member), ((ptr)->member)); \
+ } while (0)
#define DISP_utf(ptr, member) \
do { \
- printf("%-30s" "\t\t[%s]\n", #member, ((ptr)->member) ); \
- } while (0);
+ printf("%-30s" "\t\t[%s]\n", #member, ((ptr)->member)); \
+ } while (0)
/* Display to buffer */
-#define BUF_DISP_u32(buf, data, len, ptr, member) \
- do { \
- assert(sizeof((ptr)->member) <= 4); \
- snprintf(buf, len, #member); \
- snprintf(data, len, "0x%x : %u", ((ptr)->member), ((ptr)->member)); \
- } while (0);
-
-#define BUF_DISP_u64(buf, data, len, ptr, member) \
- do { \
- assert(sizeof((ptr)->member) == 8); \
- snprintf(buf, len, #member); \
- snprintf(data, len, "0x%llx : %llu", ((ptr)->member), ((ptr)->member)); \
- } while (0);
-
-#define BUF_DISP_utf(buf, data, len, ptr, member) \
- do { \
- snprintf(buf, len, #member); \
- } while (0);
+#define BUF_DISP_u32(buf, data, len, ptr, member) \
+ do { \
+ assert(sizeof((ptr)->member) <= 4); \
+ snprintf(buf, len, #member); \
+ snprintf(data, len, "0x%x : %u", ((ptr)->member), \
+ ((ptr)->member)); \
+ } while (0)
+
+#define BUF_DISP_u64(buf, data, len, ptr, member) \
+ do { \
+ assert(sizeof((ptr)->member) == 8); \
+ snprintf(buf, len, #member); \
+ snprintf(data, len, "0x%llx : %llu", ((ptr)->member), \
+ ((ptr)->member)); \
+ } while (0)
+
+#define BUF_DISP_utf(buf, data, len, ptr, member) \
+ snprintf(buf, len, #member)
/* these are defined in kernel */
#define PAGE_SIZE 4096
@@ -665,7 +659,8 @@ extern int test_bit(unsigned int nr, const void * addr);
extern int f2fs_test_bit(unsigned int, const char *);
extern int f2fs_set_bit(unsigned int, char *);
extern int f2fs_clear_bit(unsigned int, char *);
-extern unsigned long find_next_bit(const unsigned long *, unsigned long, unsigned long);
+extern unsigned long find_next_bit(const unsigned long *,
+ unsigned long, unsigned long);
extern u_int32_t f2fs_cal_crc32(u_int32_t, void *, int);
extern int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len);
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/17] fsck.f2fs: handle IS_VALID_BLK_ADDR
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 ` [PATCH 02/17] fsck.f2fs: retry to fix corrupted image Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 03/17] fsck.f2fs: clean up codes Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 05/17] fsck.f2fs: remove return value of get_node_info Jaegeuk Kim
` (12 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/f2fs.h | 21 +++++++++++----------
fsck/fsck.c | 14 +++++++++++---
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index aa43cdc..2adffd8 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -308,16 +308,17 @@ static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid)
<< (sbi->log_blocks_per_seg - 1)));
}
-#define IS_VALID_BLK_ADDR(sbi, addr) \
- do { \
- if (addr >= F2FS_RAW_SUPER(sbi)->block_count || \
- addr < SM_I(sbi)->main_blkaddr) \
- { \
- DBG(0, "block addr [0x%x]\n", addr); \
- ASSERT(addr < F2FS_RAW_SUPER(sbi)->block_count); \
- ASSERT(addr >= SM_I(sbi)->main_blkaddr); \
- } \
- } while (0);
+static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
+{
+ if (addr >= F2FS_RAW_SUPER(sbi)->block_count ||
+ addr < SM_I(sbi)->main_blkaddr) {
+ DBG(0, "block addr [0x%x]\n", addr);
+ ASSERT(addr < F2FS_RAW_SUPER(sbi)->block_count);
+ ASSERT(addr >= SM_I(sbi)->main_blkaddr);
+ return 0;
+ }
+ return 1;
+}
static inline u64 BLKOFF_FROM_MAIN(struct f2fs_sb_info *sbi, u64 blk_addr)
{
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 5c99385..5eab522 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -189,8 +189,10 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
struct f2fs_node *node_blk = NULL;
int ret = 0;
- if (!IS_VALID_NID(sbi, nid))
+ if (!IS_VALID_NID(sbi, nid)) {
ASSERT_MSG("nid is not valid. [0x%x]", nid);
+ return 0;
+ }
if (ftype != F2FS_FT_ORPHAN ||
f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0x0)
@@ -213,7 +215,10 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
return 0;
}
- IS_VALID_BLK_ADDR(sbi, ni.blk_addr);
+ if (!IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) {
+ ASSERT_MSG("blkaddres is not valid. [0x%x]", ni.blk_addr);
+ return 0;
+ }
is_valid_ssa_node_blk(sbi, nid, ni.blk_addr);
@@ -596,7 +601,10 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
return 0;
}
- IS_VALID_BLK_ADDR(sbi, blk_addr);
+ if (!IS_VALID_BLK_ADDR(sbi, blk_addr)) {
+ ASSERT_MSG("blkaddres is not valid. [0x%x]", blk_addr);
+ return 0;
+ }
is_valid_ssa_data_blk(sbi, blk_addr, parent_nid, idx_in_node, ver);
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/17] fsck.f2fs: remove return value of get_node_info
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (2 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 04/17] fsck.f2fs: handle IS_VALID_BLK_ADDR Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 06/17] fsck.f2fs: handle error cases Jaegeuk Kim
` (11 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
We don't need to get the return value.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/dump.c | 23 +++++++++--------------
fsck/fsck.c | 5 ++---
fsck/fsck.h | 4 ++--
fsck/mount.c | 23 +++++++----------------
4 files changed, 20 insertions(+), 35 deletions(-)
diff --git a/fsck/dump.c b/fsck/dump.c
index e14a190..54f9a52 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -140,8 +140,8 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype,
{
struct node_info ni;
struct f2fs_node *node_blk;
- int i, ret;
u32 idx, skip = 0;
+ int i;
switch (ntype) {
case TYPE_DIRECT_NODE:
@@ -162,8 +162,7 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype,
return;
}
- ret = get_node_info(sbi, nid, &ni);
- ASSERT(ret >= 0);
+ get_node_info(sbi, nid, &ni);
node_blk = calloc(BLOCK_SZ, 1);
dev_read_block(node_blk, ni.blk_addr);
@@ -267,14 +266,12 @@ void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni,
}
}
-int dump_node(struct f2fs_sb_info *sbi, nid_t nid)
+void dump_node(struct f2fs_sb_info *sbi, nid_t nid)
{
struct node_info ni;
struct f2fs_node *node_blk;
- int ret;
- ret = get_node_info(sbi, nid, &ni);
- ASSERT(ret >= 0);
+ get_node_info(sbi, nid, &ni);
node_blk = calloc(BLOCK_SZ, 1);
dev_read_block(node_blk, ni.blk_addr);
@@ -284,9 +281,8 @@ int dump_node(struct f2fs_sb_info *sbi, nid_t nid)
DBG(1, "nat_entry.version [0x%x]\n", ni.version);
DBG(1, "nat_entry.ino [0x%x]\n", ni.ino);
- if (ni.blk_addr == 0x0) {
+ if (ni.blk_addr == 0x0)
MSG(0, "Invalid nat entry\n\n");
- }
DBG(1, "node_blk.footer.ino [0x%x]\n", le32_to_cpu(node_blk->footer.ino));
DBG(1, "node_blk.footer.nid [0x%x]\n", le32_to_cpu(node_blk->footer.nid));
@@ -300,7 +296,6 @@ int dump_node(struct f2fs_sb_info *sbi, nid_t nid)
}
free(node_blk);
- return 0;
}
int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
@@ -314,8 +309,7 @@ int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
type = get_sum_entry(sbi, blk_addr, &sum_entry);
nid = le32_to_cpu(sum_entry.nid);
- ret = get_node_info(sbi, nid, &ni);
- ASSERT(ret >= 0);
+ get_node_info(sbi, nid, &ni);
DBG(1, "Note: blkaddr = main_blkaddr + segno * 512 + offset\n");
DBG(1, "Block_addr [0x%x]\n", blk_addr);
@@ -331,7 +325,8 @@ int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr)
node_blk = calloc(BLOCK_SZ, 1);
read_node_blk:
- dev_read_block(node_blk, blk_addr);
+ ret = dev_read_block(node_blk, blk_addr);
+ ASSERT(ret >= 0);
ino = le32_to_cpu(node_blk->footer.ino);
nid = le32_to_cpu(node_blk->footer.nid);
@@ -339,7 +334,7 @@ read_node_blk:
if (ino == nid) {
print_node_info(node_blk);
} else {
- ret = get_node_info(sbi, ino, &ni);
+ get_node_info(sbi, ino, &ni);
goto read_node_blk;
}
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 5eab522..d2781d9 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -200,8 +200,7 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
else
ASSERT_MSG("nid duplicated [0x%x]\n", nid);
- ret = get_node_info(sbi, nid, &ni);
- ASSERT(ret >= 0);
+ get_node_info(sbi, nid, &ni);
/* Is it reserved block?
* if block addresss was 0xffff,ffff,ffff,ffff
@@ -682,7 +681,7 @@ int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
fsck->chk.valid_blk_cnt++;
fsck->chk.valid_node_cnt++;
- ASSERT(get_node_info(sbi, x_nid, &ni) >= 0);
+ get_node_info(sbi, x_nid, &ni);
if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0) {
ASSERT_MSG("Duplicated node block for x_attr. "
diff --git a/fsck/fsck.h b/fsck/fsck.h
index dcb6656..b673646 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -99,7 +99,7 @@ extern struct seg_entry *get_seg_entry(struct f2fs_sb_info *, unsigned int);
extern int get_sum_block(struct f2fs_sb_info *, unsigned int,
struct f2fs_summary_block *);
extern int get_sum_entry(struct f2fs_sb_info *, u32, struct f2fs_summary *);
-extern int get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
+extern void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
extern void build_nat_area_bitmap(struct f2fs_sb_info *);
extern int build_sit_area_bitmap(struct f2fs_sb_info *);
extern int fsck_init(struct f2fs_sb_info *);
@@ -120,7 +120,7 @@ struct dump_option {
extern void sit_dump(struct f2fs_sb_info *, int, int);
extern void ssa_dump(struct f2fs_sb_info *, int, int);
-extern int dump_node(struct f2fs_sb_info *, nid_t);
+extern void dump_node(struct f2fs_sb_info *, nid_t);
extern int dump_inode_from_blkaddr(struct f2fs_sb_info *, u32);
#endif /* _FSCK_H_ */
diff --git a/fsck/mount.c b/fsck/mount.c
index 7ea3296..ab5f7f3 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -801,9 +801,9 @@ int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *s
return ret;
}
-int get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct f2fs_nat_entry *raw_nat)
+static void get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid,
+ struct f2fs_nat_entry *raw_nat)
{
- struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct f2fs_nat_block *nat_block;
pgoff_t block_off;
@@ -811,13 +811,8 @@ int get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct f2fs_nat_entry *ra
int seg_off, entry_off;
int ret;
- if ((nid / NAT_ENTRY_PER_BLOCK) > fsck->nr_nat_entries) {
- DBG(0, "nid is over max nid\n");
- return -EINVAL;
- }
-
if (lookup_nat_in_journal(sbi, nid, raw_nat) >= 0)
- return 0;
+ return;
nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
@@ -835,21 +830,17 @@ int get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct f2fs_nat_entry *ra
ret = dev_read_block(nat_block, block_addr);
ASSERT(ret >= 0);
- memcpy(raw_nat, &nat_block->entries[entry_off], sizeof(struct f2fs_nat_entry));
+ memcpy(raw_nat, &nat_block->entries[entry_off],
+ sizeof(struct f2fs_nat_entry));
free(nat_block);
-
- return 0;
}
-int get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
+void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
{
struct f2fs_nat_entry raw_nat;
- int ret;
-
- ret = get_nat_entry(sbi, nid, &raw_nat);
+ get_nat_entry(sbi, nid, &raw_nat);
ni->nid = nid;
node_info_from_raw_nat(ni, &raw_nat);
- return ret;
}
void build_sit_entries(struct f2fs_sb_info *sbi)
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/17] fsck.f2fs: handle error cases
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (3 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 05/17] fsck.f2fs: remove return value of get_node_info Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 07/17] fsck.f2fs: cleanup mount.c Jaegeuk Kim
` (10 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Do sanity check first and then update metadata.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 344 +++++++++++++++++++++++++++++-------------------------
fsck/fsck.h | 11 +-
fsck/main.c | 40 ++-----
fsck/mount.c | 3 +-
include/f2fs_fs.h | 4 +
5 files changed, 205 insertions(+), 197 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index d2781d9..9ebe2be 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -80,10 +80,8 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct hard_link_node *node = NULL, *prev = NULL;
- if (fsck->hard_link_list_head == NULL) {
- ASSERT(0);
- return -1;
- }
+ if (fsck->hard_link_list_head == NULL)
+ return -EINVAL;
node = fsck->hard_link_list_head;
@@ -92,10 +90,8 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
node = node->next;
}
- if (node == NULL || (nid != node->nid)) {
- ASSERT(0);
- return -1;
- }
+ if (node == NULL || (nid != node->nid))
+ return -EINVAL;
/* Decrease link count */
node->links = node->links - 1;
@@ -108,9 +104,7 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
prev->next = node->next;
free(node);
}
-
return 0;
-
}
static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid,
@@ -138,14 +132,16 @@ static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid,
le32_to_cpu(sum_entry.nid));
DBG(0, "--> node block's nid [0x%x]\n", nid);
ASSERT_MSG("Invalid node seg summary\n");
+ return -EINVAL;
}
+ return 0;
} else if (ret == SEG_TYPE_CUR_NODE) {
/* current node segment has no ssa */
+ return 0;
} else {
ASSERT_MSG("Invalid return value of 'get_sum_entry'");
}
-
- return 1;
+ return -EINVAL;
}
static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
@@ -177,114 +173,145 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
return 1;
}
-int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- u32 nid,
- enum FILE_TYPE ftype,
- enum NODE_TYPE ntype,
- u32 *blk_cnt)
+static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
+ struct f2fs_node *node_blk,
+ enum FILE_TYPE ftype, enum NODE_TYPE ntype,
+ struct node_info *ni)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
- struct node_info ni;
- struct f2fs_node *node_blk = NULL;
- int ret = 0;
+ int ret;
if (!IS_VALID_NID(sbi, nid)) {
ASSERT_MSG("nid is not valid. [0x%x]", nid);
- return 0;
+ return -EINVAL;
}
- if (ftype != F2FS_FT_ORPHAN ||
- f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0x0)
- f2fs_clear_bit(nid, fsck->nat_area_bitmap);
- else
- ASSERT_MSG("nid duplicated [0x%x]\n", nid);
+ get_node_info(sbi, nid, ni);
+ if (ni->blk_addr == NEW_ADDR) {
+ ASSERT_MSG("nid is NEW_ADDR. [0x%x]", nid);
+ return -EINVAL;
+ }
- get_node_info(sbi, nid, &ni);
+ if (!IS_VALID_BLK_ADDR(sbi, ni->blk_addr)) {
+ ASSERT_MSG("blkaddres is not valid. [0x%x]", ni->blk_addr);
+ return -EINVAL;
+ }
- /* Is it reserved block?
- * if block addresss was 0xffff,ffff,ffff,ffff
- * it means that block was already allocated, but not stored in disk
- */
- if (ni.blk_addr == NEW_ADDR) {
- fsck->chk.valid_blk_cnt++;
- fsck->chk.valid_node_cnt++;
- if (ntype == TYPE_INODE)
- fsck->chk.valid_inode_cnt++;
- return 0;
+ if (is_valid_ssa_node_blk(sbi, nid, ni->blk_addr)) {
+ ASSERT_MSG("summary node block is not valid. [0x%x]", nid);
+ return -EINVAL;
}
- if (!IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) {
- ASSERT_MSG("blkaddres is not valid. [0x%x]", ni.blk_addr);
- return 0;
+ ret = dev_read_block(node_blk, ni->blk_addr);
+ ASSERT(ret >= 0);
+
+ if (ntype == TYPE_INODE &&
+ node_blk->footer.nid != node_blk->footer.ino) {
+ ASSERT_MSG("nid[0x%x] footer.nid[0x%x] footer.ino[0x%x]",
+ nid, le32_to_cpu(node_blk->footer.nid),
+ le32_to_cpu(node_blk->footer.ino));
+ return -EINVAL;
+ }
+ if (ntype != TYPE_INODE &&
+ node_blk->footer.nid == node_blk->footer.ino) {
+ ASSERT_MSG("nid[0x%x] footer.nid[0x%x] footer.ino[0x%x]",
+ nid, le32_to_cpu(node_blk->footer.nid),
+ le32_to_cpu(node_blk->footer.ino));
+ return -EINVAL;
+ }
+
+ if (le32_to_cpu(node_blk->footer.nid) != nid) {
+ ASSERT_MSG("nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]",
+ nid, ni->blk_addr,
+ le32_to_cpu(node_blk->footer.nid));
+ return -EINVAL;
+ }
+
+ if (ntype == TYPE_XATTR) {
+ u32 flag = le32_to_cpu(node_blk->footer.flag);
+
+ if ((flag >> OFFSET_BIT_SHIFT) != XATTR_NODE_OFFSET) {
+ ASSERT_MSG("xnid[0x%x] has wrong ofs:[0x%x]",
+ nid, flag);
+ return -EINVAL;
+ }
+ }
+
+ if ((ntype == TYPE_INODE && ftype == F2FS_FT_DIR) ||
+ (ntype == TYPE_XATTR && ftype == F2FS_FT_XATTR)) {
+ /* not included '.' & '..' */
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) != 0) {
+ ASSERT_MSG("Duplicated node blk. nid[0x%x][0x%x]\n",
+ nid, ni->blk_addr);
+ return -EINVAL;
+ }
}
- is_valid_ssa_node_blk(sbi, nid, ni.blk_addr);
+ /* workaround to fix later */
+ if (ftype != F2FS_FT_ORPHAN ||
+ f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
+ f2fs_clear_bit(nid, fsck->nat_area_bitmap);
+ else
+ ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n",
+ nid);
- if (f2fs_test_sit_bitmap(sbi, ni.blk_addr) == 0)
- ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", ni.blk_addr);
+ if (f2fs_test_sit_bitmap(sbi, ni->blk_addr) == 0)
+ ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]",
+ ni->blk_addr);
- if (f2fs_test_main_bitmap(sbi, ni.blk_addr) == 0) {
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
fsck->chk.valid_blk_cnt++;
fsck->chk.valid_node_cnt++;
}
+ return 0;
+}
+
+int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
+ u32 nid, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
+ u32 *blk_cnt)
+{
+ struct node_info ni;
+ struct f2fs_node *node_blk = NULL;
node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
ASSERT(node_blk != NULL);
- ret = dev_read_block(node_blk, ni.blk_addr);
- ASSERT(ret >= 0);
-
- if (nid != le32_to_cpu(node_blk->footer.nid))
- ASSERT_MSG("nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]",
- nid, ni.blk_addr, le32_to_cpu(node_blk->footer.nid));
+ if (sanity_check_nid(sbi, nid, node_blk, ftype, ntype, &ni))
+ goto err;
if (ntype == TYPE_INODE) {
- ret = fsck_chk_inode_blk(sbi,
- nid,
- ftype,
- node_blk,
- blk_cnt,
- &ni);
+ fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, &ni);
} else {
- /* it's not inode */
- ASSERT(node_blk->footer.nid != node_blk->footer.ino);
-
- if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0)
- ASSERT_MSG("Duplicated node blk. nid[0x%x][0x%x]\n",
- nid, ni.blk_addr);
-
f2fs_set_main_bitmap(sbi, ni.blk_addr);
switch (ntype) {
case TYPE_DIRECT_NODE:
- ret = fsck_chk_dnode_blk(sbi, inode, nid, ftype,
- node_blk, blk_cnt, &ni);
+ fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk,
+ blk_cnt, &ni);
break;
case TYPE_INDIRECT_NODE:
- ret = fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
+ fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
blk_cnt);
break;
case TYPE_DOUBLE_INDIRECT_NODE:
- ret = fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
+ fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
blk_cnt);
break;
default:
ASSERT(0);
}
}
- ASSERT(ret >= 0);
-
free(node_blk);
return 0;
+err:
+ free(node_blk);
+ return -EINVAL;
}
-int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
- u32 nid,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt,
- struct node_info *ni)
+/* start with valid nid and blkaddr */
+void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
+ enum FILE_TYPE ftype, struct f2fs_node *node_blk,
+ u32 *blk_cnt, struct node_info *ni)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
u32 child_cnt = 0, child_files = 0;
@@ -292,31 +319,13 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
u32 i_links = le32_to_cpu(node_blk->i.i_links);
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
unsigned int idx = 0;
- int ret = 0;
-
- ASSERT(node_blk->footer.nid == node_blk->footer.ino);
- ASSERT(le32_to_cpu(node_blk->footer.nid) == nid);
+ int ret;
if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0)
fsck->chk.valid_inode_cnt++;
- /* Orphan node. i_links should be 0 */
- if (ftype == F2FS_FT_ORPHAN) {
- ASSERT(i_links == 0);
- } else {
- ASSERT(i_links > 0);
- }
-
if (ftype == F2FS_FT_DIR) {
-
- /* not included '.' & '..' */
- if (f2fs_test_main_bitmap(sbi, ni->blk_addr) != 0) {
- DBG(0, "Duplicated inode blk. ino[0x%x][0x%x]\n",
- nid, ni->blk_addr);
- ASSERT(0);
- }
f2fs_set_main_bitmap(sbi, ni->blk_addr);
-
} else {
if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
f2fs_set_main_bitmap(sbi, ni->blk_addr);
@@ -326,21 +335,15 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
fsck->chk.multi_hard_link_files++;
}
} else {
- if (i_links <= 1) {
- DBG(0, "Error. Node ID [0x%x]."
- " There are one more hard links."
- " But i_links is [0x%x]\n",
+ DBG(3, "[0x%x] has hard links [0x%x]\n", nid, i_links);
+ if (find_and_dec_hard_link_list(sbi, nid)) {
+ ASSERT_MSG("[0x%x] needs more i_links=0x%x",
nid, i_links);
- ASSERT(0);
+ if (config.fix_cnt)
+ printf("TODO: i_links++\n");
}
-
- DBG(3, "ino[0x%x] has hard links [0x%x]\n",
- nid, i_links);
- ret = find_and_dec_hard_link_list(sbi, nid);
- ASSERT(ret >= 0);
-
/* No need to go deep into the node */
- goto out;
+ return;
}
}
@@ -358,13 +361,13 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
/* check data blocks in inode */
for (idx = 0; idx < ADDRS_PER_INODE(&node_blk->i); idx++) {
if (le32_to_cpu(node_blk->i.i_addr[idx]) != 0) {
- *blk_cnt = *blk_cnt + 1;
ret = fsck_chk_data_blk(sbi,
le32_to_cpu(node_blk->i.i_addr[idx]),
&child_cnt, &child_files,
(i_blocks == *blk_cnt),
ftype, nid, idx, ni->version);
- ASSERT(ret >= 0);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
}
}
@@ -380,11 +383,13 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
ASSERT(0);
if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) {
- *blk_cnt = *blk_cnt + 1;
ret = fsck_chk_node_blk(sbi, &node_blk->i,
le32_to_cpu(node_blk->i.i_nid[idx]),
ftype, ntype, blk_cnt);
- ASSERT(ret >= 0);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
+ else if (config.fix_cnt)
+ printf("TODO delete i_nid[idx] = 0;\n");
}
}
check:
@@ -400,35 +405,46 @@ check:
node_blk->i.i_name,
(u32)i_blocks);
if ((ftype == F2FS_FT_DIR && i_links != child_cnt) ||
- (i_blocks != *blk_cnt)) {
- print_node_info(node_blk);
+ (i_blocks != *blk_cnt)) {
+ if (!config.fix_cnt)
+ print_node_info(node_blk);
+
+ /* node_blk, ni.blkaddr, child_cnt, *blk_cnt */
+ if (config.fix_cnt)
+ printf("TODO fix_inode_block\n");
+ else
+ print_node_info(node_blk);
DBG(1, "blk cnt [0x%x]\n", *blk_cnt);
DBG(1, "child cnt [0x%x]\n", child_cnt);
}
-
- ASSERT(i_blocks == *blk_cnt);
- if (ftype == F2FS_FT_DIR)
- ASSERT(i_links == child_cnt);
-out:
- return 0;
+ if (i_blocks != *blk_cnt)
+ ASSERT_MSG("ino: 0x%x has i_blocks: %lu, but has %u blocks",
+ nid, i_blocks, *blk_cnt);
+ if (ftype == F2FS_FT_DIR && i_links != child_cnt)
+ ASSERT_MSG("ino: 0x%x has i_links: %u but real links: %u",
+ nid, i_links, child_cnt);
+ if (ftype == F2FS_FT_ORPHAN && i_links)
+ ASSERT_MSG("ino: 0x%x is orphan inode, but has i_links: %u",
+ nid, i_links);
}
int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk,
u32 *blk_cnt, struct node_info *ni)
{
- int idx;
+ int idx, ret;
u32 child_cnt = 0, child_files = 0;
for (idx = 0; idx < ADDRS_PER_BLOCK; idx++) {
if (le32_to_cpu(node_blk->dn.addr[idx]) == 0x0)
continue;
- *blk_cnt = *blk_cnt + 1;
- fsck_chk_data_blk(sbi,
+ ret = fsck_chk_data_blk(sbi,
le32_to_cpu(node_blk->dn.addr[idx]),
&child_cnt, &child_files,
le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype,
nid, idx, ni->version);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
}
return 0;
}
@@ -436,14 +452,19 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt)
{
+ int ret;
int i = 0;
for (i = 0 ; i < NIDS_PER_BLOCK; i++) {
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
continue;
- *blk_cnt = *blk_cnt + 1;
- fsck_chk_node_blk(sbi, inode, le32_to_cpu(node_blk->in.nid[i]),
+ ret = fsck_chk_node_blk(sbi, inode,
+ le32_to_cpu(node_blk->in.nid[i]),
ftype, TYPE_DIRECT_NODE, blk_cnt);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
+ else if (ret == -EINVAL)
+ printf("delete in.nid[i] = 0;\n");
}
return 0;
}
@@ -452,14 +473,18 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt)
{
int i = 0;
+ int ret = 0;
for (i = 0; i < NIDS_PER_BLOCK; i++) {
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
continue;
- *blk_cnt = *blk_cnt + 1;
- fsck_chk_node_blk(sbi, inode,
+ ret = fsck_chk_node_blk(sbi, inode,
le32_to_cpu(node_blk->in.nid[i]),
ftype, TYPE_INDIRECT_NODE, blk_cnt);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
+ else if (ret == -EINVAL)
+ printf("delete in.nid[i] = 0;\n");
}
return 0;
}
@@ -570,7 +595,8 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
TYPE_INODE,
&blk_cnt);
- ASSERT(ret >= 0);
+ if (ret)
+ printf("TODO: delete dentry\n");
i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN;
dentries++;
@@ -618,35 +644,34 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
fsck->chk.valid_blk_cnt++;
- if (ftype == F2FS_FT_DIR) {
- fsck_chk_dentry_blk(sbi, blk_addr, child_cnt,
+ if (ftype == F2FS_FT_DIR)
+ return fsck_chk_dentry_blk(sbi, blk_addr, child_cnt,
child_files, last_blk);
- }
-
return 0;
}
-int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
+void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
{
- int ret = 0;
u32 blk_cnt = 0;
-
block_t start_blk, orphan_blkaddr, i, j;
struct f2fs_orphan_block *orphan_blk;
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
if (!is_set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG))
- return 0;
+ return;
+
+ if (config.fix_cnt)
+ return;
start_blk = __start_cp_addr(sbi) + 1 +
le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
-
orphan_blkaddr = __start_sum_addr(sbi) - 1;
-
orphan_blk = calloc(BLOCK_SZ, 1);
for (i = 0; i < orphan_blkaddr; i++) {
- dev_read_block(orphan_blk, start_blk + i);
+ int ret = dev_read_block(orphan_blk, start_blk + i);
+
+ ASSERT(ret >= 0);
for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
@@ -654,47 +679,42 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
blk_cnt = 1;
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
- ASSERT(ret >= 0);
+ if (ret == -EINVAL)
+ printf("TODO: nothing?\n");
}
memset(orphan_blk, 0, BLOCK_SZ);
}
free(orphan_blk);
- return 0;
}
-int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
- u32 x_nid, u32 *blk_cnt)
+void fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
+ u32 x_nid, u32 *blk_cnt)
{
- struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+ struct f2fs_node *node_blk = NULL;
struct node_info ni;
if (x_nid == 0x0)
- return 0;
+ return;
- if (f2fs_test_bit(x_nid, fsck->nat_area_bitmap) != 0x0) {
- f2fs_clear_bit(x_nid, fsck->nat_area_bitmap);
- } else {
- ASSERT_MSG("xattr_nid duplicated [0x%x]\n", x_nid);
+ node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
+ ASSERT(node_blk != NULL);
+
+ /* Sanity check */
+ if (sanity_check_nid(sbi, x_nid, node_blk,
+ F2FS_FT_XATTR, TYPE_XATTR, &ni)) {
+ /* TODO: drop xattr node */
+ printf("drop xattr node\n");
+ goto out;
}
*blk_cnt = *blk_cnt + 1;
- fsck->chk.valid_blk_cnt++;
- fsck->chk.valid_node_cnt++;
-
- get_node_info(sbi, x_nid, &ni);
-
- if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0) {
- ASSERT_MSG("Duplicated node block for x_attr. "
- "x_nid[0x%x] block addr[0x%x]\n",
- x_nid, ni.blk_addr);
- }
f2fs_set_main_bitmap(sbi, ni.blk_addr);
-
DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid);
- return 0;
+out:
+ free(node_blk);
}
-int fsck_init(struct f2fs_sb_info *sbi)
+void fsck_init(struct f2fs_sb_info *sbi)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct f2fs_sm_info *sm_i = SM_I(sbi);
@@ -718,7 +738,7 @@ int fsck_init(struct f2fs_sb_info *sbi)
build_sit_area_bitmap(sbi);
tree_mark = calloc(tree_mark_size, 1);
- return 0;
+ ASSERT(tree_mark != NULL);
}
int fsck_verify(struct f2fs_sb_info *sbi)
diff --git a/fsck/fsck.h b/fsck/fsck.h
index b673646..aecfa9a 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -59,7 +59,8 @@ enum NODE_TYPE {
TYPE_INODE = 37,
TYPE_DIRECT_NODE = 43,
TYPE_INDIRECT_NODE = 53,
- TYPE_DOUBLE_INDIRECT_NODE = 67
+ TYPE_DOUBLE_INDIRECT_NODE = 67,
+ TYPE_XATTR = 77
};
struct hard_link_node {
@@ -76,11 +77,11 @@ enum seg_type {
SEG_TYPE_MAX,
};
-extern int fsck_chk_xattr_blk(struct f2fs_sb_info *, u32, u32, u32 *);
-extern int fsck_chk_orphan_node(struct f2fs_sb_info *);
+extern void fsck_chk_xattr_blk(struct f2fs_sb_info *, u32, u32, u32 *);
+extern void fsck_chk_orphan_node(struct f2fs_sb_info *);
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
enum FILE_TYPE, enum NODE_TYPE, u32 *);
-extern int fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
+extern void fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
struct f2fs_node *, u32 *, struct node_info *);
extern int fsck_chk_dnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
u32, enum FILE_TYPE, struct f2fs_node *, u32 *,
@@ -102,7 +103,7 @@ extern int get_sum_entry(struct f2fs_sb_info *, u32, struct f2fs_summary *);
extern void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
extern void build_nat_area_bitmap(struct f2fs_sb_info *);
extern int build_sit_area_bitmap(struct f2fs_sb_info *);
-extern int fsck_init(struct f2fs_sb_info *);
+extern void fsck_init(struct f2fs_sb_info *);
extern int fsck_verify(struct f2fs_sb_info *);
extern void fsck_free(struct f2fs_sb_info *);
extern int f2fs_do_mount(struct f2fs_sb_info *);
diff --git a/fsck/main.c b/fsck/main.c
index 266e9b5..7e3bb49 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -131,44 +131,29 @@ void f2fs_parse_options(int argc, char *argv[])
config.device_name = argv[optind];
}
-int do_fsck(struct f2fs_sb_info *sbi)
+static void 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_init(sbi);
fsck_chk_orphan_node(sbi);
/* Traverse all block recursively from root inode */
blk_cnt = 1;
- ret = fsck_chk_node_blk(sbi,
- NULL,
- sbi->root_ino_num,
- F2FS_FT_DIR,
- TYPE_INODE,
- &blk_cnt);
- if (ret < 0)
- goto out1;
-
- ret = fsck_verify(sbi);
-out1:
+ fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num,
+ F2FS_FT_DIR, TYPE_INODE, &blk_cnt);
+ fsck_verify(sbi);
fsck_free(sbi);
- return ret;
}
-int do_dump(struct f2fs_sb_info *sbi)
+static void do_dump(struct f2fs_sb_info *sbi)
{
struct dump_option *opt = (struct dump_option *)config.private;
- int ret;
- ret = fsck_init(sbi);
- if (ret < 0)
- return ret;
+ fsck_init(sbi);
if (opt->end_sit == -1)
opt->end_sit = SM_I(sbi)->main_segments;
@@ -182,15 +167,12 @@ int do_dump(struct f2fs_sb_info *sbi)
dump_inode_from_blkaddr(sbi, opt->blk_addr);
goto cleanup;
}
-
dump_node(sbi, opt->nid);
-
cleanup:
fsck_free(sbi);
- return 0;
}
-int main (int argc, char **argv)
+int main(int argc, char **argv)
{
struct f2fs_sb_info *sbi;
int ret = 0;
@@ -215,10 +197,10 @@ fsck_again:
switch (config.func) {
case FSCK:
- ret = do_fsck(sbi);
+ do_fsck(sbi);
break;
case DUMP:
- ret = do_dump(sbi);
+ do_dump(sbi);
break;
}
@@ -248,5 +230,5 @@ retry:
f2fs_finalize_device(&config);
printf("\nDone.\n");
- return ret;
+ return 0;
}
diff --git a/fsck/mount.c b/fsck/mount.c
index ab5f7f3..a766157 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1020,7 +1020,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
struct node_info ni;
ni.nid = nid + i;
- if ((nid + i) == F2FS_NODE_INO(sbi) || (nid + i) == F2FS_META_INO(sbi)) {
+ if ((nid + i) == F2FS_NODE_INO(sbi) ||
+ (nid + i) == F2FS_META_INO(sbi)) {
ASSERT(nat_block->entries[i].block_addr != 0x0);
continue;
}
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index dace9aa..c3cc2aa 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -413,6 +413,9 @@ enum {
OFFSET_BIT_SHIFT
};
+#define XATTR_NODE_OFFSET ((((unsigned int)-1) << OFFSET_BIT_SHIFT) \
+ >> OFFSET_BIT_SHIFT)
+
struct node_footer {
__le32 nid; /* node id */
__le32 ino; /* inode nunmber */
@@ -640,6 +643,7 @@ enum FILE_TYPE {
F2FS_FT_MAX,
/* added for fsck */
F2FS_FT_ORPHAN,
+ F2FS_FT_XATTR,
};
/* from f2fs/segment.h */
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/17] fsck.f2fs: cleanup mount.c
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (4 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 06/17] fsck.f2fs: handle error cases Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 08/17] fsck.f2fs: give a chance to recover sit entries Jaegeuk Kim
` (9 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/mount.c | 116 +++++++++++++++++++++++++++++++++++------------------------
1 file changed, 70 insertions(+), 46 deletions(-)
diff --git a/fsck/mount.c b/fsck/mount.c
index a766157..b0dd5c7 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -53,7 +53,7 @@ void print_inode_info(struct f2fs_inode *inode)
for (i = 4; i < ADDRS_PER_INODE(inode); i++) {
if (inode->i_addr[i] != 0x0) {
- printf("i_addr[0x%x] points data block\r\t\t\t\t[0x%4x]\n",
+ printf("i_addr[0x%x] points data block\r\t\t[0x%4x]\n",
i, inode->i_addr[i]);
break;
}
@@ -79,9 +79,11 @@ void print_node_info(struct f2fs_node *node_block)
} else {
int i;
u32 *dump_blk = (u32 *)node_block;
- DBG(0, "Node ID [0x%x:%u] is direct node or indirect node.\n", nid, nid);
+ DBG(0, "Node ID [0x%x:%u] is direct node or indirect node.\n",
+ nid, nid);
for (i = 0; i <= 10; i++)
- MSG(0, "[%d]\t\t\t[0x%8x : %d]\n", i, dump_blk[i], dump_blk[i]);
+ MSG(0, "[%d]\t\t\t[0x%8x : %d]\n",
+ i, dump_blk[i], dump_blk[i]);
}
}
@@ -211,7 +213,8 @@ int sanity_check_raw_super(struct f2fs_super_block *raw_super)
return -1;
}
- if (F2FS_LOG_SECTORS_PER_BLOCK != le32_to_cpu(raw_super->log_sectors_per_block)) {
+ if (F2FS_LOG_SECTORS_PER_BLOCK !=
+ le32_to_cpu(raw_super->log_sectors_per_block)) {
return -1;
}
@@ -230,7 +233,7 @@ int validate_super_block(struct f2fs_sb_info *sbi, int block)
return 0;
free(sbi->raw_super);
- MSG(0, "\tCan't find a valid F2FS filesystem in %d superblock\n", block);
+ MSG(0, "\tCan't find a valid F2FS superblock at 0x%x\n", block);
return -EINVAL;
}
@@ -258,7 +261,8 @@ int init_sb_info(struct f2fs_sb_info *sbi)
return 0;
}
-void *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr, unsigned long long *version)
+void *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr,
+ unsigned long long *version)
{
void *cp_page_1, *cp_page_2;
struct f2fs_checkpoint *cp_block;
@@ -360,7 +364,8 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
cp_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
if (cur_page == cp2)
- cp_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg);
+ cp_blk_no += 1 <<
+ le32_to_cpu(raw_sb->log_blocks_per_seg);
/* copy sit bitmap */
for (i = 1; i < cp_blks; i++) {
unsigned char *ckpt = (unsigned char *)sbi->ckpt;
@@ -515,7 +520,8 @@ int read_compacted_summaries(struct f2fs_sb_info *sbi)
memcpy(&curseg->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE);
curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
- memcpy(&curseg->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE, SUM_JOURNAL_SIZE);
+ memcpy(&curseg->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE,
+ SUM_JOURNAL_SIZE);
offset = 2 * SUM_JOURNAL_SIZE;
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
@@ -538,7 +544,8 @@ int read_compacted_summaries(struct f2fs_sb_info *sbi)
s = (struct f2fs_summary *)(kaddr + offset);
curseg->sum_blk->entries[j] = *s;
offset += SUMMARY_SIZE;
- if (offset + SUMMARY_SIZE <= PAGE_CACHE_SIZE - SUM_FOOTER_SIZE)
+ if (offset + SUMMARY_SIZE <=
+ PAGE_CACHE_SIZE - SUM_FOOTER_SIZE)
continue;
memset(kaddr, 0, PAGE_SIZE);
dev_read_block(kaddr, start++);
@@ -597,18 +604,22 @@ int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
if (IS_DATASEG(type)) {
segno = le32_to_cpu(ckpt->cur_data_segno[type]);
- blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - CURSEG_HOT_DATA]);
+ blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
+ CURSEG_HOT_DATA]);
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
else
blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
} else {
- segno = le32_to_cpu(ckpt->cur_node_segno[type - CURSEG_HOT_NODE]);
- blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - CURSEG_HOT_NODE]);
+ segno = le32_to_cpu(ckpt->cur_node_segno[type -
+ CURSEG_HOT_NODE]);
+ blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type -
+ CURSEG_HOT_NODE]);
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
- blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, type - CURSEG_HOT_NODE);
+ blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
+ type - CURSEG_HOT_NODE);
else
blk_addr = GET_SUM_BLKADDR(sbi, segno);
}
@@ -688,7 +699,8 @@ inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
ASSERT(segno <= end_segno);
}
-struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi, unsigned int segno)
+struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi,
+ unsigned int segno)
{
struct sit_info *sit_i = SIT_I(sbi);
unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
@@ -746,7 +758,8 @@ struct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi,
return &sit_i->sentries[segno];
}
-int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summary_block *sum_blk)
+int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno,
+ struct f2fs_summary_block *sum_blk)
{
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct curseg_info *curseg;
@@ -758,7 +771,8 @@ int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summ
if (segno == ckpt->cur_node_segno[type]) {
curseg = CURSEG_I(sbi, CURSEG_HOT_NODE + type);
memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
- return SEG_TYPE_CUR_NODE; /* current node seg was not stored */
+ /* current node seg was not stored */
+ return SEG_TYPE_CUR_NODE;
}
}
@@ -767,8 +781,10 @@ int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summ
curseg = CURSEG_I(sbi, type);
memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
ASSERT(!IS_SUM_NODE_SEG(sum_blk->footer));
- DBG(2, "segno [0x%x] is current data seg[0x%x]\n", segno, type);
- return SEG_TYPE_CUR_DATA; /* current data seg was not stored */
+ DBG(2, "segno [0x%x] is current data seg[0x%x]\n",
+ segno, type);
+ /* current data seg was not stored */
+ return SEG_TYPE_CUR_DATA;
}
}
@@ -782,7 +798,8 @@ int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summ
}
-int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *sum_entry)
+int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr,
+ struct f2fs_summary *sum_entry)
{
struct f2fs_summary_block *sum_blk;
u32 segno, offset;
@@ -795,8 +812,8 @@ int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *s
ret = get_sum_block(sbi, segno, sum_blk);
- memcpy(sum_entry, &(sum_blk->entries[offset]), sizeof(struct f2fs_summary));
-
+ memcpy(sum_entry, &(sum_blk->entries[offset]),
+ sizeof(struct f2fs_summary));
free(sum_blk);
return ret;
}
@@ -955,12 +972,14 @@ int build_sit_area_bitmap(struct f2fs_sb_info *sbi)
fsck->chk.sit_valid_blocks = sum_vblocks;
fsck->chk.sit_free_segs = free_segs;
- DBG(1, "Blocks [0x%x : %d] Free Segs [0x%x : %d]\n\n", sum_vblocks, sum_vblocks,
+ DBG(1, "Blocks [0x%x : %d] Free Segs [0x%x : %d]\n\n",
+ sum_vblocks, sum_vblocks,
free_segs, free_segs);
return 0;
}
-int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_nat_entry *raw_nat)
+int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
+ struct f2fs_nat_entry *raw_nat)
{
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
struct f2fs_summary_block *sum = curseg->sum_blk;
@@ -968,7 +987,8 @@ int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_nat_ent
for (i = 0; i < nats_in_cursum(sum); i++) {
if (le32_to_cpu(nid_in_journal(sum, i)) == nid) {
- memcpy(raw_nat, &nat_in_journal(sum, i), sizeof(struct f2fs_nat_entry));
+ memcpy(raw_nat, &nat_in_journal(sum, i),
+ sizeof(struct f2fs_nat_entry));
DBG(3, "==> Found nid [0x%x] in nat cache\n", nid);
return i;
}
@@ -994,7 +1014,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
/* Alloc & build nat entry bitmap */
- nr_nat_blks = (le32_to_cpu(raw_sb->segment_count_nat) / 2) << sbi->log_blocks_per_seg;
+ nr_nat_blks = (le32_to_cpu(raw_sb->segment_count_nat) / 2) <<
+ sbi->log_blocks_per_seg;
fsck->nr_nat_entries = nr_nat_blks * NAT_ENTRY_PER_BLOCK;
fsck->nat_area_bitmap_sz = (fsck->nr_nat_entries + 7) / 8;
@@ -1005,8 +1026,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
seg_off = block_off >> sbi->log_blocks_per_seg;
block_addr = (pgoff_t)(nm_i->nat_blkaddr +
- (seg_off << sbi->log_blocks_per_seg << 1) +
- (block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
+ (seg_off << sbi->log_blocks_per_seg << 1) +
+ (block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
block_addr += sbi->blocks_per_seg;
@@ -1026,34 +1047,35 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
continue;
}
- if (lookup_nat_in_journal(sbi, nid + i, &raw_nat) >= 0) {
+ if (lookup_nat_in_journal(sbi, nid + i,
+ &raw_nat) >= 0) {
node_info_from_raw_nat(&ni, &raw_nat);
if (ni.blk_addr != 0x0) {
- f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
+ f2fs_set_bit(nid + i,
+ fsck->nat_area_bitmap);
fsck->chk.valid_nat_entry_cnt++;
- DBG(3, "nid[0x%x] in nat cache\n", nid + i);
+ DBG(3, "nid[0x%x] in nat cache\n",
+ nid + i);
}
} else {
- node_info_from_raw_nat(&ni, &nat_block->entries[i]);
- if (ni.blk_addr != 0) {
- ASSERT(nid + i != 0x0);
-
- DBG(3, "nid[0x%8x] in nat entry [0x%16x] [0x%8x]\n",
- nid + i,
- ni.blk_addr,
- ni.ino);
-
- f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
- fsck->chk.valid_nat_entry_cnt++;
- }
+ node_info_from_raw_nat(&ni,
+ &nat_block->entries[i]);
+ if (ni.blk_addr == 0)
+ continue;
+ ASSERT(nid + i != 0x0);
+
+ DBG(3, "nid[0x%8x] addr[0x%16x] ino[0x%8x]\n",
+ nid + i, ni.blk_addr, ni.ino);
+ f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
+ fsck->chk.valid_nat_entry_cnt++;
}
}
}
free(nat_block);
DBG(1, "valid nat entries (block_addr != 0x0) [0x%8x : %u]\n",
- fsck->chk.valid_nat_entry_cnt, fsck->chk.valid_nat_entry_cnt);
-
+ fsck->chk.valid_nat_entry_cnt,
+ fsck->chk.valid_nat_entry_cnt);
}
int f2fs_do_mount(struct f2fs_sb_info *sbi)
@@ -1085,9 +1107,11 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
print_ckpt_info(sbi);
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);
+ sbi->total_valid_inode_count =
+ le32_to_cpu(sbi->ckpt->valid_inode_count);
sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);
- sbi->total_valid_block_count = le64_to_cpu(sbi->ckpt->valid_block_count);
+ sbi->total_valid_block_count =
+ le64_to_cpu(sbi->ckpt->valid_block_count);
sbi->last_valid_block_count = sbi->total_valid_block_count;
sbi->alloc_valid_block_count = 0;
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/17] fsck.f2fs: give a chance to recover sit entries
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (5 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 07/17] fsck.f2fs: cleanup mount.c Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 09/17] fsck.f2fs: fix inode block inconsistency Jaegeuk Kim
` (8 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
This patch skips initial verfication on SIT entries, which checks the number of
valid blocks from its bitmap.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 2 +-
fsck/fsck.h | 2 +-
fsck/mount.c | 39 +++++++++++++--------------------------
3 files changed, 15 insertions(+), 28 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 9ebe2be..49d9ccc 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -634,7 +634,7 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
is_valid_ssa_data_blk(sbi, blk_addr, parent_nid, idx_in_node, ver);
if (f2fs_test_sit_bitmap(sbi, blk_addr) == 0)
- ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]\n", blk_addr);
+ ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", blk_addr);
if (f2fs_test_main_bitmap(sbi, blk_addr) != 0)
ASSERT_MSG("Duplicated data [0x%x]. pnid[0x%x] idx[0x%x]",
diff --git a/fsck/fsck.h b/fsck/fsck.h
index aecfa9a..a3f03fd 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -102,7 +102,7 @@ extern int get_sum_block(struct f2fs_sb_info *, unsigned int,
extern int get_sum_entry(struct f2fs_sb_info *, u32, struct f2fs_summary *);
extern void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
extern void build_nat_area_bitmap(struct f2fs_sb_info *);
-extern int build_sit_area_bitmap(struct f2fs_sb_info *);
+extern void build_sit_area_bitmap(struct f2fs_sb_info *);
extern void fsck_init(struct f2fs_sb_info *);
extern int fsck_verify(struct f2fs_sb_info *);
extern void fsck_free(struct f2fs_sb_info *);
diff --git a/fsck/mount.c b/fsck/mount.c
index b0dd5c7..4880848 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -726,18 +726,22 @@ void check_block_count(struct f2fs_sb_info *sbi,
int valid_blocks = 0;
unsigned int i;
-
/* check segment usage */
- ASSERT(GET_SIT_VBLOCKS(raw_sit) <= sbi->blocks_per_seg);
+ if (GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg)
+ ASSERT_MSG("Invalid SIT vblocks: segno=0x%x, %u",
+ segno, GET_SIT_VBLOCKS(raw_sit));
/* check boundary of a given segment number */
- ASSERT(segno <= end_segno);
+ if (segno > end_segno)
+ ASSERT_MSG("Invalid SEGNO: 0x%x", segno);
/* check bitmap with valid block count */
- for (i = 0; i < sbi->blocks_per_seg; i++)
- if (f2fs_test_bit(i, (char *)raw_sit->valid_map))
- valid_blocks++;
- ASSERT(GET_SIT_VBLOCKS(raw_sit) == valid_blocks);
+ for (i = 0; i < SIT_VBLOCK_MAP_SIZE; i++)
+ valid_blocks += get_bits_in_byte(raw_sit->valid_map[i]);
+
+ if (GET_SIT_VBLOCKS(raw_sit) != valid_blocks)
+ ASSERT_MSG("Wrong SIT valid blocks: segno=0x%x, %u vs. %u",
+ segno, GET_SIT_VBLOCKS(raw_sit), valid_blocks);
}
void seg_info_from_raw_sit(struct seg_entry *se,
@@ -918,18 +922,14 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
return 0;
}
-int build_sit_area_bitmap(struct f2fs_sb_info *sbi)
+void build_sit_area_bitmap(struct f2fs_sb_info *sbi)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct f2fs_sm_info *sm_i = SM_I(sbi);
unsigned int segno = 0;
- int j = 0;
char *ptr = NULL;
-
u32 sum_vblocks = 0;
u32 free_segs = 0;
- u32 vblocks = 0;
-
struct seg_entry *se;
fsck->sit_area_bitmap_sz = sm_i->main_segments * SIT_VBLOCK_MAP_SIZE;
@@ -938,20 +938,13 @@ int build_sit_area_bitmap(struct f2fs_sb_info *sbi)
ASSERT(fsck->sit_area_bitmap_sz == fsck->main_area_bitmap_sz);
- for (segno = 0; segno < sm_i->main_segments; segno++) {
+ for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
se = get_seg_entry(sbi, segno);
memcpy(ptr, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
ptr += SIT_VBLOCK_MAP_SIZE;
- vblocks = 0;
- for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) {
- vblocks += get_bits_in_byte(se->cur_valid_map[j]);
- }
- ASSERT(vblocks == se->valid_blocks);
-
if (se->valid_blocks == 0x0) {
-
if (sbi->ckpt->cur_node_segno[0] == segno ||
sbi->ckpt->cur_data_segno[0] == segno ||
sbi->ckpt->cur_node_segno[1] == segno ||
@@ -962,20 +955,16 @@ int build_sit_area_bitmap(struct f2fs_sb_info *sbi)
} else {
free_segs++;
}
-
} else {
- ASSERT(se->valid_blocks <= 512);
sum_vblocks += se->valid_blocks;
}
}
-
fsck->chk.sit_valid_blocks = sum_vblocks;
fsck->chk.sit_free_segs = free_segs;
DBG(1, "Blocks [0x%x : %d] Free Segs [0x%x : %d]\n\n",
sum_vblocks, sum_vblocks,
free_segs, free_segs);
- return 0;
}
int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
@@ -1003,14 +992,12 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct f2fs_nat_block *nat_block;
u32 nid, nr_nat_blks;
-
pgoff_t block_off;
pgoff_t block_addr;
int seg_off;
int ret;
unsigned int i;
-
nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
/* Alloc & build nat entry bitmap */
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/17] fsck.f2fs: fix inode block inconsistency
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (6 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 08/17] fsck.f2fs: give a chance to recover sit entries Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 10/17] fsck.f2fs: add fixing messeages Jaegeuk Kim
` (7 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
This patch is to fix inode block inconsistency such as iblocks and ilinks.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 61 +++++++++++++++++++++++++++++++++----------------------
include/f2fs_fs.h | 1 +
lib/libf2fs_io.c | 5 +++++
3 files changed, 43 insertions(+), 24 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 49d9ccc..17cf29b 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -319,6 +319,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
u32 i_links = le32_to_cpu(node_blk->i.i_links);
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
unsigned int idx = 0;
+ int need_fix = 0;
int ret;
if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0)
@@ -339,8 +340,11 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
if (find_and_dec_hard_link_list(sbi, nid)) {
ASSERT_MSG("[0x%x] needs more i_links=0x%x",
nid, i_links);
- if (config.fix_cnt)
- printf("TODO: i_links++\n");
+ if (config.fix_cnt) {
+ node_blk->i.i_links =
+ cpu_to_le32(i_links + 1);
+ need_fix = 1;
+ }
}
/* No need to go deep into the node */
return;
@@ -366,8 +370,12 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
&child_cnt, &child_files,
(i_blocks == *blk_cnt),
ftype, nid, idx, ni->version);
- if (!ret)
+ if (!ret) {
*blk_cnt = *blk_cnt + 1;
+ } else if (config.fix_cnt) {
+ node_blk->i.i_addr[idx] = 0;
+ need_fix = 1;
+ }
}
}
@@ -386,10 +394,12 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
ret = fsck_chk_node_blk(sbi, &node_blk->i,
le32_to_cpu(node_blk->i.i_nid[idx]),
ftype, ntype, blk_cnt);
- if (!ret)
+ if (!ret) {
*blk_cnt = *blk_cnt + 1;
- else if (config.fix_cnt)
- printf("TODO delete i_nid[idx] = 0;\n");
+ } else if (config.fix_cnt) {
+ node_blk->i.i_nid[idx] = 0;
+ need_fix = 1;
+ }
}
}
check:
@@ -404,28 +414,31 @@ check:
le32_to_cpu(node_blk->footer.ino),
node_blk->i.i_name,
(u32)i_blocks);
- if ((ftype == F2FS_FT_DIR && i_links != child_cnt) ||
- (i_blocks != *blk_cnt)) {
- if (!config.fix_cnt)
- print_node_info(node_blk);
-
- /* node_blk, ni.blkaddr, child_cnt, *blk_cnt */
- if (config.fix_cnt)
- printf("TODO fix_inode_block\n");
- else
- print_node_info(node_blk);
- DBG(1, "blk cnt [0x%x]\n", *blk_cnt);
- DBG(1, "child cnt [0x%x]\n", child_cnt);
- }
- if (i_blocks != *blk_cnt)
+
+ if (i_blocks != *blk_cnt) {
ASSERT_MSG("ino: 0x%x has i_blocks: %lu, but has %u blocks",
- nid, i_blocks, *blk_cnt);
- if (ftype == F2FS_FT_DIR && i_links != child_cnt)
+ nid, i_blocks, *blk_cnt);
+ if (config.fix_cnt) {
+ node_blk->i.i_blocks = cpu_to_le64(*blk_cnt);
+ need_fix = 1;
+ }
+ }
+ if (ftype == F2FS_FT_DIR && i_links != child_cnt) {
ASSERT_MSG("ino: 0x%x has i_links: %u but real links: %u",
- nid, i_links, child_cnt);
+ nid, i_links, child_cnt);
+ if (config.fix_cnt) {
+ node_blk->i.i_links = cpu_to_le32(child_cnt);
+ need_fix = 1;
+ }
+ }
+
if (ftype == F2FS_FT_ORPHAN && i_links)
ASSERT_MSG("ino: 0x%x is orphan inode, but has i_links: %u",
- nid, i_links);
+ nid, i_links);
+ if (need_fix) {
+ ret = dev_write_block(node_blk, ni->blk_addr);
+ ASSERT(ret >= 0);
+ }
}
int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index c3cc2aa..3b75bff 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -676,6 +676,7 @@ extern void f2fs_finalize_device(struct f2fs_configuration *);
extern int dev_read(void *, __u64, size_t);
extern int dev_write(void *, __u64, size_t);
+extern int dev_write_block(void *, __u64);
extern int dev_write_dump(void *, __u64, size_t);
/* All bytes in the buffer must be 0 use dev_fill(). */
extern int dev_fill(void *, __u64, size_t);
diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c
index d5ced53..0c89ee4 100644
--- a/lib/libf2fs_io.c
+++ b/lib/libf2fs_io.c
@@ -46,6 +46,11 @@ int dev_write(void *buf, __u64 offset, size_t len)
return 0;
}
+int dev_write_block(void *buf, __u64 blk_addr)
+{
+ return dev_write(buf, blk_addr * F2FS_BLKSIZE, F2FS_BLKSIZE);
+}
+
int dev_write_dump(void *buf, __u64 offset, size_t len)
{
if (lseek64(config.dump_fd, (off64_t)offset, SEEK_SET) < 0)
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/17] fsck.f2fs: add fixing messeages
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (7 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 09/17] fsck.f2fs: fix inode block inconsistency Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 11/17] fsck.f2fs: remove dentry if its inode block is corrupted Jaegeuk Kim
` (6 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 9 +++++++++
include/f2fs_fs.h | 6 ++++++
2 files changed, 15 insertions(+)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 17cf29b..00f5b27 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -344,6 +344,9 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
node_blk->i.i_links =
cpu_to_le32(i_links + 1);
need_fix = 1;
+ FIX_MSG("File: 0x%x "
+ "i_links= 0x%x -> 0x%x",
+ nid, i_links, i_links + 1);
}
}
/* No need to go deep into the node */
@@ -375,6 +378,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
} else if (config.fix_cnt) {
node_blk->i.i_addr[idx] = 0;
need_fix = 1;
+ FIX_MSG("[0x%x] i_addr[%d] = 0", nid, idx);
}
}
}
@@ -399,6 +403,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
} else if (config.fix_cnt) {
node_blk->i.i_nid[idx] = 0;
need_fix = 1;
+ FIX_MSG("[0x%x] i_nid[%d] = 0", nid, idx);
}
}
}
@@ -421,6 +426,8 @@ check:
if (config.fix_cnt) {
node_blk->i.i_blocks = cpu_to_le64(*blk_cnt);
need_fix = 1;
+ FIX_MSG("[0x%x] i_blocks=0x%lx -> 0x%x",
+ nid, i_blocks, *blk_cnt);
}
}
if (ftype == F2FS_FT_DIR && i_links != child_cnt) {
@@ -429,6 +436,8 @@ check:
if (config.fix_cnt) {
node_blk->i.i_links = cpu_to_le32(child_cnt);
need_fix = 1;
+ FIX_MSG("Dir: 0x%x i_links= 0x%x -> 0x%x",
+ nid, i_links, child_cnt);
}
}
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 3b75bff..7242690 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -54,6 +54,12 @@ typedef unsigned long pgoff_t;
/*
* Debugging interfaces
*/
+#define FIX_MSG(fmt, ...) \
+ do { \
+ printf("[FIX] (%s:%4d) ", __func__, __LINE__); \
+ printf(" --> "fmt"\n", ##__VA_ARGS__); \
+ } while (0)
+
#define ASSERT_MSG(fmt, ...) \
do { \
printf("[ASSERT] (%s:%4d) ", __func__, __LINE__); \
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 11/17] fsck.f2fs: remove dentry if its inode block is corrupted
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (8 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 10/17] fsck.f2fs: add fixing messeages Jaegeuk Kim
@ 2014-08-30 0:28 ` Jaegeuk Kim
2014-08-30 0:28 ` [PATCH 12/17] fsck.f2fs: corrupted orphan inode will be removed Jaegeuk Kim
` (5 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 00f5b27..2a47b4c 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -617,8 +617,21 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
TYPE_INODE,
&blk_cnt);
- if (ret)
- printf("TODO: delete dentry\n");
+ if (ret && config.fix_cnt) {
+ int j;
+ int slots = (name_len + F2FS_SLOT_LEN - 1) /
+ F2FS_SLOT_LEN;
+ for (j = 0; j < slots; j++)
+ clear_bit(i + j,
+ (unsigned long *)de_blk->dentry_bitmap);
+ FIX_MSG("Unlink [0x%x] - %s len[0x%x], type[0x%x]",
+ le32_to_cpu(de_blk->dentry[i].ino),
+ name, name_len,
+ de_blk->dentry[i].file_type);
+ i += slots;
+ free(name);
+ continue;
+ }
i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN;
dentries++;
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 12/17] fsck.f2fs: corrupted orphan inode will be removed
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (9 preceding siblings ...)
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 ` Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 13/17] fsck.f2fs: remove corrupted xattr block Jaegeuk Kim
` (4 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:28 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 2a47b4c..914dcb9 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -712,10 +712,8 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
DBG(1, "[%3d] ino [0x%x]\n", i, ino);
blk_cnt = 1;
- ret = fsck_chk_node_blk(sbi, NULL, ino,
+ fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
- if (ret == -EINVAL)
- printf("TODO: nothing?\n");
}
memset(orphan_blk, 0, BLOCK_SZ);
}
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 13/17] fsck.f2fs: remove corrupted xattr block
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (10 preceding siblings ...)
2014-08-30 0:28 ` [PATCH 12/17] fsck.f2fs: corrupted orphan inode will be removed Jaegeuk Kim
@ 2014-08-30 0:29 ` Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 14/17] fsck.f2fs: handle correctly segment summary entries Jaegeuk Kim
` (3 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:29 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 65 ++++++++++++++++++++++++++++++++++---------------------------
fsck/fsck.h | 1 -
2 files changed, 36 insertions(+), 30 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 914dcb9..53a64b7 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -266,6 +266,34 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
return 0;
}
+static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
+ u32 x_nid, u32 *blk_cnt)
+{
+ struct f2fs_node *node_blk = NULL;
+ struct node_info ni;
+ int ret = 0;
+
+ if (x_nid == 0x0)
+ return 0;
+
+ node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
+ ASSERT(node_blk != NULL);
+
+ /* Sanity check */
+ if (sanity_check_nid(sbi, x_nid, node_blk,
+ F2FS_FT_XATTR, TYPE_XATTR, &ni)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ *blk_cnt = *blk_cnt + 1;
+ f2fs_set_main_bitmap(sbi, ni.blk_addr);
+ DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid);
+out:
+ free(node_blk);
+ return ret;
+}
+
int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
u32 nid, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
u32 *blk_cnt)
@@ -354,8 +382,14 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
}
}
- fsck_chk_xattr_blk(sbi, nid,
- le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt);
+ if (fsck_chk_xattr_blk(sbi, nid,
+ le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt) &&
+ config.fix_cnt) {
+ node_blk->i.i_xattr_nid = 0;
+ need_fix = 1;
+ FIX_MSG("Remove xattr block: 0x%x, x_nid = 0x%x",
+ nid, le32_to_cpu(node_blk->i.i_xattr_nid));
+ }
if (ftype == F2FS_FT_CHRDEV || ftype == F2FS_FT_BLKDEV ||
ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK)
@@ -720,33 +754,6 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
free(orphan_blk);
}
-void fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
- u32 x_nid, u32 *blk_cnt)
-{
- struct f2fs_node *node_blk = NULL;
- struct node_info ni;
-
- if (x_nid == 0x0)
- return;
-
- node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
- ASSERT(node_blk != NULL);
-
- /* Sanity check */
- if (sanity_check_nid(sbi, x_nid, node_blk,
- F2FS_FT_XATTR, TYPE_XATTR, &ni)) {
- /* TODO: drop xattr node */
- printf("drop xattr node\n");
- goto out;
- }
-
- *blk_cnt = *blk_cnt + 1;
- f2fs_set_main_bitmap(sbi, ni.blk_addr);
- DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid);
-out:
- free(node_blk);
-}
-
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 a3f03fd..85cc931 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -77,7 +77,6 @@ enum seg_type {
SEG_TYPE_MAX,
};
-extern void fsck_chk_xattr_blk(struct f2fs_sb_info *, u32, u32, u32 *);
extern void fsck_chk_orphan_node(struct f2fs_sb_info *);
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
enum FILE_TYPE, enum NODE_TYPE, u32 *);
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 14/17] fsck.f2fs: handle correctly segment summary entries
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (11 preceding siblings ...)
2014-08-30 0:29 ` [PATCH 13/17] fsck.f2fs: remove corrupted xattr block Jaegeuk Kim
@ 2014-08-30 0:29 ` Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 15/17] fsck.f2fs: fix checkpoint Jaegeuk Kim
` (2 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:29 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/fsck.c | 58 ++++++++++++++++--------------
fsck/mount.c | 113 ++++++++++++++++++++++++++---------------------------------
2 files changed, 80 insertions(+), 91 deletions(-)
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 53a64b7..0a76c19 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -114,34 +114,28 @@ static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid,
struct f2fs_summary sum_entry;
ret = get_sum_entry(sbi, blk_addr, &sum_entry);
- ASSERT(ret >= 0);
- if (ret == SEG_TYPE_DATA || ret == SEG_TYPE_CUR_DATA) {
- ASSERT_MSG("Summary footer is not for node segment\n");
- } else if (ret == SEG_TYPE_NODE) {
- if (le32_to_cpu(sum_entry.nid) != nid) {
- DBG(0, "nid [0x%x]\n", nid);
- DBG(0, "target blk_addr [0x%x]\n", blk_addr);
- DBG(0, "summary blk_addr [0x%x]\n",
+ if (ret != SEG_TYPE_NODE && ret != SEG_TYPE_CUR_NODE) {
+ ASSERT_MSG("Summary footer is not for node segment");
+ return -EINVAL;
+ }
+
+ if (le32_to_cpu(sum_entry.nid) != nid) {
+ DBG(0, "nid [0x%x]\n", nid);
+ DBG(0, "target blk_addr [0x%x]\n", blk_addr);
+ DBG(0, "summary blk_addr [0x%x]\n",
GET_SUM_BLKADDR(sbi,
- GET_SEGNO(sbi, blk_addr)));
- DBG(0, "seg no / offset [0x%x / 0x%x]\n",
+ GET_SEGNO(sbi, blk_addr)));
+ DBG(0, "seg no / offset [0x%x / 0x%x]\n",
GET_SEGNO(sbi, blk_addr),
- OFFSET_IN_SEG(sbi, blk_addr));
- DBG(0, "summary_entry.nid [0x%x]\n",
+ OFFSET_IN_SEG(sbi, blk_addr));
+ DBG(0, "summary_entry.nid [0x%x]\n",
le32_to_cpu(sum_entry.nid));
- DBG(0, "--> node block's nid [0x%x]\n", nid);
- ASSERT_MSG("Invalid node seg summary\n");
- return -EINVAL;
- }
- return 0;
- } else if (ret == SEG_TYPE_CUR_NODE) {
- /* current node segment has no ssa */
- return 0;
- } else {
- ASSERT_MSG("Invalid return value of 'get_sum_entry'");
+ DBG(0, "--> node block's nid [0x%x]\n", nid);
+ ASSERT_MSG("Invalid node seg summary\n");
+ return -EINVAL;
}
- return -EINVAL;
+ return 0;
}
static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
@@ -151,7 +145,11 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
struct f2fs_summary sum_entry;
ret = get_sum_entry(sbi, blk_addr, &sum_entry);
- ASSERT(ret == SEG_TYPE_DATA || ret == SEG_TYPE_CUR_DATA);
+
+ if (ret != SEG_TYPE_DATA && ret != SEG_TYPE_CUR_DATA) {
+ ASSERT_MSG("Summary footer is not for data segment");
+ return -EINVAL;
+ }
if (le32_to_cpu(sum_entry.nid) != parent_nid ||
sum_entry.version != version ||
@@ -169,8 +167,9 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
DBG(0, "Target data block addr [0x%x]\n", blk_addr);
ASSERT_MSG("Invalid data seg summary\n");
+ return -EINVAL;
}
- return 1;
+ return 0;
}
static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
@@ -697,10 +696,15 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
if (!IS_VALID_BLK_ADDR(sbi, blk_addr)) {
ASSERT_MSG("blkaddres is not valid. [0x%x]", blk_addr);
- return 0;
+ return -EINVAL;
}
- is_valid_ssa_data_blk(sbi, blk_addr, parent_nid, idx_in_node, ver);
+ if (is_valid_ssa_data_blk(sbi, blk_addr, parent_nid,
+ idx_in_node, ver)) {
+ ASSERT_MSG("summary data block is not valid. [0x%x]",
+ parent_nid);
+ return -EINVAL;
+ }
if (f2fs_test_sit_bitmap(sbi, blk_addr) == 0)
ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", blk_addr);
diff --git a/fsck/mount.c b/fsck/mount.c
index 4880848..fb5b261 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -495,26 +495,35 @@ int build_sit_info(struct f2fs_sb_info *sbi)
void reset_curseg(struct f2fs_sb_info *sbi, int type)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
+ struct summary_footer *sum_footer;
curseg->segno = curseg->next_segno;
curseg->zone = GET_ZONENO_FROM_SEGNO(sbi, curseg->segno);
curseg->next_blkoff = 0;
curseg->next_segno = NULL_SEGNO;
+ sum_footer = &(curseg->sum_blk->footer);
+ memset(sum_footer, 0, sizeof(struct summary_footer));
+ if (IS_DATASEG(type))
+ SET_SUM_TYPE(sum_footer, SUM_TYPE_DATA);
+ if (IS_NODESEG(type))
+ SET_SUM_TYPE(sum_footer, SUM_TYPE_NODE);
}
-int read_compacted_summaries(struct f2fs_sb_info *sbi)
+static void read_compacted_summaries(struct f2fs_sb_info *sbi)
{
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct curseg_info *curseg;
+ unsigned int i, j, offset;
block_t start;
char *kaddr;
- unsigned int i, j, offset;
+ int ret;
start = start_sum_block(sbi);
kaddr = (char *)malloc(PAGE_SIZE);
- dev_read_block(kaddr, start++);
+ ret = dev_read_block(kaddr, start++);
+ ASSERT(ret >= 0);
curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
memcpy(&curseg->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE);
@@ -548,52 +557,40 @@ int read_compacted_summaries(struct f2fs_sb_info *sbi)
PAGE_CACHE_SIZE - SUM_FOOTER_SIZE)
continue;
memset(kaddr, 0, PAGE_SIZE);
- dev_read_block(kaddr, start++);
+ ret = dev_read_block(kaddr, start++);
+ ASSERT(ret >= 0);
offset = 0;
}
}
-
free(kaddr);
- return 0;
}
-int restore_node_summary(struct f2fs_sb_info *sbi,
+static void restore_node_summary(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_summary_block *sum_blk)
{
struct f2fs_node *node_blk;
struct f2fs_summary *sum_entry;
- void *page;
block_t addr;
unsigned int i;
+ int ret;
- page = malloc(PAGE_SIZE);
- if (!page)
- return -ENOMEM;
+ node_blk = malloc(F2FS_BLKSIZE);
+ ASSERT(node_blk);
/* scan the node segment */
addr = START_BLOCK(sbi, segno);
sum_entry = &sum_blk->entries[0];
for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
- if (dev_read_block(page, addr))
- goto out;
-
- node_blk = (struct f2fs_node *)page;
+ ret = dev_read_block(node_blk, addr);
+ ASSERT(ret >= 0);
sum_entry->nid = node_blk->footer.nid;
- /* do not change original value */
-#if 0
- sum_entry->version = 0;
- sum_entry->ofs_in_node = 0;
-#endif
addr++;
-
}
-out:
- free(page);
- return 0;
+ free(node_blk);
}
-int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
+static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
{
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct f2fs_summary_block *sum_blk;
@@ -601,6 +598,7 @@ int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
unsigned short blk_off;
unsigned int segno = 0;
block_t blk_addr = 0;
+ int ret;
if (IS_DATASEG(type)) {
segno = le32_to_cpu(ckpt->cur_data_segno[type]);
@@ -625,26 +623,11 @@ int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
}
sum_blk = (struct f2fs_summary_block *)malloc(PAGE_SIZE);
- dev_read_block(sum_blk, blk_addr);
-
- if (IS_NODESEG(type)) {
- if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) {
- struct f2fs_summary *sum_entry = &sum_blk->entries[0];
- unsigned int i;
- for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
- /* do not change original value */
-#if 0
- sum_entry->version = 0;
- sum_entry->ofs_in_node = 0;
-#endif
- }
- } else {
- if (restore_node_summary(sbi, segno, sum_blk)) {
- free(sum_blk);
- return -EINVAL;
- }
- }
- }
+ ret = dev_read_block(sum_blk, blk_addr);
+ ASSERT(ret >= 0);
+
+ if (IS_NODESEG(type) && !is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
+ restore_node_summary(sbi, segno, sum_blk);
curseg = CURSEG_I(sbi, type);
memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
@@ -653,44 +636,38 @@ int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
curseg->alloc_type = ckpt->alloc_type[type];
curseg->next_blkoff = blk_off;
free(sum_blk);
-
- return 0;
}
-int restore_curseg_summaries(struct f2fs_sb_info *sbi)
+static void restore_curseg_summaries(struct f2fs_sb_info *sbi)
{
int type = CURSEG_HOT_DATA;
if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) {
- if (read_compacted_summaries(sbi))
- return -EINVAL;
+ read_compacted_summaries(sbi);
type = CURSEG_HOT_NODE;
}
- for (; type <= CURSEG_COLD_NODE; type++) {
- if (read_normal_summaries(sbi, type))
- return -EINVAL;
- }
- return 0;
+ for (; type <= CURSEG_COLD_NODE; type++)
+ read_normal_summaries(sbi, type);
}
-int build_curseg(struct f2fs_sb_info *sbi)
+static void build_curseg(struct f2fs_sb_info *sbi)
{
struct curseg_info *array;
int i;
array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
+ ASSERT(array);
SM_I(sbi)->curseg_array = array;
for (i = 0; i < NR_CURSEG_TYPE; i++) {
array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
- if (!array[i].sum_blk)
- return -ENOMEM;
+ ASSERT(array[i].sum_blk);
array[i].segno = NULL_SEGNO;
array[i].next_blkoff = 0;
}
- return restore_curseg_summaries(sbi);
+ restore_curseg_summaries(sbi);
}
inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
@@ -774,8 +751,13 @@ int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno,
for (type = 0; type < NR_CURSEG_NODE_TYPE; type++) {
if (segno == ckpt->cur_node_segno[type]) {
curseg = CURSEG_I(sbi, CURSEG_HOT_NODE + type);
+ if (!IS_SUM_NODE_SEG(curseg->sum_blk->footer)) {
+ ASSERT_MSG("segno [0x%x] indicates a data "
+ "segment, but should be node",
+ segno);
+ return -EINVAL;
+ }
memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
- /* current node seg was not stored */
return SEG_TYPE_CUR_NODE;
}
}
@@ -783,11 +765,15 @@ int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno,
for (type = 0; type < NR_CURSEG_DATA_TYPE; type++) {
if (segno == ckpt->cur_data_segno[type]) {
curseg = CURSEG_I(sbi, type);
- memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
- ASSERT(!IS_SUM_NODE_SEG(sum_blk->footer));
+ if (IS_SUM_NODE_SEG(curseg->sum_blk->footer)) {
+ ASSERT_MSG("segno [0x%x] indicates a node "
+ "segment, but should be data",
+ segno);
+ return -EINVAL;
+ }
DBG(2, "segno [0x%x] is current data seg[0x%x]\n",
segno, type);
- /* current data seg was not stored */
+ memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
return SEG_TYPE_CUR_DATA;
}
}
@@ -815,7 +801,6 @@ int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr,
sum_blk = calloc(BLOCK_SZ, 1);
ret = get_sum_block(sbi, segno, sum_blk);
-
memcpy(sum_entry, &(sum_blk->entries[offset]),
sizeof(struct f2fs_summary));
free(sum_blk);
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 15/17] fsck.f2fs: fix checkpoint
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (12 preceding siblings ...)
2014-08-30 0:29 ` [PATCH 14/17] fsck.f2fs: handle correctly segment summary entries Jaegeuk Kim
@ 2014-08-30 0:29 ` 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
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:29 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
- fix nat entries
- fix sit entries
- fix checkpoint
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/f2fs.h | 1 +
fsck/fsck.c | 84 ++++++++++++++++++++++++++++++++++
fsck/fsck.h | 3 ++
fsck/mount.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 227 insertions(+), 5 deletions(-)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 2adffd8..8c31981 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -126,6 +126,7 @@ struct f2fs_sb_info {
struct f2fs_nm_info *nm_info;
struct f2fs_sm_info *sm_info;
struct f2fs_checkpoint *ckpt;
+ int cur_cp;
struct list_head orphan_inode_list;
unsigned int n_orphans;
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 0a76c19..8df489d 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -785,6 +785,64 @@ void fsck_init(struct f2fs_sb_info *sbi)
ASSERT(tree_mark != NULL);
}
+static void fix_nat_entries(struct f2fs_sb_info *sbi)
+{
+ struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+ int i;
+
+ for (i = 0; i < fsck->nr_nat_entries; i++)
+ if (f2fs_test_bit(i, fsck->nat_area_bitmap) != 0)
+ nullify_nat_entry(sbi, i);
+}
+
+static void fix_checkpoint(struct f2fs_sb_info *sbi)
+{
+ struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+ struct f2fs_super_block *raw_sb = sbi->raw_super;
+ struct f2fs_checkpoint *ckp = F2FS_CKPT(sbi);
+ unsigned long long cp_blk_no;
+ int i, ret;
+ u_int32_t crc = 0;
+
+ ckp->ckpt_flags = cpu_to_le32(CP_UMOUNT_FLAG);
+ ckp->cp_pack_total_block_count =
+ cpu_to_le32(8 + le32_to_cpu(raw_sb->cp_payload));
+ ckp->cp_pack_start_sum = cpu_to_le32(1 +
+ le32_to_cpu(raw_sb->cp_payload));
+
+ ckp->free_segment_count = cpu_to_le32(fsck->chk.free_segs);
+ ckp->valid_block_count = cpu_to_le32(fsck->chk.valid_blk_cnt);
+ ckp->valid_node_count = cpu_to_le32(fsck->chk.valid_node_cnt);
+ ckp->valid_inode_count = cpu_to_le32(fsck->chk.valid_inode_cnt);
+
+ crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, CHECKSUM_OFFSET);
+ *((__le32 *)((unsigned char *)ckp + CHECKSUM_OFFSET)) =
+ cpu_to_le32(crc);
+
+ cp_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
+ if (sbi->cur_cp == 2)
+ cp_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg);
+
+ ret = dev_write_block(ckp, cp_blk_no++);
+ ASSERT(ret >= 0);
+
+ for (i = 0; i < le32_to_cpu(raw_sb->cp_payload); i++) {
+ ret = dev_write_block(((unsigned char *)ckp) + i * F2FS_BLKSIZE,
+ cp_blk_no++);
+ ASSERT(ret >= 0);
+ }
+
+ for (i = 0; i < NO_CHECK_TYPE; i++) {
+ struct curseg_info *curseg = CURSEG_I(sbi, i);
+
+ ret = dev_write_block(curseg->sum_blk, cp_blk_no++);
+ ASSERT(ret >= 0);
+ }
+
+ ret = dev_write_block(ckp, cp_blk_no++);
+ ASSERT(ret >= 0);
+}
+
int fsck_verify(struct f2fs_sb_info *sbi)
{
unsigned int i = 0;
@@ -875,6 +933,32 @@ int fsck_verify(struct f2fs_sb_info *sbi)
ret = EXIT_ERR_CODE;
config.bug_on = 1;
}
+
+ printf("[FSCK] free segment_count matched with CP ");
+ if (le32_to_cpu(F2FS_CKPT(sbi)->free_segment_count) ==
+ fsck->chk.sit_free_segs) {
+ printf(" [Ok..] [0x%x]\n", fsck->chk.sit_free_segs);
+ } else {
+ printf(" [Fail] [0x%x]\n", fsck->chk.sit_free_segs);
+ ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
+ }
+
+ printf("[FSCK] other corrupted bugs ");
+ if (config.bug_on == 0) {
+ printf(" [Ok..]\n");
+ } else {
+ printf(" [Fail]\n");
+ ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
+ }
+
+ /* fix global metadata */
+ if (config.bug_on && config.fix_cnt) {
+ fix_nat_entries(sbi);
+ rewrite_sit_area_bitmap(sbi);
+ fix_checkpoint(sbi);
+ }
return ret;
}
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 85cc931..64b9984 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -31,6 +31,7 @@ struct f2fs_fsck {
u32 multi_hard_link_files;
u64 sit_valid_blocks;
u32 sit_free_segs;
+ u32 free_segs;
} chk;
struct hard_link_node *hard_link_list_head;
@@ -100,6 +101,8 @@ extern int get_sum_block(struct f2fs_sb_info *, unsigned int,
struct f2fs_summary_block *);
extern int get_sum_entry(struct f2fs_sb_info *, u32, struct f2fs_summary *);
extern void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
+extern void nullify_nat_entry(struct f2fs_sb_info *, u32);
+extern void rewrite_sit_area_bitmap(struct f2fs_sb_info *);
extern void build_nat_area_bitmap(struct f2fs_sb_info *);
extern void build_sit_area_bitmap(struct f2fs_sb_info *);
extern void fsck_init(struct f2fs_sb_info *);
diff --git a/fsck/mount.c b/fsck/mount.c
index fb5b261..a41320f 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -326,6 +326,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
unsigned long long cp1_version = 0, cp2_version = 0;
unsigned long long cp_start_blk_no;
unsigned int cp_blks = 1 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
+ int ret;
sbi->ckpt = malloc(cp_blks * blk_size);
if (!sbi->ckpt)
@@ -342,14 +343,19 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version);
if (cp1 && cp2) {
- if (ver_after(cp2_version, cp1_version))
+ if (ver_after(cp2_version, cp1_version)) {
cur_page = cp2;
- else
+ sbi->cur_cp = 2;
+ } else {
cur_page = cp1;
+ sbi->cur_cp = 1;
+ }
} else if (cp1) {
cur_page = cp1;
+ sbi->cur_cp = 1;
} else if (cp2) {
cur_page = cp2;
+ sbi->cur_cp = 2;
} else {
free(cp1);
free(cp2);
@@ -369,7 +375,8 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
/* copy sit bitmap */
for (i = 1; i < cp_blks; i++) {
unsigned char *ckpt = (unsigned char *)sbi->ckpt;
- dev_read_block(cur_page, cp_blk_no + i);
+ ret = dev_read_block(cur_page, cp_blk_no + i);
+ ASSERT(ret >= 0);
memcpy(ckpt + i * blk_size, cur_page, blk_size);
}
}
@@ -496,6 +503,7 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
struct summary_footer *sum_footer;
+ struct seg_entry *se;
curseg->segno = curseg->next_segno;
curseg->zone = GET_ZONENO_FROM_SEGNO(sbi, curseg->segno);
@@ -508,6 +516,8 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
SET_SUM_TYPE(sum_footer, SUM_TYPE_DATA);
if (IS_NODESEG(type))
SET_SUM_TYPE(sum_footer, SUM_TYPE_NODE);
+ se = get_seg_entry(sbi, curseg->segno);
+ se->type = type;
}
static void read_compacted_summaries(struct f2fs_sb_info *sbi)
@@ -676,13 +686,14 @@ inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
ASSERT(segno <= end_segno);
}
-struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi,
+static struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi,
unsigned int segno)
{
struct sit_info *sit_i = SIT_I(sbi);
unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
block_t blk_addr = sit_i->sit_base_addr + offset;
struct f2fs_sit_block *sit_blk = calloc(BLOCK_SZ, 1);
+ int ret;
check_seg_range(sbi, segno);
@@ -690,11 +701,28 @@ struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi,
if (f2fs_test_bit(offset, sit_i->sit_bitmap))
blk_addr += sit_i->sit_blocks;
- dev_read_block(sit_blk, blk_addr);
+ ret = dev_read_block(sit_blk, blk_addr);
+ ASSERT(ret >= 0);
return sit_blk;
}
+void rewrite_current_sit_page(struct f2fs_sb_info *sbi,
+ unsigned int segno, struct f2fs_sit_block *sit_blk)
+{
+ struct sit_info *sit_i = SIT_I(sbi);
+ unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
+ block_t blk_addr = sit_i->sit_base_addr + offset;
+ int ret;
+
+ /* calculate sit block address */
+ if (f2fs_test_bit(offset, sit_i->sit_bitmap))
+ blk_addr += sit_i->sit_blocks;
+
+ ret = dev_write_block(sit_blk, blk_addr);
+ ASSERT(ret >= 0);
+}
+
void check_block_count(struct f2fs_sb_info *sbi,
unsigned int segno, struct f2fs_sit_entry *raw_sit)
{
@@ -719,6 +747,10 @@ void check_block_count(struct f2fs_sb_info *sbi,
if (GET_SIT_VBLOCKS(raw_sit) != valid_blocks)
ASSERT_MSG("Wrong SIT valid blocks: segno=0x%x, %u vs. %u",
segno, GET_SIT_VBLOCKS(raw_sit), valid_blocks);
+
+ if (GET_SIT_TYPE(raw_sit) >= NO_CHECK_TYPE)
+ ASSERT_MSG("Wrong SIT type: segno=0x%x, %u",
+ segno, GET_SIT_TYPE(raw_sit));
}
void seg_info_from_raw_sit(struct seg_entry *se,
@@ -952,6 +984,62 @@ void build_sit_area_bitmap(struct f2fs_sb_info *sbi)
free_segs, free_segs);
}
+void rewrite_sit_area_bitmap(struct f2fs_sb_info *sbi)
+{
+ struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+ struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
+ struct sit_info *sit_i = SIT_I(sbi);
+ unsigned int segno = 0;
+ struct f2fs_summary_block *sum = curseg->sum_blk;
+ char *ptr = NULL;
+
+ /* remove sit journal */
+ sum->n_sits = 0;
+
+ fsck->chk.free_segs = 0;
+
+ ptr = fsck->main_area_bitmap;
+
+ for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
+ struct f2fs_sit_block *sit_blk;
+ struct f2fs_sit_entry *sit;
+ struct seg_entry *se;
+ u16 valid_blocks = 0;
+ u16 type;
+ int i;
+
+ sit_blk = get_current_sit_page(sbi, segno);
+ sit = &sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, segno)];
+ memcpy(sit->valid_map, ptr, SIT_VBLOCK_MAP_SIZE);
+
+ /* update valid block count */
+ for (i = 0; i < SIT_VBLOCK_MAP_SIZE; i++)
+ valid_blocks += get_bits_in_byte(sit->valid_map[i]);
+
+ se = get_seg_entry(sbi, segno);
+ type = se->type;
+ if (type >= NO_CHECK_TYPE) {
+ ASSERT(valid_blocks);
+ type = 0;
+ }
+ sit->vblocks = cpu_to_le16((type << SIT_VBLOCKS_SHIFT) |
+ valid_blocks);
+ rewrite_current_sit_page(sbi, segno, sit_blk);
+ free(sit_blk);
+
+ if (valid_blocks == 0 &&
+ sbi->ckpt->cur_node_segno[0] != segno &&
+ sbi->ckpt->cur_data_segno[0] != segno &&
+ sbi->ckpt->cur_node_segno[1] != segno &&
+ sbi->ckpt->cur_data_segno[1] != segno &&
+ sbi->ckpt->cur_node_segno[2] != segno &&
+ sbi->ckpt->cur_data_segno[2] != segno)
+ fsck->chk.free_segs++;
+
+ ptr += SIT_VBLOCK_MAP_SIZE;
+ }
+}
+
int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
struct f2fs_nat_entry *raw_nat)
{
@@ -970,6 +1058,51 @@ int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
return -1;
}
+void nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid)
+{
+ struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
+ struct f2fs_summary_block *sum = curseg->sum_blk;
+ struct f2fs_nm_info *nm_i = NM_I(sbi);
+ struct f2fs_nat_block *nat_block;
+ pgoff_t block_off;
+ pgoff_t block_addr;
+ int seg_off, entry_off;
+ int ret;
+ int i = 0;
+
+ /* check in journal */
+ for (i = 0; i < nats_in_cursum(sum); i++) {
+ if (le32_to_cpu(nid_in_journal(sum, i)) == nid) {
+ memset(&nat_in_journal(sum, i), 0,
+ sizeof(struct f2fs_nat_entry));
+ FIX_MSG("Remove nid [0x%x] in nat journal\n", nid);
+ return;
+ }
+ }
+ nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
+
+ block_off = nid / NAT_ENTRY_PER_BLOCK;
+ entry_off = nid % NAT_ENTRY_PER_BLOCK;
+
+ seg_off = block_off >> sbi->log_blocks_per_seg;
+ block_addr = (pgoff_t)(nm_i->nat_blkaddr +
+ (seg_off << sbi->log_blocks_per_seg << 1) +
+ (block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
+
+ if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
+ block_addr += sbi->blocks_per_seg;
+
+ ret = dev_read_block(nat_block, block_addr);
+ ASSERT(ret >= 0);
+
+ memset(&nat_block->entries[entry_off], 0,
+ sizeof(struct f2fs_nat_entry));
+
+ ret = dev_write_block(nat_block, block_addr);
+ ASSERT(ret >= 0);
+ free(nat_block);
+}
+
void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
@@ -984,6 +1117,7 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
unsigned int i;
nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
+ ASSERT(nat_block);
/* Alloc & build nat entry bitmap */
nr_nat_blks = (le32_to_cpu(raw_sb->segment_count_nat) / 2) <<
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 16/17] fsck.f2fs: check next block is free or not
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (13 preceding siblings ...)
2014-08-30 0:29 ` [PATCH 15/17] fsck.f2fs: fix checkpoint Jaegeuk Kim
@ 2014-08-30 0:29 ` Jaegeuk Kim
2014-08-30 0:29 ` [PATCH 17/17] fsck.f2fs: remove list.h Jaegeuk Kim
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:29 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
If block allocation is made to the next block offset, we should drop that
block.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/f2fs.h | 19 +++++++++++++++++--
fsck/fsck.c | 27 +++++++++++++++++++++++++++
fsck/mount.c | 46 +++++++++++++++++++++-------------------------
3 files changed, 65 insertions(+), 27 deletions(-)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 8c31981..f674ede 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -266,10 +266,15 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
#define GET_SEGNO_FROM_SEG0(sbi, blk_addr) \
(GET_SEGOFF_FROM_SEG0(sbi, blk_addr) >> sbi->log_blocks_per_seg)
-#define FREE_I_START_SEGNO(sbi) GET_SEGNO_FROM_SEG0(sbi, SM_I(sbi)->main_blkaddr)
+#define GET_BLKOFF_FROM_SEG0(sbi, blk_addr) \
+ (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (sbi->blocks_per_seg - 1))
+
+#define FREE_I_START_SEGNO(sbi) \
+ GET_SEGNO_FROM_SEG0(sbi, SM_I(sbi)->main_blkaddr)
#define GET_R2L_SEGNO(sbi, segno) (segno + FREE_I_START_SEGNO(sbi))
-#define START_BLOCK(sbi, segno) (SM_I(sbi)->main_blkaddr + (segno << sbi->log_blocks_per_seg))
+#define START_BLOCK(sbi, segno) (SM_I(sbi)->main_blkaddr + \
+ (segno << sbi->log_blocks_per_seg))
static inline struct curseg_info *CURSEG_I(struct f2fs_sb_info *sbi, int type)
{
@@ -311,6 +316,8 @@ static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid)
static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
{
+ int i;
+
if (addr >= F2FS_RAW_SUPER(sbi)->block_count ||
addr < SM_I(sbi)->main_blkaddr) {
DBG(0, "block addr [0x%x]\n", addr);
@@ -318,6 +325,14 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)
ASSERT(addr >= SM_I(sbi)->main_blkaddr);
return 0;
}
+
+ for (i = 0; i < NO_CHECK_TYPE; i++) {
+ struct curseg_info *curseg = CURSEG_I(sbi, i);
+
+ if (START_BLOCK(sbi, curseg->segno) +
+ curseg->next_blkoff == addr)
+ return 0;
+ }
return 1;
}
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 8df489d..560b541 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -843,6 +843,24 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)
ASSERT(ret >= 0);
}
+int check_curseg_offset(struct f2fs_sb_info *sbi)
+{
+ int i;
+
+ for (i = 0; i < NO_CHECK_TYPE; i++) {
+ struct curseg_info *curseg = CURSEG_I(sbi, i);
+ struct seg_entry *se;
+
+ se = get_seg_entry(sbi, curseg->segno);
+ if (f2fs_test_bit(curseg->next_blkoff,
+ (const char *)se->cur_valid_map) == 1) {
+ ASSERT_MSG("Next block offset is not free, type:%d", i);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
int fsck_verify(struct f2fs_sb_info *sbi)
{
unsigned int i = 0;
@@ -944,6 +962,15 @@ int fsck_verify(struct f2fs_sb_info *sbi)
config.bug_on = 1;
}
+ printf("[FSCK] next block offset is free ");
+ if (check_curseg_offset(sbi) == 0) {
+ printf(" [Ok..]\n");
+ } else {
+ printf(" [Fail]\n");
+ ret = EXIT_ERR_CODE;
+ config.bug_on = 1;
+ }
+
printf("[FSCK] other corrupted bugs ");
if (config.bug_on == 0) {
printf(" [Ok..]\n");
diff --git a/fsck/mount.c b/fsck/mount.c
index a41320f..2bbd3c5 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -505,11 +505,6 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
struct summary_footer *sum_footer;
struct seg_entry *se;
- curseg->segno = curseg->next_segno;
- curseg->zone = GET_ZONENO_FROM_SEGNO(sbi, curseg->segno);
- curseg->next_blkoff = 0;
- curseg->next_segno = NULL_SEGNO;
-
sum_footer = &(curseg->sum_blk->footer);
memset(sum_footer, 0, sizeof(struct summary_footer));
if (IS_DATASEG(type))
@@ -522,7 +517,6 @@ void reset_curseg(struct f2fs_sb_info *sbi, int type)
static void read_compacted_summaries(struct f2fs_sb_info *sbi)
{
- struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct curseg_info *curseg;
unsigned int i, j, offset;
block_t start;
@@ -545,18 +539,14 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
offset = 2 * SUM_JOURNAL_SIZE;
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
unsigned short blk_off;
- unsigned int segno;
+ struct curseg_info *curseg = CURSEG_I(sbi, i);
- curseg = CURSEG_I(sbi, i);
- segno = le32_to_cpu(ckpt->cur_data_segno[i]);
- blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
- curseg->next_segno = segno;
reset_curseg(sbi, i);
- curseg->alloc_type = ckpt->alloc_type[i];
- curseg->next_blkoff = blk_off;
if (curseg->alloc_type == SSR)
blk_off = sbi->blocks_per_seg;
+ else
+ blk_off = curseg->next_blkoff;
for (j = 0; j < blk_off; j++) {
struct f2fs_summary *s;
@@ -605,16 +595,12 @@ static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct f2fs_summary_block *sum_blk;
struct curseg_info *curseg;
- unsigned short blk_off;
unsigned int segno = 0;
block_t blk_addr = 0;
int ret;
if (IS_DATASEG(type)) {
segno = le32_to_cpu(ckpt->cur_data_segno[type]);
- blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
- CURSEG_HOT_DATA]);
-
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
else
@@ -622,9 +608,6 @@ static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
} else {
segno = le32_to_cpu(ckpt->cur_node_segno[type -
CURSEG_HOT_NODE]);
- blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type -
- CURSEG_HOT_NODE]);
-
if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
type - CURSEG_HOT_NODE);
@@ -641,10 +624,7 @@ static void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
curseg = CURSEG_I(sbi, type);
memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
- curseg->next_segno = segno;
reset_curseg(sbi, type);
- curseg->alloc_type = ckpt->alloc_type[type];
- curseg->next_blkoff = blk_off;
free(sum_blk);
}
@@ -663,7 +643,10 @@ static void restore_curseg_summaries(struct f2fs_sb_info *sbi)
static void build_curseg(struct f2fs_sb_info *sbi)
{
+ struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
struct curseg_info *array;
+ unsigned short blk_off;
+ unsigned int segno;
int i;
array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
@@ -674,8 +657,21 @@ static void build_curseg(struct f2fs_sb_info *sbi)
for (i = 0; i < NR_CURSEG_TYPE; i++) {
array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
ASSERT(array[i].sum_blk);
- array[i].segno = NULL_SEGNO;
- array[i].next_blkoff = 0;
+ if (i <= CURSEG_COLD_DATA) {
+ blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
+ segno = le32_to_cpu(ckpt->cur_data_segno[i]);
+ }
+ if (i > CURSEG_COLD_DATA) {
+ blk_off = le16_to_cpu(ckpt->cur_node_blkoff[i -
+ CURSEG_HOT_NODE]);
+ segno = le32_to_cpu(ckpt->cur_node_segno[i -
+ CURSEG_HOT_NODE]);
+ }
+ array[i].segno = segno;
+ array[i].zone = GET_ZONENO_FROM_SEGNO(sbi, segno);
+ array[i].next_segno = NULL_SEGNO;
+ array[i].next_blkoff = blk_off;
+ array[i].alloc_type = ckpt->alloc_type[i];
}
restore_curseg_summaries(sbi);
}
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 17/17] fsck.f2fs: remove list.h
2014-08-30 0:28 [PATCH 01/17] f2fs_dentry_hash: avoid casting unsigned char to singed char Jaegeuk Kim
` (14 preceding siblings ...)
2014-08-30 0:29 ` [PATCH 16/17] fsck.f2fs: check next block is free or not Jaegeuk Kim
@ 2014-08-30 0:29 ` Jaegeuk Kim
15 siblings, 0 replies; 17+ messages in thread
From: Jaegeuk Kim @ 2014-08-30 0:29 UTC (permalink / raw)
To: linux-f2fs-devel; +Cc: Jaegeuk Kim
Just use list_head only.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fsck/f2fs.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index f674ede..edb1480 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -26,7 +26,6 @@
#include <sys/mount.h>
#include <assert.h>
-#include <list.h>
#include <f2fs_fs.h>
#define EXIT_ERR_CODE (-1)
@@ -34,6 +33,10 @@
typecheck(unsigned long long, b) && \
((long long)((a) - (b)) > 0))
+struct list_head {
+ struct list_head *next, *prev;
+};
+
enum {
NAT_BITMAP,
SIT_BITMAP
--
1.8.5.2 (Apple Git-48)
------------------------------------------------------------------------------
Slashdot TV.
Video for Nerds. Stuff that matters.
http://tv.slashdot.org/
^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2014-08-30 0:30 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 02/17] fsck.f2fs: retry to fix corrupted image Jaegeuk Kim
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
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).