[RFC PATCH v0 4/4] erofs-utils: fuse: add LZMA algorithm support
Gao Xiang
hsiangkao at aol.com
Mon Jan 18 04:46:03 AEDT 2021
From: Gao Xiang <hsiangkao at aol.com>
This patch adds LZMA compression algorithms to erofsfuse to test
if LZMA fixed-sized output algorithm works as expected.
Cc: Lasse Collin <lasse.collin at tukaani.org>
Signed-off-by: Gao Xiang <hsiangkao at aol.com>
---
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
More information about the Linux-erofs
mailing list