xref: /linux/drivers/block/zram/backend_lz4.c (revision 52c7b4e2ba508a924c991e681db534e66a851adf)
122d651c3SSergey Senozhatsky #include <linux/kernel.h>
222d651c3SSergey Senozhatsky #include <linux/lz4.h>
322d651c3SSergey Senozhatsky #include <linux/slab.h>
422d651c3SSergey Senozhatsky #include <linux/vmalloc.h>
522d651c3SSergey Senozhatsky 
622d651c3SSergey Senozhatsky #include "backend_lz4.h"
722d651c3SSergey Senozhatsky 
822d651c3SSergey Senozhatsky struct lz4_ctx {
922d651c3SSergey Senozhatsky 	void *mem;
1022d651c3SSergey Senozhatsky 	s32 level;
1122d651c3SSergey Senozhatsky };
1222d651c3SSergey Senozhatsky 
1322d651c3SSergey Senozhatsky static void lz4_destroy(void *ctx)
1422d651c3SSergey Senozhatsky {
1522d651c3SSergey Senozhatsky 	struct lz4_ctx *zctx = ctx;
1622d651c3SSergey Senozhatsky 
1722d651c3SSergey Senozhatsky 	vfree(zctx->mem);
1822d651c3SSergey Senozhatsky 	kfree(zctx);
1922d651c3SSergey Senozhatsky }
2022d651c3SSergey Senozhatsky 
21f2bac7adSSergey Senozhatsky static void *lz4_create(struct zcomp_params *params)
2222d651c3SSergey Senozhatsky {
2322d651c3SSergey Senozhatsky 	struct lz4_ctx *ctx;
2422d651c3SSergey Senozhatsky 
2522d651c3SSergey Senozhatsky 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2622d651c3SSergey Senozhatsky 	if (!ctx)
2722d651c3SSergey Senozhatsky 		return NULL;
2822d651c3SSergey Senozhatsky 
29f2bac7adSSergey Senozhatsky 	if (params->level != ZCOMP_PARAM_NO_LEVEL)
30f2bac7adSSergey Senozhatsky 		ctx->level = params->level;
31f2bac7adSSergey Senozhatsky 	else
3222d651c3SSergey Senozhatsky 		ctx->level = LZ4_ACCELERATION_DEFAULT;
33f2bac7adSSergey Senozhatsky 
3422d651c3SSergey Senozhatsky 	ctx->mem = vmalloc(LZ4_MEM_COMPRESS);
3522d651c3SSergey Senozhatsky 	if (!ctx->mem)
3622d651c3SSergey Senozhatsky 		goto error;
3722d651c3SSergey Senozhatsky 
3822d651c3SSergey Senozhatsky 	return ctx;
3922d651c3SSergey Senozhatsky error:
4022d651c3SSergey Senozhatsky 	lz4_destroy(ctx);
4122d651c3SSergey Senozhatsky 	return NULL;
4222d651c3SSergey Senozhatsky }
4322d651c3SSergey Senozhatsky 
44*52c7b4e2SSergey Senozhatsky static int lz4_compress(void *ctx, struct zcomp_req *req)
4522d651c3SSergey Senozhatsky {
4622d651c3SSergey Senozhatsky 	struct lz4_ctx *zctx = ctx;
4722d651c3SSergey Senozhatsky 	int ret;
4822d651c3SSergey Senozhatsky 
49*52c7b4e2SSergey Senozhatsky 	ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
50*52c7b4e2SSergey Senozhatsky 				req->dst_len, zctx->level, zctx->mem);
5122d651c3SSergey Senozhatsky 	if (!ret)
5222d651c3SSergey Senozhatsky 		return -EINVAL;
53*52c7b4e2SSergey Senozhatsky 	req->dst_len = ret;
5422d651c3SSergey Senozhatsky 	return 0;
5522d651c3SSergey Senozhatsky }
5622d651c3SSergey Senozhatsky 
57*52c7b4e2SSergey Senozhatsky static int lz4_decompress(void *ctx, struct zcomp_req *req)
5822d651c3SSergey Senozhatsky {
5922d651c3SSergey Senozhatsky 	int ret;
6022d651c3SSergey Senozhatsky 
61*52c7b4e2SSergey Senozhatsky 	ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
62*52c7b4e2SSergey Senozhatsky 				  req->dst_len);
6322d651c3SSergey Senozhatsky 	if (ret < 0)
6422d651c3SSergey Senozhatsky 		return -EINVAL;
6522d651c3SSergey Senozhatsky 	return 0;
6622d651c3SSergey Senozhatsky }
6722d651c3SSergey Senozhatsky 
6822d651c3SSergey Senozhatsky const struct zcomp_ops backend_lz4 = {
6922d651c3SSergey Senozhatsky 	.compress	= lz4_compress,
7022d651c3SSergey Senozhatsky 	.decompress	= lz4_decompress,
7122d651c3SSergey Senozhatsky 	.create_ctx	= lz4_create,
7222d651c3SSergey Senozhatsky 	.destroy_ctx	= lz4_destroy,
7322d651c3SSergey Senozhatsky 	.name		= "lz4",
7422d651c3SSergey Senozhatsky };
75