Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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"

+72 -33
+2 -1
fs/btrfs/compression.c
··· 172 172 /* Hash through the page sector by sector */ 173 173 for (pg_offset = 0; pg_offset < bytes_left; 174 174 pg_offset += sectorsize) { 175 - kaddr = page_address(page); 175 + kaddr = kmap_atomic(page); 176 176 crypto_shash_digest(shash, kaddr + pg_offset, 177 177 sectorsize, csum); 178 + kunmap_atomic(kaddr); 178 179 179 180 if (memcmp(&csum, cb_sum, csum_size) != 0) { 180 181 btrfs_print_data_csum_error(inode, disk_start,
+2 -1
fs/btrfs/inode.c
··· 287 287 cur_size = min_t(unsigned long, compressed_size, 288 288 PAGE_SIZE); 289 289 290 - kaddr = page_address(cpage); 290 + kaddr = kmap_atomic(cpage); 291 291 write_extent_buffer(leaf, kaddr, ptr, cur_size); 292 + kunmap_atomic(kaddr); 292 293 293 294 i++; 294 295 ptr += cur_size;
+25 -11
fs/btrfs/lzo.c
··· 141 141 *total_in = 0; 142 142 143 143 in_page = find_get_page(mapping, start >> PAGE_SHIFT); 144 - data_in = page_address(in_page); 144 + data_in = kmap(in_page); 145 145 146 146 /* 147 147 * store the size of all chunks of compressed data in ··· 152 152 ret = -ENOMEM; 153 153 goto out; 154 154 } 155 - cpage_out = page_address(out_page); 155 + cpage_out = kmap(out_page); 156 156 out_offset = LZO_LEN; 157 157 tot_out = LZO_LEN; 158 158 pages[0] = out_page; ··· 210 210 if (out_len == 0 && tot_in >= len) 211 211 break; 212 212 213 + kunmap(out_page); 213 214 if (nr_pages == nr_dest_pages) { 214 215 out_page = NULL; 215 216 ret = -E2BIG; ··· 222 221 ret = -ENOMEM; 223 222 goto out; 224 223 } 225 - cpage_out = page_address(out_page); 224 + cpage_out = kmap(out_page); 226 225 pages[nr_pages++] = out_page; 227 226 228 227 pg_bytes_left = PAGE_SIZE; ··· 244 243 break; 245 244 246 245 bytes_left = len - tot_in; 246 + kunmap(in_page); 247 247 put_page(in_page); 248 248 249 249 start += PAGE_SIZE; 250 250 in_page = find_get_page(mapping, start >> PAGE_SHIFT); 251 - data_in = page_address(in_page); 251 + data_in = kmap(in_page); 252 252 in_len = min(bytes_left, PAGE_SIZE); 253 253 } 254 254 ··· 259 257 } 260 258 261 259 /* store the size of all chunks of compressed data */ 262 - sizes_ptr = page_address(pages[0]); 260 + sizes_ptr = kmap_local_page(pages[0]); 263 261 write_compress_length(sizes_ptr, tot_out); 262 + kunmap_local(sizes_ptr); 264 263 265 264 ret = 0; 266 265 *total_out = tot_out; 267 266 *total_in = tot_in; 268 267 out: 269 268 *out_pages = nr_pages; 269 + if (out_page) 270 + kunmap(out_page); 270 271 271 - if (in_page) 272 + if (in_page) { 273 + kunmap(in_page); 272 274 put_page(in_page); 275 + } 273 276 274 277 return ret; 275 278 } ··· 290 283 u32 orig_in = *cur_in; 291 284 292 285 while (*cur_in < orig_in + len) { 286 + char *kaddr; 293 287 struct page *cur_page; 294 288 u32 copy_len = min_t(u32, PAGE_SIZE - offset_in_page(*cur_in), 295 289 orig_in + len - *cur_in); ··· 298 290 ASSERT(copy_len); 299 291 cur_page = cb->compressed_pages[*cur_in / PAGE_SIZE]; 300 292 293 + kaddr = kmap(cur_page); 301 294 memcpy(dest + *cur_in - orig_in, 302 - page_address(cur_page) + offset_in_page(*cur_in), 295 + kaddr + offset_in_page(*cur_in), 303 296 copy_len); 297 + kunmap(cur_page); 304 298 305 299 *cur_in += copy_len; 306 300 } ··· 313 303 struct workspace *workspace = list_entry(ws, struct workspace, list); 314 304 const struct btrfs_fs_info *fs_info = btrfs_sb(cb->inode->i_sb); 315 305 const u32 sectorsize = fs_info->sectorsize; 306 + char *kaddr; 316 307 int ret; 317 308 /* Compressed data length, can be unaligned */ 318 309 u32 len_in; ··· 322 311 /* Bytes decompressed so far */ 323 312 u32 cur_out = 0; 324 313 325 - len_in = read_compress_length(page_address(cb->compressed_pages[0])); 314 + kaddr = kmap(cb->compressed_pages[0]); 315 + len_in = read_compress_length(kaddr); 316 + kunmap(cb->compressed_pages[0]); 326 317 cur_in += LZO_LEN; 327 318 328 319 /* ··· 357 344 ASSERT(cur_in / sectorsize == 358 345 (cur_in + LZO_LEN - 1) / sectorsize); 359 346 cur_page = cb->compressed_pages[cur_in / PAGE_SIZE]; 347 + kaddr = kmap(cur_page); 360 348 ASSERT(cur_page); 361 - seg_len = read_compress_length(page_address(cur_page) + 362 - offset_in_page(cur_in)); 349 + seg_len = read_compress_length(kaddr + offset_in_page(cur_in)); 363 350 cur_in += LZO_LEN; 364 351 365 352 /* Copy the compressed segment payload into workspace */ ··· 444 431 destlen = min_t(unsigned long, destlen, PAGE_SIZE); 445 432 bytes = min_t(unsigned long, destlen, out_len - start_byte); 446 433 447 - kaddr = page_address(dest_page); 434 + kaddr = kmap_local_page(dest_page); 448 435 memcpy(kaddr, workspace->buf + start_byte, bytes); 449 436 450 437 /* ··· 454 441 */ 455 442 if (bytes < destlen) 456 443 memset(kaddr+bytes, 0, destlen-bytes); 444 + kunmap_local(kaddr); 457 445 out: 458 446 return ret; 459 447 }
+25 -11
fs/btrfs/zlib.c
··· 126 126 ret = -ENOMEM; 127 127 goto out; 128 128 } 129 - cpage_out = page_address(out_page); 129 + cpage_out = kmap(out_page); 130 130 pages[0] = out_page; 131 131 nr_pages = 1; 132 132 ··· 148 148 int i; 149 149 150 150 for (i = 0; i < in_buf_pages; i++) { 151 - if (in_page) 151 + if (in_page) { 152 + kunmap(in_page); 152 153 put_page(in_page); 154 + } 153 155 in_page = find_get_page(mapping, 154 156 start >> PAGE_SHIFT); 155 - data_in = page_address(in_page); 157 + data_in = kmap(in_page); 156 158 memcpy(workspace->buf + i * PAGE_SIZE, 157 159 data_in, PAGE_SIZE); 158 160 start += PAGE_SIZE; 159 161 } 160 162 workspace->strm.next_in = workspace->buf; 161 163 } else { 162 - if (in_page) 164 + if (in_page) { 165 + kunmap(in_page); 163 166 put_page(in_page); 167 + } 164 168 in_page = find_get_page(mapping, 165 169 start >> PAGE_SHIFT); 166 - data_in = page_address(in_page); 170 + data_in = kmap(in_page); 167 171 start += PAGE_SIZE; 168 172 workspace->strm.next_in = data_in; 169 173 } ··· 196 192 * the stream end if required 197 193 */ 198 194 if (workspace->strm.avail_out == 0) { 195 + kunmap(out_page); 199 196 if (nr_pages == nr_dest_pages) { 200 197 out_page = NULL; 201 198 ret = -E2BIG; ··· 207 202 ret = -ENOMEM; 208 203 goto out; 209 204 } 210 - cpage_out = page_address(out_page); 205 + cpage_out = kmap(out_page); 211 206 pages[nr_pages] = out_page; 212 207 nr_pages++; 213 208 workspace->strm.avail_out = PAGE_SIZE; ··· 234 229 goto out; 235 230 } else if (workspace->strm.avail_out == 0) { 236 231 /* get another page for the stream end */ 232 + kunmap(out_page); 237 233 if (nr_pages == nr_dest_pages) { 238 234 out_page = NULL; 239 235 ret = -E2BIG; ··· 245 239 ret = -ENOMEM; 246 240 goto out; 247 241 } 248 - cpage_out = page_address(out_page); 242 + cpage_out = kmap(out_page); 249 243 pages[nr_pages] = out_page; 250 244 nr_pages++; 251 245 workspace->strm.avail_out = PAGE_SIZE; ··· 264 258 *total_in = workspace->strm.total_in; 265 259 out: 266 260 *out_pages = nr_pages; 267 - if (in_page) 261 + if (out_page) 262 + kunmap(out_page); 263 + 264 + if (in_page) { 265 + kunmap(in_page); 268 266 put_page(in_page); 267 + } 269 268 return ret; 270 269 } 271 270 ··· 287 276 unsigned long buf_start; 288 277 struct page **pages_in = cb->compressed_pages; 289 278 290 - data_in = page_address(pages_in[page_in_index]); 279 + data_in = kmap(pages_in[page_in_index]); 291 280 workspace->strm.next_in = data_in; 292 281 workspace->strm.avail_in = min_t(size_t, srclen, PAGE_SIZE); 293 282 workspace->strm.total_in = 0; ··· 309 298 310 299 if (Z_OK != zlib_inflateInit2(&workspace->strm, wbits)) { 311 300 pr_warn("BTRFS: inflateInit failed\n"); 301 + kunmap(pages_in[page_in_index]); 312 302 return -EIO; 313 303 } 314 304 while (workspace->strm.total_in < srclen) { ··· 336 324 337 325 if (workspace->strm.avail_in == 0) { 338 326 unsigned long tmp; 339 - 327 + kunmap(pages_in[page_in_index]); 340 328 page_in_index++; 341 329 if (page_in_index >= total_pages_in) { 342 330 data_in = NULL; 343 331 break; 344 332 } 345 - data_in = page_address(pages_in[page_in_index]); 333 + data_in = kmap(pages_in[page_in_index]); 346 334 workspace->strm.next_in = data_in; 347 335 tmp = srclen - workspace->strm.total_in; 348 336 workspace->strm.avail_in = min(tmp, PAGE_SIZE); ··· 354 342 ret = 0; 355 343 done: 356 344 zlib_inflateEnd(&workspace->strm); 345 + if (data_in) 346 + kunmap(pages_in[page_in_index]); 357 347 if (!ret) 358 348 zero_fill_bio(cb->orig_bio); 359 349 return ret;
+18 -9
fs/btrfs/zstd.c
··· 399 399 400 400 /* map in the first page of input data */ 401 401 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); 403 403 workspace->in_buf.pos = 0; 404 404 workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE); 405 405 ··· 411 411 goto out; 412 412 } 413 413 pages[nr_pages++] = out_page; 414 - workspace->out_buf.dst = page_address(out_page); 414 + workspace->out_buf.dst = kmap(out_page); 415 415 workspace->out_buf.pos = 0; 416 416 workspace->out_buf.size = min_t(size_t, max_out, PAGE_SIZE); 417 417 ··· 446 446 if (workspace->out_buf.pos == workspace->out_buf.size) { 447 447 tot_out += PAGE_SIZE; 448 448 max_out -= PAGE_SIZE; 449 + kunmap(out_page); 449 450 if (nr_pages == nr_dest_pages) { 450 451 out_page = NULL; 451 452 ret = -E2BIG; ··· 458 457 goto out; 459 458 } 460 459 pages[nr_pages++] = out_page; 461 - workspace->out_buf.dst = page_address(out_page); 460 + workspace->out_buf.dst = kmap(out_page); 462 461 workspace->out_buf.pos = 0; 463 462 workspace->out_buf.size = min_t(size_t, max_out, 464 463 PAGE_SIZE); ··· 473 472 /* Check if we need more input */ 474 473 if (workspace->in_buf.pos == workspace->in_buf.size) { 475 474 tot_in += PAGE_SIZE; 475 + kunmap(in_page); 476 476 put_page(in_page); 477 477 478 478 start += PAGE_SIZE; 479 479 len -= PAGE_SIZE; 480 480 in_page = find_get_page(mapping, start >> PAGE_SHIFT); 481 - workspace->in_buf.src = page_address(in_page); 481 + workspace->in_buf.src = kmap(in_page); 482 482 workspace->in_buf.pos = 0; 483 483 workspace->in_buf.size = min_t(size_t, len, PAGE_SIZE); 484 484 } ··· 506 504 507 505 tot_out += PAGE_SIZE; 508 506 max_out -= PAGE_SIZE; 507 + kunmap(out_page); 509 508 if (nr_pages == nr_dest_pages) { 510 509 out_page = NULL; 511 510 ret = -E2BIG; ··· 518 515 goto out; 519 516 } 520 517 pages[nr_pages++] = out_page; 521 - workspace->out_buf.dst = page_address(out_page); 518 + workspace->out_buf.dst = kmap(out_page); 522 519 workspace->out_buf.pos = 0; 523 520 workspace->out_buf.size = min_t(size_t, max_out, PAGE_SIZE); 524 521 } ··· 534 531 out: 535 532 *out_pages = nr_pages; 536 533 /* Cleanup */ 537 - if (in_page) 534 + if (in_page) { 535 + kunmap(in_page); 538 536 put_page(in_page); 537 + } 538 + if (out_page) 539 + kunmap(out_page); 539 540 return ret; 540 541 } 541 542 ··· 563 556 goto done; 564 557 } 565 558 566 - workspace->in_buf.src = page_address(pages_in[page_in_index]); 559 + workspace->in_buf.src = kmap(pages_in[page_in_index]); 567 560 workspace->in_buf.pos = 0; 568 561 workspace->in_buf.size = min_t(size_t, srclen, PAGE_SIZE); 569 562 ··· 599 592 break; 600 593 601 594 if (workspace->in_buf.pos == workspace->in_buf.size) { 602 - page_in_index++; 595 + kunmap(pages_in[page_in_index++]); 603 596 if (page_in_index >= total_pages_in) { 604 597 workspace->in_buf.src = NULL; 605 598 ret = -EIO; 606 599 goto done; 607 600 } 608 601 srclen -= PAGE_SIZE; 609 - workspace->in_buf.src = page_address(pages_in[page_in_index]); 602 + workspace->in_buf.src = kmap(pages_in[page_in_index]); 610 603 workspace->in_buf.pos = 0; 611 604 workspace->in_buf.size = min_t(size_t, srclen, PAGE_SIZE); 612 605 } ··· 614 607 ret = 0; 615 608 zero_fill_bio(cb->orig_bio); 616 609 done: 610 + if (workspace->in_buf.src) 611 + kunmap(pages_in[page_in_index]); 617 612 return ret; 618 613 } 619 614