1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 #include <linux/kernel.h> 4 #include <linux/slab.h> 5 #include <linux/vmalloc.h> 6 #include <linux/zstd.h> 7 8 #include "backend_zstd.h" 9 10 struct zstd_ctx { 11 zstd_cctx *cctx; 12 zstd_dctx *dctx; 13 void *cctx_mem; 14 void *dctx_mem; 15 s32 level; 16 }; 17 18 static void zstd_destroy(void *ctx) 19 { 20 struct zstd_ctx *zctx = ctx; 21 22 vfree(zctx->cctx_mem); 23 vfree(zctx->dctx_mem); 24 kfree(zctx); 25 } 26 27 static void *zstd_create(void) 28 { 29 zstd_parameters params; 30 struct zstd_ctx *ctx; 31 size_t sz; 32 33 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 34 if (!ctx) 35 return NULL; 36 37 ctx->level = zstd_default_clevel(); 38 params = zstd_get_params(ctx->level, 0); 39 sz = zstd_cctx_workspace_bound(¶ms.cParams); 40 ctx->cctx_mem = vzalloc(sz); 41 if (!ctx->cctx_mem) 42 goto error; 43 44 ctx->cctx = zstd_init_cctx(ctx->cctx_mem, sz); 45 if (!ctx->cctx) 46 goto error; 47 48 sz = zstd_dctx_workspace_bound(); 49 ctx->dctx_mem = vzalloc(sz); 50 if (!ctx->dctx_mem) 51 goto error; 52 53 ctx->dctx = zstd_init_dctx(ctx->dctx_mem, sz); 54 if (!ctx->dctx) 55 goto error; 56 57 return ctx; 58 59 error: 60 zstd_destroy(ctx); 61 return NULL; 62 } 63 64 static int zstd_compress(void *ctx, const unsigned char *src, size_t src_len, 65 unsigned char *dst, size_t *dst_len) 66 { 67 struct zstd_ctx *zctx = ctx; 68 const zstd_parameters params = zstd_get_params(zctx->level, 0); 69 size_t ret; 70 71 ret = zstd_compress_cctx(zctx->cctx, dst, *dst_len, 72 src, src_len, ¶ms); 73 if (zstd_is_error(ret)) 74 return -EINVAL; 75 *dst_len = ret; 76 return 0; 77 } 78 79 static int zstd_decompress(void *ctx, const unsigned char *src, size_t src_len, 80 unsigned char *dst, size_t dst_len) 81 { 82 struct zstd_ctx *zctx = ctx; 83 size_t ret; 84 85 ret = zstd_decompress_dctx(zctx->dctx, dst, dst_len, src, src_len); 86 if (zstd_is_error(ret)) 87 return -EINVAL; 88 return 0; 89 } 90 91 const struct zcomp_ops backend_zstd = { 92 .compress = zstd_compress, 93 .decompress = zstd_decompress, 94 .create_ctx = zstd_create, 95 .destroy_ctx = zstd_destroy, 96 .name = "zstd", 97 }; 98