File Index
Files and directories
Sign in
FILE

backend_lz4hc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/block/zram/backend_lz4hc.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_lz4hc.h"
  7
  8struct lz4hc_ctx {
  9	void *mem;
 10
 11	LZ4_streamDecode_t *dstrm;
 12	LZ4_streamHC_t *cstrm;
 13};
 14
 15static void lz4hc_release_params(struct zcomp_params *params)
 16{
 17}
 18
 19static int lz4hc_setup_params(struct zcomp_params *params)
 20{
 21	if (params->level == ZCOMP_PARAM_NOT_SET)
 22		params->level = LZ4HC_DEFAULT_CLEVEL;
 23
 24	return 0;
 25}
 26
 27static void lz4hc_destroy(struct zcomp_ctx *ctx)
 28{
 29	struct lz4hc_ctx *zctx = ctx->context;
 30
 31	if (!zctx)
 32		return;
 33
 34	kfree(zctx->dstrm);
 35	kfree(zctx->cstrm);
 36	vfree(zctx->mem);
 37	kfree(zctx);
 38}
 39
 40static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
 41{
 42	struct lz4hc_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(LZ4HC_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	lz4hc_destroy(ctx);
 67	return -EINVAL;
 68}
 69
 70static int lz4hc_compress(struct zcomp_params *params, struct zcomp_ctx *ctx,
 71			  struct zcomp_req *req)
 72{
 73	struct lz4hc_ctx *zctx = ctx->context;
 74	int ret;
 75
 76	if (!zctx->cstrm) {
 77		ret = LZ4_compress_HC(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		LZ4_resetStreamHC(zctx->cstrm, params->level);
 83		ret = LZ4_loadDictHC(zctx->cstrm, params->dict,
 84				     params->dict_sz);
 85		if (ret != params->dict_sz)
 86			return -EINVAL;
 87		ret = LZ4_compress_HC_continue(zctx->cstrm, req->src, req->dst,
 88					       req->src_len, req->dst_len);
 89	}
 90	if (!ret)
 91		return -EINVAL;
 92	req->dst_len = ret;
 93	return 0;
 94}
 95
 96static int lz4hc_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx,
 97			    struct zcomp_req *req)
 98{
 99	struct lz4hc_ctx *zctx = ctx->context;
100	int ret;
101
102	if (!zctx->dstrm) {
103		ret = LZ4_decompress_safe(req->src, req->dst, req->src_len,
104					  req->dst_len);
105	} else {
106		/* Dstrm needs to be reset */
107		ret = LZ4_setStreamDecode(zctx->dstrm, params->dict,
108					  params->dict_sz);
109		if (!ret)
110			return -EINVAL;
111		ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src,
112						   req->dst, req->src_len,
113						   req->dst_len);
114	}
115	if (ret < 0)
116		return -EINVAL;
117	return 0;
118}
119
120const struct zcomp_ops backend_lz4hc = {
121	.compress	= lz4hc_compress,
122	.decompress	= lz4hc_decompress,
123	.create_ctx	= lz4hc_create,
124	.destroy_ctx	= lz4hc_destroy,
125	.setup_params	= lz4hc_setup_params,
126	.release_params	= lz4hc_release_params,
127	.name		= "lz4hc",
128};
~/ Read-only file preview.