xref: /linux/drivers/block/zram/backend_lz4hc.c (revision f2bac7ad187d77e2a053d3cd04b158a06b683d26)
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 
21*f2bac7adSSergey 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 
29*f2bac7adSSergey Senozhatsky 	if (params->level != ZCOMP_PARAM_NO_LEVEL)
30*f2bac7adSSergey Senozhatsky 		ctx->level = params->level;
31*f2bac7adSSergey Senozhatsky 	else
32c60a4ef5SSergey Senozhatsky 		ctx->level = LZ4HC_DEFAULT_CLEVEL;
33*f2bac7adSSergey 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 
44c60a4ef5SSergey Senozhatsky static int lz4hc_compress(void *ctx, const unsigned char *src, size_t src_len,
45c60a4ef5SSergey Senozhatsky 			  unsigned char *dst, size_t *dst_len)
46c60a4ef5SSergey Senozhatsky {
47c60a4ef5SSergey Senozhatsky 	struct lz4hc_ctx *zctx = ctx;
48c60a4ef5SSergey Senozhatsky 	int ret;
49c60a4ef5SSergey Senozhatsky 
50c60a4ef5SSergey Senozhatsky 	ret = LZ4_compress_HC(src, dst, src_len, *dst_len,
51c60a4ef5SSergey Senozhatsky 			      zctx->level, zctx->mem);
52c60a4ef5SSergey Senozhatsky 	if (!ret)
53c60a4ef5SSergey Senozhatsky 		return -EINVAL;
54c60a4ef5SSergey Senozhatsky 	*dst_len = ret;
55c60a4ef5SSergey Senozhatsky 	return 0;
56c60a4ef5SSergey Senozhatsky }
57c60a4ef5SSergey Senozhatsky 
58c60a4ef5SSergey Senozhatsky static int lz4hc_decompress(void *ctx, const unsigned char *src,
59c60a4ef5SSergey Senozhatsky 			    size_t src_len, unsigned char *dst, size_t dst_len)
60c60a4ef5SSergey Senozhatsky {
61c60a4ef5SSergey Senozhatsky 	int ret;
62c60a4ef5SSergey Senozhatsky 
63c60a4ef5SSergey Senozhatsky 	ret = LZ4_decompress_safe(src, dst, src_len, dst_len);
64c60a4ef5SSergey Senozhatsky 	if (ret < 0)
65c60a4ef5SSergey Senozhatsky 		return -EINVAL;
66c60a4ef5SSergey Senozhatsky 	return 0;
67c60a4ef5SSergey Senozhatsky }
68c60a4ef5SSergey Senozhatsky 
69c60a4ef5SSergey Senozhatsky const struct zcomp_ops backend_lz4hc = {
70c60a4ef5SSergey Senozhatsky 	.compress	= lz4hc_compress,
71c60a4ef5SSergey Senozhatsky 	.decompress	= lz4hc_decompress,
72c60a4ef5SSergey Senozhatsky 	.create_ctx	= lz4hc_create,
73c60a4ef5SSergey Senozhatsky 	.destroy_ctx	= lz4hc_destroy,
74c60a4ef5SSergey Senozhatsky 	.name		= "lz4hc",
75c60a4ef5SSergey Senozhatsky };
76