summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/ubifs.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2022-02-07 16:08:54 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2022-02-07 16:11:23 +0100
commitcd1610d8ab3038c28ce7083b84196bb87090b14c (patch)
tree5de19de38e4752215c21bbe79583dc3b60d8d143 /fs/ubifs/ubifs.c
parente4a7f8e21cc55e633ca7997819d8ebdb94d305af (diff)
downloadbarebox-cd1610d8ab3038c28ce7083b84196bb87090b14c.tar.gz
barebox-cd1610d8ab3038c28ce7083b84196bb87090b14c.tar.xz
ubifs: Add zstd support
zstd shows a good compression rate and is faster than lzo. This adds UBIFS support for it. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs/ubifs/ubifs.c')
-rw-r--r--fs/ubifs/ubifs.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
index ced3d1f47f..88a4340a38 100644
--- a/fs/ubifs/ubifs.c
+++ b/fs/ubifs/ubifs.c
@@ -19,6 +19,7 @@
#include <magicvar.h>
#include <linux/stat.h>
#include <linux/zlib.h>
+#include <linux/zstd.h>
#include <linux/mtd/mtd.h>
#include "ubifs.h"
@@ -33,6 +34,7 @@ struct ubifs_priv {
static struct z_stream_s ubifs_zlib_stream;
+static ZSTD_DCtx *ubifs_zstd_cctx;
/* compress.c */
@@ -48,6 +50,22 @@ static int gzip_decompress(const unsigned char *in, size_t in_len,
}
#endif
+#if defined(CONFIG_ZSTD_DECOMPRESS)
+static int zstd_decompress(const unsigned char *in, size_t in_len,
+ unsigned char *out, size_t *out_len)
+{
+ size_t olen;
+
+ olen = ZSTD_decompressDCtx(ubifs_zstd_cctx, out, *out_len, in, in_len);
+ if (ZSTD_isError(olen))
+ return -EINVAL;
+
+ *out_len = olen;
+
+ return 0;
+}
+#endif
+
/* Fake description object for the "none" compressor */
static struct ubifs_compressor none_compr = {
.compr_type = UBIFS_COMPR_NONE,
@@ -74,6 +92,15 @@ static struct ubifs_compressor zlib_compr = {
#endif
};
+static struct ubifs_compressor zstd_compr = {
+ .compr_type = UBIFS_COMPR_ZSTD,
+ .name = "zstd",
+#ifdef CONFIG_ZSTD_DECOMPRESS
+ .capi_name = "zstd",
+ .decompress = zstd_decompress,
+#endif
+};
+
/* All UBIFS compressors */
struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
@@ -238,6 +265,10 @@ int __init ubifs_compressors_init(void)
if (err)
return err;
+ err = compr_init(&zstd_compr);
+ if (err)
+ return err;
+
err = compr_init(&none_compr);
if (err)
return err;
@@ -492,6 +523,21 @@ static int zlib_decomp_init(void)
return 0;
}
+static int zstd_decomp_init(void)
+{
+ const size_t wksp_size = ZSTD_DCtxWorkspaceBound();
+ void *wksp = malloc(wksp_size);
+
+ if (!wksp)
+ return -ENOMEM;
+
+ ubifs_zstd_cctx = ZSTD_initDCtx(wksp, wksp_size);
+ if (!ubifs_zstd_cctx)
+ return -EINVAL;
+
+ return 0;
+}
+
int ubifs_allow_encrypted;
int ubifs_allow_authenticated_unauthenticated;
@@ -505,6 +551,12 @@ static int ubifs_init(void)
return ret;
}
+ if (IS_ENABLED(CONFIG_ZSTD_DECOMPRESS)) {
+ ret = zstd_decomp_init();
+ if (ret)
+ return ret;
+ }
+
globalvar_add_simple_bool("ubifs.allow_encrypted", &ubifs_allow_encrypted);
globalvar_add_simple_bool("ubifs.allow_authenticated_unauthenticated",
&ubifs_allow_authenticated_unauthenticated);