History

Merge tag 'for-5.15-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba: "Last minute fixes for crash on 32bit architectures when compression is in use. It's a regression introduced in 5.15-rc and I'd really like not let this into the final release, fixes via stable trees would add unnecessary delay. The problem is on 32bit architectures with highmem enabled, the pages for compression may need to be kmapped, while the patches removed that as we don't use GFP_HIGHMEM allocations anymore. The pages that don't come from local allocation still may be from highmem. Despite being on 32bit there's enough such ARM machines in use so it's not a marginal issue. I did full reverts of the patches one by one instead of a huge one. There's one exception for the "lzo" revert as there was an intermediate patch touching the same code to make it compatible with subpage. I can't revert that one too, so the revert in lzo.c is manual. Qu Wenruo has worked on that with me and verified the changes" * tag 'for-5.15-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: Revert "btrfs: compression: drop kmap/kunmap from lzo" Revert "btrfs: compression: drop kmap/kunmap from zlib" Revert "btrfs: compression: drop kmap/kunmap from zstd" Revert "btrfs: compression: drop kmap/kunmap from generic helpers"

Linus Torvalds committed 5 years ago

Commit fd919bb2 parents 6f11521 ccaa66c5 files · +72 −33Browse files

Unified · Split

5 files
  1. fs/btrfs/compression.c +2 −1
  2. fs/btrfs/inode.c +2 −1
  3. fs/btrfs/lzo.c +25 −11
  4. fs/btrfs/zlib.c +25 −11
  5. fs/btrfs/zstd.c +18 −9
fs/btrfs/compression.c+2−1
@@ -172,9 +172,10 @@ static int check_compressed_csum(struct btrfs_inode *inode, struct bio *bio, · 171 unmodified lines
172172 /* Hash through the page sector by sector */
173173 for (pg_offset = 0; pg_offset < bytes_left;
174174 pg_offset += sectorsize) {
175− kaddr = page_address(page);
175+ kaddr = kmap_atomic(page);
176176 crypto_shash_digest(shash, kaddr + pg_offset,
177177 sectorsize, csum);
178+ kunmap_atomic(kaddr);
178179
179180 if (memcmp(&csum, cb_sum, csum_size) != 0) {
180181 btrfs_print_data_csum_error(inode, disk_start,
fs/btrfs/inode.c+2−1
@@ -287,8 +287,9 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, · 286 unmodified lines
287287 cur_size = min_t(unsigned long, compressed_size,
288288 PAGE_SIZE);
289289
290− kaddr = page_address(cpage);
290+ kaddr = kmap_atomic(cpage);
291291 write_extent_buffer(leaf, kaddr, ptr, cur_size);
292+ kunmap_atomic(kaddr);
292293
293294 i++;
294295 ptr += cur_size;
fs/btrfs/lzo.c+25−11
@@ -141,7 +141,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, · 140 unmodified lines
141141 *total_in = 0;
142142
143143 in_page = find_get_page(mapping, start >> PAGE_SHIFT);
144− data_in = page_address(in_page);
144+ data_in = kmap(in_page);
145145
146146 /*
147147 * store the size of all chunks of compressed data in
@@ -152,7 +152,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, · 4 unmodified lines
152152 ret = -ENOMEM;
153153 goto out;
154154 }
155− cpage_out = page_address(out_page);
155+ cpage_out = kmap(out_page);
156156 out_offset = LZO_LEN;
157157 tot_out = LZO_LEN;
158158 pages[0] = out_page;
@@ -210,6 +210,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, · 51 unmodified lines
210210 if (out_len == 0 && tot_in >= len)
211211 break;
212212
213+ kunmap(out_page);
213214 if (nr_pages == nr_dest_pages) {
214215 out_page = NULL;
215216 ret = -E2BIG;
@@ -221,7 +222,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, · 5 unmodified lines
221222 ret = -ENOMEM;
222223 goto out;
223224 }
224− cpage_out = page_address(out_page);
225+ cpage_out = kmap(out_page);
225226 pages[nr_pages++] = out_page;
226227
227228 pg_bytes_left = PAGE_SIZE;
@@ -243,11 +244,12 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, · 15 unmodified lines
243244 break;
244245
245246 bytes_left = len - tot_in;
247+ kunmap(in_page);
246248 put_page(in_page);
247249
248250 start += PAGE_SIZE;
249251 in_page = find_get_page(mapping, start >> PAGE_SHIFT);
250− data_in = page_address(in_page);
252+ data_in = kmap(in_page);
251253 in_len = min(bytes_left, PAGE_SIZE);
252254 }
253255
@@ -257,17 +259,22 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, · 3 unmodified lines
257259 }
258260
259261 /* store the size of all chunks of compressed data */
260− sizes_ptr = page_address(pages[0]);
262+ sizes_ptr = kmap_local_page(pages[0]);
261263 write_compress_length(sizes_ptr, tot_out);
264+ kunmap_local(sizes_ptr);
262265
263266 ret = 0;
264267 *total_out = tot_out;
265268 *total_in = tot_in;
266269 out:
267270 *out_pages = nr_pages;
271+ if (out_page)
272+ kunmap(out_page);
268273
269− if (in_page)
274+ if (in_page) {
275+ kunmap(in_page);
270276 put_page(in_page);
277+ }
271278
272279 return ret;
273280 }
@@ -283,6 +290,7 @@ static void copy_compressed_segment(struct compressed_bio *cb, · 9 unmodified lines
283290 u32 orig_in = *cur_in;
284291
285292 while (*cur_in < orig_in + len) {
293+ char *kaddr;
286294 struct page *cur_page;
287295 u32 copy_len = min_t(u32, PAGE_SIZE - offset_in_page(*cur_in),
288296 orig_in + len - *cur_in);
@@ -290,9 +298,11 @@ static void copy_compressed_segment(struct compressed_bio *cb, · 1 unmodified line
290298 ASSERT(copy_len);
291299 cur_page = cb->compressed_pages[*cur_in / PAGE_SIZE];
292300
301+ kaddr = kmap(cur_page);
293302 memcpy(dest + *cur_in - orig_in,
294− page_address(cur_page) + offset_in_page(*cur_in),
303+ kaddr + offset_in_page(*cur_in),
295304 copy_len);
305+ kunmap(cur_page);
296306
297307 *cur_in += copy_len;
298308 }
@@ -303,6 +313,7 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 4 unmodified lines
303313 struct workspace *workspace = list_entry(ws, struct workspace, list);
304314 const struct btrfs_fs_info *fs_info = btrfs_sb(cb->inode->i_sb);
305315 const u32 sectorsize = fs_info->sectorsize;
316+ char *kaddr;
306317 int ret;
307318 /* Compressed data length, can be unaligned */
308319 u32 len_in;
@@ -311,7 +322,9 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 2 unmodified lines
311322 /* Bytes decompressed so far */
312323 u32 cur_out = 0;
313324
314− len_in = read_compress_length(page_address(cb->compressed_pages[0]));
325+ kaddr = kmap(cb->compressed_pages[0]);
326+ len_in = read_compress_length(kaddr);
327+ kunmap(cb->compressed_pages[0]);
315328 cur_in += LZO_LEN;
316329
317330 /*
@@ -344,9 +357,9 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 26 unmodified lines
344357 ASSERT(cur_in / sectorsize ==
345358 (cur_in + LZO_LEN - 1) / sectorsize);
346359 cur_page = cb->compressed_pages[cur_in / PAGE_SIZE];
360+ kaddr = kmap(cur_page);
347361 ASSERT(cur_page);
348− seg_len = read_compress_length(page_address(cur_page) +
349− offset_in_page(cur_in));
362+ seg_len = read_compress_length(kaddr + offset_in_page(cur_in));
350363 cur_in += LZO_LEN;
351364
352365 /* Copy the compressed segment payload into workspace */
@@ -431,7 +444,7 @@ int lzo_decompress(struct list_head *ws, unsigned char *data_in, · 78 unmodified lines
431444 destlen = min_t(unsigned long, destlen, PAGE_SIZE);
432445 bytes = min_t(unsigned long, destlen, out_len - start_byte);
433446
434− kaddr = page_address(dest_page);
447+ kaddr = kmap_local_page(dest_page);
435448 memcpy(kaddr, workspace->buf + start_byte, bytes);
436449
437450 /*
@@ -441,6 +454,7 @@ int lzo_decompress(struct list_head *ws, unsigned char *data_in, · 3 unmodified lines
441454 */
442455 if (bytes < destlen)
443456 memset(kaddr+bytes, 0, destlen-bytes);
457+ kunmap_local(kaddr);
444458 out:
445459 return ret;
446460 }
fs/btrfs/zlib.c+25−11
@@ -126,7 +126,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 125 unmodified lines
126126 ret = -ENOMEM;
127127 goto out;
128128 }
129− cpage_out = page_address(out_page);
129+ cpage_out = kmap(out_page);
130130 pages[0] = out_page;
131131 nr_pages = 1;
132132
@@ -148,22 +148,26 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 15 unmodified lines
148148 int i;
149149
150150 for (i = 0; i < in_buf_pages; i++) {
151− if (in_page)
151+ if (in_page) {
152+ kunmap(in_page);
152153 put_page(in_page);
154+ }
153155 in_page = find_get_page(mapping,
154156 start >> PAGE_SHIFT);
155− data_in = page_address(in_page);
157+ data_in = kmap(in_page);
156158 memcpy(workspace->buf + i * PAGE_SIZE,
157159 data_in, PAGE_SIZE);
158160 start += PAGE_SIZE;
159161 }
160162 workspace->strm.next_in = workspace->buf;
161163 } else {
162− if (in_page)
164+ if (in_page) {
165+ kunmap(in_page);
163166 put_page(in_page);
167+ }
164168 in_page = find_get_page(mapping,
165169 start >> PAGE_SHIFT);
166− data_in = page_address(in_page);
170+ data_in = kmap(in_page);
167171 start += PAGE_SIZE;
168172 workspace->strm.next_in = data_in;
169173 }
@@ -192,6 +196,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 22 unmodified lines
192196 * the stream end if required
193197 */
194198 if (workspace->strm.avail_out == 0) {
199+ kunmap(out_page);
195200 if (nr_pages == nr_dest_pages) {
196201 out_page = NULL;
197202 ret = -E2BIG;
@@ -202,7 +207,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 4 unmodified lines
202207 ret = -ENOMEM;
203208 goto out;
204209 }
205− cpage_out = page_address(out_page);
210+ cpage_out = kmap(out_page);
206211 pages[nr_pages] = out_page;
207212 nr_pages++;
208213 workspace->strm.avail_out = PAGE_SIZE;
@@ -229,6 +234,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 20 unmodified lines
229234 goto out;
230235 } else if (workspace->strm.avail_out == 0) {
231236 /* get another page for the stream end */
237+ kunmap(out_page);
232238 if (nr_pages == nr_dest_pages) {
233239 out_page = NULL;
234240 ret = -E2BIG;
@@ -239,7 +245,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 4 unmodified lines
239245 ret = -ENOMEM;
240246 goto out;
241247 }
242− cpage_out = page_address(out_page);
248+ cpage_out = kmap(out_page);
243249 pages[nr_pages] = out_page;
244250 nr_pages++;
245251 workspace->strm.avail_out = PAGE_SIZE;
@@ -258,8 +264,13 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, · 12 unmodified lines
258264 *total_in = workspace->strm.total_in;
259265 out:
260266 *out_pages = nr_pages;
261− if (in_page)
267+ if (out_page)
268+ kunmap(out_page);
269+
270+ if (in_page) {
271+ kunmap(in_page);
262272 put_page(in_page);
273+ }
263274 return ret;
264275 }
265276
@@ -276,7 +287,7 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 10 unmodified lines
276287 unsigned long buf_start;
277288 struct page **pages_in = cb->compressed_pages;
278289
279− data_in = page_address(pages_in[page_in_index]);
290+ data_in = kmap(pages_in[page_in_index]);
280291 workspace->strm.next_in = data_in;
281292 workspace->strm.avail_in = min_t(size_t, srclen, PAGE_SIZE);
282293 workspace->strm.total_in = 0;
@@ -298,6 +309,7 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 15 unmodified lines
298309
299310 if (Z_OK != zlib_inflateInit2(&workspace->strm, wbits)) {
300311 pr_warn("BTRFS: inflateInit failed\n");
312+ kunmap(pages_in[page_in_index]);
301313 return -EIO;
302314 }
303315 while (workspace->strm.total_in < srclen) {
@@ -324,13 +336,13 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 20 unmodified lines
324336
325337 if (workspace->strm.avail_in == 0) {
326338 unsigned long tmp;
327−
339+ kunmap(pages_in[page_in_index]);
328340 page_in_index++;
329341 if (page_in_index >= total_pages_in) {
330342 data_in = NULL;
331343 break;
332344 }
333− data_in = page_address(pages_in[page_in_index]);
345+ data_in = kmap(pages_in[page_in_index]);
334346 workspace->strm.next_in = data_in;
335347 tmp = srclen - workspace->strm.total_in;
336348 workspace->strm.avail_in = min(tmp, PAGE_SIZE);
@@ -342,6 +354,8 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 5 unmodified lines
342354 ret = 0;
343355 done:
344356 zlib_inflateEnd(&workspace->strm);
357+ if (data_in)
358+ kunmap(pages_in[page_in_index]);
345359 if (!ret)
346360 zero_fill_bio(cb->orig_bio);
347361 return ret;
fs/btrfs/zstd.c+18−9
@@ -399,7 +399,7 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 398 unmodified lines
399399
400400 /* map in the first page of input data */
401401 in_page = find_get_page(mapping, start >> PAGE_SHIFT);
402− workspace->in_buf.src = page_address(in_page);
402+ workspace->in_buf.src = kmap(in_page);
403403 workspace->in_buf.pos = 0;
404404 workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE);
405405
@@ -411,7 +411,7 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 5 unmodified lines
411411 goto out;
412412 }
413413 pages[nr_pages++] = out_page;
414− workspace->out_buf.dst = page_address(out_page);
414+ workspace->out_buf.dst = kmap(out_page);
415415 workspace->out_buf.pos = 0;
416416 workspace->out_buf.size = min_t(size_t, max_out, PAGE_SIZE);
417417
@@ -446,6 +446,7 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 28 unmodified lines
446446 if (workspace->out_buf.pos == workspace->out_buf.size) {
447447 tot_out += PAGE_SIZE;
448448 max_out -= PAGE_SIZE;
449+ kunmap(out_page);
449450 if (nr_pages == nr_dest_pages) {
450451 out_page = NULL;
451452 ret = -E2BIG;
@@ -457,7 +458,7 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 5 unmodified lines
457458 goto out;
458459 }
459460 pages[nr_pages++] = out_page;
460− workspace->out_buf.dst = page_address(out_page);
461+ workspace->out_buf.dst = kmap(out_page);
461462 workspace->out_buf.pos = 0;
462463 workspace->out_buf.size = min_t(size_t, max_out,
463464 PAGE_SIZE);
@@ -472,12 +473,13 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 8 unmodified lines
472473 /* Check if we need more input */
473474 if (workspace->in_buf.pos == workspace->in_buf.size) {
474475 tot_in += PAGE_SIZE;
476+ kunmap(in_page);
475477 put_page(in_page);
476478
477479 start += PAGE_SIZE;
478480 len -= PAGE_SIZE;
479481 in_page = find_get_page(mapping, start >> PAGE_SHIFT);
480− workspace->in_buf.src = page_address(in_page);
482+ workspace->in_buf.src = kmap(in_page);
481483 workspace->in_buf.pos = 0;
482484 workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE);
483485 }
@@ -504,6 +506,7 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 20 unmodified lines
504506
505507 tot_out += PAGE_SIZE;
506508 max_out -= PAGE_SIZE;
509+ kunmap(out_page);
507510 if (nr_pages == nr_dest_pages) {
508511 out_page = NULL;
509512 ret = -E2BIG;
@@ -515,7 +518,7 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 5 unmodified lines
515518 goto out;
516519 }
517520 pages[nr_pages++] = out_page;
518− workspace->out_buf.dst = page_address(out_page);
521+ workspace->out_buf.dst = kmap(out_page);
519522 workspace->out_buf.pos = 0;
520523 workspace->out_buf.size = min_t(size_t, max_out, PAGE_SIZE);
521524 }
@@ -531,8 +534,12 @@ int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, · 9 unmodified lines
531534 out:
532535 *out_pages = nr_pages;
533536 /* Cleanup */
534− if (in_page)
537+ if (in_page) {
538+ kunmap(in_page);
535539 put_page(in_page);
540+ }
541+ if (out_page)
542+ kunmap(out_page);
536543 return ret;
537544 }
538545
@@ -556,7 +563,7 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 17 unmodified lines
556563 goto done;
557564 }
558565
559− workspace->in_buf.src = page_address(pages_in[page_in_index]);
566+ workspace->in_buf.src = kmap(pages_in[page_in_index]);
560567 workspace->in_buf.pos = 0;
561568 workspace->in_buf.size = min_t(size_t, srclen, PAGE_SIZE);
562569
@@ -592,14 +599,14 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 29 unmodified lines
592599 break;
593600
594601 if (workspace->in_buf.pos == workspace->in_buf.size) {
595− page_in_index++;
602+ kunmap(pages_in[page_in_index++]);
596603 if (page_in_index >= total_pages_in) {
597604 workspace->in_buf.src = NULL;
598605 ret = -EIO;
599606 goto done;
600607 }
601608 srclen -= PAGE_SIZE;
602− workspace->in_buf.src = page_address(pages_in[page_in_index]);
609+ workspace->in_buf.src = kmap(pages_in[page_in_index]);
603610 workspace->in_buf.pos = 0;
604611 workspace->in_buf.size = min_t(size_t, srclen, PAGE_SIZE);
605612 }
@@ -607,6 +614,8 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb) · 1 unmodified line
607614 ret = 0;
608615 zero_fill_bio(cb->orig_bio);
609616 done:
617+ if (workspace->in_buf.src)
618+ kunmap(pages_in[page_in_index]);
610619 return ret;
611620 }
612621