1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 2 /* 3 * Copyright (c) Facebook, Inc. 4 * All rights reserved. 5 * 6 * This source code is licensed under both the BSD-style license (found in the 7 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 8 * in the COPYING file in the root directory of this source tree). 9 * You may select, at your option, one of the above-listed licenses. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/string.h> 15 #include <linux/zstd.h> 16 17 #include "common/zstd_deps.h" 18 #include "common/zstd_internal.h" 19 20 #define ZSTD_FORWARD_IF_ERR(ret) \ 21 do { \ 22 size_t const __ret = (ret); \ 23 if (ZSTD_isError(__ret)) \ 24 return __ret; \ 25 } while (0) 26 27 static size_t zstd_cctx_init(zstd_cctx *cctx, const zstd_parameters *parameters, 28 unsigned long long pledged_src_size) 29 { 30 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_reset( 31 cctx, ZSTD_reset_session_and_parameters)); 32 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setPledgedSrcSize( 33 cctx, pledged_src_size)); 34 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 35 cctx, ZSTD_c_windowLog, parameters->cParams.windowLog)); 36 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 37 cctx, ZSTD_c_hashLog, parameters->cParams.hashLog)); 38 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 39 cctx, ZSTD_c_chainLog, parameters->cParams.chainLog)); 40 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 41 cctx, ZSTD_c_searchLog, parameters->cParams.searchLog)); 42 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 43 cctx, ZSTD_c_minMatch, parameters->cParams.minMatch)); 44 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 45 cctx, ZSTD_c_targetLength, parameters->cParams.targetLength)); 46 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 47 cctx, ZSTD_c_strategy, parameters->cParams.strategy)); 48 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 49 cctx, ZSTD_c_contentSizeFlag, parameters->fParams.contentSizeFlag)); 50 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 51 cctx, ZSTD_c_checksumFlag, parameters->fParams.checksumFlag)); 52 ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( 53 cctx, ZSTD_c_dictIDFlag, !parameters->fParams.noDictIDFlag)); 54 return 0; 55 } 56 57 int zstd_min_clevel(void) 58 { 59 return ZSTD_minCLevel(); 60 } 61 EXPORT_SYMBOL(zstd_min_clevel); 62 63 int zstd_max_clevel(void) 64 { 65 return ZSTD_maxCLevel(); 66 } 67 EXPORT_SYMBOL(zstd_max_clevel); 68 69 int zstd_default_clevel(void) 70 { 71 return ZSTD_defaultCLevel(); 72 } 73 EXPORT_SYMBOL(zstd_default_clevel); 74 75 size_t zstd_compress_bound(size_t src_size) 76 { 77 return ZSTD_compressBound(src_size); 78 } 79 EXPORT_SYMBOL(zstd_compress_bound); 80 81 zstd_parameters zstd_get_params(int level, 82 unsigned long long estimated_src_size) 83 { 84 return ZSTD_getParams(level, estimated_src_size, 0); 85 } 86 EXPORT_SYMBOL(zstd_get_params); 87 88 zstd_compression_parameters zstd_get_cparams(int level, 89 unsigned long long estimated_src_size, size_t dict_size) 90 { 91 return ZSTD_getCParams(level, estimated_src_size, dict_size); 92 } 93 EXPORT_SYMBOL(zstd_get_cparams); 94 95 size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *cparams) 96 { 97 return ZSTD_estimateCCtxSize_usingCParams(*cparams); 98 } 99 EXPORT_SYMBOL(zstd_cctx_workspace_bound); 100 101 zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size) 102 { 103 if (workspace == NULL) 104 return NULL; 105 return ZSTD_initStaticCCtx(workspace, workspace_size); 106 } 107 EXPORT_SYMBOL(zstd_init_cctx); 108 109 zstd_cctx *zstd_create_cctx_advanced(zstd_custom_mem custom_mem) 110 { 111 return ZSTD_createCCtx_advanced(custom_mem); 112 } 113 EXPORT_SYMBOL(zstd_create_cctx_advanced); 114 115 size_t zstd_free_cctx(zstd_cctx *cctx) 116 { 117 return ZSTD_freeCCtx(cctx); 118 } 119 EXPORT_SYMBOL(zstd_free_cctx); 120 121 zstd_cdict *zstd_create_cdict_byreference(const void *dict, size_t dict_size, 122 zstd_compression_parameters cparams, 123 zstd_custom_mem custom_mem) 124 { 125 return ZSTD_createCDict_advanced(dict, dict_size, ZSTD_dlm_byRef, 126 ZSTD_dct_auto, cparams, custom_mem); 127 } 128 EXPORT_SYMBOL(zstd_create_cdict_byreference); 129 130 size_t zstd_free_cdict(zstd_cdict *cdict) 131 { 132 return ZSTD_freeCDict(cdict); 133 } 134 EXPORT_SYMBOL(zstd_free_cdict); 135 136 size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, 137 const void *src, size_t src_size, const zstd_parameters *parameters) 138 { 139 ZSTD_FORWARD_IF_ERR(zstd_cctx_init(cctx, parameters, src_size)); 140 return ZSTD_compress2(cctx, dst, dst_capacity, src, src_size); 141 } 142 EXPORT_SYMBOL(zstd_compress_cctx); 143 144 size_t zstd_compress_using_cdict(zstd_cctx *cctx, void *dst, 145 size_t dst_capacity, const void *src, size_t src_size, 146 const ZSTD_CDict *cdict) 147 { 148 return ZSTD_compress_usingCDict(cctx, dst, dst_capacity, 149 src, src_size, cdict); 150 } 151 EXPORT_SYMBOL(zstd_compress_using_cdict); 152 153 size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams) 154 { 155 return ZSTD_estimateCStreamSize_usingCParams(*cparams); 156 } 157 EXPORT_SYMBOL(zstd_cstream_workspace_bound); 158 159 zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters, 160 unsigned long long pledged_src_size, void *workspace, size_t workspace_size) 161 { 162 zstd_cstream *cstream; 163 164 if (workspace == NULL) 165 return NULL; 166 167 cstream = ZSTD_initStaticCStream(workspace, workspace_size); 168 if (cstream == NULL) 169 return NULL; 170 171 /* 0 means unknown in linux zstd API but means 0 in new zstd API */ 172 if (pledged_src_size == 0) 173 pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; 174 175 if (ZSTD_isError(zstd_cctx_init(cstream, parameters, pledged_src_size))) 176 return NULL; 177 178 return cstream; 179 } 180 EXPORT_SYMBOL(zstd_init_cstream); 181 182 size_t zstd_reset_cstream(zstd_cstream *cstream, 183 unsigned long long pledged_src_size) 184 { 185 if (pledged_src_size == 0) 186 pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; 187 ZSTD_FORWARD_IF_ERR( ZSTD_CCtx_reset(cstream, ZSTD_reset_session_only) ); 188 ZSTD_FORWARD_IF_ERR( ZSTD_CCtx_setPledgedSrcSize(cstream, pledged_src_size) ); 189 return 0; 190 } 191 EXPORT_SYMBOL(zstd_reset_cstream); 192 193 size_t zstd_compress_stream(zstd_cstream *cstream, zstd_out_buffer *output, 194 zstd_in_buffer *input) 195 { 196 return ZSTD_compressStream(cstream, output, input); 197 } 198 EXPORT_SYMBOL(zstd_compress_stream); 199 200 size_t zstd_flush_stream(zstd_cstream *cstream, zstd_out_buffer *output) 201 { 202 return ZSTD_flushStream(cstream, output); 203 } 204 EXPORT_SYMBOL(zstd_flush_stream); 205 206 size_t zstd_end_stream(zstd_cstream *cstream, zstd_out_buffer *output) 207 { 208 return ZSTD_endStream(cstream, output); 209 } 210 EXPORT_SYMBOL(zstd_end_stream); 211 212 MODULE_LICENSE("Dual BSD/GPL"); 213 MODULE_DESCRIPTION("Zstd Compressor"); 214