xref: /linux/drivers/block/zram/backend_lz4.c (revision 6a81bdfeb35094c3097650306a5fda9a990d8a97)
1 #include <linux/kernel.h>
2 #include <linux/lz4.h>
3 #include <linux/slab.h>
4 #include <linux/vmalloc.h>
5 
6 #include "backend_lz4.h"
7 
8 struct lz4_ctx {
9 	void *mem;
10 	s32 level;
11 };
12 
13 static void lz4_destroy(struct zcomp_ctx *ctx)
14 {
15 	struct lz4_ctx *zctx = ctx->context;
16 
17 	if (!zctx)
18 		return;
19 
20 	vfree(zctx->mem);
21 	kfree(zctx);
22 }
23 
24 static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
25 {
26 	struct lz4_ctx *zctx;
27 
28 	zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
29 	if (!zctx)
30 		return -ENOMEM;
31 
32 	ctx->context = zctx;
33 	if (params->level != ZCOMP_PARAM_NO_LEVEL)
34 		zctx->level = params->level;
35 	else
36 		zctx->level = LZ4_ACCELERATION_DEFAULT;
37 
38 	zctx->mem = vmalloc(LZ4_MEM_COMPRESS);
39 	if (!zctx->mem)
40 		goto error;
41 
42 	return 0;
43 error:
44 	lz4_destroy(ctx);
45 	return -EINVAL;
46 }
47 
48 static int lz4_compress(struct zcomp_ctx *ctx, struct zcomp_req *req)
49 {
50 	struct lz4_ctx *zctx = ctx->context;
51 	int ret;
52 
53 	ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
54 				req->dst_len, zctx->level, zctx->mem);
55 	if (!ret)
56 		return -EINVAL;
57 	req->dst_len = ret;
58 	return 0;
59 }
60 
61 static int lz4_decompress(struct zcomp_ctx *ctx, struct zcomp_req *req)
62 {
63 	int ret;
64 
65 	ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
66 				  req->dst_len);
67 	if (ret < 0)
68 		return -EINVAL;
69 	return 0;
70 }
71 
72 const struct zcomp_ops backend_lz4 = {
73 	.compress	= lz4_compress,
74 	.decompress	= lz4_decompress,
75 	.create_ctx	= lz4_create,
76 	.destroy_ctx	= lz4_destroy,
77 	.name		= "lz4",
78 };
79