diff mbox series

[v5,1/9] lib: zstd: Add zstd compatibility wrapper

Message ID 20201103060535.8460-2-nickrterrell@gmail.com (mailing list archive)
State New, archived
Headers show
Series Update to zstd-1.4.6 | expand

Commit Message

Nick Terrell Nov. 3, 2020, 6:05 a.m. UTC
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

Comments

Christoph Hellwig Nov. 6, 2020, 6:38 p.m. UTC | #1
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---
Chris Mason Nov. 9, 2020, 7:01 p.m. UTC | #2
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
David Sterba Nov. 10, 2020, 3:25 p.m. UTC | #3
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.
Christoph Hellwig Nov. 10, 2020, 6:39 p.m. UTC | #4
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.
Chris Mason Nov. 10, 2020, 7:24 p.m. UTC | #5
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
Nick Terrell Nov. 10, 2020, 7:33 p.m. UTC | #6
> 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
Nick Terrell Nov. 10, 2020, 8:38 p.m. UTC | #7
> 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.
Christoph Hellwig Nov. 16, 2020, 4:52 p.m. UTC | #8
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 mbox series

Patch

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)