btrfs-progs/check
Qu Wenruo b02b426a78 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>
2018-10-23 14:48:40 +02:00
..
main.c btrfs-progs: fix infinite loop when bad key order repair fails 2018-10-23 14:48:40 +02:00
mode-common.c btrfs-progs: check: Initialize all filed of btrfs_inode_item in insert_inode_item() 2018-06-07 16:37:40 +02:00
mode-common.h btrfs-progs: check: enhanced progress indicator 2018-08-06 15:03:23 +02:00
mode-lowmem.c btrfs-progs: check: enhanced progress indicator 2018-08-06 15:03:23 +02:00
mode-lowmem.h btrfs-progs: check: lowmem: check symlinks with append/immutable flags 2018-06-07 16:37:38 +02:00
mode-original.h btrfs-progs: check/original: Detect and repair wrong inline ram_bytes 2018-08-06 15:00:44 +02:00