backend_lz4.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <linux/kernel.h>
  2. #include <linux/lz4.h>
  3. #include <linux/slab.h>
  4. #include <linux/vmalloc.h>
  5. #include "backend_lz4.h"
  6. struct lz4_ctx {
  7. void *mem;
  8. LZ4_streamDecode_t *dstrm;
  9. LZ4_stream_t *cstrm;
  10. };
  11. static void lz4_release_params(struct zcomp_params *params)
  12. {
  13. }
  14. static int lz4_setup_params(struct zcomp_params *params)
  15. {
  16. if (params->level == ZCOMP_PARAM_NO_LEVEL)
  17. params->level = LZ4_ACCELERATION_DEFAULT;
  18. return 0;
  19. }
  20. static void lz4_destroy(struct zcomp_ctx *ctx)
  21. {
  22. struct lz4_ctx *zctx = ctx->context;
  23. if (!zctx)
  24. return;
  25. vfree(zctx->mem);
  26. kfree(zctx->dstrm);
  27. kfree(zctx->cstrm);
  28. kfree(zctx);
  29. }
  30. static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
  31. {
  32. struct lz4_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(LZ4_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. lz4_destroy(ctx);
  52. return -ENOMEM;
  53. }
  54. static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
  55. struct zcomp_req *req)
  56. {
  57. struct lz4_ctx *zctx = ctx->context;
  58. int ret;
  59. if (!zctx->cstrm) {
  60. ret = LZ4_compress_fast(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. ret = LZ4_loadDict(zctx->cstrm, params->dict, params->dict_sz);
  66. if (ret != params->dict_sz)
  67. return -EINVAL;
  68. ret = LZ4_compress_fast_continue(zctx->cstrm, req->src,
  69. req->dst, req->src_len,
  70. req->dst_len, params->level);
  71. }
  72. if (!ret)
  73. return -EINVAL;
  74. req->dst_len = ret;
  75. return 0;
  76. }
  77. static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
  78. struct zcomp_req *req)
  79. {
  80. struct lz4_ctx *zctx = ctx->context;
  81. int ret;
  82. if (!zctx->dstrm) {
  83. ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
  84. req->dst_len);
  85. } else {
  86. /* Dstrm needs to be reset */
  87. ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
  88. params->dict_sz);
  89. if (!ret)
  90. return -EINVAL;
  91. ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
  92. req->dst, req->src_len,
  93. req->dst_len);
  94. }
  95. if (ret < 0)
  96. return -EINVAL;
  97. return 0;
  98. }
  99. const struct zcomp_ops backend_lz4 = {
  100. .compress = lz4_compress,
  101. .decompress = lz4_decompress,
  102. .create_ctx = lz4_create,
  103. .destroy_ctx = lz4_destroy,
  104. .setup_params = lz4_setup_params,
  105. .release_params = lz4_release_params,
  106. .name = "lz4",
  107. };