summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2025-03-15 18:30:34 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2025-03-21 17:33:39 +0800
commit5416b8a741d6d09369b973cd9d4dacb1887c24df (patch)
tree1c266b14a2604cb6c14656a885af9a6dc645e64d /crypto
parent2c1808e5fe5afda22cd49f31b24219d147c785fc (diff)
crypto: acomp - Add ACOMP_REQUEST_ALLOC and acomp_request_alloc_extra
Add ACOMP_REQUEST_ALLOC which is a wrapper around acomp_request_alloc that falls back to a synchronous stack reqeust if the allocation fails. Also add ACOMP_REQUEST_ON_STACK which stores the request on the stack only. The request should be freed with acomp_request_free. Finally add acomp_request_alloc_extra which gives the user extra memory to use in conjunction with the request. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/acompress.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/crypto/acompress.c b/crypto/acompress.c
index 194a4b36f97f..9da033ded193 100644
--- a/crypto/acompress.c
+++ b/crypto/acompress.c
@@ -60,28 +60,56 @@ static void crypto_acomp_exit_tfm(struct crypto_tfm *tfm)
struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
struct acomp_alg *alg = crypto_acomp_alg(acomp);
- alg->exit(acomp);
+ if (alg->exit)
+ alg->exit(acomp);
+
+ if (acomp_is_async(acomp))
+ crypto_free_acomp(acomp->fb);
}
static int crypto_acomp_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_acomp *acomp = __crypto_acomp_tfm(tfm);
struct acomp_alg *alg = crypto_acomp_alg(acomp);
+ struct crypto_acomp *fb = NULL;
+ int err;
+
+ acomp->fb = acomp;
if (tfm->__crt_alg->cra_type != &crypto_acomp_type)
return crypto_init_scomp_ops_async(tfm);
+ if (acomp_is_async(acomp)) {
+ fb = crypto_alloc_acomp(crypto_acomp_alg_name(acomp), 0,
+ CRYPTO_ALG_ASYNC);
+ if (IS_ERR(fb))
+ return PTR_ERR(fb);
+
+ err = -EINVAL;
+ if (crypto_acomp_reqsize(fb) > MAX_SYNC_COMP_REQSIZE)
+ goto out_free_fb;
+
+ acomp->fb = fb;
+ }
+
acomp->compress = alg->compress;
acomp->decompress = alg->decompress;
acomp->reqsize = alg->reqsize;
- if (alg->exit)
- acomp->base.exit = crypto_acomp_exit_tfm;
+ acomp->base.exit = crypto_acomp_exit_tfm;
- if (alg->init)
- return alg->init(acomp);
+ if (!alg->init)
+ return 0;
+
+ err = alg->init(acomp);
+ if (err)
+ goto out_free_fb;
return 0;
+
+out_free_fb:
+ crypto_free_acomp(fb);
+ return err;
}
static unsigned int crypto_acomp_extsize(struct crypto_alg *alg)