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