Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/block/zram/backend_lz4hc.c
26282 views
1
#include <linux/kernel.h>
2
#include <linux/lz4.h>
3
#include <linux/slab.h>
4
#include <linux/vmalloc.h>
5
6
#include "backend_lz4hc.h"
7
8
struct lz4hc_ctx {
9
void *mem;
10
11
LZ4_streamDecode_t *dstrm;
12
LZ4_streamHC_t *cstrm;
13
};
14
15
static void lz4hc_release_params(struct zcomp_params *params)
16
{
17
}
18
19
static int lz4hc_setup_params(struct zcomp_params *params)
20
{
21
if (params->level == ZCOMP_PARAM_NOT_SET)
22
params->level = LZ4HC_DEFAULT_CLEVEL;
23
24
return 0;
25
}
26
27
static void lz4hc_destroy(struct zcomp_ctx *ctx)
28
{
29
struct lz4hc_ctx *zctx = ctx->context;
30
31
if (!zctx)
32
return;
33
34
kfree(zctx->dstrm);
35
kfree(zctx->cstrm);
36
vfree(zctx->mem);
37
kfree(zctx);
38
}
39
40
static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
41
{
42
struct lz4hc_ctx *zctx;
43
44
zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
45
if (!zctx)
46
return -ENOMEM;
47
48
ctx->context = zctx;
49
if (params->dict_sz == 0) {
50
zctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
51
if (!zctx->mem)
52
goto error;
53
} else {
54
zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL);
55
if (!zctx->dstrm)
56
goto error;
57
58
zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL);
59
if (!zctx->cstrm)
60
goto error;
61
}
62
63
return 0;
64
65
error:
66
lz4hc_destroy(ctx);
67
return -EINVAL;
68
}
69
70
static int lz4hc_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
71
struct zcomp_req *req)
72
{
73
struct lz4hc_ctx *zctx = ctx->context;
74
int ret;
75
76
if (!zctx->cstrm) {
77
ret = LZ4_compress_HC(req->src, req->dst, req->src_len,
78
req->dst_len, params->level,
79
zctx->mem);
80
} else {
81
/* Cstrm needs to be reset */
82
LZ4_resetStreamHC(zctx->cstrm, params->level);
83
ret = LZ4_loadDictHC(zctx->cstrm, params->dict,
84
params->dict_sz);
85
if (ret != params->dict_sz)
86
return -EINVAL;
87
ret = LZ4_compress_HC_continue(zctx->cstrm, req->src, req->dst,
88
req->src_len, req->dst_len);
89
}
90
if (!ret)
91
return -EINVAL;
92
req->dst_len = ret;
93
return 0;
94
}
95
96
static int lz4hc_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
97
struct zcomp_req *req)
98
{
99
struct lz4hc_ctx *zctx = ctx->context;
100
int ret;
101
102
if (!zctx->dstrm) {
103
ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
104
req->dst_len);
105
} else {
106
/* Dstrm needs to be reset */
107
ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
108
params->dict_sz);
109
if (!ret)
110
return -EINVAL;
111
ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
112
req->dst, req->src_len,
113
req->dst_len);
114
}
115
if (ret < 0)
116
return -EINVAL;
117
return 0;
118
}
119
120
const struct zcomp_ops backend_lz4hc = {
121
.compress = lz4hc_compress,
122
.decompress = lz4hc_decompress,
123
.create_ctx = lz4hc_create,
124
.destroy_ctx = lz4hc_destroy,
125
.setup_params = lz4hc_setup_params,
126
.release_params = lz4hc_release_params,
127
.name = "lz4hc",
128
};
129
130