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