diff options
author | Qu Wenruo <wqu@suse.com> | 2018-01-22 13:45:29 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-06-07 16:31:24 +0200 |
commit | 87103ff3412bcf1d6bddda2544f42da62243cc62 (patch) | |
tree | ad5824aa6136b940719860066b900ccfb19bd9e6 /dir-item.c | |
parent | a5f0e46ac37f0d8de88a7af8fbb541129d94c27c (diff) |
btrfs-progs: dir-item: Don't do extra filetype validation check for btrfs_match_dir_item_name
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 following 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 <wqu@suse.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'dir-item.c')
-rw-r--r-- | dir-item.c | 6 |
1 files changed, 0 insertions, 6 deletions
@@ -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; |