xref: /linux/drivers/block/zram/backend_zstd.c (revision 73e7d81abbc80b04595cc7da09dcaa05a3a92602)
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(&params.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, &params);
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