From: Gao Xiang <[email protected]> This patch adds LZMA compression algorithms to erofsfuse to test if LZMA fixed-sized output algorithm works as expected.
Cc: Lasse Collin <[email protected]> Signed-off-by: Gao Xiang <[email protected]> --- lib/data.c | 7 +++--- lib/decompress.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/lib/data.c b/lib/data.c index 3781846743aa..4247dd3a33aa 100644 --- a/lib/data.c +++ b/lib/data.c @@ -146,9 +146,10 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, if (ret < 0) return -EIO; - algorithmformat = map.m_flags & EROFS_MAP_ZIPPED ? - Z_EROFS_COMPRESSION_LZ4 : - Z_EROFS_COMPRESSION_SHIFTED; + if (map.m_flags & EROFS_MAP_ZIPPED) + algorithmformat = inode->z_algorithmtype[0]; + else + algorithmformat = Z_EROFS_COMPRESSION_SHIFTED; /* * trim to the needed size if the returned extent is quite diff --git a/lib/decompress.c b/lib/decompress.c index 490c4bc771da..fd9f24bcbeb6 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -10,6 +10,66 @@ #include "erofs/decompress.h" #include "erofs/err.h" +#include <lzma.h> + +/* FIXME! need to record it into superblock */ +#define DICT_SIZE (64U << 10) + +static int z_erofs_decompress_lzma(struct z_erofs_decompress_req *rq) +{ + int ret = 0; + u8 *dest = (u8 *)rq->out; + u8 *src = (u8 *)rq->in; + u8 *buff = NULL; + unsigned int inputmargin = 0; + lzma_stream strm; + lzma_ret ret2; + + if (!erofs_sb_has_lz4_0padding()) + return -EFSCORRUPTED; + + while (!src[inputmargin & ~PAGE_MASK]) + if (!(++inputmargin & ~PAGE_MASK)) + break; + + if (inputmargin >= rq->inputsize) + return -EFSCORRUPTED; + + if (rq->decodedskip) { + buff = malloc(rq->decodedlength); + if (!buff) + return -ENOMEM; + dest = buff; + } + + strm = (lzma_stream)LZMA_STREAM_INIT; + strm.next_in = src + inputmargin; + strm.avail_in = rq->inputsize - inputmargin; + strm.next_out = dest; + strm.avail_out = rq->decodedlength; + + ret2 = lzma_erofs_decoder(&strm, strm.avail_in, rq->decodedlength, + !rq->partial_decoding, DICT_SIZE); + if (ret2 != LZMA_OK) { + ret = -EFAULT; + goto out; + } + + ret2 = lzma_code(&strm, LZMA_FINISH); + if (ret2 != LZMA_STREAM_END) { + ret = -EFSCORRUPTED; + goto out; + } + + if (rq->decodedskip) + memcpy(rq->out, dest + rq->decodedskip, + rq->decodedlength - rq->decodedskip); +out: + if (buff) + free(buff); + return ret; +} + #ifdef LZ4_ENABLED #include <lz4.h> @@ -84,5 +144,7 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq) if (rq->alg == Z_EROFS_COMPRESSION_LZ4) return z_erofs_decompress_lz4(rq); #endif + if (rq->alg == Z_EROFS_COMPRESSION_LZMA) + return z_erofs_decompress_lzma(rq); return -EOPNOTSUPP; } -- 2.24.0
