#include #include #include #include #include "backend_lz4.h" struct lz4_ctx { void *mem; LZ4_streamDecode_t *dstrm; LZ4_stream_t *cstrm; }; static void lz4_release_params(struct zcomp_params *params) { } static int lz4_setup_params(struct zcomp_params *params) { if (params->level == ZCOMP_PARAM_NO_LEVEL) params->level = LZ4_ACCELERATION_DEFAULT; return 0; } static void lz4_destroy(struct zcomp_ctx *ctx) { struct lz4_ctx *zctx = ctx->context; if (!zctx) return; vfree(zctx->mem); kfree(zctx->dstrm); kfree(zctx->cstrm); kfree(zctx); } static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx) { struct lz4_ctx *zctx; zctx = kzalloc(sizeof(*zctx), GFP_KERNEL); if (!zctx) return -ENOMEM; ctx->context = zctx; if (params->dict_sz == 0) { zctx->mem = vmalloc(LZ4_MEM_COMPRESS); if (!zctx->mem) goto error; } else { zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL); if (!zctx->dstrm) goto error; zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL); if (!zctx->cstrm) goto error; } return 0; error: lz4_destroy(ctx); return -ENOMEM; } static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx, struct zcomp_req *req) { struct lz4_ctx *zctx = ctx->context; int ret; if (!zctx->cstrm) { ret = LZ4_compress_fast(req->src, req->dst, req->src_len, req->dst_len, params->level, zctx->mem); } else { /* Cstrm needs to be reset */ ret = LZ4_loadDict(zctx->cstrm, params->dict, params->dict_sz); if (ret != params->dict_sz) return -EINVAL; ret = LZ4_compress_fast_continue(zctx->cstrm, req->src, req->dst, req->src_len, req->dst_len, params->level); } if (!ret) return -EINVAL; req->dst_len = ret; return 0; } static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx, struct zcomp_req *req) { struct lz4_ctx *zctx = ctx->context; int ret; if (!zctx->dstrm) { ret = LZ4_decompress_safe(req->src, req->dst, req->src_len, req->dst_len); } else { /* Dstrm needs to be reset */ ret = LZ4_setStreamDecode(zctx->dstrm, params->dict, params->dict_sz); if (!ret) return -EINVAL; ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src, req->dst, req->src_len, req->dst_len); } if (ret < 0) return -EINVAL; return 0; } const struct zcomp_ops backend_lz4 = { .compress = lz4_compress, .decompress = lz4_decompress, .create_ctx = lz4_create, .destroy_ctx = lz4_destroy, .setup_params = lz4_setup_params, .release_params = lz4_release_params, .name = "lz4", };