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