diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-03-27 13:32:17 -0700 |
---|---|---|
committer | Dan Pasanen <dan.pasanen@gmail.com> | 2015-11-12 09:37:22 -0600 |
commit | 89e4a169166c50794943a3970e7ee604e1d84d11 (patch) | |
tree | 09a39dfabeca5f84a4163bd68cb78edfde0d13e1 | |
parent | 3d94bd967aab181a86970d587c7a8800689d5906 (diff) | |
download | android_external_f2fs-tools-89e4a169166c50794943a3970e7ee604e1d84d11.tar.gz android_external_f2fs-tools-89e4a169166c50794943a3970e7ee604e1d84d11.tar.bz2 android_external_f2fs-tools-89e4a169166c50794943a3970e7ee604e1d84d11.zip |
fsck.f2fs: fix corrupted dentries
This patch fixes corrupted dentries such as name_len == 0.
Change-Id: I635949546eb35a0a1f2013b337ae858764e6dee7
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/fsck.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c index ecb18f2..debae1c 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -796,22 +796,24 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt, int i; /* readahead inode blocks */ - for (i = 0; i < max;) { - if (test_bit(i, bitmap) == 0) { - i++; + for (i = 0; i < max; i++) { + if (test_bit(i, bitmap) == 0) continue; - } + ino = le32_to_cpu(dentry[i].ino); if (IS_VALID_NID(sbi, ino)) { struct node_info ni; get_node_info(sbi, ino, &ni); - if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) + if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) { dev_reada_block(ni.blk_addr); + name_len = le16_to_cpu(dentry[i].name_len); + if (name_len > 0) + i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN - 1; + continue; + } } - name_len = le16_to_cpu(dentry[i].name_len); - i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; } for (i = 0; i < max;) { @@ -820,31 +822,44 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt, 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)); + ASSERT_MSG("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++; fixed = 1; - continue; } + 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 ((ftype <= F2FS_FT_UNKNOWN || ftype > F2FS_FT_LAST_FILE_TYPE)) { + ASSERT_MSG("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++; fixed = 1; - continue; } + i++; + continue; } + name_len = le16_to_cpu(dentry[i].name_len); + + if (name_len == 0) { + ASSERT_MSG("Bad dentry 0x%x with zero name_len", i); + if (config.fix_on) { + FIX_MSG("Clear bad dentry 0x%x", i); + clear_bit(i, bitmap); + fixed = 1; + } + i++; + continue; + } + name = calloc(name_len + 1, 1); memcpy(name, filenames[i], name_len); hash_code = f2fs_dentry_hash((const unsigned char *)name, |