Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 150 lines 3.0 kB view raw
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 LZ4_stream_t *dict_stream = params->drv_data; 18 19 params->drv_data = NULL; 20 if (!dict_stream) 21 return; 22 23 kfree(dict_stream); 24} 25 26static int lz4_setup_params(struct zcomp_params *params) 27{ 28 LZ4_stream_t *dict_stream; 29 int ret; 30 31 if (params->level == ZCOMP_PARAM_NOT_SET) 32 params->level = LZ4_ACCELERATION_DEFAULT; 33 34 if (!params->dict || !params->dict_sz) 35 return 0; 36 37 dict_stream = kzalloc_obj(*dict_stream, GFP_KERNEL); 38 if (!dict_stream) 39 return -ENOMEM; 40 41 ret = LZ4_loadDict(dict_stream, 42 params->dict, params->dict_sz); 43 if (ret != params->dict_sz) { 44 kfree(dict_stream); 45 return -EINVAL; 46 } 47 params->drv_data = dict_stream; 48 49 return 0; 50} 51 52static void lz4_destroy(struct zcomp_ctx *ctx) 53{ 54 struct lz4_ctx *zctx = ctx->context; 55 56 if (!zctx) 57 return; 58 59 vfree(zctx->mem); 60 kfree(zctx->dstrm); 61 kfree(zctx->cstrm); 62 kfree(zctx); 63} 64 65static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx) 66{ 67 struct lz4_ctx *zctx; 68 69 zctx = kzalloc_obj(*zctx); 70 if (!zctx) 71 return -ENOMEM; 72 73 ctx->context = zctx; 74 if (params->dict_sz == 0) { 75 zctx->mem = vmalloc(LZ4_MEM_COMPRESS); 76 if (!zctx->mem) 77 goto error; 78 } else { 79 zctx->dstrm = kzalloc_obj(*zctx->dstrm); 80 if (!zctx->dstrm) 81 goto error; 82 83 zctx->cstrm = kzalloc_obj(*zctx->cstrm); 84 if (!zctx->cstrm) 85 goto error; 86 } 87 88 return 0; 89 90error: 91 lz4_destroy(ctx); 92 return -ENOMEM; 93} 94 95static int lz4_compress(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->cstrm) { 102 ret = LZ4_compress_fast(req->src, req->dst, req->src_len, 103 req->dst_len, params->level, 104 zctx->mem); 105 } else { 106 /* Cstrm needs to be reset */ 107 memcpy(zctx->cstrm, params->drv_data, sizeof(*zctx->cstrm)); 108 ret = LZ4_compress_fast_continue(zctx->cstrm, req->src, 109 req->dst, req->src_len, 110 req->dst_len, params->level); 111 } 112 if (!ret) 113 return -EINVAL; 114 req->dst_len = ret; 115 return 0; 116} 117 118static int lz4_decompress(struct zcomp_params *params, struct zcomp_ctx *ctx, 119 struct zcomp_req *req) 120{ 121 struct lz4_ctx *zctx = ctx->context; 122 int ret; 123 124 if (!zctx->dstrm) { 125 ret = LZ4_decompress_safe(req->src, req->dst, req->src_len, 126 req->dst_len); 127 } else { 128 /* Dstrm needs to be reset */ 129 ret = LZ4_setStreamDecode(zctx->dstrm, params->dict, 130 params->dict_sz); 131 if (!ret) 132 return -EINVAL; 133 ret = LZ4_decompress_safe_continue(zctx->dstrm, req->src, 134 req->dst, req->src_len, 135 req->dst_len); 136 } 137 if (ret < 0) 138 return -EINVAL; 139 return 0; 140} 141 142const struct zcomp_ops backend_lz4 = { 143 .compress = lz4_compress, 144 .decompress = lz4_decompress, 145 .create_ctx = lz4_create, 146 .destroy_ctx = lz4_destroy, 147 .setup_params = lz4_setup_params, 148 .release_params = lz4_release_params, 149 .name = "lz4", 150};