.. | .. |
---|
12 | 12 | #include <linux/lzo.h> |
---|
13 | 13 | #include <linux/lz4.h> |
---|
14 | 14 | #include <linux/zstd.h> |
---|
15 | | -#include <linux/moduleparam.h> |
---|
| 15 | +#include <linux/pagevec.h> |
---|
16 | 16 | |
---|
17 | 17 | #include "f2fs.h" |
---|
18 | 18 | #include "node.h" |
---|
| 19 | +#include "segment.h" |
---|
19 | 20 | #include <trace/events/f2fs.h> |
---|
| 21 | + |
---|
| 22 | +static struct kmem_cache *cic_entry_slab; |
---|
| 23 | +static struct kmem_cache *dic_entry_slab; |
---|
| 24 | + |
---|
| 25 | +static void *page_array_alloc(struct inode *inode, int nr) |
---|
| 26 | +{ |
---|
| 27 | + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
---|
| 28 | + unsigned int size = sizeof(struct page *) * nr; |
---|
| 29 | + |
---|
| 30 | + if (likely(size <= sbi->page_array_slab_size)) |
---|
| 31 | + return kmem_cache_zalloc(sbi->page_array_slab, GFP_NOFS); |
---|
| 32 | + return f2fs_kzalloc(sbi, size, GFP_NOFS); |
---|
| 33 | +} |
---|
| 34 | + |
---|
| 35 | +static void page_array_free(struct inode *inode, void *pages, int nr) |
---|
| 36 | +{ |
---|
| 37 | + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
---|
| 38 | + unsigned int size = sizeof(struct page *) * nr; |
---|
| 39 | + |
---|
| 40 | + if (!pages) |
---|
| 41 | + return; |
---|
| 42 | + |
---|
| 43 | + if (likely(size <= sbi->page_array_slab_size)) |
---|
| 44 | + kmem_cache_free(sbi->page_array_slab, pages); |
---|
| 45 | + else |
---|
| 46 | + kfree(pages); |
---|
| 47 | +} |
---|
20 | 48 | |
---|
21 | 49 | struct f2fs_compress_ops { |
---|
22 | 50 | int (*init_compress_ctx)(struct compress_ctx *cc); |
---|
.. | .. |
---|
48 | 76 | return false; |
---|
49 | 77 | if (!page_private(page)) |
---|
50 | 78 | return false; |
---|
51 | | - if (IS_ATOMIC_WRITTEN_PAGE(page) || IS_DUMMY_WRITTEN_PAGE(page)) |
---|
| 79 | + if (page_private_nonpointer(page)) |
---|
52 | 80 | return false; |
---|
| 81 | + |
---|
53 | 82 | f2fs_bug_on(F2FS_M_SB(page->mapping), |
---|
54 | 83 | *((u32 *)page_private(page)) != F2FS_COMPRESSED_PAGE_MAGIC); |
---|
55 | 84 | return true; |
---|
.. | .. |
---|
58 | 87 | static void f2fs_set_compressed_page(struct page *page, |
---|
59 | 88 | struct inode *inode, pgoff_t index, void *data) |
---|
60 | 89 | { |
---|
61 | | - SetPagePrivate(page); |
---|
62 | | - set_page_private(page, (unsigned long)data); |
---|
| 90 | + attach_page_private(page, (void *)data); |
---|
63 | 91 | |
---|
64 | 92 | /* i_crypto_info and iv index */ |
---|
65 | 93 | page->index = index; |
---|
.. | .. |
---|
90 | 118 | f2fs_drop_rpages(cc, len, true); |
---|
91 | 119 | } |
---|
92 | 120 | |
---|
93 | | -static void f2fs_put_rpages_mapping(struct address_space *mapping, |
---|
94 | | - pgoff_t start, int len) |
---|
95 | | -{ |
---|
96 | | - int i; |
---|
97 | | - |
---|
98 | | - for (i = 0; i < len; i++) { |
---|
99 | | - struct page *page = find_get_page(mapping, start + i); |
---|
100 | | - |
---|
101 | | - put_page(page); |
---|
102 | | - put_page(page); |
---|
103 | | - } |
---|
104 | | -} |
---|
105 | | - |
---|
106 | 121 | static void f2fs_put_rpages_wbc(struct compress_ctx *cc, |
---|
107 | 122 | struct writeback_control *wbc, bool redirty, int unlock) |
---|
108 | 123 | { |
---|
.. | .. |
---|
124 | 139 | |
---|
125 | 140 | int f2fs_init_compress_ctx(struct compress_ctx *cc) |
---|
126 | 141 | { |
---|
127 | | - struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); |
---|
128 | | - |
---|
129 | | - if (cc->nr_rpages) |
---|
| 142 | + if (cc->rpages) |
---|
130 | 143 | return 0; |
---|
131 | 144 | |
---|
132 | | - cc->rpages = f2fs_kzalloc(sbi, sizeof(struct page *) << |
---|
133 | | - cc->log_cluster_size, GFP_NOFS); |
---|
| 145 | + cc->rpages = page_array_alloc(cc->inode, cc->cluster_size); |
---|
134 | 146 | return cc->rpages ? 0 : -ENOMEM; |
---|
135 | 147 | } |
---|
136 | 148 | |
---|
137 | | -void f2fs_destroy_compress_ctx(struct compress_ctx *cc) |
---|
| 149 | +void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse) |
---|
138 | 150 | { |
---|
139 | | - kfree(cc->rpages); |
---|
| 151 | + page_array_free(cc->inode, cc->rpages, cc->cluster_size); |
---|
140 | 152 | cc->rpages = NULL; |
---|
141 | 153 | cc->nr_rpages = 0; |
---|
142 | 154 | cc->nr_cpages = 0; |
---|
143 | | - cc->cluster_idx = NULL_CLUSTER; |
---|
| 155 | + if (!reuse) |
---|
| 156 | + cc->cluster_idx = NULL_CLUSTER; |
---|
144 | 157 | } |
---|
145 | 158 | |
---|
146 | 159 | void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page) |
---|
.. | .. |
---|
222 | 235 | #ifdef CONFIG_F2FS_FS_LZ4 |
---|
223 | 236 | static int lz4_init_compress_ctx(struct compress_ctx *cc) |
---|
224 | 237 | { |
---|
225 | | - cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), |
---|
226 | | - LZ4_MEM_COMPRESS, GFP_NOFS); |
---|
| 238 | + unsigned int size = LZ4_MEM_COMPRESS; |
---|
| 239 | + |
---|
| 240 | +#ifdef CONFIG_F2FS_FS_LZ4HC |
---|
| 241 | + if (F2FS_I(cc->inode)->i_compress_flag >> COMPRESS_LEVEL_OFFSET) |
---|
| 242 | + size = LZ4HC_MEM_COMPRESS; |
---|
| 243 | +#endif |
---|
| 244 | + |
---|
| 245 | + cc->private = f2fs_kvmalloc(F2FS_I_SB(cc->inode), size, GFP_NOFS); |
---|
227 | 246 | if (!cc->private) |
---|
228 | 247 | return -ENOMEM; |
---|
229 | 248 | |
---|
.. | .. |
---|
242 | 261 | cc->private = NULL; |
---|
243 | 262 | } |
---|
244 | 263 | |
---|
| 264 | +#ifdef CONFIG_F2FS_FS_LZ4HC |
---|
| 265 | +static int lz4hc_compress_pages(struct compress_ctx *cc) |
---|
| 266 | +{ |
---|
| 267 | + unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> |
---|
| 268 | + COMPRESS_LEVEL_OFFSET; |
---|
| 269 | + int len; |
---|
| 270 | + |
---|
| 271 | + if (level) |
---|
| 272 | + len = LZ4_compress_HC(cc->rbuf, cc->cbuf->cdata, cc->rlen, |
---|
| 273 | + cc->clen, level, cc->private); |
---|
| 274 | + else |
---|
| 275 | + len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen, |
---|
| 276 | + cc->clen, cc->private); |
---|
| 277 | + if (!len) |
---|
| 278 | + return -EAGAIN; |
---|
| 279 | + |
---|
| 280 | + cc->clen = len; |
---|
| 281 | + return 0; |
---|
| 282 | +} |
---|
| 283 | +#endif |
---|
| 284 | + |
---|
245 | 285 | static int lz4_compress_pages(struct compress_ctx *cc) |
---|
246 | 286 | { |
---|
247 | 287 | int len; |
---|
248 | 288 | |
---|
| 289 | +#ifdef CONFIG_F2FS_FS_LZ4HC |
---|
| 290 | + return lz4hc_compress_pages(cc); |
---|
| 291 | +#endif |
---|
249 | 292 | len = LZ4_compress_default(cc->rbuf, cc->cbuf->cdata, cc->rlen, |
---|
250 | 293 | cc->clen, cc->private); |
---|
251 | 294 | if (!len) |
---|
.. | .. |
---|
268 | 311 | } |
---|
269 | 312 | |
---|
270 | 313 | if (ret != PAGE_SIZE << dic->log_cluster_size) { |
---|
271 | | - printk_ratelimited("%sF2FS-fs (%s): lz4 invalid rlen:%zu, " |
---|
| 314 | + printk_ratelimited("%sF2FS-fs (%s): lz4 invalid ret:%d, " |
---|
272 | 315 | "expected:%lu\n", KERN_ERR, |
---|
273 | | - F2FS_I_SB(dic->inode)->sb->s_id, |
---|
274 | | - dic->rlen, |
---|
| 316 | + F2FS_I_SB(dic->inode)->sb->s_id, ret, |
---|
275 | 317 | PAGE_SIZE << dic->log_cluster_size); |
---|
276 | 318 | return -EIO; |
---|
277 | 319 | } |
---|
.. | .. |
---|
295 | 337 | ZSTD_CStream *stream; |
---|
296 | 338 | void *workspace; |
---|
297 | 339 | unsigned int workspace_size; |
---|
| 340 | + unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> |
---|
| 341 | + COMPRESS_LEVEL_OFFSET; |
---|
298 | 342 | |
---|
299 | | - params = ZSTD_getParams(F2FS_ZSTD_DEFAULT_CLEVEL, cc->rlen, 0); |
---|
| 343 | + if (!level) |
---|
| 344 | + level = F2FS_ZSTD_DEFAULT_CLEVEL; |
---|
| 345 | + |
---|
| 346 | + params = ZSTD_getParams(level, cc->rlen, 0); |
---|
300 | 347 | workspace_size = ZSTD_CStreamWorkspaceBound(params.cParams); |
---|
301 | 348 | |
---|
302 | 349 | workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode), |
---|
.. | .. |
---|
376 | 423 | ZSTD_DStream *stream; |
---|
377 | 424 | void *workspace; |
---|
378 | 425 | unsigned int workspace_size; |
---|
| 426 | + unsigned int max_window_size = |
---|
| 427 | + MAX_COMPRESS_WINDOW_SIZE(dic->log_cluster_size); |
---|
379 | 428 | |
---|
380 | | - workspace_size = ZSTD_DStreamWorkspaceBound(MAX_COMPRESS_WINDOW_SIZE); |
---|
| 429 | + workspace_size = ZSTD_DStreamWorkspaceBound(max_window_size); |
---|
381 | 430 | |
---|
382 | 431 | workspace = f2fs_kvmalloc(F2FS_I_SB(dic->inode), |
---|
383 | 432 | workspace_size, GFP_NOFS); |
---|
384 | 433 | if (!workspace) |
---|
385 | 434 | return -ENOMEM; |
---|
386 | 435 | |
---|
387 | | - stream = ZSTD_initDStream(MAX_COMPRESS_WINDOW_SIZE, |
---|
388 | | - workspace, workspace_size); |
---|
| 436 | + stream = ZSTD_initDStream(max_window_size, workspace, workspace_size); |
---|
389 | 437 | if (!stream) { |
---|
390 | 438 | printk_ratelimited("%sF2FS-fs (%s): %s ZSTD_initDStream failed\n", |
---|
391 | 439 | KERN_ERR, F2FS_I_SB(dic->inode)->sb->s_id, |
---|
.. | .. |
---|
452 | 500 | }; |
---|
453 | 501 | #endif |
---|
454 | 502 | |
---|
| 503 | +#ifdef CONFIG_F2FS_FS_LZO |
---|
| 504 | +#ifdef CONFIG_F2FS_FS_LZORLE |
---|
| 505 | +static int lzorle_compress_pages(struct compress_ctx *cc) |
---|
| 506 | +{ |
---|
| 507 | + int ret; |
---|
| 508 | + |
---|
| 509 | + ret = lzorle1x_1_compress(cc->rbuf, cc->rlen, cc->cbuf->cdata, |
---|
| 510 | + &cc->clen, cc->private); |
---|
| 511 | + if (ret != LZO_E_OK) { |
---|
| 512 | + printk_ratelimited("%sF2FS-fs (%s): lzo-rle compress failed, ret:%d\n", |
---|
| 513 | + KERN_ERR, F2FS_I_SB(cc->inode)->sb->s_id, ret); |
---|
| 514 | + return -EIO; |
---|
| 515 | + } |
---|
| 516 | + return 0; |
---|
| 517 | +} |
---|
| 518 | + |
---|
| 519 | +static const struct f2fs_compress_ops f2fs_lzorle_ops = { |
---|
| 520 | + .init_compress_ctx = lzo_init_compress_ctx, |
---|
| 521 | + .destroy_compress_ctx = lzo_destroy_compress_ctx, |
---|
| 522 | + .compress_pages = lzorle_compress_pages, |
---|
| 523 | + .decompress_pages = lzo_decompress_pages, |
---|
| 524 | +}; |
---|
| 525 | +#endif |
---|
| 526 | +#endif |
---|
| 527 | + |
---|
455 | 528 | static const struct f2fs_compress_ops *f2fs_cops[COMPRESS_MAX] = { |
---|
456 | 529 | #ifdef CONFIG_F2FS_FS_LZO |
---|
457 | 530 | &f2fs_lzo_ops, |
---|
.. | .. |
---|
468 | 541 | #else |
---|
469 | 542 | NULL, |
---|
470 | 543 | #endif |
---|
| 544 | +#if defined(CONFIG_F2FS_FS_LZO) && defined(CONFIG_F2FS_FS_LZORLE) |
---|
| 545 | + &f2fs_lzorle_ops, |
---|
| 546 | +#else |
---|
| 547 | + NULL, |
---|
| 548 | +#endif |
---|
471 | 549 | }; |
---|
472 | 550 | |
---|
473 | 551 | bool f2fs_is_compress_backend_ready(struct inode *inode) |
---|
.. | .. |
---|
477 | 555 | return f2fs_cops[F2FS_I(inode)->i_compress_algorithm]; |
---|
478 | 556 | } |
---|
479 | 557 | |
---|
480 | | -static mempool_t *compress_page_pool = NULL; |
---|
| 558 | +static mempool_t *compress_page_pool; |
---|
481 | 559 | static int num_compress_pages = 512; |
---|
482 | 560 | module_param(num_compress_pages, uint, 0444); |
---|
483 | 561 | MODULE_PARM_DESC(num_compress_pages, |
---|
.. | .. |
---|
511 | 589 | { |
---|
512 | 590 | if (!page) |
---|
513 | 591 | return; |
---|
514 | | - set_page_private(page, (unsigned long)NULL); |
---|
515 | | - ClearPagePrivate(page); |
---|
| 592 | + detach_page_private(page); |
---|
516 | 593 | page->mapping = NULL; |
---|
517 | 594 | unlock_page(page); |
---|
518 | 595 | mempool_free(page, compress_page_pool); |
---|
519 | 596 | } |
---|
520 | 597 | |
---|
| 598 | +#define MAX_VMAP_RETRIES 3 |
---|
| 599 | + |
---|
| 600 | +static void *f2fs_vmap(struct page **pages, unsigned int count) |
---|
| 601 | +{ |
---|
| 602 | + int i; |
---|
| 603 | + void *buf = NULL; |
---|
| 604 | + |
---|
| 605 | + for (i = 0; i < MAX_VMAP_RETRIES; i++) { |
---|
| 606 | + buf = vm_map_ram(pages, count, -1); |
---|
| 607 | + if (buf) |
---|
| 608 | + break; |
---|
| 609 | + vm_unmap_aliases(); |
---|
| 610 | + } |
---|
| 611 | + return buf; |
---|
| 612 | +} |
---|
| 613 | + |
---|
521 | 614 | static int f2fs_compress_pages(struct compress_ctx *cc) |
---|
522 | 615 | { |
---|
523 | | - struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); |
---|
524 | 616 | struct f2fs_inode_info *fi = F2FS_I(cc->inode); |
---|
525 | 617 | const struct f2fs_compress_ops *cops = |
---|
526 | 618 | f2fs_cops[fi->i_compress_algorithm]; |
---|
527 | | - unsigned int max_len, nr_cpages; |
---|
| 619 | + unsigned int max_len, new_nr_cpages; |
---|
| 620 | + struct page **new_cpages; |
---|
| 621 | + u32 chksum = 0; |
---|
528 | 622 | int i, ret; |
---|
529 | 623 | |
---|
530 | 624 | trace_f2fs_compress_pages_start(cc->inode, cc->cluster_idx, |
---|
.. | .. |
---|
539 | 633 | max_len = COMPRESS_HEADER_SIZE + cc->clen; |
---|
540 | 634 | cc->nr_cpages = DIV_ROUND_UP(max_len, PAGE_SIZE); |
---|
541 | 635 | |
---|
542 | | - cc->cpages = f2fs_kzalloc(sbi, sizeof(struct page *) * |
---|
543 | | - cc->nr_cpages, GFP_NOFS); |
---|
| 636 | + cc->cpages = page_array_alloc(cc->inode, cc->nr_cpages); |
---|
544 | 637 | if (!cc->cpages) { |
---|
545 | 638 | ret = -ENOMEM; |
---|
546 | 639 | goto destroy_compress_ctx; |
---|
.. | .. |
---|
554 | 647 | } |
---|
555 | 648 | } |
---|
556 | 649 | |
---|
557 | | - cc->rbuf = vmap(cc->rpages, cc->cluster_size, VM_MAP, PAGE_KERNEL_RO); |
---|
| 650 | + cc->rbuf = f2fs_vmap(cc->rpages, cc->cluster_size); |
---|
558 | 651 | if (!cc->rbuf) { |
---|
559 | 652 | ret = -ENOMEM; |
---|
560 | 653 | goto out_free_cpages; |
---|
561 | 654 | } |
---|
562 | 655 | |
---|
563 | | - cc->cbuf = vmap(cc->cpages, cc->nr_cpages, VM_MAP, PAGE_KERNEL); |
---|
| 656 | + cc->cbuf = f2fs_vmap(cc->cpages, cc->nr_cpages); |
---|
564 | 657 | if (!cc->cbuf) { |
---|
565 | 658 | ret = -ENOMEM; |
---|
566 | 659 | goto out_vunmap_rbuf; |
---|
.. | .. |
---|
579 | 672 | |
---|
580 | 673 | cc->cbuf->clen = cpu_to_le32(cc->clen); |
---|
581 | 674 | |
---|
| 675 | + if (fi->i_compress_flag & 1 << COMPRESS_CHKSUM) |
---|
| 676 | + chksum = f2fs_crc32(F2FS_I_SB(cc->inode), |
---|
| 677 | + cc->cbuf->cdata, cc->clen); |
---|
| 678 | + cc->cbuf->chksum = cpu_to_le32(chksum); |
---|
| 679 | + |
---|
582 | 680 | for (i = 0; i < COMPRESS_DATA_RESERVED_SIZE; i++) |
---|
583 | 681 | cc->cbuf->reserved[i] = cpu_to_le32(0); |
---|
584 | 682 | |
---|
585 | | - nr_cpages = DIV_ROUND_UP(cc->clen + COMPRESS_HEADER_SIZE, PAGE_SIZE); |
---|
| 683 | + new_nr_cpages = DIV_ROUND_UP(cc->clen + COMPRESS_HEADER_SIZE, PAGE_SIZE); |
---|
| 684 | + |
---|
| 685 | + /* Now we're going to cut unnecessary tail pages */ |
---|
| 686 | + new_cpages = page_array_alloc(cc->inode, new_nr_cpages); |
---|
| 687 | + if (!new_cpages) { |
---|
| 688 | + ret = -ENOMEM; |
---|
| 689 | + goto out_vunmap_cbuf; |
---|
| 690 | + } |
---|
586 | 691 | |
---|
587 | 692 | /* zero out any unused part of the last page */ |
---|
588 | 693 | memset(&cc->cbuf->cdata[cc->clen], 0, |
---|
589 | | - (nr_cpages * PAGE_SIZE) - (cc->clen + COMPRESS_HEADER_SIZE)); |
---|
| 694 | + (new_nr_cpages * PAGE_SIZE) - |
---|
| 695 | + (cc->clen + COMPRESS_HEADER_SIZE)); |
---|
590 | 696 | |
---|
591 | | - vunmap(cc->cbuf); |
---|
592 | | - vunmap(cc->rbuf); |
---|
| 697 | + vm_unmap_ram(cc->cbuf, cc->nr_cpages); |
---|
| 698 | + vm_unmap_ram(cc->rbuf, cc->cluster_size); |
---|
593 | 699 | |
---|
594 | | - for (i = nr_cpages; i < cc->nr_cpages; i++) { |
---|
| 700 | + for (i = 0; i < cc->nr_cpages; i++) { |
---|
| 701 | + if (i < new_nr_cpages) { |
---|
| 702 | + new_cpages[i] = cc->cpages[i]; |
---|
| 703 | + continue; |
---|
| 704 | + } |
---|
595 | 705 | f2fs_compress_free_page(cc->cpages[i]); |
---|
596 | 706 | cc->cpages[i] = NULL; |
---|
597 | 707 | } |
---|
.. | .. |
---|
599 | 709 | if (cops->destroy_compress_ctx) |
---|
600 | 710 | cops->destroy_compress_ctx(cc); |
---|
601 | 711 | |
---|
602 | | - cc->nr_cpages = nr_cpages; |
---|
| 712 | + page_array_free(cc->inode, cc->cpages, cc->nr_cpages); |
---|
| 713 | + cc->cpages = new_cpages; |
---|
| 714 | + cc->nr_cpages = new_nr_cpages; |
---|
603 | 715 | |
---|
604 | 716 | trace_f2fs_compress_pages_end(cc->inode, cc->cluster_idx, |
---|
605 | 717 | cc->clen, ret); |
---|
606 | 718 | return 0; |
---|
607 | 719 | |
---|
608 | 720 | out_vunmap_cbuf: |
---|
609 | | - vunmap(cc->cbuf); |
---|
| 721 | + vm_unmap_ram(cc->cbuf, cc->nr_cpages); |
---|
610 | 722 | out_vunmap_rbuf: |
---|
611 | | - vunmap(cc->rbuf); |
---|
| 723 | + vm_unmap_ram(cc->rbuf, cc->cluster_size); |
---|
612 | 724 | out_free_cpages: |
---|
613 | 725 | for (i = 0; i < cc->nr_cpages; i++) { |
---|
614 | 726 | if (cc->cpages[i]) |
---|
615 | 727 | f2fs_compress_free_page(cc->cpages[i]); |
---|
616 | 728 | } |
---|
617 | | - kfree(cc->cpages); |
---|
| 729 | + page_array_free(cc->inode, cc->cpages, cc->nr_cpages); |
---|
618 | 730 | cc->cpages = NULL; |
---|
619 | 731 | destroy_compress_ctx: |
---|
620 | 732 | if (cops->destroy_compress_ctx) |
---|
.. | .. |
---|
625 | 737 | return ret; |
---|
626 | 738 | } |
---|
627 | 739 | |
---|
628 | | -void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity) |
---|
| 740 | +static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, |
---|
| 741 | + bool pre_alloc); |
---|
| 742 | +static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, |
---|
| 743 | + bool bypass_destroy_callback, bool pre_alloc); |
---|
| 744 | + |
---|
| 745 | +void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) |
---|
629 | 746 | { |
---|
630 | | - struct decompress_io_ctx *dic = |
---|
631 | | - (struct decompress_io_ctx *)page_private(page); |
---|
632 | 747 | struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); |
---|
633 | | - struct f2fs_inode_info *fi= F2FS_I(dic->inode); |
---|
| 748 | + struct f2fs_inode_info *fi = F2FS_I(dic->inode); |
---|
634 | 749 | const struct f2fs_compress_ops *cops = |
---|
635 | 750 | f2fs_cops[fi->i_compress_algorithm]; |
---|
| 751 | + bool bypass_callback = false; |
---|
636 | 752 | int ret; |
---|
637 | | - |
---|
638 | | - dec_page_count(sbi, F2FS_RD_DATA); |
---|
639 | | - |
---|
640 | | - if (bio->bi_status || PageError(page)) |
---|
641 | | - dic->failed = true; |
---|
642 | | - |
---|
643 | | - if (refcount_dec_not_one(&dic->ref)) |
---|
644 | | - return; |
---|
645 | 753 | |
---|
646 | 754 | trace_f2fs_decompress_pages_start(dic->inode, dic->cluster_idx, |
---|
647 | 755 | dic->cluster_size, fi->i_compress_algorithm); |
---|
648 | 756 | |
---|
649 | | - /* submit partial compressed pages */ |
---|
650 | 757 | if (dic->failed) { |
---|
651 | 758 | ret = -EIO; |
---|
652 | | - goto out_free_dic; |
---|
| 759 | + goto out_end_io; |
---|
653 | 760 | } |
---|
654 | 761 | |
---|
655 | | - if (cops->init_decompress_ctx) { |
---|
656 | | - ret = cops->init_decompress_ctx(dic); |
---|
657 | | - if (ret) |
---|
658 | | - goto out_free_dic; |
---|
659 | | - } |
---|
660 | | - |
---|
661 | | - dic->rbuf = vmap(dic->tpages, dic->cluster_size, VM_MAP, PAGE_KERNEL); |
---|
662 | | - if (!dic->rbuf) { |
---|
663 | | - ret = -ENOMEM; |
---|
664 | | - goto destroy_decompress_ctx; |
---|
665 | | - } |
---|
666 | | - |
---|
667 | | - dic->cbuf = vmap(dic->cpages, dic->nr_cpages, VM_MAP, PAGE_KERNEL_RO); |
---|
668 | | - if (!dic->cbuf) { |
---|
669 | | - ret = -ENOMEM; |
---|
670 | | - goto out_vunmap_rbuf; |
---|
| 762 | + ret = f2fs_prepare_decomp_mem(dic, false); |
---|
| 763 | + if (ret) { |
---|
| 764 | + bypass_callback = true; |
---|
| 765 | + goto out_release; |
---|
671 | 766 | } |
---|
672 | 767 | |
---|
673 | 768 | dic->clen = le32_to_cpu(dic->cbuf->clen); |
---|
.. | .. |
---|
675 | 770 | |
---|
676 | 771 | if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) { |
---|
677 | 772 | ret = -EFSCORRUPTED; |
---|
678 | | - goto out_vunmap_cbuf; |
---|
| 773 | + goto out_release; |
---|
679 | 774 | } |
---|
680 | 775 | |
---|
681 | 776 | ret = cops->decompress_pages(dic); |
---|
682 | 777 | |
---|
683 | | -out_vunmap_cbuf: |
---|
684 | | - vunmap(dic->cbuf); |
---|
685 | | -out_vunmap_rbuf: |
---|
686 | | - vunmap(dic->rbuf); |
---|
687 | | -destroy_decompress_ctx: |
---|
688 | | - if (cops->destroy_decompress_ctx) |
---|
689 | | - cops->destroy_decompress_ctx(dic); |
---|
690 | | -out_free_dic: |
---|
691 | | - if (verity) |
---|
692 | | - refcount_set(&dic->ref, dic->nr_cpages); |
---|
693 | | - if (!verity) |
---|
694 | | - f2fs_decompress_end_io(dic->rpages, dic->cluster_size, |
---|
695 | | - ret, false); |
---|
| 778 | + if (!ret && (fi->i_compress_flag & 1 << COMPRESS_CHKSUM)) { |
---|
| 779 | + u32 provided = le32_to_cpu(dic->cbuf->chksum); |
---|
| 780 | + u32 calculated = f2fs_crc32(sbi, dic->cbuf->cdata, dic->clen); |
---|
696 | 781 | |
---|
| 782 | + if (provided != calculated) { |
---|
| 783 | + if (!is_inode_flag_set(dic->inode, FI_COMPRESS_CORRUPT)) { |
---|
| 784 | + set_inode_flag(dic->inode, FI_COMPRESS_CORRUPT); |
---|
| 785 | + printk_ratelimited( |
---|
| 786 | + "%sF2FS-fs (%s): checksum invalid, nid = %lu, %x vs %x", |
---|
| 787 | + KERN_INFO, sbi->sb->s_id, dic->inode->i_ino, |
---|
| 788 | + provided, calculated); |
---|
| 789 | + } |
---|
| 790 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
---|
| 791 | + } |
---|
| 792 | + } |
---|
| 793 | + |
---|
| 794 | +out_release: |
---|
| 795 | + f2fs_release_decomp_mem(dic, bypass_callback, false); |
---|
| 796 | + |
---|
| 797 | +out_end_io: |
---|
697 | 798 | trace_f2fs_decompress_pages_end(dic->inode, dic->cluster_idx, |
---|
698 | 799 | dic->clen, ret); |
---|
699 | | - if (!verity) |
---|
700 | | - f2fs_free_dic(dic); |
---|
| 800 | + f2fs_decompress_end_io(dic, ret, in_task); |
---|
| 801 | +} |
---|
| 802 | + |
---|
| 803 | +/* |
---|
| 804 | + * This is called when a page of a compressed cluster has been read from disk |
---|
| 805 | + * (or failed to be read from disk). It checks whether this page was the last |
---|
| 806 | + * page being waited on in the cluster, and if so, it decompresses the cluster |
---|
| 807 | + * (or in the case of a failure, cleans up without actually decompressing). |
---|
| 808 | + */ |
---|
| 809 | +void f2fs_end_read_compressed_page(struct page *page, bool failed, |
---|
| 810 | + block_t blkaddr, bool in_task) |
---|
| 811 | +{ |
---|
| 812 | + struct decompress_io_ctx *dic = |
---|
| 813 | + (struct decompress_io_ctx *)page_private(page); |
---|
| 814 | + struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); |
---|
| 815 | + |
---|
| 816 | + dec_page_count(sbi, F2FS_RD_DATA); |
---|
| 817 | + |
---|
| 818 | + if (failed) |
---|
| 819 | + WRITE_ONCE(dic->failed, true); |
---|
| 820 | + else if (blkaddr && in_task) |
---|
| 821 | + f2fs_cache_compressed_page(sbi, page, |
---|
| 822 | + dic->inode->i_ino, blkaddr); |
---|
| 823 | + |
---|
| 824 | + if (atomic_dec_and_test(&dic->remaining_pages)) |
---|
| 825 | + f2fs_decompress_cluster(dic, in_task); |
---|
701 | 826 | } |
---|
702 | 827 | |
---|
703 | 828 | static bool is_page_in_cluster(struct compress_ctx *cc, pgoff_t index) |
---|
.. | .. |
---|
724 | 849 | return is_page_in_cluster(cc, index); |
---|
725 | 850 | } |
---|
726 | 851 | |
---|
727 | | -static bool __cluster_may_compress(struct compress_ctx *cc) |
---|
| 852 | +static bool cluster_has_invalid_data(struct compress_ctx *cc) |
---|
728 | 853 | { |
---|
729 | | - struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); |
---|
730 | 854 | loff_t i_size = i_size_read(cc->inode); |
---|
731 | 855 | unsigned nr_pages = DIV_ROUND_UP(i_size, PAGE_SIZE); |
---|
732 | 856 | int i; |
---|
.. | .. |
---|
734 | 858 | for (i = 0; i < cc->cluster_size; i++) { |
---|
735 | 859 | struct page *page = cc->rpages[i]; |
---|
736 | 860 | |
---|
737 | | - f2fs_bug_on(sbi, !page); |
---|
738 | | - |
---|
739 | | - if (unlikely(f2fs_cp_error(sbi))) |
---|
740 | | - return false; |
---|
741 | | - if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) |
---|
742 | | - return false; |
---|
| 861 | + f2fs_bug_on(F2FS_I_SB(cc->inode), !page); |
---|
743 | 862 | |
---|
744 | 863 | /* beyond EOF */ |
---|
745 | 864 | if (page->index >= nr_pages) |
---|
746 | | - return false; |
---|
| 865 | + return true; |
---|
747 | 866 | } |
---|
748 | | - return true; |
---|
| 867 | + return false; |
---|
749 | 868 | } |
---|
750 | 869 | |
---|
751 | | -static int __f2fs_cluster_blocks(struct compress_ctx *cc, bool compr) |
---|
| 870 | +static int __f2fs_cluster_blocks(struct inode *inode, |
---|
| 871 | + unsigned int cluster_idx, bool compr) |
---|
752 | 872 | { |
---|
753 | 873 | struct dnode_of_data dn; |
---|
| 874 | + unsigned int cluster_size = F2FS_I(inode)->i_cluster_size; |
---|
| 875 | + unsigned int start_idx = cluster_idx << |
---|
| 876 | + F2FS_I(inode)->i_log_cluster_size; |
---|
754 | 877 | int ret; |
---|
755 | 878 | |
---|
756 | | - set_new_dnode(&dn, cc->inode, NULL, NULL, 0); |
---|
757 | | - ret = f2fs_get_dnode_of_data(&dn, start_idx_of_cluster(cc), |
---|
758 | | - LOOKUP_NODE); |
---|
| 879 | + set_new_dnode(&dn, inode, NULL, NULL, 0); |
---|
| 880 | + ret = f2fs_get_dnode_of_data(&dn, start_idx, LOOKUP_NODE); |
---|
759 | 881 | if (ret) { |
---|
760 | 882 | if (ret == -ENOENT) |
---|
761 | 883 | ret = 0; |
---|
.. | .. |
---|
766 | 888 | int i; |
---|
767 | 889 | |
---|
768 | 890 | ret = 1; |
---|
769 | | - for (i = 1; i < cc->cluster_size; i++) { |
---|
| 891 | + for (i = 1; i < cluster_size; i++) { |
---|
770 | 892 | block_t blkaddr; |
---|
771 | 893 | |
---|
772 | 894 | blkaddr = data_blkaddr(dn.inode, |
---|
.. | .. |
---|
779 | 901 | ret++; |
---|
780 | 902 | } |
---|
781 | 903 | } |
---|
| 904 | + |
---|
| 905 | + f2fs_bug_on(F2FS_I_SB(inode), |
---|
| 906 | + !compr && ret != cluster_size && |
---|
| 907 | + !is_inode_flag_set(inode, FI_COMPRESS_RELEASED)); |
---|
782 | 908 | } |
---|
783 | 909 | fail: |
---|
784 | 910 | f2fs_put_dnode(&dn); |
---|
.. | .. |
---|
788 | 914 | /* return # of compressed blocks in compressed cluster */ |
---|
789 | 915 | static int f2fs_compressed_blocks(struct compress_ctx *cc) |
---|
790 | 916 | { |
---|
791 | | - return __f2fs_cluster_blocks(cc, true); |
---|
| 917 | + return __f2fs_cluster_blocks(cc->inode, cc->cluster_idx, true); |
---|
792 | 918 | } |
---|
793 | 919 | |
---|
794 | 920 | /* return # of valid blocks in compressed cluster */ |
---|
795 | | -static int f2fs_cluster_blocks(struct compress_ctx *cc, bool compr) |
---|
796 | | -{ |
---|
797 | | - return __f2fs_cluster_blocks(cc, false); |
---|
798 | | -} |
---|
799 | | - |
---|
800 | 921 | int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index) |
---|
801 | 922 | { |
---|
802 | | - struct compress_ctx cc = { |
---|
803 | | - .inode = inode, |
---|
804 | | - .log_cluster_size = F2FS_I(inode)->i_log_cluster_size, |
---|
805 | | - .cluster_size = F2FS_I(inode)->i_cluster_size, |
---|
806 | | - .cluster_idx = index >> F2FS_I(inode)->i_log_cluster_size, |
---|
807 | | - }; |
---|
808 | | - |
---|
809 | | - return f2fs_cluster_blocks(&cc, false); |
---|
| 923 | + return __f2fs_cluster_blocks(inode, |
---|
| 924 | + index >> F2FS_I(inode)->i_log_cluster_size, |
---|
| 925 | + false); |
---|
810 | 926 | } |
---|
811 | 927 | |
---|
812 | 928 | static bool cluster_may_compress(struct compress_ctx *cc) |
---|
813 | 929 | { |
---|
814 | | - if (!f2fs_compressed_file(cc->inode)) |
---|
| 930 | + if (!f2fs_need_compress_data(cc->inode)) |
---|
815 | 931 | return false; |
---|
816 | 932 | if (f2fs_is_atomic_file(cc->inode)) |
---|
817 | | - return false; |
---|
818 | | - if (f2fs_is_mmap_file(cc->inode)) |
---|
819 | 933 | return false; |
---|
820 | 934 | if (!f2fs_cluster_is_full(cc)) |
---|
821 | 935 | return false; |
---|
822 | 936 | if (unlikely(f2fs_cp_error(F2FS_I_SB(cc->inode)))) |
---|
823 | 937 | return false; |
---|
824 | | - return __cluster_may_compress(cc); |
---|
| 938 | + return !cluster_has_invalid_data(cc); |
---|
825 | 939 | } |
---|
826 | 940 | |
---|
827 | 941 | static void set_cluster_writeback(struct compress_ctx *cc) |
---|
.. | .. |
---|
849 | 963 | struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); |
---|
850 | 964 | struct address_space *mapping = cc->inode->i_mapping; |
---|
851 | 965 | struct page *page; |
---|
852 | | - struct dnode_of_data dn; |
---|
853 | 966 | sector_t last_block_in_bio; |
---|
854 | 967 | unsigned fgp_flag = FGP_LOCK | FGP_WRITE | FGP_CREAT; |
---|
855 | 968 | pgoff_t start_idx = start_idx_of_cluster(cc); |
---|
856 | 969 | int i, ret; |
---|
857 | | - bool prealloc; |
---|
858 | 970 | |
---|
859 | 971 | retry: |
---|
860 | | - ret = f2fs_cluster_blocks(cc, false); |
---|
| 972 | + ret = f2fs_is_compressed_cluster(cc->inode, start_idx); |
---|
861 | 973 | if (ret <= 0) |
---|
862 | 974 | return ret; |
---|
863 | | - |
---|
864 | | - /* compressed case */ |
---|
865 | | - prealloc = (ret < cc->cluster_size); |
---|
866 | 975 | |
---|
867 | 976 | ret = f2fs_init_compress_ctx(cc); |
---|
868 | 977 | if (ret) |
---|
.. | .. |
---|
878 | 987 | } |
---|
879 | 988 | |
---|
880 | 989 | if (PageUptodate(page)) |
---|
881 | | - unlock_page(page); |
---|
| 990 | + f2fs_put_page(page, 1); |
---|
882 | 991 | else |
---|
883 | 992 | f2fs_compress_ctx_add_page(cc, page); |
---|
884 | 993 | } |
---|
.. | .. |
---|
888 | 997 | |
---|
889 | 998 | ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size, |
---|
890 | 999 | &last_block_in_bio, false, true); |
---|
891 | | - f2fs_destroy_compress_ctx(cc); |
---|
| 1000 | + f2fs_put_rpages(cc); |
---|
| 1001 | + f2fs_destroy_compress_ctx(cc, true); |
---|
892 | 1002 | if (ret) |
---|
893 | | - goto release_pages; |
---|
| 1003 | + goto out; |
---|
894 | 1004 | if (bio) |
---|
895 | 1005 | f2fs_submit_bio(sbi, bio, DATA); |
---|
896 | 1006 | |
---|
897 | 1007 | ret = f2fs_init_compress_ctx(cc); |
---|
898 | 1008 | if (ret) |
---|
899 | | - goto release_pages; |
---|
| 1009 | + goto out; |
---|
900 | 1010 | } |
---|
901 | 1011 | |
---|
902 | 1012 | for (i = 0; i < cc->cluster_size; i++) { |
---|
903 | 1013 | f2fs_bug_on(sbi, cc->rpages[i]); |
---|
904 | 1014 | |
---|
905 | 1015 | page = find_lock_page(mapping, start_idx + i); |
---|
906 | | - f2fs_bug_on(sbi, !page); |
---|
| 1016 | + if (!page) { |
---|
| 1017 | + /* page can be truncated */ |
---|
| 1018 | + goto release_and_retry; |
---|
| 1019 | + } |
---|
907 | 1020 | |
---|
908 | 1021 | f2fs_wait_on_page_writeback(page, DATA, true, true); |
---|
909 | | - |
---|
910 | 1022 | f2fs_compress_ctx_add_page(cc, page); |
---|
911 | | - f2fs_put_page(page, 0); |
---|
912 | 1023 | |
---|
913 | 1024 | if (!PageUptodate(page)) { |
---|
| 1025 | +release_and_retry: |
---|
| 1026 | + f2fs_put_rpages(cc); |
---|
914 | 1027 | f2fs_unlock_rpages(cc, i + 1); |
---|
915 | | - f2fs_put_rpages_mapping(mapping, start_idx, |
---|
916 | | - cc->cluster_size); |
---|
917 | | - f2fs_destroy_compress_ctx(cc); |
---|
| 1028 | + f2fs_destroy_compress_ctx(cc, true); |
---|
918 | 1029 | goto retry; |
---|
919 | 1030 | } |
---|
920 | | - } |
---|
921 | | - |
---|
922 | | - if (prealloc) { |
---|
923 | | - __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, true); |
---|
924 | | - |
---|
925 | | - set_new_dnode(&dn, cc->inode, NULL, NULL, 0); |
---|
926 | | - |
---|
927 | | - for (i = cc->cluster_size - 1; i > 0; i--) { |
---|
928 | | - ret = f2fs_get_block(&dn, start_idx + i); |
---|
929 | | - if (ret) { |
---|
930 | | - i = cc->cluster_size; |
---|
931 | | - break; |
---|
932 | | - } |
---|
933 | | - |
---|
934 | | - if (dn.data_blkaddr != NEW_ADDR) |
---|
935 | | - break; |
---|
936 | | - } |
---|
937 | | - |
---|
938 | | - __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, false); |
---|
939 | 1031 | } |
---|
940 | 1032 | |
---|
941 | 1033 | if (likely(!ret)) { |
---|
.. | .. |
---|
945 | 1037 | } |
---|
946 | 1038 | |
---|
947 | 1039 | unlock_pages: |
---|
| 1040 | + f2fs_put_rpages(cc); |
---|
948 | 1041 | f2fs_unlock_rpages(cc, i); |
---|
949 | | -release_pages: |
---|
950 | | - f2fs_put_rpages_mapping(mapping, start_idx, i); |
---|
951 | | - f2fs_destroy_compress_ctx(cc); |
---|
| 1042 | + f2fs_destroy_compress_ctx(cc, true); |
---|
| 1043 | +out: |
---|
952 | 1044 | return ret; |
---|
953 | 1045 | } |
---|
954 | 1046 | |
---|
.. | .. |
---|
972 | 1064 | |
---|
973 | 1065 | { |
---|
974 | 1066 | struct compress_ctx cc = { |
---|
| 1067 | + .inode = inode, |
---|
975 | 1068 | .log_cluster_size = F2FS_I(inode)->i_log_cluster_size, |
---|
976 | 1069 | .cluster_size = F2FS_I(inode)->i_cluster_size, |
---|
977 | 1070 | .rpages = fsdata, |
---|
.. | .. |
---|
982 | 1075 | set_cluster_dirty(&cc); |
---|
983 | 1076 | |
---|
984 | 1077 | f2fs_put_rpages_wbc(&cc, NULL, false, 1); |
---|
985 | | - f2fs_destroy_compress_ctx(&cc); |
---|
| 1078 | + f2fs_destroy_compress_ctx(&cc, false); |
---|
986 | 1079 | |
---|
987 | 1080 | return first_index; |
---|
988 | 1081 | } |
---|
.. | .. |
---|
1057 | 1150 | .submitted = false, |
---|
1058 | 1151 | .io_type = io_type, |
---|
1059 | 1152 | .io_wbc = wbc, |
---|
1060 | | - .encrypted = f2fs_encrypted_file(cc->inode), |
---|
| 1153 | + .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode), |
---|
1061 | 1154 | }; |
---|
1062 | 1155 | struct dnode_of_data dn; |
---|
1063 | 1156 | struct node_info ni; |
---|
.. | .. |
---|
1067 | 1160 | loff_t psize; |
---|
1068 | 1161 | int i, err; |
---|
1069 | 1162 | |
---|
1070 | | - if (!IS_NOQUOTA(inode) && !f2fs_trylock_op(sbi)) |
---|
1071 | | - return -EAGAIN; |
---|
| 1163 | + /* we should bypass data pages to proceed the kworkder jobs */ |
---|
| 1164 | + if (unlikely(f2fs_cp_error(sbi))) { |
---|
| 1165 | + mapping_set_error(cc->rpages[0]->mapping, -EIO); |
---|
| 1166 | + goto out_free; |
---|
| 1167 | + } |
---|
| 1168 | + |
---|
| 1169 | + if (IS_NOQUOTA(inode)) { |
---|
| 1170 | + /* |
---|
| 1171 | + * We need to wait for node_write to avoid block allocation during |
---|
| 1172 | + * checkpoint. This can only happen to quota writes which can cause |
---|
| 1173 | + * the below discard race condition. |
---|
| 1174 | + */ |
---|
| 1175 | + f2fs_down_read(&sbi->node_write); |
---|
| 1176 | + } else if (!f2fs_trylock_op(sbi)) { |
---|
| 1177 | + goto out_free; |
---|
| 1178 | + } |
---|
1072 | 1179 | |
---|
1073 | 1180 | set_new_dnode(&dn, cc->inode, NULL, NULL, 0); |
---|
1074 | 1181 | |
---|
.. | .. |
---|
1084 | 1191 | |
---|
1085 | 1192 | psize = (loff_t)(cc->rpages[last_index]->index + 1) << PAGE_SHIFT; |
---|
1086 | 1193 | |
---|
1087 | | - err = f2fs_get_node_info(fio.sbi, dn.nid, &ni); |
---|
| 1194 | + err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false); |
---|
1088 | 1195 | if (err) |
---|
1089 | 1196 | goto out_put_dnode; |
---|
1090 | 1197 | |
---|
1091 | 1198 | fio.version = ni.version; |
---|
1092 | 1199 | |
---|
1093 | | - cic = f2fs_kzalloc(sbi, sizeof(struct compress_io_ctx), GFP_NOFS); |
---|
| 1200 | + cic = kmem_cache_zalloc(cic_entry_slab, GFP_NOFS); |
---|
1094 | 1201 | if (!cic) |
---|
1095 | 1202 | goto out_put_dnode; |
---|
1096 | 1203 | |
---|
1097 | 1204 | cic->magic = F2FS_COMPRESSED_PAGE_MAGIC; |
---|
1098 | 1205 | cic->inode = inode; |
---|
1099 | | - refcount_set(&cic->ref, cc->nr_cpages); |
---|
1100 | | - cic->rpages = f2fs_kzalloc(sbi, sizeof(struct page *) << |
---|
1101 | | - cc->log_cluster_size, GFP_NOFS); |
---|
| 1206 | + atomic_set(&cic->pending_pages, cc->nr_cpages); |
---|
| 1207 | + cic->rpages = page_array_alloc(cc->inode, cc->cluster_size); |
---|
1102 | 1208 | if (!cic->rpages) |
---|
1103 | 1209 | goto out_put_cic; |
---|
1104 | 1210 | |
---|
.. | .. |
---|
1108 | 1214 | f2fs_set_compressed_page(cc->cpages[i], inode, |
---|
1109 | 1215 | cc->rpages[i + 1]->index, cic); |
---|
1110 | 1216 | fio.compressed_page = cc->cpages[i]; |
---|
| 1217 | + |
---|
| 1218 | + fio.old_blkaddr = data_blkaddr(dn.inode, dn.node_page, |
---|
| 1219 | + dn.ofs_in_node + i + 1); |
---|
| 1220 | + |
---|
| 1221 | + /* wait for GCed page writeback via META_MAPPING */ |
---|
| 1222 | + f2fs_wait_on_block_writeback(inode, fio.old_blkaddr); |
---|
| 1223 | + |
---|
1111 | 1224 | if (fio.encrypted) { |
---|
1112 | 1225 | fio.page = cc->rpages[i + 1]; |
---|
1113 | 1226 | err = f2fs_encrypt_one_page(&fio); |
---|
1114 | 1227 | if (err) |
---|
1115 | 1228 | goto out_destroy_crypt; |
---|
1116 | | - if (fscrypt_inode_uses_fs_layer_crypto(inode)) |
---|
1117 | | - cc->cpages[i] = fio.encrypted_page; |
---|
| 1229 | + cc->cpages[i] = fio.encrypted_page; |
---|
1118 | 1230 | } |
---|
1119 | 1231 | } |
---|
1120 | 1232 | |
---|
.. | .. |
---|
1153 | 1265 | |
---|
1154 | 1266 | f2fs_bug_on(fio.sbi, blkaddr == NULL_ADDR); |
---|
1155 | 1267 | |
---|
1156 | | - if (fio.encrypted && fscrypt_inode_uses_fs_layer_crypto(inode)) |
---|
| 1268 | + if (fio.encrypted) |
---|
1157 | 1269 | fio.encrypted_page = cc->cpages[i - 1]; |
---|
1158 | 1270 | else |
---|
1159 | 1271 | fio.compressed_page = cc->cpages[i - 1]; |
---|
.. | .. |
---|
1169 | 1281 | if (fio.compr_blocks) |
---|
1170 | 1282 | f2fs_i_compr_blocks_update(inode, fio.compr_blocks - 1, false); |
---|
1171 | 1283 | f2fs_i_compr_blocks_update(inode, cc->nr_cpages, true); |
---|
| 1284 | + add_compr_block_stat(inode, cc->nr_cpages); |
---|
1172 | 1285 | |
---|
1173 | 1286 | set_inode_flag(cc->inode, FI_APPEND_WRITE); |
---|
1174 | 1287 | if (cc->cluster_idx == 0) |
---|
1175 | 1288 | set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); |
---|
1176 | 1289 | |
---|
1177 | 1290 | f2fs_put_dnode(&dn); |
---|
1178 | | - if (!IS_NOQUOTA(inode)) |
---|
| 1291 | + if (IS_NOQUOTA(inode)) |
---|
| 1292 | + f2fs_up_read(&sbi->node_write); |
---|
| 1293 | + else |
---|
1179 | 1294 | f2fs_unlock_op(sbi); |
---|
1180 | 1295 | |
---|
1181 | 1296 | spin_lock(&fi->i_size_lock); |
---|
.. | .. |
---|
1184 | 1299 | spin_unlock(&fi->i_size_lock); |
---|
1185 | 1300 | |
---|
1186 | 1301 | f2fs_put_rpages(cc); |
---|
1187 | | - f2fs_destroy_compress_ctx(cc); |
---|
| 1302 | + page_array_free(cc->inode, cc->cpages, cc->nr_cpages); |
---|
| 1303 | + cc->cpages = NULL; |
---|
| 1304 | + f2fs_destroy_compress_ctx(cc, false); |
---|
1188 | 1305 | return 0; |
---|
1189 | 1306 | |
---|
1190 | 1307 | out_destroy_crypt: |
---|
1191 | | - kfree(cic->rpages); |
---|
| 1308 | + page_array_free(cc->inode, cic->rpages, cc->cluster_size); |
---|
1192 | 1309 | |
---|
1193 | 1310 | for (--i; i >= 0; i--) |
---|
1194 | 1311 | fscrypt_finalize_bounce_page(&cc->cpages[i]); |
---|
1195 | | - for (i = 0; i < cc->nr_cpages; i++) { |
---|
1196 | | - if (!cc->cpages[i]) |
---|
1197 | | - continue; |
---|
1198 | | - f2fs_put_page(cc->cpages[i], 1); |
---|
1199 | | - } |
---|
1200 | 1312 | out_put_cic: |
---|
1201 | | - kfree(cic); |
---|
| 1313 | + kmem_cache_free(cic_entry_slab, cic); |
---|
1202 | 1314 | out_put_dnode: |
---|
1203 | 1315 | f2fs_put_dnode(&dn); |
---|
1204 | 1316 | out_unlock_op: |
---|
1205 | | - if (!IS_NOQUOTA(inode)) |
---|
| 1317 | + if (IS_NOQUOTA(inode)) |
---|
| 1318 | + f2fs_up_read(&sbi->node_write); |
---|
| 1319 | + else |
---|
1206 | 1320 | f2fs_unlock_op(sbi); |
---|
| 1321 | +out_free: |
---|
| 1322 | + for (i = 0; i < cc->nr_cpages; i++) { |
---|
| 1323 | + if (!cc->cpages[i]) |
---|
| 1324 | + continue; |
---|
| 1325 | + f2fs_compress_free_page(cc->cpages[i]); |
---|
| 1326 | + cc->cpages[i] = NULL; |
---|
| 1327 | + } |
---|
| 1328 | + page_array_free(cc->inode, cc->cpages, cc->nr_cpages); |
---|
| 1329 | + cc->cpages = NULL; |
---|
1207 | 1330 | return -EAGAIN; |
---|
1208 | 1331 | } |
---|
1209 | 1332 | |
---|
.. | .. |
---|
1221 | 1344 | |
---|
1222 | 1345 | dec_page_count(sbi, F2FS_WB_DATA); |
---|
1223 | 1346 | |
---|
1224 | | - if (refcount_dec_not_one(&cic->ref)) |
---|
| 1347 | + if (atomic_dec_return(&cic->pending_pages)) |
---|
1225 | 1348 | return; |
---|
1226 | 1349 | |
---|
1227 | 1350 | for (i = 0; i < cic->nr_rpages; i++) { |
---|
1228 | 1351 | WARN_ON(!cic->rpages[i]); |
---|
1229 | | - clear_cold_data(cic->rpages[i]); |
---|
| 1352 | + clear_page_private_gcing(cic->rpages[i]); |
---|
1230 | 1353 | end_page_writeback(cic->rpages[i]); |
---|
1231 | 1354 | } |
---|
1232 | 1355 | |
---|
1233 | | - kfree(cic->rpages); |
---|
1234 | | - kfree(cic); |
---|
| 1356 | + page_array_free(cic->inode, cic->rpages, cic->nr_rpages); |
---|
| 1357 | + kmem_cache_free(cic_entry_slab, cic); |
---|
1235 | 1358 | } |
---|
1236 | 1359 | |
---|
1237 | 1360 | static int f2fs_write_raw_pages(struct compress_ctx *cc, |
---|
.. | .. |
---|
1240 | 1363 | enum iostat_type io_type) |
---|
1241 | 1364 | { |
---|
1242 | 1365 | struct address_space *mapping = cc->inode->i_mapping; |
---|
1243 | | - int _submitted, compr_blocks, ret; |
---|
1244 | | - int i = -1, err = 0; |
---|
| 1366 | + int _submitted, compr_blocks, ret, i; |
---|
1245 | 1367 | |
---|
1246 | 1368 | compr_blocks = f2fs_compressed_blocks(cc); |
---|
1247 | | - if (compr_blocks < 0) { |
---|
1248 | | - err = compr_blocks; |
---|
1249 | | - goto out_err; |
---|
| 1369 | + |
---|
| 1370 | + for (i = 0; i < cc->cluster_size; i++) { |
---|
| 1371 | + if (!cc->rpages[i]) |
---|
| 1372 | + continue; |
---|
| 1373 | + |
---|
| 1374 | + redirty_page_for_writepage(wbc, cc->rpages[i]); |
---|
| 1375 | + unlock_page(cc->rpages[i]); |
---|
1250 | 1376 | } |
---|
| 1377 | + |
---|
| 1378 | + if (compr_blocks < 0) |
---|
| 1379 | + return compr_blocks; |
---|
1251 | 1380 | |
---|
1252 | 1381 | for (i = 0; i < cc->cluster_size; i++) { |
---|
1253 | 1382 | if (!cc->rpages[i]) |
---|
1254 | 1383 | continue; |
---|
1255 | 1384 | retry_write: |
---|
| 1385 | + lock_page(cc->rpages[i]); |
---|
| 1386 | + |
---|
1256 | 1387 | if (cc->rpages[i]->mapping != mapping) { |
---|
| 1388 | +continue_unlock: |
---|
1257 | 1389 | unlock_page(cc->rpages[i]); |
---|
1258 | 1390 | continue; |
---|
1259 | 1391 | } |
---|
1260 | 1392 | |
---|
1261 | | - BUG_ON(!PageLocked(cc->rpages[i])); |
---|
| 1393 | + if (!PageDirty(cc->rpages[i])) |
---|
| 1394 | + goto continue_unlock; |
---|
| 1395 | + |
---|
| 1396 | + if (PageWriteback(cc->rpages[i])) { |
---|
| 1397 | + if (wbc->sync_mode == WB_SYNC_NONE) |
---|
| 1398 | + goto continue_unlock; |
---|
| 1399 | + f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, true); |
---|
| 1400 | + } |
---|
| 1401 | + |
---|
| 1402 | + if (!clear_page_dirty_for_io(cc->rpages[i])) |
---|
| 1403 | + goto continue_unlock; |
---|
1262 | 1404 | |
---|
1263 | 1405 | ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted, |
---|
1264 | 1406 | NULL, NULL, wbc, io_type, |
---|
1265 | | - compr_blocks); |
---|
| 1407 | + compr_blocks, false); |
---|
1266 | 1408 | if (ret) { |
---|
1267 | 1409 | if (ret == AOP_WRITEPAGE_ACTIVATE) { |
---|
1268 | 1410 | unlock_page(cc->rpages[i]); |
---|
.. | .. |
---|
1273 | 1415 | * avoid deadlock caused by cluster update race |
---|
1274 | 1416 | * from foreground operation. |
---|
1275 | 1417 | */ |
---|
1276 | | - if (IS_NOQUOTA(cc->inode)) { |
---|
1277 | | - err = 0; |
---|
1278 | | - goto out_err; |
---|
1279 | | - } |
---|
| 1418 | + if (IS_NOQUOTA(cc->inode)) |
---|
| 1419 | + return 0; |
---|
1280 | 1420 | ret = 0; |
---|
1281 | 1421 | cond_resched(); |
---|
1282 | 1422 | congestion_wait(BLK_RW_ASYNC, |
---|
1283 | 1423 | DEFAULT_IO_TIMEOUT); |
---|
1284 | | - lock_page(cc->rpages[i]); |
---|
1285 | | - clear_page_dirty_for_io(cc->rpages[i]); |
---|
1286 | 1424 | goto retry_write; |
---|
1287 | 1425 | } |
---|
1288 | | - err = ret; |
---|
1289 | | - goto out_err; |
---|
| 1426 | + return ret; |
---|
1290 | 1427 | } |
---|
1291 | 1428 | |
---|
1292 | 1429 | *submitted += _submitted; |
---|
1293 | 1430 | } |
---|
| 1431 | + |
---|
| 1432 | + f2fs_balance_fs(F2FS_M_SB(mapping), true); |
---|
| 1433 | + |
---|
1294 | 1434 | return 0; |
---|
1295 | | -out_err: |
---|
1296 | | - for (++i; i < cc->cluster_size; i++) { |
---|
1297 | | - if (!cc->rpages[i]) |
---|
1298 | | - continue; |
---|
1299 | | - redirty_page_for_writepage(wbc, cc->rpages[i]); |
---|
1300 | | - unlock_page(cc->rpages[i]); |
---|
1301 | | - } |
---|
1302 | | - return err; |
---|
1303 | 1435 | } |
---|
1304 | 1436 | |
---|
1305 | 1437 | int f2fs_write_multi_pages(struct compress_ctx *cc, |
---|
.. | .. |
---|
1307 | 1439 | struct writeback_control *wbc, |
---|
1308 | 1440 | enum iostat_type io_type) |
---|
1309 | 1441 | { |
---|
1310 | | - struct f2fs_inode_info *fi = F2FS_I(cc->inode); |
---|
1311 | | - const struct f2fs_compress_ops *cops = |
---|
1312 | | - f2fs_cops[fi->i_compress_algorithm]; |
---|
1313 | 1442 | int err; |
---|
1314 | 1443 | |
---|
1315 | 1444 | *submitted = 0; |
---|
1316 | 1445 | if (cluster_may_compress(cc)) { |
---|
1317 | 1446 | err = f2fs_compress_pages(cc); |
---|
1318 | 1447 | if (err == -EAGAIN) { |
---|
| 1448 | + add_compr_block_stat(cc->inode, cc->cluster_size); |
---|
1319 | 1449 | goto write; |
---|
1320 | 1450 | } else if (err) { |
---|
1321 | 1451 | f2fs_put_rpages_wbc(cc, wbc, true, 1); |
---|
.. | .. |
---|
1324 | 1454 | |
---|
1325 | 1455 | err = f2fs_write_compressed_pages(cc, submitted, |
---|
1326 | 1456 | wbc, io_type); |
---|
1327 | | - cops->destroy_compress_ctx(cc); |
---|
1328 | 1457 | if (!err) |
---|
1329 | 1458 | return 0; |
---|
1330 | 1459 | f2fs_bug_on(F2FS_I_SB(cc->inode), err != -EAGAIN); |
---|
.. | .. |
---|
1335 | 1464 | err = f2fs_write_raw_pages(cc, submitted, wbc, io_type); |
---|
1336 | 1465 | f2fs_put_rpages_wbc(cc, wbc, false, 0); |
---|
1337 | 1466 | destroy_out: |
---|
1338 | | - f2fs_destroy_compress_ctx(cc); |
---|
| 1467 | + f2fs_destroy_compress_ctx(cc, false); |
---|
1339 | 1468 | return err; |
---|
1340 | 1469 | } |
---|
1341 | 1470 | |
---|
1342 | | -struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) |
---|
| 1471 | +static inline bool allow_memalloc_for_decomp(struct f2fs_sb_info *sbi, |
---|
| 1472 | + bool pre_alloc) |
---|
1343 | 1473 | { |
---|
1344 | | - struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); |
---|
1345 | | - struct decompress_io_ctx *dic; |
---|
1346 | | - pgoff_t start_idx = start_idx_of_cluster(cc); |
---|
| 1474 | + return pre_alloc ^ f2fs_low_mem_mode(sbi); |
---|
| 1475 | +} |
---|
| 1476 | + |
---|
| 1477 | +static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, |
---|
| 1478 | + bool pre_alloc) |
---|
| 1479 | +{ |
---|
| 1480 | + const struct f2fs_compress_ops *cops = |
---|
| 1481 | + f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; |
---|
1347 | 1482 | int i; |
---|
1348 | 1483 | |
---|
1349 | | - dic = f2fs_kzalloc(sbi, sizeof(struct decompress_io_ctx), GFP_NOFS); |
---|
| 1484 | + if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) |
---|
| 1485 | + return 0; |
---|
| 1486 | + |
---|
| 1487 | + dic->tpages = page_array_alloc(dic->inode, dic->cluster_size); |
---|
| 1488 | + if (!dic->tpages) |
---|
| 1489 | + return -ENOMEM; |
---|
| 1490 | + |
---|
| 1491 | + for (i = 0; i < dic->cluster_size; i++) { |
---|
| 1492 | + if (dic->rpages[i]) { |
---|
| 1493 | + dic->tpages[i] = dic->rpages[i]; |
---|
| 1494 | + continue; |
---|
| 1495 | + } |
---|
| 1496 | + |
---|
| 1497 | + dic->tpages[i] = f2fs_compress_alloc_page(); |
---|
| 1498 | + if (!dic->tpages[i]) |
---|
| 1499 | + return -ENOMEM; |
---|
| 1500 | + } |
---|
| 1501 | + |
---|
| 1502 | + dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size); |
---|
| 1503 | + if (!dic->rbuf) |
---|
| 1504 | + return -ENOMEM; |
---|
| 1505 | + |
---|
| 1506 | + dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages); |
---|
| 1507 | + if (!dic->cbuf) |
---|
| 1508 | + return -ENOMEM; |
---|
| 1509 | + |
---|
| 1510 | + if (cops->init_decompress_ctx) { |
---|
| 1511 | + int ret = cops->init_decompress_ctx(dic); |
---|
| 1512 | + |
---|
| 1513 | + if (ret) |
---|
| 1514 | + return ret; |
---|
| 1515 | + } |
---|
| 1516 | + |
---|
| 1517 | + return 0; |
---|
| 1518 | +} |
---|
| 1519 | + |
---|
| 1520 | +static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, |
---|
| 1521 | + bool bypass_destroy_callback, bool pre_alloc) |
---|
| 1522 | +{ |
---|
| 1523 | + const struct f2fs_compress_ops *cops = |
---|
| 1524 | + f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; |
---|
| 1525 | + |
---|
| 1526 | + if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) |
---|
| 1527 | + return; |
---|
| 1528 | + |
---|
| 1529 | + if (!bypass_destroy_callback && cops->destroy_decompress_ctx) |
---|
| 1530 | + cops->destroy_decompress_ctx(dic); |
---|
| 1531 | + |
---|
| 1532 | + if (dic->cbuf) |
---|
| 1533 | + vm_unmap_ram(dic->cbuf, dic->nr_cpages); |
---|
| 1534 | + |
---|
| 1535 | + if (dic->rbuf) |
---|
| 1536 | + vm_unmap_ram(dic->rbuf, dic->cluster_size); |
---|
| 1537 | +} |
---|
| 1538 | + |
---|
| 1539 | +static void f2fs_free_dic(struct decompress_io_ctx *dic, |
---|
| 1540 | + bool bypass_destroy_callback); |
---|
| 1541 | + |
---|
| 1542 | +struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) |
---|
| 1543 | +{ |
---|
| 1544 | + struct decompress_io_ctx *dic; |
---|
| 1545 | + pgoff_t start_idx = start_idx_of_cluster(cc); |
---|
| 1546 | + int i, ret; |
---|
| 1547 | + |
---|
| 1548 | + dic = kmem_cache_zalloc(dic_entry_slab, GFP_NOFS); |
---|
1350 | 1549 | if (!dic) |
---|
1351 | 1550 | return ERR_PTR(-ENOMEM); |
---|
1352 | 1551 | |
---|
1353 | | - dic->rpages = f2fs_kzalloc(sbi, sizeof(struct page *) << |
---|
1354 | | - cc->log_cluster_size, GFP_NOFS); |
---|
| 1552 | + dic->rpages = page_array_alloc(cc->inode, cc->cluster_size); |
---|
1355 | 1553 | if (!dic->rpages) { |
---|
1356 | | - kfree(dic); |
---|
| 1554 | + kmem_cache_free(dic_entry_slab, dic); |
---|
1357 | 1555 | return ERR_PTR(-ENOMEM); |
---|
1358 | 1556 | } |
---|
1359 | 1557 | |
---|
1360 | 1558 | dic->magic = F2FS_COMPRESSED_PAGE_MAGIC; |
---|
1361 | 1559 | dic->inode = cc->inode; |
---|
1362 | | - refcount_set(&dic->ref, cc->nr_cpages); |
---|
| 1560 | + atomic_set(&dic->remaining_pages, cc->nr_cpages); |
---|
1363 | 1561 | dic->cluster_idx = cc->cluster_idx; |
---|
1364 | 1562 | dic->cluster_size = cc->cluster_size; |
---|
1365 | 1563 | dic->log_cluster_size = cc->log_cluster_size; |
---|
1366 | 1564 | dic->nr_cpages = cc->nr_cpages; |
---|
| 1565 | + refcount_set(&dic->refcnt, 1); |
---|
1367 | 1566 | dic->failed = false; |
---|
| 1567 | + dic->need_verity = f2fs_need_verity(cc->inode, start_idx); |
---|
1368 | 1568 | |
---|
1369 | 1569 | for (i = 0; i < dic->cluster_size; i++) |
---|
1370 | 1570 | dic->rpages[i] = cc->rpages[i]; |
---|
1371 | 1571 | dic->nr_rpages = cc->cluster_size; |
---|
1372 | 1572 | |
---|
1373 | | - dic->cpages = f2fs_kzalloc(sbi, sizeof(struct page *) * |
---|
1374 | | - dic->nr_cpages, GFP_NOFS); |
---|
1375 | | - if (!dic->cpages) |
---|
| 1573 | + dic->cpages = page_array_alloc(dic->inode, dic->nr_cpages); |
---|
| 1574 | + if (!dic->cpages) { |
---|
| 1575 | + ret = -ENOMEM; |
---|
1376 | 1576 | goto out_free; |
---|
| 1577 | + } |
---|
1377 | 1578 | |
---|
1378 | 1579 | for (i = 0; i < dic->nr_cpages; i++) { |
---|
1379 | 1580 | struct page *page; |
---|
1380 | 1581 | |
---|
1381 | 1582 | page = f2fs_compress_alloc_page(); |
---|
1382 | | - if (!page) |
---|
| 1583 | + if (!page) { |
---|
| 1584 | + ret = -ENOMEM; |
---|
1383 | 1585 | goto out_free; |
---|
| 1586 | + } |
---|
1384 | 1587 | |
---|
1385 | 1588 | f2fs_set_compressed_page(page, cc->inode, |
---|
1386 | 1589 | start_idx + i + 1, dic); |
---|
1387 | 1590 | dic->cpages[i] = page; |
---|
1388 | 1591 | } |
---|
1389 | 1592 | |
---|
1390 | | - dic->tpages = f2fs_kzalloc(sbi, sizeof(struct page *) * |
---|
1391 | | - dic->cluster_size, GFP_NOFS); |
---|
1392 | | - if (!dic->tpages) |
---|
| 1593 | + ret = f2fs_prepare_decomp_mem(dic, true); |
---|
| 1594 | + if (ret) |
---|
1393 | 1595 | goto out_free; |
---|
1394 | | - |
---|
1395 | | - for (i = 0; i < dic->cluster_size; i++) { |
---|
1396 | | - if (cc->rpages[i]) { |
---|
1397 | | - dic->tpages[i] = cc->rpages[i]; |
---|
1398 | | - continue; |
---|
1399 | | - } |
---|
1400 | | - |
---|
1401 | | - dic->tpages[i] = f2fs_compress_alloc_page(); |
---|
1402 | | - if (!dic->tpages[i]) |
---|
1403 | | - goto out_free; |
---|
1404 | | - } |
---|
1405 | 1596 | |
---|
1406 | 1597 | return dic; |
---|
1407 | 1598 | |
---|
1408 | 1599 | out_free: |
---|
1409 | | - f2fs_free_dic(dic); |
---|
1410 | | - return ERR_PTR(-ENOMEM); |
---|
| 1600 | + f2fs_free_dic(dic, true); |
---|
| 1601 | + return ERR_PTR(ret); |
---|
1411 | 1602 | } |
---|
1412 | 1603 | |
---|
1413 | | -void f2fs_free_dic(struct decompress_io_ctx *dic) |
---|
| 1604 | +static void f2fs_free_dic(struct decompress_io_ctx *dic, |
---|
| 1605 | + bool bypass_destroy_callback) |
---|
1414 | 1606 | { |
---|
1415 | 1607 | int i; |
---|
| 1608 | + |
---|
| 1609 | + f2fs_release_decomp_mem(dic, bypass_destroy_callback, true); |
---|
1416 | 1610 | |
---|
1417 | 1611 | if (dic->tpages) { |
---|
1418 | 1612 | for (i = 0; i < dic->cluster_size; i++) { |
---|
.. | .. |
---|
1422 | 1616 | continue; |
---|
1423 | 1617 | f2fs_compress_free_page(dic->tpages[i]); |
---|
1424 | 1618 | } |
---|
1425 | | - kfree(dic->tpages); |
---|
| 1619 | + page_array_free(dic->inode, dic->tpages, dic->cluster_size); |
---|
1426 | 1620 | } |
---|
1427 | 1621 | |
---|
1428 | 1622 | if (dic->cpages) { |
---|
.. | .. |
---|
1431 | 1625 | continue; |
---|
1432 | 1626 | f2fs_compress_free_page(dic->cpages[i]); |
---|
1433 | 1627 | } |
---|
1434 | | - kfree(dic->cpages); |
---|
| 1628 | + page_array_free(dic->inode, dic->cpages, dic->nr_cpages); |
---|
1435 | 1629 | } |
---|
1436 | 1630 | |
---|
1437 | | - kfree(dic->rpages); |
---|
1438 | | - kfree(dic); |
---|
| 1631 | + page_array_free(dic->inode, dic->rpages, dic->nr_rpages); |
---|
| 1632 | + kmem_cache_free(dic_entry_slab, dic); |
---|
1439 | 1633 | } |
---|
1440 | 1634 | |
---|
1441 | | -void f2fs_decompress_end_io(struct page **rpages, |
---|
1442 | | - unsigned int cluster_size, bool err, bool verity) |
---|
| 1635 | +static void f2fs_late_free_dic(struct work_struct *work) |
---|
| 1636 | +{ |
---|
| 1637 | + struct decompress_io_ctx *dic = |
---|
| 1638 | + container_of(work, struct decompress_io_ctx, free_work); |
---|
| 1639 | + |
---|
| 1640 | + f2fs_free_dic(dic, false); |
---|
| 1641 | +} |
---|
| 1642 | + |
---|
| 1643 | +static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task) |
---|
| 1644 | +{ |
---|
| 1645 | + if (refcount_dec_and_test(&dic->refcnt)) { |
---|
| 1646 | + if (in_task) { |
---|
| 1647 | + f2fs_free_dic(dic, false); |
---|
| 1648 | + } else { |
---|
| 1649 | + INIT_WORK(&dic->free_work, f2fs_late_free_dic); |
---|
| 1650 | + queue_work(F2FS_I_SB(dic->inode)->post_read_wq, |
---|
| 1651 | + &dic->free_work); |
---|
| 1652 | + } |
---|
| 1653 | + } |
---|
| 1654 | +} |
---|
| 1655 | + |
---|
| 1656 | +/* |
---|
| 1657 | + * Update and unlock the cluster's pagecache pages, and release the reference to |
---|
| 1658 | + * the decompress_io_ctx that was being held for I/O completion. |
---|
| 1659 | + */ |
---|
| 1660 | +static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, |
---|
| 1661 | + bool in_task) |
---|
1443 | 1662 | { |
---|
1444 | 1663 | int i; |
---|
1445 | 1664 | |
---|
1446 | | - for (i = 0; i < cluster_size; i++) { |
---|
1447 | | - struct page *rpage = rpages[i]; |
---|
| 1665 | + for (i = 0; i < dic->cluster_size; i++) { |
---|
| 1666 | + struct page *rpage = dic->rpages[i]; |
---|
1448 | 1667 | |
---|
1449 | 1668 | if (!rpage) |
---|
1450 | 1669 | continue; |
---|
1451 | 1670 | |
---|
1452 | | - if (err || PageError(rpage)) |
---|
1453 | | - goto clear_uptodate; |
---|
1454 | | - |
---|
1455 | | - if (!verity || fsverity_verify_page(rpage)) { |
---|
| 1671 | + /* PG_error was set if verity failed. */ |
---|
| 1672 | + if (failed || PageError(rpage)) { |
---|
| 1673 | + ClearPageUptodate(rpage); |
---|
| 1674 | + /* will re-read again later */ |
---|
| 1675 | + ClearPageError(rpage); |
---|
| 1676 | + } else { |
---|
1456 | 1677 | SetPageUptodate(rpage); |
---|
1457 | | - goto unlock; |
---|
1458 | 1678 | } |
---|
1459 | | -clear_uptodate: |
---|
1460 | | - ClearPageUptodate(rpage); |
---|
1461 | | - ClearPageError(rpage); |
---|
1462 | | -unlock: |
---|
1463 | 1679 | unlock_page(rpage); |
---|
1464 | 1680 | } |
---|
| 1681 | + |
---|
| 1682 | + f2fs_put_dic(dic, in_task); |
---|
| 1683 | +} |
---|
| 1684 | + |
---|
| 1685 | +static void f2fs_verify_cluster(struct work_struct *work) |
---|
| 1686 | +{ |
---|
| 1687 | + struct decompress_io_ctx *dic = |
---|
| 1688 | + container_of(work, struct decompress_io_ctx, verity_work); |
---|
| 1689 | + int i; |
---|
| 1690 | + |
---|
| 1691 | + /* Verify the cluster's decompressed pages with fs-verity. */ |
---|
| 1692 | + for (i = 0; i < dic->cluster_size; i++) { |
---|
| 1693 | + struct page *rpage = dic->rpages[i]; |
---|
| 1694 | + |
---|
| 1695 | + if (rpage && !fsverity_verify_page(rpage)) |
---|
| 1696 | + SetPageError(rpage); |
---|
| 1697 | + } |
---|
| 1698 | + |
---|
| 1699 | + __f2fs_decompress_end_io(dic, false, true); |
---|
| 1700 | +} |
---|
| 1701 | + |
---|
| 1702 | +/* |
---|
| 1703 | + * This is called when a compressed cluster has been decompressed |
---|
| 1704 | + * (or failed to be read and/or decompressed). |
---|
| 1705 | + */ |
---|
| 1706 | +void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, |
---|
| 1707 | + bool in_task) |
---|
| 1708 | +{ |
---|
| 1709 | + if (!failed && dic->need_verity) { |
---|
| 1710 | + /* |
---|
| 1711 | + * Note that to avoid deadlocks, the verity work can't be done |
---|
| 1712 | + * on the decompression workqueue. This is because verifying |
---|
| 1713 | + * the data pages can involve reading metadata pages from the |
---|
| 1714 | + * file, and these metadata pages may be compressed. |
---|
| 1715 | + */ |
---|
| 1716 | + INIT_WORK(&dic->verity_work, f2fs_verify_cluster); |
---|
| 1717 | + fsverity_enqueue_verify_work(&dic->verity_work); |
---|
| 1718 | + } else { |
---|
| 1719 | + __f2fs_decompress_end_io(dic, failed, in_task); |
---|
| 1720 | + } |
---|
| 1721 | +} |
---|
| 1722 | + |
---|
| 1723 | +/* |
---|
| 1724 | + * Put a reference to a compressed page's decompress_io_ctx. |
---|
| 1725 | + * |
---|
| 1726 | + * This is called when the page is no longer needed and can be freed. |
---|
| 1727 | + */ |
---|
| 1728 | +void f2fs_put_page_dic(struct page *page, bool in_task) |
---|
| 1729 | +{ |
---|
| 1730 | + struct decompress_io_ctx *dic = |
---|
| 1731 | + (struct decompress_io_ctx *)page_private(page); |
---|
| 1732 | + |
---|
| 1733 | + f2fs_put_dic(dic, in_task); |
---|
| 1734 | +} |
---|
| 1735 | + |
---|
| 1736 | +/* |
---|
| 1737 | + * check whether cluster blocks are contiguous, and add extent cache entry |
---|
| 1738 | + * only if cluster blocks are logically and physically contiguous. |
---|
| 1739 | + */ |
---|
| 1740 | +unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn) |
---|
| 1741 | +{ |
---|
| 1742 | + bool compressed = f2fs_data_blkaddr(dn) == COMPRESS_ADDR; |
---|
| 1743 | + int i = compressed ? 1 : 0; |
---|
| 1744 | + block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page, |
---|
| 1745 | + dn->ofs_in_node + i); |
---|
| 1746 | + |
---|
| 1747 | + for (i += 1; i < F2FS_I(dn->inode)->i_cluster_size; i++) { |
---|
| 1748 | + block_t blkaddr = data_blkaddr(dn->inode, dn->node_page, |
---|
| 1749 | + dn->ofs_in_node + i); |
---|
| 1750 | + |
---|
| 1751 | + if (!__is_valid_data_blkaddr(blkaddr)) |
---|
| 1752 | + break; |
---|
| 1753 | + if (first_blkaddr + i - (compressed ? 1 : 0) != blkaddr) |
---|
| 1754 | + return 0; |
---|
| 1755 | + } |
---|
| 1756 | + |
---|
| 1757 | + return compressed ? i - 1 : i; |
---|
| 1758 | +} |
---|
| 1759 | + |
---|
| 1760 | +const struct address_space_operations f2fs_compress_aops = { |
---|
| 1761 | + .releasepage = f2fs_release_page, |
---|
| 1762 | + .invalidatepage = f2fs_invalidate_page, |
---|
| 1763 | +}; |
---|
| 1764 | + |
---|
| 1765 | +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi) |
---|
| 1766 | +{ |
---|
| 1767 | + return sbi->compress_inode->i_mapping; |
---|
| 1768 | +} |
---|
| 1769 | + |
---|
| 1770 | +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr) |
---|
| 1771 | +{ |
---|
| 1772 | + if (!sbi->compress_inode) |
---|
| 1773 | + return; |
---|
| 1774 | + invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr); |
---|
| 1775 | +} |
---|
| 1776 | + |
---|
| 1777 | +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, |
---|
| 1778 | + nid_t ino, block_t blkaddr) |
---|
| 1779 | +{ |
---|
| 1780 | + struct page *cpage; |
---|
| 1781 | + int ret; |
---|
| 1782 | + |
---|
| 1783 | + if (!test_opt(sbi, COMPRESS_CACHE)) |
---|
| 1784 | + return; |
---|
| 1785 | + |
---|
| 1786 | + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) |
---|
| 1787 | + return; |
---|
| 1788 | + |
---|
| 1789 | + if (!f2fs_available_free_memory(sbi, COMPRESS_PAGE)) |
---|
| 1790 | + return; |
---|
| 1791 | + |
---|
| 1792 | + cpage = find_get_page(COMPRESS_MAPPING(sbi), blkaddr); |
---|
| 1793 | + if (cpage) { |
---|
| 1794 | + f2fs_put_page(cpage, 0); |
---|
| 1795 | + return; |
---|
| 1796 | + } |
---|
| 1797 | + |
---|
| 1798 | + cpage = alloc_page(__GFP_NOWARN | __GFP_IO); |
---|
| 1799 | + if (!cpage) |
---|
| 1800 | + return; |
---|
| 1801 | + |
---|
| 1802 | + ret = add_to_page_cache_lru(cpage, COMPRESS_MAPPING(sbi), |
---|
| 1803 | + blkaddr, GFP_NOFS); |
---|
| 1804 | + if (ret) { |
---|
| 1805 | + f2fs_put_page(cpage, 0); |
---|
| 1806 | + return; |
---|
| 1807 | + } |
---|
| 1808 | + |
---|
| 1809 | + set_page_private_data(cpage, ino); |
---|
| 1810 | + |
---|
| 1811 | + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) |
---|
| 1812 | + goto out; |
---|
| 1813 | + |
---|
| 1814 | + memcpy(page_address(cpage), page_address(page), PAGE_SIZE); |
---|
| 1815 | + SetPageUptodate(cpage); |
---|
| 1816 | +out: |
---|
| 1817 | + f2fs_put_page(cpage, 1); |
---|
| 1818 | +} |
---|
| 1819 | + |
---|
| 1820 | +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, |
---|
| 1821 | + block_t blkaddr) |
---|
| 1822 | +{ |
---|
| 1823 | + struct page *cpage; |
---|
| 1824 | + bool hitted = false; |
---|
| 1825 | + |
---|
| 1826 | + if (!test_opt(sbi, COMPRESS_CACHE)) |
---|
| 1827 | + return false; |
---|
| 1828 | + |
---|
| 1829 | + cpage = f2fs_pagecache_get_page(COMPRESS_MAPPING(sbi), |
---|
| 1830 | + blkaddr, FGP_LOCK | FGP_NOWAIT, GFP_NOFS); |
---|
| 1831 | + if (cpage) { |
---|
| 1832 | + if (PageUptodate(cpage)) { |
---|
| 1833 | + atomic_inc(&sbi->compress_page_hit); |
---|
| 1834 | + memcpy(page_address(page), |
---|
| 1835 | + page_address(cpage), PAGE_SIZE); |
---|
| 1836 | + hitted = true; |
---|
| 1837 | + } |
---|
| 1838 | + f2fs_put_page(cpage, 1); |
---|
| 1839 | + } |
---|
| 1840 | + |
---|
| 1841 | + return hitted; |
---|
| 1842 | +} |
---|
| 1843 | + |
---|
| 1844 | +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino) |
---|
| 1845 | +{ |
---|
| 1846 | + struct address_space *mapping = sbi->compress_inode->i_mapping; |
---|
| 1847 | + struct pagevec pvec; |
---|
| 1848 | + pgoff_t index = 0; |
---|
| 1849 | + pgoff_t end = MAX_BLKADDR(sbi); |
---|
| 1850 | + |
---|
| 1851 | + if (!mapping->nrpages) |
---|
| 1852 | + return; |
---|
| 1853 | + |
---|
| 1854 | + pagevec_init(&pvec); |
---|
| 1855 | + |
---|
| 1856 | + do { |
---|
| 1857 | + unsigned int nr_pages; |
---|
| 1858 | + int i; |
---|
| 1859 | + |
---|
| 1860 | + nr_pages = pagevec_lookup_range(&pvec, mapping, |
---|
| 1861 | + &index, end - 1); |
---|
| 1862 | + if (!nr_pages) |
---|
| 1863 | + break; |
---|
| 1864 | + |
---|
| 1865 | + for (i = 0; i < nr_pages; i++) { |
---|
| 1866 | + struct page *page = pvec.pages[i]; |
---|
| 1867 | + |
---|
| 1868 | + if (page->index > end) |
---|
| 1869 | + break; |
---|
| 1870 | + |
---|
| 1871 | + lock_page(page); |
---|
| 1872 | + if (page->mapping != mapping) { |
---|
| 1873 | + unlock_page(page); |
---|
| 1874 | + continue; |
---|
| 1875 | + } |
---|
| 1876 | + |
---|
| 1877 | + if (ino != get_page_private_data(page)) { |
---|
| 1878 | + unlock_page(page); |
---|
| 1879 | + continue; |
---|
| 1880 | + } |
---|
| 1881 | + |
---|
| 1882 | + generic_error_remove_page(mapping, page); |
---|
| 1883 | + unlock_page(page); |
---|
| 1884 | + } |
---|
| 1885 | + pagevec_release(&pvec); |
---|
| 1886 | + cond_resched(); |
---|
| 1887 | + } while (index < end); |
---|
| 1888 | +} |
---|
| 1889 | + |
---|
| 1890 | +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) |
---|
| 1891 | +{ |
---|
| 1892 | + struct inode *inode; |
---|
| 1893 | + |
---|
| 1894 | + if (!test_opt(sbi, COMPRESS_CACHE)) |
---|
| 1895 | + return 0; |
---|
| 1896 | + |
---|
| 1897 | + inode = f2fs_iget(sbi->sb, F2FS_COMPRESS_INO(sbi)); |
---|
| 1898 | + if (IS_ERR(inode)) |
---|
| 1899 | + return PTR_ERR(inode); |
---|
| 1900 | + sbi->compress_inode = inode; |
---|
| 1901 | + |
---|
| 1902 | + sbi->compress_percent = COMPRESS_PERCENT; |
---|
| 1903 | + sbi->compress_watermark = COMPRESS_WATERMARK; |
---|
| 1904 | + |
---|
| 1905 | + atomic_set(&sbi->compress_page_hit, 0); |
---|
| 1906 | + |
---|
| 1907 | + return 0; |
---|
| 1908 | +} |
---|
| 1909 | + |
---|
| 1910 | +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) |
---|
| 1911 | +{ |
---|
| 1912 | + if (!sbi->compress_inode) |
---|
| 1913 | + return; |
---|
| 1914 | + iput(sbi->compress_inode); |
---|
| 1915 | + sbi->compress_inode = NULL; |
---|
| 1916 | +} |
---|
| 1917 | + |
---|
| 1918 | +int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) |
---|
| 1919 | +{ |
---|
| 1920 | + dev_t dev = sbi->sb->s_bdev->bd_dev; |
---|
| 1921 | + char slab_name[32]; |
---|
| 1922 | + |
---|
| 1923 | + sprintf(slab_name, "f2fs_page_array_entry-%u:%u", MAJOR(dev), MINOR(dev)); |
---|
| 1924 | + |
---|
| 1925 | + sbi->page_array_slab_size = sizeof(struct page *) << |
---|
| 1926 | + F2FS_OPTION(sbi).compress_log_size; |
---|
| 1927 | + |
---|
| 1928 | + sbi->page_array_slab = f2fs_kmem_cache_create(slab_name, |
---|
| 1929 | + sbi->page_array_slab_size); |
---|
| 1930 | + if (!sbi->page_array_slab) |
---|
| 1931 | + return -ENOMEM; |
---|
| 1932 | + return 0; |
---|
| 1933 | +} |
---|
| 1934 | + |
---|
| 1935 | +void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi) |
---|
| 1936 | +{ |
---|
| 1937 | + kmem_cache_destroy(sbi->page_array_slab); |
---|
| 1938 | +} |
---|
| 1939 | + |
---|
| 1940 | +static int __init f2fs_init_cic_cache(void) |
---|
| 1941 | +{ |
---|
| 1942 | + cic_entry_slab = f2fs_kmem_cache_create("f2fs_cic_entry", |
---|
| 1943 | + sizeof(struct compress_io_ctx)); |
---|
| 1944 | + if (!cic_entry_slab) |
---|
| 1945 | + return -ENOMEM; |
---|
| 1946 | + return 0; |
---|
| 1947 | +} |
---|
| 1948 | + |
---|
| 1949 | +static void f2fs_destroy_cic_cache(void) |
---|
| 1950 | +{ |
---|
| 1951 | + kmem_cache_destroy(cic_entry_slab); |
---|
| 1952 | +} |
---|
| 1953 | + |
---|
| 1954 | +static int __init f2fs_init_dic_cache(void) |
---|
| 1955 | +{ |
---|
| 1956 | + dic_entry_slab = f2fs_kmem_cache_create("f2fs_dic_entry", |
---|
| 1957 | + sizeof(struct decompress_io_ctx)); |
---|
| 1958 | + if (!dic_entry_slab) |
---|
| 1959 | + return -ENOMEM; |
---|
| 1960 | + return 0; |
---|
| 1961 | +} |
---|
| 1962 | + |
---|
| 1963 | +static void f2fs_destroy_dic_cache(void) |
---|
| 1964 | +{ |
---|
| 1965 | + kmem_cache_destroy(dic_entry_slab); |
---|
| 1966 | +} |
---|
| 1967 | + |
---|
| 1968 | +int __init f2fs_init_compress_cache(void) |
---|
| 1969 | +{ |
---|
| 1970 | + int err; |
---|
| 1971 | + |
---|
| 1972 | + err = f2fs_init_cic_cache(); |
---|
| 1973 | + if (err) |
---|
| 1974 | + goto out; |
---|
| 1975 | + err = f2fs_init_dic_cache(); |
---|
| 1976 | + if (err) |
---|
| 1977 | + goto free_cic; |
---|
| 1978 | + return 0; |
---|
| 1979 | +free_cic: |
---|
| 1980 | + f2fs_destroy_cic_cache(); |
---|
| 1981 | +out: |
---|
| 1982 | + return -ENOMEM; |
---|
| 1983 | +} |
---|
| 1984 | + |
---|
| 1985 | +void f2fs_destroy_compress_cache(void) |
---|
| 1986 | +{ |
---|
| 1987 | + f2fs_destroy_dic_cache(); |
---|
| 1988 | + f2fs_destroy_cic_cache(); |
---|
1465 | 1989 | } |
---|