aboutsummaryrefslogtreecommitdiff
path: root/fs/erofs/zdata.h
diff options
context:
space:
mode:
authorGao Xiang <hsiangkao@linux.alibaba.com>2022-07-15 23:41:51 +0800
committerGao Xiang <hsiangkao@linux.alibaba.com>2022-07-21 22:54:10 +0800
commit06a304cd9cc095d9c6537621ebde5169de7f8270 (patch)
tree064c14fab48b5faaa68b0d0625f0807e3c16722c /fs/erofs/zdata.h
parent42fec235f122cb1ae3bf20d91f14e9df0005848c (diff)
erofs: introduce bufvec to store decompressed buffers
For each pcluster, the total compressed buffers are determined in advance, yet the number of decompressed buffers actually vary. Too many decompressed pages can be recorded if one pcluster is highly compressed or its pcluster size is large. That takes extra memory footprints compared to uncompressed filesystems, especially a lot of I/O in flight on low-ended devices. Therefore, similar to inplace I/O, pagevec was introduced to reuse page cache to store these pointers in the time-sharing way since these pages are actually unused before decompressing. In order to make it more flexable, a cleaner bufvec is used to replace the old pagevec stuffs so that - Decompressed offsets can be stored inline, thus it can be used for the upcoming feature like compressed data deduplication. It's calculated by `page_offset(page) - map->m_la'; - Towards supporting large folios for compressed inodes since our final goal is to completely avoid page->private but use folio->private only for all page cache pages. Acked-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20220715154203.48093-5-hsiangkao@linux.alibaba.com
Diffstat (limited to 'fs/erofs/zdata.h')
-rw-r--r--fs/erofs/zdata.h26
1 files changed, 22 insertions, 4 deletions
diff --git a/fs/erofs/zdata.h b/fs/erofs/zdata.h
index 58053bb5066f..f8daadb19e37 100644
--- a/fs/erofs/zdata.h
+++ b/fs/erofs/zdata.h
@@ -21,6 +21,21 @@
*/
typedef void *z_erofs_next_pcluster_t;
+struct z_erofs_bvec {
+ struct page *page;
+ int offset;
+ unsigned int end;
+};
+
+#define __Z_EROFS_BVSET(name, total) \
+struct name { \
+ /* point to the next page which contains the following bvecs */ \
+ struct page *nextpage; \
+ struct z_erofs_bvec bvec[total]; \
+}
+__Z_EROFS_BVSET(z_erofs_bvset,);
+__Z_EROFS_BVSET(z_erofs_bvset_inline, Z_EROFS_NR_INLINE_PAGEVECS);
+
/*
* Structure fields follow one of the following exclusion rules.
*
@@ -41,22 +56,25 @@ struct z_erofs_pcluster {
/* A: lower limit of decompressed length and if full length or not */
unsigned int length;
+ /* L: total number of bvecs */
+ unsigned int vcnt;
+
/* I: page offset of start position of decompression */
unsigned short pageofs_out;
/* I: page offset of inline compressed data */
unsigned short pageofs_in;
- /* L: maximum relative page index in pagevec[] */
+ /* L: maximum relative page index in bvecs */
unsigned short nr_pages;
- /* L: total number of pages in pagevec[] */
- unsigned int vcnt;
-
union {
/* L: inline a certain number of pagevecs for bootstrap */
erofs_vtptr_t pagevec[Z_EROFS_NR_INLINE_PAGEVECS];
+ /* L: inline a certain number of bvec for bootstrap */
+ struct z_erofs_bvset_inline bvset;
+
/* I: can be used to free the pcluster by RCU. */
struct rcu_head rcu;
};