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