commit: 5ceffccd28e7d4cc987afb63c276189d7d3925e0 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Tue Nov 1 12:45:24 2022 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Tue Nov 1 12:45:24 2022 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5ceffccd
btrfs: don't use btrfs_chunk::sub_stripes from disk Bug: https://bugs.gentoo.org/878023 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 8 ++- 1900_btrfs-chunk-sub_stripes-fix.patch | 92 ++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/0000_README b/0000_README index 68ada3e5..a0b5ecc7 100644 --- a/0000_README +++ b/0000_README @@ -76,8 +76,12 @@ From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/ Desc: Enable link security restrictions by default. Patch: 1700_sparc-address-warray-bound-warnings.patch -From: https://github.com/KSPP/linux/issues/109 -Desc: Address -Warray-bounds warnings +From: https://github.com/KSPP/linux/issues/109 +Desc: Address -Warray-bounds warnings + +Patch: 1900_btrfs-chunk-sub_stripes-fix.patch +From: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +Desc: btrfs: Don't use btrfs_chunk::sub_stripes from disk Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch From: https://lore.kernel.org/linux-bluetooth/[email protected]/raw diff --git a/1900_btrfs-chunk-sub_stripes-fix.patch b/1900_btrfs-chunk-sub_stripes-fix.patch new file mode 100644 index 00000000..2ffe02fe --- /dev/null +++ b/1900_btrfs-chunk-sub_stripes-fix.patch @@ -0,0 +1,92 @@ +From 76a66ba101329316a5d7f4275070be22eb85fdf2 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo <[email protected]> +Date: Fri, 21 Oct 2022 08:43:45 +0800 +Subject: btrfs: don't use btrfs_chunk::sub_stripes from disk + +[BUG] +There are two reports (the earliest one from LKP, a more recent one from +kernel bugzilla) that we can have some chunks with 0 as sub_stripes. + +This will cause divide-by-zero errors at btrfs_rmap_block, which is +introduced by a recent kernel patch ac0677348f3c ("btrfs: merge +calculations for simple striped profiles in btrfs_rmap_block"): + + if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | + BTRFS_BLOCK_GROUP_RAID10)) { + stripe_nr = stripe_nr * map->num_stripes + i; + stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<< + } + +[CAUSE] +From the more recent report, it has been proven that we have some chunks +with 0 as sub_stripes, mostly caused by older mkfs. + +It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa +("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk") +which is included in v5.4 btrfs-progs release. + +So there would be quite some old filesystems with such 0 sub_stripes. + +[FIX] +Just don't trust the sub_stripes values from disk. + +We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes +numbers for each profile and that are fixed. + +By this, we can keep the compatibility with older filesystems while +still avoid divide-by-zero bugs. + +Reported-by: kernel test robot <[email protected]> +Reported-by: Viktor Kuzmin <[email protected]> +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216559 +Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block") +CC: [email protected] # 6.0 +Reviewed-by: Su Yue <[email protected]> +Reviewed-by: Johannes Thumshirn <[email protected]> +Signed-off-by: Qu Wenruo <[email protected]> +Signed-off-by: David Sterba <[email protected]> +--- + fs/btrfs/volumes.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +(limited to 'fs/btrfs/volumes.c') + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 94ba46d579205..a8d4bc6a19379 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, + u64 devid; + u64 type; + u8 uuid[BTRFS_UUID_SIZE]; ++ int index; + int num_stripes; + int ret; + int i; +@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, + logical = key->offset; + length = btrfs_chunk_length(leaf, chunk); + type = btrfs_chunk_type(leaf, chunk); ++ index = btrfs_bg_flags_to_raid_index(type); + num_stripes = btrfs_chunk_num_stripes(leaf, chunk); + + #if BITS_PER_LONG == 32 +@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, + map->io_align = btrfs_chunk_io_align(leaf, chunk); + map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk); + map->type = type; +- map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk); ++ /* ++ * We can't use the sub_stripes value, as for profiles other than ++ * RAID10, they may have 0 as sub_stripes for filesystems created by ++ * older mkfs (<v5.4). ++ * In that case, it can cause divide-by-zero errors later. ++ * Since currently sub_stripes is fixed for each profile, let's ++ * use the trusted value instead. ++ */ ++ map->sub_stripes = btrfs_raid_array[index].sub_stripes; + map->verified_stripes = 0; + em->orig_block_len = btrfs_calc_stripe_length(em); + for (i = 0; i < num_stripes; i++) { +-- +cgit
