Signed-off-by: Piotr Wojtaszczyk <piotr.wojtaszc...@timesys.com>
---

 fs/ubifs/ubifs-media.h |  2 ++
 fs/ubifs/ubifs.c       | 55 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index 2b5b26a01b..299d80f928 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -320,12 +320,14 @@ enum {
  * UBIFS_COMPR_NONE: no compression
  * UBIFS_COMPR_LZO: LZO compression
  * UBIFS_COMPR_ZLIB: ZLIB compression
+ * UBIFS_COMPR_ZSTD: ZSTD compression
  * UBIFS_COMPR_TYPES_CNT: count of supported compression types
  */
 enum {
        UBIFS_COMPR_NONE,
        UBIFS_COMPR_LZO,
        UBIFS_COMPR_ZLIB,
+       UBIFS_COMPR_ZSTD,
        UBIFS_COMPR_TYPES_CNT,
 };
 
diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
index a509584e5d..4df7cbb951 100644
--- a/fs/ubifs/ubifs.c
+++ b/fs/ubifs/ubifs.c
@@ -27,6 +27,11 @@
 #include <linux/err.h>
 #include <linux/lzo.h>
 
+#if IS_ENABLED(CONFIG_ZSTD)
+#include <linux/zstd.h>
+#include <abuf.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* compress.c */
@@ -42,6 +47,26 @@ static int gzip_decompress(const unsigned char *in, size_t 
in_len,
                      (unsigned long *)out_len, 0, 0);
 }
 
+#if IS_ENABLED(CONFIG_ZSTD)
+static int zstd_decompress_wrapper(const unsigned char *in, size_t in_len,
+                          unsigned char *out, size_t *out_len)
+{
+       struct abuf abuf_in, abuf_out;
+       int ret;
+
+       abuf_init_set(&abuf_in, (void *)in, in_len);
+       abuf_init_set(&abuf_out, (void *)out, *out_len);
+
+       ret = zstd_decompress(&abuf_in, &abuf_out);
+       if (ret < 0) {
+               return ret;
+       }
+
+       *out_len = ret;
+       return 0;
+}
+#endif
+
 /* Fake description object for the "none" compressor */
 static struct ubifs_compressor none_compr = {
        .compr_type = UBIFS_COMPR_NONE,
@@ -71,8 +96,22 @@ static struct ubifs_compressor zlib_compr = {
        .decompress = gzip_decompress,
 };
 
+#if IS_ENABLED(CONFIG_ZSTD)
+static struct ubifs_compressor zstd_compr = {
+       .compr_type = UBIFS_COMPR_ZSTD,
+#ifndef __UBOOT__
+       .comp_mutex = &zstd_enc_mutex,
+       .decomp_mutex = &zstd_dec_mutex,
+#endif
+       .name = "zstd",
+       .capi_name = "zstd",
+       .decompress = zstd_decompress_wrapper,
+};
+#endif
+
+
 /* All UBIFS compressors */
-struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
+struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT] = {NULL};
 
 
 #ifdef __UBOOT__
@@ -166,8 +205,14 @@ int ubifs_decompress(const struct ubifs_info *c, const 
void *in_buf,
 
        compr = ubifs_compressors[compr_type];
 
+       if (unlikely(!compr)) {
+               ubifs_err(c, "compression type %d is not compiled in", 
compr_type);
+               return -EINVAL;
+       }
+
        if (unlikely(!compr->capi_name)) {
-               ubifs_err(c, "%s compression is not compiled in", compr->name);
+               ubifs_err(c, "%s compression is not compiled in",
+                               compr->name ? compr->name : "unknown");
                return -EINVAL;
        }
 
@@ -232,6 +277,12 @@ int __init ubifs_compressors_init(void)
        if (err)
                return err;
 
+#if IS_ENABLED(CONFIG_ZSTD)
+       err = compr_init(&zstd_compr);
+       if (err)
+               return err;
+#endif
+
        err = compr_init(&none_compr);
        if (err)
                return err;
-- 
2.25.1

Reply via email to