[PATCH] ubifs: Add zstd support

Sascha Hauer s.hauer at pengutronix.de
Mon Feb 7 07:14:57 PST 2022


zstd shows a good compression rate and is faster than lzo. This adds
UBIFS support for it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/ubifs/Kconfig       |  5 ++++
 fs/ubifs/ubifs-media.h |  2 ++
 fs/ubifs/ubifs.c       | 52 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index ae58c2b7f2..15fcec4459 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -17,4 +17,9 @@ config FS_UBIFS_COMPRESSION_ZLIB
 	select ZLIB
 	prompt "ZLIB compression support"
 
+config FS_UBIFS_COMPRESSION_ZSTD
+	bool
+	select ZSTD_DECOMPRESS
+	prompt "ZSTD compression support"
+
 endif
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index 8b7c184401..697b1b8906 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -348,12 +348,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 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);
-- 
2.30.2




More information about the barebox mailing list