fsck.f2fs: attempt to identify bad dentries

If a dentry has a bad ino (fsck_chk_nod_blk() fails)
and has a name len of 0, then __chk_dentries() will end up stuck:

....
[__chk_dentries: 663] [  4]-[0x0] name[] len[0x0] ino[0x5f1710dc] type[0xd1]
[ASSERT] (sanity_check_nid: 184)  --> nid is not valid. [0x5f1710dc]
[__chk_dentries: 663] [  4]-[0x0] name[] len[0x0] ino[0x5f1710dc] type[0xd1]
[ASSERT] (sanity_check_nid: 184)  --> nid is not valid. [0x5f1710dc]
[__chk_dentries: 663] [  4]-[0x0] name[] len[0x0] ino[0x5f1710dc] type[0xd1]
[ASSERT] (sanity_check_nid: 184)  --> nid is not valid. [0x5f1710dc]
....

This change tries to identify bad dentries:
 - is the ino a valid NID?
 - is the FILE_TYPE a happy type?

Change-Id: I5fb2f3869c96f2c928baaace148de1af102e558e
Signed-off-by: JP Abgrall <jpa@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
JP Abgrall 2014-10-28 19:11:52 -07:00 committed by Jaegeuk Kim
parent 5007756839
commit 056e4b04fc
2 changed files with 24 additions and 3 deletions

View File

@ -629,7 +629,29 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt,
i++;
continue;
}
if (!IS_VALID_NID(sbi, le32_to_cpu(dentry[i].ino))) {
DBG(1, "Bad dentry 0x%x with invalid NID/ino 0x%x",
i, le32_to_cpu(dentry[i].ino));
if (config.fix_on) {
FIX_MSG("Clear bad dentry 0x%x with bad ino 0x%x",
i, le32_to_cpu(dentry[i].ino));
clear_bit(i, bitmap);
i++;
continue;
}
}
ftype = dentry[i].file_type;
if ((ftype <= F2FS_FT_UNKNOWN || ftype > F2FS_FT_LAST_FILE_TYPE) && config.fix_on) {
DBG(1, "Bad dentry 0x%x with unexpected ftype 0x%x",
i, ftype);
if (config.fix_on) {
FIX_MSG("Clear bad dentry 0x%x with bad ftype 0x%x",
i, ftype);
clear_bit(i, bitmap);
i++;
continue;
}
}
name_len = le16_to_cpu(dentry[i].name_len);
name = calloc(name_len + 1, 1);
memcpy(name, filenames[i], name_len);
@ -643,8 +665,6 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt,
FIX_MSG("hash_code[%d] of %s", i, name);
}
ftype = dentry[i].file_type;
/* Becareful. 'dentry.file_type' is not imode. */
if (ftype == F2FS_FT_DIR) {
*child_cnt = *child_cnt + 1;

View File

@ -731,6 +731,7 @@ enum FILE_TYPE {
/* added for fsck */
F2FS_FT_ORPHAN,
F2FS_FT_XATTR,
F2FS_FT_LAST_FILE_TYPE = F2FS_FT_XATTR,
};
/* from f2fs/segment.h */