1 |
commit: 5ceffccd28e7d4cc987afb63c276189d7d3925e0 |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Nov 1 12:45:24 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Nov 1 12:45:24 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5ceffccd |
7 |
|
8 |
btrfs: don't use btrfs_chunk::sub_stripes from disk |
9 |
|
10 |
Bug: https://bugs.gentoo.org/878023 |
11 |
|
12 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
13 |
|
14 |
0000_README | 8 ++- |
15 |
1900_btrfs-chunk-sub_stripes-fix.patch | 92 ++++++++++++++++++++++++++++++++++ |
16 |
2 files changed, 98 insertions(+), 2 deletions(-) |
17 |
|
18 |
diff --git a/0000_README b/0000_README |
19 |
index 68ada3e5..a0b5ecc7 100644 |
20 |
--- a/0000_README |
21 |
+++ b/0000_README |
22 |
@@ -76,8 +76,12 @@ From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/ |
23 |
Desc: Enable link security restrictions by default. |
24 |
|
25 |
Patch: 1700_sparc-address-warray-bound-warnings.patch |
26 |
-From: https://github.com/KSPP/linux/issues/109 |
27 |
-Desc: Address -Warray-bounds warnings |
28 |
+From: https://github.com/KSPP/linux/issues/109 |
29 |
+Desc: Address -Warray-bounds warnings |
30 |
+ |
31 |
+Patch: 1900_btrfs-chunk-sub_stripes-fix.patch |
32 |
+From: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git |
33 |
+Desc: btrfs: Don't use btrfs_chunk::sub_stripes from disk |
34 |
|
35 |
Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch |
36 |
From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@××××××××.org/raw |
37 |
|
38 |
diff --git a/1900_btrfs-chunk-sub_stripes-fix.patch b/1900_btrfs-chunk-sub_stripes-fix.patch |
39 |
new file mode 100644 |
40 |
index 00000000..2ffe02fe |
41 |
--- /dev/null |
42 |
+++ b/1900_btrfs-chunk-sub_stripes-fix.patch |
43 |
@@ -0,0 +1,92 @@ |
44 |
+From 76a66ba101329316a5d7f4275070be22eb85fdf2 Mon Sep 17 00:00:00 2001 |
45 |
+From: Qu Wenruo <wqu@××××.com> |
46 |
+Date: Fri, 21 Oct 2022 08:43:45 +0800 |
47 |
+Subject: btrfs: don't use btrfs_chunk::sub_stripes from disk |
48 |
+ |
49 |
+[BUG] |
50 |
+There are two reports (the earliest one from LKP, a more recent one from |
51 |
+kernel bugzilla) that we can have some chunks with 0 as sub_stripes. |
52 |
+ |
53 |
+This will cause divide-by-zero errors at btrfs_rmap_block, which is |
54 |
+introduced by a recent kernel patch ac0677348f3c ("btrfs: merge |
55 |
+calculations for simple striped profiles in btrfs_rmap_block"): |
56 |
+ |
57 |
+ if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | |
58 |
+ BTRFS_BLOCK_GROUP_RAID10)) { |
59 |
+ stripe_nr = stripe_nr * map->num_stripes + i; |
60 |
+ stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<< |
61 |
+ } |
62 |
+ |
63 |
+[CAUSE] |
64 |
+From the more recent report, it has been proven that we have some chunks |
65 |
+with 0 as sub_stripes, mostly caused by older mkfs. |
66 |
+ |
67 |
+It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa |
68 |
+("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk") |
69 |
+which is included in v5.4 btrfs-progs release. |
70 |
+ |
71 |
+So there would be quite some old filesystems with such 0 sub_stripes. |
72 |
+ |
73 |
+[FIX] |
74 |
+Just don't trust the sub_stripes values from disk. |
75 |
+ |
76 |
+We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes |
77 |
+numbers for each profile and that are fixed. |
78 |
+ |
79 |
+By this, we can keep the compatibility with older filesystems while |
80 |
+still avoid divide-by-zero bugs. |
81 |
+ |
82 |
+Reported-by: kernel test robot <oliver.sang@×××××.com> |
83 |
+Reported-by: Viktor Kuzmin <kvaster@×××××.com> |
84 |
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216559 |
85 |
+Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block") |
86 |
+CC: stable@×××××××××××.org # 6.0 |
87 |
+Reviewed-by: Su Yue <glass@××××××.io> |
88 |
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@×××.com> |
89 |
+Signed-off-by: Qu Wenruo <wqu@××××.com> |
90 |
+Signed-off-by: David Sterba <dsterba@××××.com> |
91 |
+--- |
92 |
+ fs/btrfs/volumes.c | 12 +++++++++++- |
93 |
+ 1 file changed, 11 insertions(+), 1 deletion(-) |
94 |
+ |
95 |
+(limited to 'fs/btrfs/volumes.c') |
96 |
+ |
97 |
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
98 |
+index 94ba46d579205..a8d4bc6a19379 100644 |
99 |
+--- a/fs/btrfs/volumes.c |
100 |
++++ b/fs/btrfs/volumes.c |
101 |
+@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, |
102 |
+ u64 devid; |
103 |
+ u64 type; |
104 |
+ u8 uuid[BTRFS_UUID_SIZE]; |
105 |
++ int index; |
106 |
+ int num_stripes; |
107 |
+ int ret; |
108 |
+ int i; |
109 |
+@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, |
110 |
+ logical = key->offset; |
111 |
+ length = btrfs_chunk_length(leaf, chunk); |
112 |
+ type = btrfs_chunk_type(leaf, chunk); |
113 |
++ index = btrfs_bg_flags_to_raid_index(type); |
114 |
+ num_stripes = btrfs_chunk_num_stripes(leaf, chunk); |
115 |
+ |
116 |
+ #if BITS_PER_LONG == 32 |
117 |
+@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf, |
118 |
+ map->io_align = btrfs_chunk_io_align(leaf, chunk); |
119 |
+ map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk); |
120 |
+ map->type = type; |
121 |
+- map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk); |
122 |
++ /* |
123 |
++ * We can't use the sub_stripes value, as for profiles other than |
124 |
++ * RAID10, they may have 0 as sub_stripes for filesystems created by |
125 |
++ * older mkfs (<v5.4). |
126 |
++ * In that case, it can cause divide-by-zero errors later. |
127 |
++ * Since currently sub_stripes is fixed for each profile, let's |
128 |
++ * use the trusted value instead. |
129 |
++ */ |
130 |
++ map->sub_stripes = btrfs_raid_array[index].sub_stripes; |
131 |
+ map->verified_stripes = 0; |
132 |
+ em->orig_block_len = btrfs_calc_stripe_length(em); |
133 |
+ for (i = 0; i < num_stripes; i++) { |
134 |
+-- |
135 |
+cgit |