1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * erofs-utils/lib/compressor.c
4 *
5 * Copyright (C) 2018-2019 HUAWEI, Inc.
6 * http://www.huawei.com/
7 * Created by Gao Xiang <gaoxiang25@huawei.com>
8 */
9 #include "erofs/internal.h"
10 #include "compressor.h"
11 #include "erofs/print.h"
12
13 #define EROFS_CONFIG_COMPR_DEF_BOUNDARY (128)
14
15 static struct erofs_compressor *compressors[] = {
16 #if LZ4_ENABLED
17 #if LZ4HC_ENABLED
18 &erofs_compressor_lz4hc,
19 #endif
20 &erofs_compressor_lz4,
21 #endif
22 };
23
erofs_compress_destsize(struct erofs_compress * c,int compression_level,void * src,unsigned int * srcsize,void * dst,unsigned int dstsize)24 int erofs_compress_destsize(struct erofs_compress *c,
25 int compression_level,
26 void *src,
27 unsigned int *srcsize,
28 void *dst,
29 unsigned int dstsize)
30 {
31 int ret;
32
33 DBG_BUGON(!c->alg);
34 if (!c->alg->compress_destsize)
35 return -ENOTSUP;
36
37 ret = c->alg->compress_destsize(c, compression_level,
38 src, srcsize, dst, dstsize);
39 if (ret < 0)
40 return ret;
41
42 /* check if there is enough gains to compress */
43 if (*srcsize <= dstsize * c->compress_threshold / 100)
44 return -EAGAIN;
45 return ret;
46 }
47
z_erofs_list_available_compressors(unsigned int i)48 const char *z_erofs_list_available_compressors(unsigned int i)
49 {
50 return i >= ARRAY_SIZE(compressors) ? NULL : compressors[i]->name;
51 }
52
erofs_compressor_init(struct erofs_compress * c,char * alg_name)53 int erofs_compressor_init(struct erofs_compress *c, char *alg_name)
54 {
55 int ret, i;
56
57 /* should be written in "minimum compression ratio * 100" */
58 c->compress_threshold = 100;
59
60 /* optimize for 4k size page */
61 c->destsize_alignsize = PAGE_SIZE;
62 c->destsize_redzone_begin = PAGE_SIZE - 16;
63 c->destsize_redzone_end = EROFS_CONFIG_COMPR_DEF_BOUNDARY;
64
65 if (!alg_name) {
66 c->alg = NULL;
67 return 0;
68 }
69
70 ret = -EINVAL;
71 for (i = 0; i < ARRAY_SIZE(compressors); ++i) {
72 if (alg_name && strcmp(alg_name, compressors[i]->name))
73 continue;
74
75 ret = compressors[i]->init(c);
76 if (!ret) {
77 DBG_BUGON(!c->alg);
78 return 0;
79 }
80 }
81 erofs_err("Cannot find a valid compressor %s", alg_name);
82 return ret;
83 }
84
erofs_compressor_exit(struct erofs_compress * c)85 int erofs_compressor_exit(struct erofs_compress *c)
86 {
87 if (c->alg && c->alg->exit)
88 return c->alg->exit(c);
89 return 0;
90 }
91
92