File Index
Files and directories
Sign in
FILE

backend_lz4.c

File preview with syntax highlighting.

linux-6.19.14/drivers/block/zram/backend_lz4.c C
  1#include <linux/kernel.h>
  2#include <linux/lz4.h>
  3#include <linux/slab.h>
  4#include <linux/vmalloc.h>
  5
  6#include "backend_lz4.h"
  7
  8struct lz4_ctx {
  9	void *mem;
 10
 11	LZ4_streamDecode_t *dstrm;
 12	LZ4_stream_t *cstrm;
 13};
 14
 15static void lz4_release_params(struct zcomp_params *params)
 16{
 17}
 18
 19static int lz4_setup_params(struct zcomp_params *params)
 20{
 21	if (params->level == ZCOMP_PARAM_NOT_SET)
 22		params->level = LZ4_ACCELERATION_DEFAULT;
 23
 24	return 0;
 25}
 26
 27static void lz4_destroy(struct zcomp_ctx *ctx)
 28{
 29	struct lz4_ctx *zctx = ctx->context;
 30
 31	if (!zctx)
 32		return;
 33
 34	vfree(zctx->mem);
 35	kfree(zctx->dstrm);
 36	kfree(zctx->cstrm);
 37	kfree(zctx);
 38}
 39
 40static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
 41{
 42	struct lz4_ctx *zctx;
 43
 44	zctx = kzalloc(sizeof(*zctx), GFP_KERNEL);
 45	if (!zctx)
 46		return -ENOMEM;
 47
 48	ctx->context = zctx;
 49	if (params->dict_sz == 0) {
 50		zctx->mem = vmalloc(LZ4_MEM_COMPRESS);
 51		if (!zctx->mem)
 52			goto error;
 53	} else {
 54		zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL);
 55		if (!zctx->dstrm)
 56			goto error;
 57
 58		zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL);
 59		if (!zctx->cstrm)
 60			goto error;
 61	}
 62
 63	return 0;
 64
 65error:
 66	lz4_destroy(ctx);
 67	return -ENOMEM;
 68}
 69
 70static int lz4_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
 71			struct zcomp_req *req)
 72{
 73	struct lz4_ctx *zctx = ctx->context;
 74	int ret;
 75
 76	if (!zctx->cstrm) {
 77		ret = LZ4_compress_fast(req->src, req->dst, req->src_len,
 78					req->dst_len, params->level,
 79					zctx->mem);
 80	} else {
 81		/* Cstrm needs to be reset */
 82		ret = LZ4_loadDict(zctx->cstrm, params->dict, params->dict_sz);
 83		if (ret != params->dict_sz)
 84			return -EINVAL;
 85		ret = LZ4_compress_fast_continue(zctx->cstrm, req->src,
 86						 req->dst, req->src_len,
 87						 req->dst_len, params->level);
 88	}
 89	if (!ret)
 90		return -EINVAL;
 91	req->dst_len = ret;
 92	return 0;
 93}
 94
 95static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
 96			  struct zcomp_req *req)
 97{
 98	struct lz4_ctx *zctx = ctx->context;
 99	int ret;
100
101	if (!zctx->dstrm) {
102		ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
103					  req->dst_len);
104	} else {
105		/* Dstrm needs to be reset */
106		ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
107					  params->dict_sz);
108		if (!ret)
109			return -EINVAL;
110		ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
111						   req->dst, req->src_len,
112						   req->dst_len);
113	}
114	if (ret < 0)
115		return -EINVAL;
116	return 0;
117}
118
119const struct zcomp_ops backend_lz4 = {
120	.compress	= lz4_compress,
121	.decompress	= lz4_decompress,
122	.create_ctx	= lz4_create,
123	.destroy_ctx	= lz4_destroy,
124	.setup_params	= lz4_setup_params,
125	.release_params	= lz4_release_params,
126	.name		= "lz4",
127};
~/ Read-only file preview.