diff options
author | Qu Wenruo <wqu@suse.com> | 2018-08-03 13:50:20 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-10-23 14:48:40 +0200 |
commit | b02b426a784cb327b13a15df752ca285652a45c4 (patch) | |
tree | d14eb6a51a9ebc7b8b5caff32c80ba7ef8445104 /btrfs-select-super.c | |
parent | 6dbc43b8670d03f7b87f7d3f056c3771b8865e48 (diff) |
btrfs-progs: fix infinite loop when bad key order repair fails
An infinite loop can be triggered during fuzz/003:
====== RUN MAYFAIL btrfs check --repair tests/fuzz-tests/images/bko-199833-reloc-recovery-crash.raw.restored
[1/7] checking root items
Fixed 0 roots.
[2/7] checking extents
ctree.c:1650: leaf_space_used: Warning: assertion `data_len < 0` failed, value 1
bad key ordering 18 19
ctree.c:1650: leaf_space_used: Warning: assertion `data_len < 0` failed, value 1
bad key ordering 18 19
ctree.c:1650: leaf_space_used: Warning: assertion `data_len < 0` failed, value 1
bad key ordering 18 19
[CAUSE]
In try_to_fix_bad_block() it's possible that btrfs_find_all_roots()
finds no root referring to that tree block, thus we can't do any repair.
However in that case, we still return 0 since the last caller assigning
@ret is btrfs_find_all_roots(), and the ulist while loop doesn't get run
at all.
And since try_to_fix_bad_block() returns 0, check_block() in
check/main.c will return -EAGAIN to re-check the tree block.
This leads to the infinite loop.
[FIX]
Change the default return value from 0 to -EIO in
try_to_fix_bad_block(), so if there is no tree referring to the bad tree
block, it won't cause infinite loop anymore.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'btrfs-select-super.c')
0 files changed, 0 insertions, 0 deletions