]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
fs: ubifs: Add support for ZSTD decompression
authorPiotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
Tue, 28 May 2024 15:05:28 +0000 (17:05 +0200)
committerHeiko Schocher <hs@denx.de>
Wed, 3 Jul 2024 06:01:31 +0000 (08:01 +0200)
ZSTD can be a better tradeoff between NAND IO operations and decompression
speed giving a better boot time.

Signed-off-by: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
Reviewed-by: Heiko Schocher <hs@denx.de>
fs/ubifs/ubifs-media.h
fs/ubifs/ubifs.c

index 2b5b26a01b00733160cd5ab25f2f1731711731bb..299d80f928c45a1147e18b8a6d7efae55f1a97f5 100644 (file)
@@ -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,
 };
 
index 75de01e95f7cb8b4cdb813b31124e3f401c11e96..f0ea7e5c1682d8a9866e7a38b4793e421e7f3f0d 100644 (file)
 #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 */
@@ -41,6 +46,25 @@ 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,
@@ -70,8 +94,21 @@ 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__
@@ -165,8 +202,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;
        }
 
@@ -231,6 +274,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;