xref: /linux/drivers/block/zram/backend_lz4hc.c (revision f2bac7ad187d77e2a053d3cd04b158a06b683d26)
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 	s32 level;
11 };
12 
13 static void lz4hc_destroy(void *ctx)
14 {
15 	struct lz4hc_ctx *zctx = ctx;
16 
17 	vfree(zctx->mem);
18 	kfree(zctx);
19 }
20 
21 static void *lz4hc_create(struct zcomp_params *params)
22 {
23 	struct lz4hc_ctx *ctx;
24 
25 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
26 	if (!ctx)
27 		return NULL;
28 
29 	if (params->level != ZCOMP_PARAM_NO_LEVEL)
30 		ctx->level = params->level;
31 	else
32 		ctx->level = LZ4HC_DEFAULT_CLEVEL;
33 
34 	ctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
35 	if (!ctx->mem)
36 		goto error;
37 
38 	return ctx;
39 error:
40 	lz4hc_destroy(ctx);
41 	return NULL;
42 }
43 
44 static int lz4hc_compress(void *ctx, const unsigned char *src, size_t src_len,
45 			  unsigned char *dst, size_t *dst_len)
46 {
47 	struct lz4hc_ctx *zctx = ctx;
48 	int ret;
49 
50 	ret = LZ4_compress_HC(src, dst, src_len, *dst_len,
51 			      zctx->level, zctx->mem);
52 	if (!ret)
53 		return -EINVAL;
54 	*dst_len = ret;
55 	return 0;
56 }
57 
58 static int lz4hc_decompress(void *ctx, const unsigned char *src,
59 			    size_t src_len, unsigned char *dst, size_t dst_len)
60 {
61 	int ret;
62 
63 	ret = LZ4_decompress_safe(src, dst, src_len, dst_len);
64 	if (ret < 0)
65 		return -EINVAL;
66 	return 0;
67 }
68 
69 const struct zcomp_ops backend_lz4hc = {
70 	.compress	= lz4hc_compress,
71 	.decompress	= lz4hc_decompress,
72 	.create_ctx	= lz4hc_create,
73 	.destroy_ctx	= lz4hc_destroy,
74 	.name		= "lz4hc",
75 };
76