u-boot/fs/btrfs
Qu Wenruo 511a1303c9 fs: btrfs: limit the mapped length to the original length
[BUG]
There is a bug report that btrfs driver caused hang during file read:

  This breaks btrfs on the HiFive Unmatched.

  => pci enum
  PCIE-0: Link up (Gen1-x8, Bus0)
  => nvme scan
  => load nvme 0:2 0x8c000000 /boot/dtb/sifive/hifive-unmatched-a00.dtb
  [hangs]

[CAUSE]
The reporter provided some debug output:

  read_extent_data: cur=615817216, orig_len=16384, cur_len=16384
  read_extent_data: btrfs_map_block: cur_len=479944704; ret=0
  read_extent_data: ret=0
  read_extent_data: cur=615833600, orig_len=4096, cur_len=4096
  read_extent_data: btrfs_map_block: cur_len=479928320; ret=0

Note the second and the last line, the @cur_len is 450+MiB, which is
almost a chunk size.

And inside __btrfs_map_block(), we limits the returned value to stripe
length, but that's depending on the chunk type:

	if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
			 BTRFS_BLOCK_GROUP_RAID1C3 | BTRFS_BLOCK_GROUP_RAID1C4 |
			 BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6 |
			 BTRFS_BLOCK_GROUP_RAID10 |
			 BTRFS_BLOCK_GROUP_DUP)) {
		/* we limit the length of each bio to what fits in a stripe */
		*length = min_t(u64, ce->size - offset,
			      map->stripe_len - stripe_offset);
	} else {
		*length = ce->size - offset;
	}

This means, if the chunk is SINGLE profile, then we don't limit the
returned length at all, and even for other profiles, we can still return
a length much larger than the requested one.

[FIX]
Properly clamp the returned length, preventing it from returning a much
larger range than expected.

Reported-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Qu Wenruo <wqu@suse.com>
2023-02-23 13:29:19 -05:00
..
common fs: btrfs: Crossport rbtree-utils from btrfs-progs 2020-09-07 20:57:27 -04:00
crypto fs/btrfs: add dependency on BLAKE2 hash 2022-01-18 08:31:02 -05:00
kernel-shared WS cleanup: remove excessive empty lines 2021-09-30 08:08:56 -04:00
btrfs.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
btrfs.h treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
compat.h fs: btrfs: Introduce function to resolve path in one subvolume 2020-09-07 21:00:36 -04:00
compression.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
conv-funcs.h treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
ctree.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
ctree.h treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
dev.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
dir-item.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
disk-io.c fs/btrfs: handle data extents, which crosss stripe boundaries, correctly 2023-01-11 15:02:24 -05:00
disk-io.h fs: btrfs: Cleanup the old implementation 2020-09-07 21:00:36 -04:00
extent-cache.c fs: btrfs: Crossport extent-cache.[ch] from btrfs-progs 2020-09-07 20:57:27 -04:00
extent-cache.h fs: btrfs: Crossport extent-cache.[ch] from btrfs-progs 2020-09-07 20:57:27 -04:00
extent-io.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
extent-io.h fs: btrfs: Crossport extent-io.[ch] from btrfs-progs 2020-09-07 20:57:27 -04:00
inode.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
Kconfig fs/btrfs: add dependency on BLAKE2 hash 2022-01-18 08:31:02 -05:00
Makefile treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
root-tree.c fs: btrfs: Crossport open_ctree_fs_info() from btrfs-progs 2020-09-07 20:57:27 -04:00
subvolume.c treewide: Fix Marek's name and change my e-mail address 2022-07-21 10:14:04 +02:00
volumes.c fs: btrfs: limit the mapped length to the original length 2023-02-23 13:29:19 -05:00
volumes.h fs: btrfs: Crossport btrfs_read_sys_array() and btrfs_read_chunk_tree() 2020-09-07 20:57:27 -04:00