--- linux-4.9.37/fs/jffs2/compr_lzma.c 1970-01-01 03:00:00.000000000 +0300 +++ linux-4.9.y/fs/jffs2/compr_lzma.c 2021-06-07 13:01:34.000000000 +0300 @@ -0,0 +1,125 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * For licensing information, see the file 'LICENCE' in this directory. + * + * JFFS2 wrapper to the LZMA C SDK + * + */ + +#include +#include "compr.h" + +#ifdef __KERNEL__ + static DEFINE_MUTEX(deflate_mutex); +#endif + +CLzmaEncHandle *p; +Byte propsEncoded[LZMA_PROPS_SIZE]; +SizeT propsSize = sizeof(propsEncoded); + +STATIC void lzma_free_workspace(void) +{ + LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); +} + +STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) +{ + if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) { + PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); + return -ENOMEM; + } + + if (LzmaEnc_SetProps(p, props) != SZ_OK) { + lzma_free_workspace(); + return -1; + } + + if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) { + lzma_free_workspace(); + return -1; + } + + return 0; +} + +STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen) +{ + SizeT compress_size = (SizeT)(*dstlen); + int ret; + +#ifdef __KERNEL__ + mutex_lock(&deflate_mutex); +#endif + + ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, + 0, NULL, &lzma_alloc, &lzma_alloc); + +#ifdef __KERNEL__ + mutex_unlock(&deflate_mutex); +#endif + + if (ret != SZ_OK) + return -1; + + *dstlen = (uint32_t)compress_size; + + return 0; +} + +STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen) +{ + int ret; + SizeT dl = (SizeT)destlen; + SizeT sl = (SizeT)srclen; + ELzmaStatus status; + + ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, + propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); + + if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) + return -1; + + return 0; +} + +static struct jffs2_compressor jffs2_lzma_comp = { + .priority = JFFS2_LZMA_PRIORITY, + .name = "lzma", + .compr = JFFS2_COMPR_LZMA, + .compress = &jffs2_lzma_compress, + .decompress = &jffs2_lzma_decompress, + .disabled = 0, +}; + +int INIT jffs2_lzma_init(void) +{ + int ret; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + + props.dictSize = LZMA_BEST_DICT(0x2000); + props.level = LZMA_BEST_LEVEL; + props.lc = LZMA_BEST_LC; + props.lp = LZMA_BEST_LP; + props.pb = LZMA_BEST_PB; + props.fb = LZMA_BEST_FB; + + ret = lzma_alloc_workspace(&props); + if (ret < 0) + return ret; + + ret = jffs2_register_compressor(&jffs2_lzma_comp); + if (ret) + lzma_free_workspace(); + + return ret; +} + +void jffs2_lzma_exit(void) +{ + jffs2_unregister_compressor(&jffs2_lzma_comp); + lzma_free_workspace(); +}