From: Rui Salvaterra <rsalvaterra@gmail.com> To: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org Cc: lizhe67@huawei.com, christian.brauner@ubuntu.com, gustavoars@kernel.org, trix@redhat.com, keescook@chromium.org, Rui Salvaterra <rsalvaterra@gmail.com> Subject: [RFC PATCH v2] jffs2: add support for zstd compression Date: Tue, 16 Mar 2021 14:19:16 +0000 [thread overview] Message-ID: <20210316141916.447493-1-rsalvaterra@gmail.com> (raw) Implement support for zstd compression in jffs2 at the default compression level (3). Lightly tested in OpenWrt, on a single CPU embedded MIPS32 system (AirGrid M2). Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com> --- v2: fix blunder in compression context allocation fs/jffs2/Kconfig | 9 +++ fs/jffs2/Makefile | 1 + fs/jffs2/compr.c | 10 +++ fs/jffs2/compr.h | 6 ++ fs/jffs2/compr_zstd.c | 131 +++++++++++++++++++++++++++++++++++++ fs/jffs2/super.c | 7 ++ include/uapi/linux/jffs2.h | 1 + 7 files changed, 165 insertions(+) create mode 100644 fs/jffs2/compr_zstd.c diff --git a/fs/jffs2/Kconfig b/fs/jffs2/Kconfig index 7c96bc107218..31308eb7267b 100644 --- a/fs/jffs2/Kconfig +++ b/fs/jffs2/Kconfig @@ -136,6 +136,15 @@ config JFFS2_LZO This feature was added in July, 2007. Say 'N' if you need compatibility with older bootloaders or kernels. +config JFFS2_ZSTD + bool "JFFS2 zstd compression support" if JFFS2_COMPRESSION_OPTIONS + select ZSTD_COMPRESS + select ZSTD_DECOMPRESS + depends on JFFS2_FS + default n + help + Zstd compression. + config JFFS2_RTIME bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS depends on JFFS2_FS diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile index 5294969d5bf9..75f84b1467c5 100644 --- a/fs/jffs2/Makefile +++ b/fs/jffs2/Makefile @@ -19,4 +19,5 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o +jffs2-$(CONFIG_JFFS2_ZSTD) += compr_zstd.o jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index 4849a4c9a0e2..d65e0c39c9c5 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c @@ -237,6 +237,10 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ret = jffs2_selected_compress(JFFS2_COMPR_ZLIB, data_in, cpage_out, datalen, cdatalen); break; + case JFFS2_COMPR_MODE_FORCEZSTD: + ret = jffs2_selected_compress(JFFS2_COMPR_ZSTD, data_in, + cpage_out, datalen, cdatalen); + break; default: pr_err("unknown compression mode\n"); } @@ -378,6 +382,9 @@ int __init jffs2_compressors_init(void) #ifdef CONFIG_JFFS2_LZO jffs2_lzo_init(); #endif +#ifdef CONFIG_JFFS2_ZSTD + jffs2_zstd_init(); +#endif /* Setting default compression mode */ #ifdef CONFIG_JFFS2_CMODE_NONE jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; @@ -413,6 +420,9 @@ int jffs2_compressors_exit(void) #endif #ifdef CONFIG_JFFS2_ZLIB jffs2_zlib_exit(); +#endif +#ifdef CONFIG_JFFS2_ZSTD + jffs2_zstd_exit(); #endif return 0; } diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h index 5e91d578f4ed..8f7032c5ecb2 100644 --- a/fs/jffs2/compr.h +++ b/fs/jffs2/compr.h @@ -31,6 +31,7 @@ #define JFFS2_RTIME_PRIORITY 50 #define JFFS2_ZLIB_PRIORITY 60 #define JFFS2_LZO_PRIORITY 80 +#define JFFS2_ZSTD_PRIORITY 90 #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ @@ -42,6 +43,7 @@ #define JFFS2_COMPR_MODE_FAVOURLZO 3 #define JFFS2_COMPR_MODE_FORCELZO 4 #define JFFS2_COMPR_MODE_FORCEZLIB 5 +#define JFFS2_COMPR_MODE_FORCEZSTD 6 #define FAVOUR_LZO_PERCENT 80 @@ -101,5 +103,9 @@ void jffs2_zlib_exit(void); int jffs2_lzo_init(void); void jffs2_lzo_exit(void); #endif +#ifdef CONFIG_JFFS2_ZSTD +int jffs2_zstd_init(void); +void jffs2_zstd_exit(void); +#endif #endif /* __JFFS2_COMPR_H__ */ diff --git a/fs/jffs2/compr_zstd.c b/fs/jffs2/compr_zstd.c new file mode 100644 index 000000000000..bfe4607575da --- /dev/null +++ b/fs/jffs2/compr_zstd.c @@ -0,0 +1,131 @@ + +#include <linux/zstd.h> +#include "compr.h" + +#define ZSTD_DEF_LEVEL 3 + +static ZSTD_CCtx *cctx; +static ZSTD_DCtx *dctx; +static void *cwksp; +static void *dwksp; + +static ZSTD_parameters zstd_params(void) +{ + return ZSTD_getParams(ZSTD_DEF_LEVEL, 0, 0); +} + +static int zstd_comp_init(void) +{ + int ret = 0; + const ZSTD_parameters params = zstd_params(); + const size_t wksp_size = ZSTD_CCtxWorkspaceBound(params.cParams); + + cwksp = vzalloc(wksp_size); + if (!cwksp) { + ret = -ENOMEM; + goto out; + } + + cctx = ZSTD_initCCtx(cwksp, wksp_size); + if (!cctx) { + ret = -EINVAL; + goto out_free; + } +out: + return ret; +out_free: + vfree(cwksp); + goto out; +} + +static int zstd_decomp_init(void) +{ + int ret = 0; + const size_t wksp_size = ZSTD_DCtxWorkspaceBound(); + + dwksp = vzalloc(wksp_size); + if (!dwksp) { + ret = -ENOMEM; + goto out; + } + + dctx = ZSTD_initDCtx(dwksp, wksp_size); + if (!dctx) { + ret = -EINVAL; + goto out_free; + } +out: + return ret; +out_free: + vfree(dwksp); + goto out; +} + +static void zstd_comp_exit(void) +{ + vfree(cwksp); + cwksp = NULL; + cctx = NULL; +} + +static void zstd_decomp_exit(void) +{ + vfree(dwksp); + dwksp = NULL; + dctx = NULL; +} + +static int jffs2_zstd_compress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen) +{ + size_t out_len; + const ZSTD_parameters params = zstd_params(); + + out_len = ZSTD_compressCCtx(cctx, cpage_out, *dstlen, data_in, *sourcelen, params); + if (ZSTD_isError(out_len) || out_len > *dstlen) + return -1; + *dstlen = out_len; + return 0; +} + +static int jffs2_zstd_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen) +{ + size_t out_len; + + out_len = ZSTD_decompressDCtx(dctx, cpage_out, destlen, data_in, srclen); + if (ZSTD_isError(out_len) || out_len != destlen) + return -1; + + return 0; +} + +static struct jffs2_compressor jffs2_zstd_comp = { + .priority = JFFS2_ZSTD_PRIORITY, + .name = "zstd", + .compr = JFFS2_COMPR_ZSTD, + .compress = &jffs2_zstd_compress, + .decompress = &jffs2_zstd_decompress, + .disabled = 0, +}; + +int __init jffs2_zstd_init(void) +{ + int ret; + + ret = zstd_comp_init(); + if (ret) + return ret; + ret = zstd_decomp_init(); + if (ret) + zstd_comp_exit(); + ret = jffs2_register_compressor(&jffs2_zstd_comp); + return ret; +} + +void jffs2_zstd_exit(void) +{ + jffs2_unregister_compressor(&jffs2_zstd_comp); + zstd_comp_exit(); + zstd_decomp_exit(); +} diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 81ca58c10b72..ddce95c55dde 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -73,6 +73,10 @@ static const char *jffs2_compr_name(unsigned int compr) #ifdef CONFIG_JFFS2_ZLIB case JFFS2_COMPR_MODE_FORCEZLIB: return "zlib"; +#endif +#ifdef CONFIG_JFFS2_ZSTD + case JFFS2_COMPR_MODE_FORCEZSTD: + return "zstd"; #endif default: /* should never happen; programmer error */ @@ -174,6 +178,9 @@ static const struct constant_table jffs2_param_compr[] = { #endif #ifdef CONFIG_JFFS2_ZLIB {"zlib", JFFS2_COMPR_MODE_FORCEZLIB }, +#endif +#ifdef CONFIG_JFFS2_ZSTD + {"zstd", JFFS2_COMPR_MODE_FORCEZSTD }, #endif {} }; diff --git a/include/uapi/linux/jffs2.h b/include/uapi/linux/jffs2.h index 784ba0b9690a..af4fb69c8d69 100644 --- a/include/uapi/linux/jffs2.h +++ b/include/uapi/linux/jffs2.h @@ -46,6 +46,7 @@ #define JFFS2_COMPR_DYNRUBIN 0x05 #define JFFS2_COMPR_ZLIB 0x06 #define JFFS2_COMPR_LZO 0x07 +#define JFFS2_COMPR_ZSTD 0x08 /* Compatibility flags. */ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ #define JFFS2_NODE_ACCURATE 0x2000 -- 2.31.0
WARNING: multiple messages have this Message-ID (diff)
From: Rui Salvaterra <rsalvaterra@gmail.com> To: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org Cc: lizhe67@huawei.com, christian.brauner@ubuntu.com, gustavoars@kernel.org, trix@redhat.com, keescook@chromium.org, Rui Salvaterra <rsalvaterra@gmail.com> Subject: [RFC PATCH v2] jffs2: add support for zstd compression Date: Tue, 16 Mar 2021 14:19:16 +0000 [thread overview] Message-ID: <20210316141916.447493-1-rsalvaterra@gmail.com> (raw) Implement support for zstd compression in jffs2 at the default compression level (3). Lightly tested in OpenWrt, on a single CPU embedded MIPS32 system (AirGrid M2). Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com> --- v2: fix blunder in compression context allocation fs/jffs2/Kconfig | 9 +++ fs/jffs2/Makefile | 1 + fs/jffs2/compr.c | 10 +++ fs/jffs2/compr.h | 6 ++ fs/jffs2/compr_zstd.c | 131 +++++++++++++++++++++++++++++++++++++ fs/jffs2/super.c | 7 ++ include/uapi/linux/jffs2.h | 1 + 7 files changed, 165 insertions(+) create mode 100644 fs/jffs2/compr_zstd.c diff --git a/fs/jffs2/Kconfig b/fs/jffs2/Kconfig index 7c96bc107218..31308eb7267b 100644 --- a/fs/jffs2/Kconfig +++ b/fs/jffs2/Kconfig @@ -136,6 +136,15 @@ config JFFS2_LZO This feature was added in July, 2007. Say 'N' if you need compatibility with older bootloaders or kernels. +config JFFS2_ZSTD + bool "JFFS2 zstd compression support" if JFFS2_COMPRESSION_OPTIONS + select ZSTD_COMPRESS + select ZSTD_DECOMPRESS + depends on JFFS2_FS + default n + help + Zstd compression. + config JFFS2_RTIME bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS depends on JFFS2_FS diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile index 5294969d5bf9..75f84b1467c5 100644 --- a/fs/jffs2/Makefile +++ b/fs/jffs2/Makefile @@ -19,4 +19,5 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o +jffs2-$(CONFIG_JFFS2_ZSTD) += compr_zstd.o jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index 4849a4c9a0e2..d65e0c39c9c5 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c @@ -237,6 +237,10 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ret = jffs2_selected_compress(JFFS2_COMPR_ZLIB, data_in, cpage_out, datalen, cdatalen); break; + case JFFS2_COMPR_MODE_FORCEZSTD: + ret = jffs2_selected_compress(JFFS2_COMPR_ZSTD, data_in, + cpage_out, datalen, cdatalen); + break; default: pr_err("unknown compression mode\n"); } @@ -378,6 +382,9 @@ int __init jffs2_compressors_init(void) #ifdef CONFIG_JFFS2_LZO jffs2_lzo_init(); #endif +#ifdef CONFIG_JFFS2_ZSTD + jffs2_zstd_init(); +#endif /* Setting default compression mode */ #ifdef CONFIG_JFFS2_CMODE_NONE jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; @@ -413,6 +420,9 @@ int jffs2_compressors_exit(void) #endif #ifdef CONFIG_JFFS2_ZLIB jffs2_zlib_exit(); +#endif +#ifdef CONFIG_JFFS2_ZSTD + jffs2_zstd_exit(); #endif return 0; } diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h index 5e91d578f4ed..8f7032c5ecb2 100644 --- a/fs/jffs2/compr.h +++ b/fs/jffs2/compr.h @@ -31,6 +31,7 @@ #define JFFS2_RTIME_PRIORITY 50 #define JFFS2_ZLIB_PRIORITY 60 #define JFFS2_LZO_PRIORITY 80 +#define JFFS2_ZSTD_PRIORITY 90 #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ @@ -42,6 +43,7 @@ #define JFFS2_COMPR_MODE_FAVOURLZO 3 #define JFFS2_COMPR_MODE_FORCELZO 4 #define JFFS2_COMPR_MODE_FORCEZLIB 5 +#define JFFS2_COMPR_MODE_FORCEZSTD 6 #define FAVOUR_LZO_PERCENT 80 @@ -101,5 +103,9 @@ void jffs2_zlib_exit(void); int jffs2_lzo_init(void); void jffs2_lzo_exit(void); #endif +#ifdef CONFIG_JFFS2_ZSTD +int jffs2_zstd_init(void); +void jffs2_zstd_exit(void); +#endif #endif /* __JFFS2_COMPR_H__ */ diff --git a/fs/jffs2/compr_zstd.c b/fs/jffs2/compr_zstd.c new file mode 100644 index 000000000000..bfe4607575da --- /dev/null +++ b/fs/jffs2/compr_zstd.c @@ -0,0 +1,131 @@ + +#include <linux/zstd.h> +#include "compr.h" + +#define ZSTD_DEF_LEVEL 3 + +static ZSTD_CCtx *cctx; +static ZSTD_DCtx *dctx; +static void *cwksp; +static void *dwksp; + +static ZSTD_parameters zstd_params(void) +{ + return ZSTD_getParams(ZSTD_DEF_LEVEL, 0, 0); +} + +static int zstd_comp_init(void) +{ + int ret = 0; + const ZSTD_parameters params = zstd_params(); + const size_t wksp_size = ZSTD_CCtxWorkspaceBound(params.cParams); + + cwksp = vzalloc(wksp_size); + if (!cwksp) { + ret = -ENOMEM; + goto out; + } + + cctx = ZSTD_initCCtx(cwksp, wksp_size); + if (!cctx) { + ret = -EINVAL; + goto out_free; + } +out: + return ret; +out_free: + vfree(cwksp); + goto out; +} + +static int zstd_decomp_init(void) +{ + int ret = 0; + const size_t wksp_size = ZSTD_DCtxWorkspaceBound(); + + dwksp = vzalloc(wksp_size); + if (!dwksp) { + ret = -ENOMEM; + goto out; + } + + dctx = ZSTD_initDCtx(dwksp, wksp_size); + if (!dctx) { + ret = -EINVAL; + goto out_free; + } +out: + return ret; +out_free: + vfree(dwksp); + goto out; +} + +static void zstd_comp_exit(void) +{ + vfree(cwksp); + cwksp = NULL; + cctx = NULL; +} + +static void zstd_decomp_exit(void) +{ + vfree(dwksp); + dwksp = NULL; + dctx = NULL; +} + +static int jffs2_zstd_compress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen) +{ + size_t out_len; + const ZSTD_parameters params = zstd_params(); + + out_len = ZSTD_compressCCtx(cctx, cpage_out, *dstlen, data_in, *sourcelen, params); + if (ZSTD_isError(out_len) || out_len > *dstlen) + return -1; + *dstlen = out_len; + return 0; +} + +static int jffs2_zstd_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen) +{ + size_t out_len; + + out_len = ZSTD_decompressDCtx(dctx, cpage_out, destlen, data_in, srclen); + if (ZSTD_isError(out_len) || out_len != destlen) + return -1; + + return 0; +} + +static struct jffs2_compressor jffs2_zstd_comp = { + .priority = JFFS2_ZSTD_PRIORITY, + .name = "zstd", + .compr = JFFS2_COMPR_ZSTD, + .compress = &jffs2_zstd_compress, + .decompress = &jffs2_zstd_decompress, + .disabled = 0, +}; + +int __init jffs2_zstd_init(void) +{ + int ret; + + ret = zstd_comp_init(); + if (ret) + return ret; + ret = zstd_decomp_init(); + if (ret) + zstd_comp_exit(); + ret = jffs2_register_compressor(&jffs2_zstd_comp); + return ret; +} + +void jffs2_zstd_exit(void) +{ + jffs2_unregister_compressor(&jffs2_zstd_comp); + zstd_comp_exit(); + zstd_decomp_exit(); +} diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 81ca58c10b72..ddce95c55dde 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -73,6 +73,10 @@ static const char *jffs2_compr_name(unsigned int compr) #ifdef CONFIG_JFFS2_ZLIB case JFFS2_COMPR_MODE_FORCEZLIB: return "zlib"; +#endif +#ifdef CONFIG_JFFS2_ZSTD + case JFFS2_COMPR_MODE_FORCEZSTD: + return "zstd"; #endif default: /* should never happen; programmer error */ @@ -174,6 +178,9 @@ static const struct constant_table jffs2_param_compr[] = { #endif #ifdef CONFIG_JFFS2_ZLIB {"zlib", JFFS2_COMPR_MODE_FORCEZLIB }, +#endif +#ifdef CONFIG_JFFS2_ZSTD + {"zstd", JFFS2_COMPR_MODE_FORCEZSTD }, #endif {} }; diff --git a/include/uapi/linux/jffs2.h b/include/uapi/linux/jffs2.h index 784ba0b9690a..af4fb69c8d69 100644 --- a/include/uapi/linux/jffs2.h +++ b/include/uapi/linux/jffs2.h @@ -46,6 +46,7 @@ #define JFFS2_COMPR_DYNRUBIN 0x05 #define JFFS2_COMPR_ZLIB 0x06 #define JFFS2_COMPR_LZO 0x07 +#define JFFS2_COMPR_ZSTD 0x08 /* Compatibility flags. */ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ #define JFFS2_NODE_ACCURATE 0x2000 -- 2.31.0 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
next reply other threads:[~2021-03-16 14:20 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-03-16 14:19 Rui Salvaterra [this message] 2021-03-16 14:19 ` [RFC PATCH v2] jffs2: add support for zstd compression Rui Salvaterra 2021-03-25 14:47 ` Rui Salvaterra 2021-03-25 14:47 ` Rui Salvaterra 2021-04-26 7:45 ` Rui Salvaterra 2021-04-26 7:45 ` Rui Salvaterra 2021-04-26 8:24 ` David Woodhouse 2021-04-26 8:24 ` David Woodhouse 2021-04-26 8:49 ` Rui Salvaterra 2021-04-26 8:49 ` Rui Salvaterra
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210316141916.447493-1-rsalvaterra@gmail.com \ --to=rsalvaterra@gmail.com \ --cc=christian.brauner@ubuntu.com \ --cc=gustavoars@kernel.org \ --cc=keescook@chromium.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mtd@lists.infradead.org \ --cc=lizhe67@huawei.com \ --cc=trix@redhat.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.