backend_lz4hc.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <linux/kernel.h>
  2. #include <linux/lz4.h>
  3. #include <linux/slab.h>
  4. #include <linux/vmalloc.h>
  5. #include "backend_lz4hc.h"
  6. struct lz4hc_ctx {
  7. void *mem;
  8. LZ4_streamDecode_t *dstrm;
  9. LZ4_streamHC_t *cstrm;
  10. };
  11. static void lz4hc_release_params(struct zcomp_params *params)
  12. {
  13. }
  14. static int lz4hc_setup_params(struct zcomp_params *params)
  15. {
  16. if (params->level == ZCOMP_PARAM_NO_LEVEL)
  17. params->level = LZ4HC_DEFAULT_CLEVEL;
  18. return 0;
  19. }
  20. static void lz4hc_destroy(struct zcomp_ctx *ctx)
  21. {
  22. struct lz4hc_ctx *zctx = ctx->context;
  23. if (!zctx)
  24. return;
  25. kfree(zctx->dstrm);
  26. kfree(zctx->cstrm);
  27. vfree(zctx->mem);
  28. kfree(zctx);
  29. }
  30. static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
  31. {
  32. struct lz4hc_ctx *zctx;
  33. zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
  34. if (!zctx)
  35. return -ENOMEM;
  36. ctx->context = zctx;
  37. if (params->dict_sz == 0) {
  38. zctx->mem = vmalloc(LZ4HC_MEM_COMPRESS);
  39. if (!zctx->mem)
  40. goto error;
  41. } else {
  42. zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL);
  43. if (!zctx->dstrm)
  44. goto error;
  45. zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL);
  46. if (!zctx->cstrm)
  47. goto error;
  48. }
  49. return 0;
  50. error:
  51. lz4hc_destroy(ctx);
  52. return -EINVAL;
  53. }
  54. static int lz4hc_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
  55. struct zcomp_req *req)
  56. {
  57. struct lz4hc_ctx *zctx = ctx->context;
  58. int ret;
  59. if (!zctx->cstrm) {
  60. ret = LZ4_compress_HC(req->src, req->dst, req->src_len,
  61. req->dst_len, params->level,
  62. zctx->mem);
  63. } else {
  64. /* Cstrm needs to be reset */
  65. LZ4_resetStreamHC(zctx->cstrm, params->level);
  66. ret = LZ4_loadDictHC(zctx->cstrm, params->dict,
  67. params->dict_sz);
  68. if (ret != params->dict_sz)
  69. return -EINVAL;
  70. ret = LZ4_compress_HC_continue(zctx->cstrm, req->src, req->dst,
  71. req->src_len, req->dst_len);
  72. }
  73. if (!ret)
  74. return -EINVAL;
  75. req->dst_len = ret;
  76. return 0;
  77. }
  78. static int lz4hc_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
  79. struct zcomp_req *req)
  80. {
  81. struct lz4hc_ctx *zctx = ctx->context;
  82. int ret;
  83. if (!zctx->dstrm) {
  84. ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
  85. req->dst_len);
  86. } else {
  87. /* Dstrm needs to be reset */
  88. ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
  89. params->dict_sz);
  90. if (!ret)
  91. return -EINVAL;
  92. ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
  93. req->dst, req->src_len,
  94. req->dst_len);
  95. }
  96. if (ret < 0)
  97. return -EINVAL;
  98. return 0;
  99. }
  100. const struct zcomp_ops backend_lz4hc = {
  101. .compress = lz4hc_compress,
  102. .decompress = lz4hc_decompress,
  103. .create_ctx = lz4hc_create,
  104. .destroy_ctx = lz4hc_destroy,
  105. .setup_params = lz4hc_setup_params,
  106. .release_params = lz4hc_release_params,
  107. .name = "lz4hc",
  108. };