
Signed-off-by: Piotr Wojtaszczyk piotr.wojtaszczyk@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;