verify_dir_item() is called in btrfs_match_dir_item_name() to ensure we won't search beyond item boundary and does extra filetype check.
However in the follow call chain, such extra filetype check can cause problems: 1) btrfs_add_link() |- check_dir_conflict() |- btrfs_lookup_dir_index() |- btrfs_match_dir_item_name() And if we have an offending dir index whose filetype is invalid, btrfs_match_dir_item_name() will return NULL, meaning no match dir index is found. So btrfs_add_link() will still try to insert a dir index, which may have same key->offset and leading to duplicated dir index. 2) btrfs_unlink() |- btrfs_lookup_dir_index() |- btrfs_lookup_dir_index() |- btrfs_match_dir_item_name() For the same offending dir index with invalid filetype, this will return NULL, and btrfs_unlink() will just consider there is no existing dir_index and do nothing. Leave an orphan and invalid dir_index hanging there forever. The patch removes the extra filetype check, as "btrfs check" can already handle invalid filetype correctly for both modes. And this makes "btrfs check --repair --mode=lowmem" to delete the offending dir index to repair it correctly. Signed-off-by: Qu Wenruo <w...@suse.com> --- v2: Get rid of the new parameter. v2.1: Better commit message. --- dir-item.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dir-item.c b/dir-item.c index 462546c0eaf4..e0a0ab4d7a5d 100644 --- a/dir-item.c +++ b/dir-item.c @@ -294,12 +294,6 @@ static int verify_dir_item(struct btrfs_root *root, u16 namelen = BTRFS_NAME_LEN; u8 type = btrfs_dir_type(leaf, dir_item); - if (type >= BTRFS_FT_MAX) { - fprintf(stderr, "invalid dir item type: %d\n", - (int)type); - return 1; - } - if (type == BTRFS_FT_XATTR) namelen = XATTR_NAME_MAX; -- 2.15.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html