btrfs-progs/kernel-lib
Qu Wenruo 2aa4085bf7 btrfs-progs: properly handle degraded raid56 reads
[BUG]
For a degraded RAID5, btrfs check will fail to even read the chunk root:

  # mkfs.btrfs -f -m raid5 -d raid5 $dev1 $dev2 $dev3
  # wipefs -fa $dev1
  # btrfs check $dev2
  Opening filesystem to check...
  warning, device 1 is missing
  bad tree block 22036480, bytenr mismatch, want=22036480, have=0
  ERROR: cannot read chunk root
  ERROR: cannot open file system

[CAUSE]
Although read_tree_block() function from btrfs-progs is properly
iterating the mirrors (mirror 1 is reading from the disk directly,
mirror 2 will be rebuild from parity), the raid56 recovery path is not
handling the read error correctly.

The existing code will try to read the full stripe, but any read failure
(including missing device) will immediately cause an error:

	for (i = 0; i < num_stripes; i++) {
		ret = btrfs_pread(multi->stripes[i].dev->fd, pointers[i],
				  BTRFS_STRIPE_LEN, multi->stripes[i].physical,
				  fs_info->zoned);
		if (ret < BTRFS_STRIPE_LEN) {
			ret = -EIO;
			goto out;
		}
	}

[FIX]
To make failed_a/failed_b calculation much easier, and properly handle
too many missing devices, here this patch will introduce a new bitmap
based solution.

The new @failed_stripe_bitmap will represent all the failed stripes.

So the initial read will mark all the missing devices in the
@failed_stripe_bitmap, and later operations will all operate on that
bitmap.

Only before we call raid56_recov(), we convert the bitmap to the old
failed_a/failed_b interface and continue.

Now btrfs check can handle above case properly:

  # btrfs check $dev2
  Opening filesystem to check...
  warning, device 1 is missing
  Checking filesystem on /dev/test/scratch2
  UUID: 8b2e1cb4-f35b-4856-9b11-262d39d8458b
  [1/7] checking root items
  [2/7] checking extents
  [3/7] checking free space tree
  [4/7] checking fs roots
  [5/7] checking only csums items (without verifying data)
  [6/7] checking root refs
  [7/7] checking quota groups skipped (not enabled on this FS)
  found 147456 bytes used, no error found
  total csum bytes: 0
  total tree bytes: 147456
  total fs tree bytes: 32768
  total extent tree bytes: 16384
  btree space waste bytes: 139871
  file data blocks allocated: 0
   referenced 0

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2022-11-24 17:29:12 +01:00
..
bitmap.h btrfs-progs: properly handle degraded raid56 reads 2022-11-24 17:29:12 +01:00
bitops.h btrfs-progs: remove unnecessary linux/*.h includes 2021-05-06 16:41:47 +02:00
interval_tree_generic.h btrfs-progs: build: drop kernel-lib from -I and update paths 2019-07-03 20:49:04 +02:00
list_sort.c btrfs-progs: build: drop kernel-lib from -I and update paths 2019-07-03 20:49:04 +02:00
list_sort.h
list.h btrfs-progs: kernel-lib: make headers C++ compatible 2022-06-06 15:47:53 +02:00
mktables.c btrfs-progs: raid56: Introduce tables for RAID6 recovery 2017-07-03 13:35:11 +02:00
overflow.h btrfs-progs: kernel-lib: add stubs for overflow builtins 2022-08-16 15:18:12 +02:00
raid56.c btrfs-progs: raid56: fix the wrong recovery condition for data and P case 2021-11-18 10:17:33 +01:00
raid56.h btrfs-progs: Introduce wrapper to recover raid56 data 2017-07-03 13:35:11 +02:00
rbtree_augmented.h btrfs-progs: kernel-lib: add rb_root_cached helpers 2022-05-12 12:53:38 +02:00
rbtree_types.h btrfs-progs: kernel-lib: add rbtree_types.h from linux 2022-05-12 12:32:18 +02:00
rbtree.c btrfs-progs: kernel-lib: sync lib/rbtree.c 2022-05-12 13:07:15 +02:00
rbtree.h btrfs-progs: kernel-lib: sync include/rtree.h 2022-05-12 13:40:09 +02:00
sizes.h btrfs-progs: Introduce kernel sizes to cleanup large intermediate number 2017-03-08 13:00:45 +01:00
tables.c btrfs-progs: kernel-lib: add generated tables.c 2017-08-24 19:06:31 +02:00