mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
crypto: acomp - Add ACOMP_REQUEST_CLONE
Add a new helper ACOMP_REQUEST_CLONE that will transform a stack request into a dynamically allocated one if possible, and otherwise switch it over to the sycnrhonous fallback transform. The intended usage is: ACOMP_STACK_ON_REQUEST(req, tfm); ... err = crypto_acomp_compress(req); /* The request cannot complete synchronously. */ if (err == -EAGAIN) { /* This will not fail. */ req = ACOMP_REQUEST_CLONE(req, gfp); /* Redo operation. */ err = crypto_acomp_compress(req); } Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
d0a5c9d079
commit
097c432caa
3 changed files with 52 additions and 12 deletions
|
@ -316,6 +316,8 @@ int crypto_acomp_compress(struct acomp_req *req)
|
|||
{
|
||||
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
|
||||
|
||||
if (acomp_req_on_stack(req) && acomp_is_async(tfm))
|
||||
return -EAGAIN;
|
||||
if (crypto_acomp_req_chain(tfm) || acomp_request_issg(req))
|
||||
crypto_acomp_reqtfm(req)->compress(req);
|
||||
return acomp_do_req_chain(req, true);
|
||||
|
@ -326,6 +328,8 @@ int crypto_acomp_decompress(struct acomp_req *req)
|
|||
{
|
||||
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
|
||||
|
||||
if (acomp_req_on_stack(req) && acomp_is_async(tfm))
|
||||
return -EAGAIN;
|
||||
if (crypto_acomp_req_chain(tfm) || acomp_request_issg(req))
|
||||
crypto_acomp_reqtfm(req)->decompress(req);
|
||||
return acomp_do_req_chain(req, false);
|
||||
|
@ -603,5 +607,24 @@ int acomp_walk_virt(struct acomp_walk *__restrict walk,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(acomp_walk_virt);
|
||||
|
||||
struct acomp_req *acomp_request_clone(struct acomp_req *req,
|
||||
size_t total, gfp_t gfp)
|
||||
{
|
||||
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
|
||||
struct acomp_req *nreq;
|
||||
|
||||
nreq = kmalloc(total, gfp);
|
||||
if (!nreq) {
|
||||
acomp_request_set_tfm(req, tfm->fb);
|
||||
req->base.flags = CRYPTO_TFM_REQ_ON_STACK;
|
||||
return req;
|
||||
}
|
||||
|
||||
memcpy(nreq, req, total);
|
||||
acomp_request_set_tfm(req, tfm);
|
||||
return req;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acomp_request_clone);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Asynchronous compression type");
|
||||
|
|
|
@ -49,10 +49,19 @@
|
|||
#define MAX_SYNC_COMP_REQSIZE 0
|
||||
|
||||
#define ACOMP_REQUEST_ALLOC(name, tfm, gfp) \
|
||||
char __##name##_req[sizeof(struct acomp_req) + \
|
||||
MAX_SYNC_COMP_REQSIZE] CRYPTO_MINALIGN_ATTR; \
|
||||
struct acomp_req *name = acomp_request_alloc_init( \
|
||||
__##name##_req, (tfm), (gfp))
|
||||
|
||||
#define ACOMP_REQUEST_ON_STACK(name, tfm) \
|
||||
char __##name##_req[sizeof(struct acomp_req) + \
|
||||
MAX_SYNC_COMP_REQSIZE] CRYPTO_MINALIGN_ATTR; \
|
||||
struct acomp_req *name = acomp_request_on_stack_init( \
|
||||
__##name##_req, (tfm), (gfp), false)
|
||||
__##name##_req, (tfm))
|
||||
|
||||
#define ACOMP_REQUEST_CLONE(name, gfp) \
|
||||
acomp_request_clone(name, sizeof(__##name##_req), gfp)
|
||||
|
||||
struct acomp_req;
|
||||
struct folio;
|
||||
|
@ -571,12 +580,12 @@ int crypto_acomp_compress(struct acomp_req *req);
|
|||
*/
|
||||
int crypto_acomp_decompress(struct acomp_req *req);
|
||||
|
||||
static inline struct acomp_req *acomp_request_on_stack_init(
|
||||
char *buf, struct crypto_acomp *tfm, gfp_t gfp, bool stackonly)
|
||||
static inline struct acomp_req *acomp_request_alloc_init(
|
||||
char *buf, struct crypto_acomp *tfm, gfp_t gfp)
|
||||
{
|
||||
struct acomp_req *req;
|
||||
|
||||
if (!stackonly && (req = acomp_request_alloc(tfm, gfp)))
|
||||
if ((req = acomp_request_alloc(tfm, gfp)))
|
||||
return req;
|
||||
|
||||
req = (void *)buf;
|
||||
|
@ -586,4 +595,17 @@ static inline struct acomp_req *acomp_request_on_stack_init(
|
|||
return req;
|
||||
}
|
||||
|
||||
static inline struct acomp_req *acomp_request_on_stack_init(
|
||||
char *buf, struct crypto_acomp *tfm)
|
||||
{
|
||||
struct acomp_req *req = (void *)buf;
|
||||
|
||||
acomp_request_set_tfm(req, tfm);
|
||||
req->base.flags = CRYPTO_TFM_REQ_ON_STACK;
|
||||
return req;
|
||||
}
|
||||
|
||||
struct acomp_req *acomp_request_clone(struct acomp_req *req,
|
||||
size_t total, gfp_t gfp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/workqueue_types.h>
|
||||
|
||||
#define ACOMP_REQUEST_ON_STACK(name, tfm) \
|
||||
char __##name##_req[sizeof(struct acomp_req) + \
|
||||
MAX_SYNC_COMP_REQSIZE] CRYPTO_MINALIGN_ATTR; \
|
||||
struct acomp_req *name = acomp_request_on_stack_init( \
|
||||
__##name##_req, (tfm), 0, true)
|
||||
|
||||
#define ACOMP_FBREQ_ON_STACK(name, req) \
|
||||
char __##name##_req[sizeof(struct acomp_req) + \
|
||||
MAX_SYNC_COMP_REQSIZE] CRYPTO_MINALIGN_ATTR; \
|
||||
|
@ -245,9 +239,10 @@ static inline struct acomp_req *acomp_fbreq_on_stack_init(
|
|||
char *buf, struct acomp_req *old)
|
||||
{
|
||||
struct crypto_acomp *tfm = crypto_acomp_reqtfm(old);
|
||||
struct acomp_req *req;
|
||||
struct acomp_req *req = (void *)buf;
|
||||
|
||||
req = acomp_request_on_stack_init(buf, tfm, 0, true);
|
||||
acomp_request_set_tfm(req, tfm->fb);
|
||||
req->base.flags = CRYPTO_TFM_REQ_ON_STACK;
|
||||
acomp_request_set_callback(req, acomp_request_flags(old), NULL, NULL);
|
||||
req->base.flags &= ~CRYPTO_ACOMP_REQ_PRIVATE;
|
||||
req->base.flags |= old->base.flags & CRYPTO_ACOMP_REQ_PRIVATE;
|
||||
|
|
Loading…
Add table
Reference in a new issue