Gao Xiang | 29b24f6 | 2019-07-31 23:57:31 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 2 | /* |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 3 | * Copyright (C) 2019 HUAWEI, Inc. |
Alexander A. Klimov | 592e7cd | 2020-07-13 15:09:44 +0200 | [diff] [blame] | 4 | * https://www.huawei.com/ |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 5 | * Created by Gao Xiang <gaoxiang25@huawei.com> |
| 6 | */ |
| 7 | #ifndef __EROFS_FS_COMPRESS_H |
| 8 | #define __EROFS_FS_COMPRESS_H |
| 9 | |
Gao Xiang | 7fc45db | 2019-06-24 15:22:55 +0800 | [diff] [blame] | 10 | #include "internal.h" |
| 11 | |
| 12 | enum { |
| 13 | Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX, |
| 14 | Z_EROFS_COMPRESSION_RUNTIME_MAX |
| 15 | }; |
| 16 | |
| 17 | struct z_erofs_decompress_req { |
Gao Xiang | 0ffd71b | 2019-06-24 15:22:56 +0800 | [diff] [blame] | 18 | struct super_block *sb; |
Gao Xiang | 7fc45db | 2019-06-24 15:22:55 +0800 | [diff] [blame] | 19 | struct page **in, **out; |
| 20 | |
| 21 | unsigned short pageofs_out; |
| 22 | unsigned int inputsize, outputsize; |
| 23 | |
| 24 | /* indicate the algorithm will be used for decompression */ |
| 25 | unsigned int alg; |
| 26 | bool inplace_io, partial_decoding; |
| 27 | }; |
| 28 | |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 29 | /* some special page->private (unsigned long, see below) */ |
| 30 | #define Z_EROFS_SHORTLIVED_PAGE (-1UL << 2) |
Gao Xiang | 1825c8d | 2020-12-09 20:37:17 +0800 | [diff] [blame] | 31 | #define Z_EROFS_PREALLOCATED_PAGE (-2UL << 2) |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 32 | |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 33 | /* |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 34 | * For all pages in a pcluster, page->private should be one of |
| 35 | * Type Last 2bits page->private |
| 36 | * short-lived page 00 Z_EROFS_SHORTLIVED_PAGE |
Gao Xiang | 1825c8d | 2020-12-09 20:37:17 +0800 | [diff] [blame] | 37 | * preallocated page (tryalloc) 00 Z_EROFS_PREALLOCATED_PAGE |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 38 | * cached/managed page 00 pointer to z_erofs_pcluster |
| 39 | * online page (file-backed, 01/10/11 sub-index << 2 | count |
| 40 | * some pages can be used for inplace I/O) |
| 41 | * |
| 42 | * page->mapping should be one of |
| 43 | * Type page->mapping |
| 44 | * short-lived page NULL |
Gao Xiang | 1825c8d | 2020-12-09 20:37:17 +0800 | [diff] [blame] | 45 | * preallocated page NULL |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 46 | * cached/managed page non-NULL or NULL (invalidated/truncated page) |
| 47 | * online page non-NULL |
| 48 | * |
| 49 | * For all managed pages, PG_private should be set with 1 extra refcount, |
| 50 | * which is used for page reclaim / migration. |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 51 | */ |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 52 | |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 53 | /* |
| 54 | * short-lived pages are pages directly from buddy system with specific |
| 55 | * page->private (no need to set PagePrivate since these are non-LRU / |
| 56 | * non-movable pages and bypass reclaim / migration code). |
| 57 | */ |
| 58 | static inline bool z_erofs_is_shortlived_page(struct page *page) |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 59 | { |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 60 | if (page->private != Z_EROFS_SHORTLIVED_PAGE) |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 61 | return false; |
| 62 | |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 63 | DBG_BUGON(page->mapping); |
| 64 | return true; |
| 65 | } |
| 66 | |
| 67 | static inline bool z_erofs_put_shortlivedpage(struct list_head *pagepool, |
| 68 | struct page *page) |
| 69 | { |
| 70 | if (!z_erofs_is_shortlived_page(page)) |
| 71 | return false; |
| 72 | |
| 73 | /* short-lived pages should not be used by others at the same time */ |
| 74 | if (page_ref_count(page) > 1) { |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 75 | put_page(page); |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 76 | } else { |
| 77 | /* follow the pcluster rule above. */ |
| 78 | set_page_private(page, 0); |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 79 | list_add(&page->lru, pagepool); |
Gao Xiang | 6aaa7b0 | 2020-12-08 17:58:32 +0800 | [diff] [blame] | 80 | } |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 81 | return true; |
| 82 | } |
| 83 | |
Gao Xiang | 7fc45db | 2019-06-24 15:22:55 +0800 | [diff] [blame] | 84 | int z_erofs_decompress(struct z_erofs_decompress_req *rq, |
| 85 | struct list_head *pagepool); |
| 86 | |
Gao Xiang | 2748123 | 2019-06-24 15:22:54 +0800 | [diff] [blame] | 87 | #endif |
| 88 | |