Message ID | 20201103060535.8460-2-nickrterrell@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v5,1/9] lib: zstd: Add zstd compatibility wrapper | expand |
You just keep resedning this crap, don't you? Haven't you been told multiple times to provide a proper kernel API by now? On Mon, Nov 02, 2020 at 10:05:27PM -0800, Nick Terrell wrote: > From: Nick Terrell <terrelln@fb.com> > > Adds zstd_compat.h which provides the necessary functions from the > current zstd.h API. It is only active for zstd versions 1.4.6 and newer. > That means it is disabled currently, but will become active when a later > patch in this series updates the zstd library in the kernel to 1.4.6. > > This header allows the zstd upgrade to 1.4.6 without changing any > callers, since they all include zstd through the compatibility wrapper. > Later patches in this series transition each caller away from the > compatibility wrapper. After all the callers have been transitioned away > from the compatibility wrapper, the final patch in this series deletes > it. > > Signed-off-by: Nick Terrell <terrelln@fb.com> > --- > crypto/zstd.c | 2 +- > fs/btrfs/zstd.c | 2 +- > fs/f2fs/compress.c | 2 +- > fs/squashfs/zstd_wrapper.c | 2 +- > include/linux/zstd_compat.h | 116 ++++++++++++++++++++++++++++++++++++ > lib/decompress_unzstd.c | 2 +- > 6 files changed, 121 insertions(+), 5 deletions(-) > create mode 100644 include/linux/zstd_compat.h > > diff --git a/crypto/zstd.c b/crypto/zstd.c > index 1a3309f066f7..dcda3cad3b5c 100644 > --- a/crypto/zstd.c > +++ b/crypto/zstd.c > @@ -11,7 +11,7 @@ > #include <linux/module.h> > #include <linux/net.h> > #include <linux/vmalloc.h> > -#include <linux/zstd.h> > +#include <linux/zstd_compat.h> > #include <crypto/internal/scompress.h> > > > diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c > index 9a4871636c6c..a7367ff573d4 100644 > --- a/fs/btrfs/zstd.c > +++ b/fs/btrfs/zstd.c > @@ -16,7 +16,7 @@ > #include <linux/refcount.h> > #include <linux/sched.h> > #include <linux/slab.h> > -#include <linux/zstd.h> > +#include <linux/zstd_compat.h> > #include "misc.h" > #include "compression.h" > #include "ctree.h" > diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c > index 14262e0f1cd6..57a6360b9827 100644 > --- a/fs/f2fs/compress.c > +++ b/fs/f2fs/compress.c > @@ -11,7 +11,7 @@ > #include <linux/backing-dev.h> > #include <linux/lzo.h> > #include <linux/lz4.h> > -#include <linux/zstd.h> > +#include <linux/zstd_compat.h> > > #include "f2fs.h" > #include "node.h" > diff --git a/fs/squashfs/zstd_wrapper.c b/fs/squashfs/zstd_wrapper.c > index b7cb1faa652d..f8c512a6204e 100644 > --- a/fs/squashfs/zstd_wrapper.c > +++ b/fs/squashfs/zstd_wrapper.c > @@ -11,7 +11,7 @@ > #include <linux/mutex.h> > #include <linux/bio.h> > #include <linux/slab.h> > -#include <linux/zstd.h> > +#include <linux/zstd_compat.h> > #include <linux/vmalloc.h> > > #include "squashfs_fs.h" > diff --git a/include/linux/zstd_compat.h b/include/linux/zstd_compat.h > new file mode 100644 > index 000000000000..cda9208bf04a > --- /dev/null > +++ b/include/linux/zstd_compat.h > @@ -0,0 +1,116 @@ > +/* > + * Copyright (c) 2016-present, Facebook, Inc. > + * All rights reserved. > + * > + * This source code is licensed under the BSD-style license found in the > + * LICENSE file in the root directory of https://github.com/facebook/zstd. > + * An additional grant of patent rights can be found in the PATENTS file in the > + * same directory. > + * > + * This program is free software; you can redistribute it and/or modify it under > + * the terms of the GNU General Public License version 2 as published by the > + * Free Software Foundation. This program is dual-licensed; you may select > + * either version 2 of the GNU General Public License ("GPL") or BSD license > + * ("BSD"). > + */ > + > +#ifndef ZSTD_COMPAT_H > +#define ZSTD_COMPAT_H > + > +#include <linux/zstd.h> > + > +#if defined(ZSTD_VERSION_NUMBER) && (ZSTD_VERSION_NUMBER >= 10406) > +/* > + * This header provides backwards compatibility for the zstd-1.4.6 library > + * upgrade. This header allows us to upgrade the zstd library version without > + * modifying any callers. Then we will migrate callers from the compatibility > + * wrapper one at a time until none remain. At which point we will delete this > + * header. > + * > + * It is temporary and will be deleted once the upgrade is complete. > + */ > + > +#include <linux/zstd_errors.h> > + > +static inline size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters compression_params) > +{ > + return ZSTD_estimateCCtxSize_usingCParams(compression_params); > +} > + > +static inline size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters compression_params) > +{ > + return ZSTD_estimateCStreamSize_usingCParams(compression_params); > +} > + > +static inline size_t ZSTD_DCtxWorkspaceBound(void) > +{ > + return ZSTD_estimateDCtxSize(); > +} > + > +static inline size_t ZSTD_DStreamWorkspaceBound(unsigned long long window_size) > +{ > + return ZSTD_estimateDStreamSize(window_size); > +} > + > +static inline ZSTD_CCtx* ZSTD_initCCtx(void* wksp, size_t wksp_size) > +{ > + if (wksp == NULL) > + return NULL; > + return ZSTD_initStaticCCtx(wksp, wksp_size); > +} > + > +static inline ZSTD_CStream* ZSTD_initCStream_compat(ZSTD_parameters params, uint64_t pledged_src_size, void* wksp, size_t wksp_size) > +{ > + ZSTD_CStream* cstream; > + size_t ret; > + > + if (wksp == NULL) > + return NULL; > + > + cstream = ZSTD_initStaticCStream(wksp, wksp_size); > + if (cstream == NULL) > + return NULL; > + > + /* 0 means unknown in old API but means 0 in new API */ > + if (pledged_src_size == 0) > + pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; > + > + ret = ZSTD_initCStream_advanced(cstream, NULL, 0, params, pledged_src_size); > + if (ZSTD_isError(ret)) > + return NULL; > + > + return cstream; > +} > +#define ZSTD_initCStream ZSTD_initCStream_compat > + > +static inline ZSTD_DCtx* ZSTD_initDCtx(void* wksp, size_t wksp_size) > +{ > + if (wksp == NULL) > + return NULL; > + return ZSTD_initStaticDCtx(wksp, wksp_size); > +} > + > +static inline ZSTD_DStream* ZSTD_initDStream_compat(unsigned long long window_size, void* wksp, size_t wksp_size) > +{ > + if (wksp == NULL) > + return NULL; > + (void)window_size; > + return ZSTD_initStaticDStream(wksp, wksp_size); > +} > +#define ZSTD_initDStream ZSTD_initDStream_compat > + > +typedef ZSTD_frameHeader ZSTD_frameParams; > + > +static inline size_t ZSTD_getFrameParams(ZSTD_frameParams* frame_params, const void* src, size_t src_size) > +{ > + return ZSTD_getFrameHeader(frame_params, src, src_size); > +} > + > +static inline size_t ZSTD_compressCCtx_compat(ZSTD_CCtx* cctx, void* dst, size_t dst_capacity, const void* src, size_t src_size, ZSTD_parameters params) > +{ > + return ZSTD_compress_advanced(cctx, dst, dst_capacity, src, src_size, NULL, 0, params); > +} > +#define ZSTD_compressCCtx ZSTD_compressCCtx_compat > + > +#endif /* ZSTD_VERSION_NUMBER >= 10406 */ > +#endif /* ZSTD_COMPAT_H */ > diff --git a/lib/decompress_unzstd.c b/lib/decompress_unzstd.c > index 790abc472f5b..6bb805aeec08 100644 > --- a/lib/decompress_unzstd.c > +++ b/lib/decompress_unzstd.c > @@ -77,7 +77,7 @@ > > #include <linux/decompress/mm.h> > #include <linux/kernel.h> > -#include <linux/zstd.h> > +#include <linux/zstd_compat.h> > > /* 128MB is the maximum window size supported by zstd. */ > #define ZSTD_WINDOWSIZE_MAX (1 << ZSTD_WINDOWLOG_MAX) > -- > 2.28.0 > ---end quoted text---
On 6 Nov 2020, at 13:38, Christoph Hellwig wrote: > You just keep resedning this crap, don't you? Haven't you been told > multiple times to provide a proper kernel API by now? You do consistently ask for a shim layer, but you haven’t explained what we gain by diverging from the documented and tested API of the upstream zstd project. It’s an important discussion given that we hope to regularly update the kernel side as they make improvements in zstd. The only benefit described so far seems to be camelcase related, but if there are problems in the API beyond that, I haven’t seen you describe them. I don’t think the camelcase alone justifies the added costs of the shim. -chris
On Mon, Nov 09, 2020 at 02:01:41PM -0500, Chris Mason wrote: > On 6 Nov 2020, at 13:38, Christoph Hellwig wrote: > > You just keep resedning this crap, don't you? Haven't you been told > > multiple times to provide a proper kernel API by now? > > You do consistently ask for a shim layer, but you haven’t explained > what we gain by diverging from the documented and tested API of the > upstream zstd project. It’s an important discussion given that we > hope to regularly update the kernel side as they make improvements in > zstd. > > The only benefit described so far seems to be camelcase related, but if > there are problems in the API beyond that, I haven’t seen you describe > them. I don’t think the camelcase alone justifies the added costs of > the shim. The API change in this patchset is adding churn that wouldn't be necessary if there were an upstream<->kernel API from the beginning. The patch 5/9 is almost entirely renaming just some internal identifiers - ZSTD_CStreamWorkspaceBound(params.cParams), - ZSTD_DStreamWorkspaceBound(ZSTD_BTRFS_MAX_INPUT)); + ZSTD_estimateCStreamSize_usingCParams(params.cParams), + ZSTD_estimateDStreamSize(ZSTD_BTRFS_MAX_INPUT)); plus updating the names in the error strings. The compression API that filesystems need is simple: - set up workspace and parameters - compress buffer - decompress buffer We really should not care if upstream has 3 functions for initializing stream (ZSTD_initCStream/ZSTD_initStaticCStream/ZSTD_initCStream_advanced), or if the name changes again in the future. This should not require explicit explanation, this should be a natural requirement especially for separate projects that don't share the same coding style but have to be integrated in some way.
On Mon, Nov 09, 2020 at 02:01:41PM -0500, Chris Mason wrote: > You do consistently ask for a shim layer, but you haven???t explained what > we gain by diverging from the documented and tested API of the upstream zstd > project. It???s an important discussion given that we hope to regularly > update the kernel side as they make improvements in zstd. An API that looks like every other kernel API, and doesn't cause endless amount of churn because someone decided they need a new API flavor of the day. Btw, I'm not asking for a shim layer - that was the compromise we ended up with. If zstd folks can't maintain a sane code base maybe we should just drop this childish churning code base from the tree.
On 10 Nov 2020, at 13:39, Christoph Hellwig wrote: > On Mon, Nov 09, 2020 at 02:01:41PM -0500, Chris Mason wrote: >> You do consistently ask for a shim layer, but you haven???t explained >> what >> we gain by diverging from the documented and tested API of the >> upstream zstd >> project. It???s an important discussion given that we hope to >> regularly >> update the kernel side as they make improvements in zstd. > > An API that looks like every other kernel API, and doesn't cause > endless > amount of churn because someone decided they need a new API flavor of > the day. Btw, I'm not asking for a shim layer - that was the > compromise > we ended up with. > > If zstd folks can't maintain a sane code base maybe we should just > drop > this childish churning code base from the tree. I think APIs change based on the needs of the project. We do this all the time in the kernel, and we don’t think twice about updating users of the API as needed. The zstd changes look awkward and large today because it’ a long time period, but we’ve all been pretty vocal in the past about the importance of being able to advance APIs. -chris
> On Nov 10, 2020, at 7:25 AM, David Sterba <dsterba@suse.cz> wrote: > > On Mon, Nov 09, 2020 at 02:01:41PM -0500, Chris Mason wrote: >> On 6 Nov 2020, at 13:38, Christoph Hellwig wrote: >>> You just keep resedning this crap, don't you? Haven't you been told >>> multiple times to provide a proper kernel API by now? >> >> You do consistently ask for a shim layer, but you haven’t explained >> what we gain by diverging from the documented and tested API of the >> upstream zstd project. It’s an important discussion given that we >> hope to regularly update the kernel side as they make improvements in >> zstd. >> >> The only benefit described so far seems to be camelcase related, but if >> there are problems in the API beyond that, I haven’t seen you describe >> them. I don’t think the camelcase alone justifies the added costs of >> the shim. > > The API change in this patchset is adding churn that wouldn't be > necessary if there were an upstream<->kernel API from the beginning. > > The patch 5/9 is almost entirely renaming just some internal identifiers > > - ZSTD_CStreamWorkspaceBound(params.cParams), > - ZSTD_DStreamWorkspaceBound(ZSTD_BTRFS_MAX_INPUT)); > + ZSTD_estimateCStreamSize_usingCParams(params.cParams), > + ZSTD_estimateDStreamSize(ZSTD_BTRFS_MAX_INPUT)); > > plus updating the names in the error strings. The compression API that > filesystems need is simple: > > - set up workspace and parameters > - compress buffer > - decompress buffer > > We really should not care if upstream has 3 functions for initializing > stream (ZSTD_initCStream/ZSTD_initStaticCStream/ZSTD_initCStream_advanced), > or if the name changes again in the future. Upstream will not change these function names. We guarantee the stable portion of our API has a fixed ABI. The unstable portion doesn’t make this guarantee, but we guarantee never to change function semantics in an incompatible way, and to provide long deprecation periods (years) when we delete functions. For reference, the only functions we’ve deleted/modified since v1.0.0 when we stabilized the zstd format 4 years ago are an old streaming API that was deprecated before v1.0.0. We’ve added new functions, and provided new recommended ways to use our API that we think are better. But, we highly value not breaking our users code, so all the older APIs are still supported. This churn is caused because the current version of zstd inside the kernel is not upstream zstd. At the time of integration upstream zstd wasn’t ready to be used as-is in the kernel. When I integrated zstd into the kernel, I should’ve done more work to use upstream as-is. It was a mistake that I would like to correct, so the kernel can benefit from the significant performance improvements that upstream has made in the last few years. > This should not require explicit explanation, this should be a natural > requirement especially for separate projects that don't share the same > coding style but have to be integrated in some way. I’m not completely against providing a kernel shim. Personally, I don’t believe it provides much benefit. But if the consensus of kernel developers is that a shim provides a better API, then I’m happy to provide it. So far, I haven’t seen a clear consensus either way. That leaves me kind of stuck. Best, Nick
> On Nov 10, 2020, at 10:39 AM, Christoph Hellwig <hch@infradead.org> wrote: > > On Mon, Nov 09, 2020 at 02:01:41PM -0500, Chris Mason wrote: >> You do consistently ask for a shim layer, but you haven???t explained what >> we gain by diverging from the documented and tested API of the upstream zstd >> project. It???s an important discussion given that we hope to regularly >> update the kernel side as they make improvements in zstd. > > An API that looks like every other kernel API, and doesn't cause endless > amount of churn because someone decided they need a new API flavor of > the day. Btw, I'm not asking for a shim layer - that was the compromise > we ended up with. I will put up a version of the patch set with the shim layer. I will follow the kernel style guide for the shim, which will involve function renaming. I will prefix the functions with “zstd_” instead of “ZSTD_” to make it clear that this is not the upstream zstd API, but rather a kernel wrapper (and be closer to the style guide). Other than renaming to follow the kernel style guide, I will keep the API as similar as possible to the existing API, to minimize churn. Please let me know if you have any particular requests for the shim that I haven't mentioned, or if you would prefer something else. Alternatively, comment on the patches once I put them up. Expect them later this week or weekend. Best, Nick > If zstd folks can't maintain a sane code base maybe we should just drop > this childish churning code base from the tree.
On Tue, Nov 10, 2020 at 02:24:35PM -0500, Chris Mason wrote: > I think APIs change based on the needs of the project. We do this all the > time in the kernel, and we don???t think twice about updating users of the > API as needed. We update kernel APIs when: - we need additional functionality - thew new API is clearly better than the old one None of that seems to be the case here.
diff --git a/crypto/zstd.c b/crypto/zstd.c index 1a3309f066f7..dcda3cad3b5c 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/net.h> #include <linux/vmalloc.h> -#include <linux/zstd.h> +#include <linux/zstd_compat.h> #include <crypto/internal/scompress.h> diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 9a4871636c6c..a7367ff573d4 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -16,7 +16,7 @@ #include <linux/refcount.h> #include <linux/sched.h> #include <linux/slab.h> -#include <linux/zstd.h> +#include <linux/zstd_compat.h> #include "misc.h" #include "compression.h" #include "ctree.h" diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 14262e0f1cd6..57a6360b9827 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -11,7 +11,7 @@ #include <linux/backing-dev.h> #include <linux/lzo.h> #include <linux/lz4.h> -#include <linux/zstd.h> +#include <linux/zstd_compat.h> #include "f2fs.h" #include "node.h" diff --git a/fs/squashfs/zstd_wrapper.c b/fs/squashfs/zstd_wrapper.c index b7cb1faa652d..f8c512a6204e 100644 --- a/fs/squashfs/zstd_wrapper.c +++ b/fs/squashfs/zstd_wrapper.c @@ -11,7 +11,7 @@ #include <linux/mutex.h> #include <linux/bio.h> #include <linux/slab.h> -#include <linux/zstd.h> +#include <linux/zstd_compat.h> #include <linux/vmalloc.h> #include "squashfs_fs.h" diff --git a/include/linux/zstd_compat.h b/include/linux/zstd_compat.h new file mode 100644 index 000000000000..cda9208bf04a --- /dev/null +++ b/include/linux/zstd_compat.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +#ifndef ZSTD_COMPAT_H +#define ZSTD_COMPAT_H + +#include <linux/zstd.h> + +#if defined(ZSTD_VERSION_NUMBER) && (ZSTD_VERSION_NUMBER >= 10406) +/* + * This header provides backwards compatibility for the zstd-1.4.6 library + * upgrade. This header allows us to upgrade the zstd library version without + * modifying any callers. Then we will migrate callers from the compatibility + * wrapper one at a time until none remain. At which point we will delete this + * header. + * + * It is temporary and will be deleted once the upgrade is complete. + */ + +#include <linux/zstd_errors.h> + +static inline size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters compression_params) +{ + return ZSTD_estimateCCtxSize_usingCParams(compression_params); +} + +static inline size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters compression_params) +{ + return ZSTD_estimateCStreamSize_usingCParams(compression_params); +} + +static inline size_t ZSTD_DCtxWorkspaceBound(void) +{ + return ZSTD_estimateDCtxSize(); +} + +static inline size_t ZSTD_DStreamWorkspaceBound(unsigned long long window_size) +{ + return ZSTD_estimateDStreamSize(window_size); +} + +static inline ZSTD_CCtx* ZSTD_initCCtx(void* wksp, size_t wksp_size) +{ + if (wksp == NULL) + return NULL; + return ZSTD_initStaticCCtx(wksp, wksp_size); +} + +static inline ZSTD_CStream* ZSTD_initCStream_compat(ZSTD_parameters params, uint64_t pledged_src_size, void* wksp, size_t wksp_size) +{ + ZSTD_CStream* cstream; + size_t ret; + + if (wksp == NULL) + return NULL; + + cstream = ZSTD_initStaticCStream(wksp, wksp_size); + if (cstream == NULL) + return NULL; + + /* 0 means unknown in old API but means 0 in new API */ + if (pledged_src_size == 0) + pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; + + ret = ZSTD_initCStream_advanced(cstream, NULL, 0, params, pledged_src_size); + if (ZSTD_isError(ret)) + return NULL; + + return cstream; +} +#define ZSTD_initCStream ZSTD_initCStream_compat + +static inline ZSTD_DCtx* ZSTD_initDCtx(void* wksp, size_t wksp_size) +{ + if (wksp == NULL) + return NULL; + return ZSTD_initStaticDCtx(wksp, wksp_size); +} + +static inline ZSTD_DStream* ZSTD_initDStream_compat(unsigned long long window_size, void* wksp, size_t wksp_size) +{ + if (wksp == NULL) + return NULL; + (void)window_size; + return ZSTD_initStaticDStream(wksp, wksp_size); +} +#define ZSTD_initDStream ZSTD_initDStream_compat + +typedef ZSTD_frameHeader ZSTD_frameParams; + +static inline size_t ZSTD_getFrameParams(ZSTD_frameParams* frame_params, const void* src, size_t src_size) +{ + return ZSTD_getFrameHeader(frame_params, src, src_size); +} + +static inline size_t ZSTD_compressCCtx_compat(ZSTD_CCtx* cctx, void* dst, size_t dst_capacity, const void* src, size_t src_size, ZSTD_parameters params) +{ + return ZSTD_compress_advanced(cctx, dst, dst_capacity, src, src_size, NULL, 0, params); +} +#define ZSTD_compressCCtx ZSTD_compressCCtx_compat + +#endif /* ZSTD_VERSION_NUMBER >= 10406 */ +#endif /* ZSTD_COMPAT_H */ diff --git a/lib/decompress_unzstd.c b/lib/decompress_unzstd.c index 790abc472f5b..6bb805aeec08 100644 --- a/lib/decompress_unzstd.c +++ b/lib/decompress_unzstd.c @@ -77,7 +77,7 @@ #include <linux/decompress/mm.h> #include <linux/kernel.h> -#include <linux/zstd.h> +#include <linux/zstd_compat.h> /* 128MB is the maximum window size supported by zstd. */ #define ZSTD_WINDOWSIZE_MAX (1 << ZSTD_WINDOWLOG_MAX)