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