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