]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
fscrypt: move to generic async completion
authorGilad Ben-Yossef <gilad@benyossef.com>
Wed, 18 Oct 2017 07:00:44 +0000 (08:00 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 3 Nov 2017 14:11:20 +0000 (22:11 +0800)
fscrypt starts several async. crypto ops and waiting for them to
complete. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
fs/crypto/crypto.c
fs/crypto/fname.c
fs/crypto/fscrypt_private.h
fs/crypto/keyinfo.c

index c7835df7e7b847a1f33cacfa8248214c483a381d..80a3cada53defa534d385059e43c8230a278e1f5 100644 (file)
@@ -126,21 +126,6 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
 }
 EXPORT_SYMBOL(fscrypt_get_ctx);
 
-/**
- * page_crypt_complete() - completion callback for page crypto
- * @req: The asynchronous cipher request context
- * @res: The result of the cipher operation
- */
-static void page_crypt_complete(struct crypto_async_request *req, int res)
-{
-       struct fscrypt_completion_result *ecr = req->data;
-
-       if (res == -EINPROGRESS)
-               return;
-       ecr->res = res;
-       complete(&ecr->completion);
-}
-
 int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
                           u64 lblk_num, struct page *src_page,
                           struct page *dest_page, unsigned int len,
@@ -151,7 +136,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
                u8 padding[FS_IV_SIZE - sizeof(__le64)];
        } iv;
        struct skcipher_request *req = NULL;
-       DECLARE_FS_COMPLETION_RESULT(ecr);
+       DECLARE_CRYPTO_WAIT(wait);
        struct scatterlist dst, src;
        struct fscrypt_info *ci = inode->i_crypt_info;
        struct crypto_skcipher *tfm = ci->ci_ctfm;
@@ -179,7 +164,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 
        skcipher_request_set_callback(
                req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-               page_crypt_complete, &ecr);
+               crypto_req_done, &wait);
 
        sg_init_table(&dst, 1);
        sg_set_page(&dst, dest_page, len, offs);
@@ -187,14 +172,9 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
        sg_set_page(&src, src_page, len, offs);
        skcipher_request_set_crypt(req, &src, &dst, len, &iv);
        if (rw == FS_DECRYPT)
-               res = crypto_skcipher_decrypt(req);
+               res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
        else
-               res = crypto_skcipher_encrypt(req);
-       if (res == -EINPROGRESS || res == -EBUSY) {
-               BUG_ON(req->base.data != &ecr);
-               wait_for_completion(&ecr.completion);
-               res = ecr.res;
-       }
+               res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
        skcipher_request_free(req);
        if (res) {
                printk_ratelimited(KERN_ERR
index ad9f814fdead370eaa420a423139938687c3047b..a80a0d317fde4824f090d849f69dd43f93e704d3 100644 (file)
 #include <linux/ratelimit.h>
 #include "fscrypt_private.h"
 
-/**
- * fname_crypt_complete() - completion callback for filename crypto
- * @req: The asynchronous cipher request context
- * @res: The result of the cipher operation
- */
-static void fname_crypt_complete(struct crypto_async_request *req, int res)
-{
-       struct fscrypt_completion_result *ecr = req->data;
-
-       if (res == -EINPROGRESS)
-               return;
-       ecr->res = res;
-       complete(&ecr->completion);
-}
-
 /**
  * fname_encrypt() - encrypt a filename
  *
@@ -40,7 +25,7 @@ static int fname_encrypt(struct inode *inode,
                        const struct qstr *iname, struct fscrypt_str *oname)
 {
        struct skcipher_request *req = NULL;
-       DECLARE_FS_COMPLETION_RESULT(ecr);
+       DECLARE_CRYPTO_WAIT(wait);
        struct fscrypt_info *ci = inode->i_crypt_info;
        struct crypto_skcipher *tfm = ci->ci_ctfm;
        int res = 0;
@@ -76,17 +61,12 @@ static int fname_encrypt(struct inode *inode,
        }
        skcipher_request_set_callback(req,
                        CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-                       fname_crypt_complete, &ecr);
+                       crypto_req_done, &wait);
        sg_init_one(&sg, oname->name, cryptlen);
        skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv);
 
        /* Do the encryption */
-       res = crypto_skcipher_encrypt(req);
-       if (res == -EINPROGRESS || res == -EBUSY) {
-               /* Request is being completed asynchronously; wait for it */
-               wait_for_completion(&ecr.completion);
-               res = ecr.res;
-       }
+       res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
        skcipher_request_free(req);
        if (res < 0) {
                printk_ratelimited(KERN_ERR
@@ -110,7 +90,7 @@ static int fname_decrypt(struct inode *inode,
                                struct fscrypt_str *oname)
 {
        struct skcipher_request *req = NULL;
-       DECLARE_FS_COMPLETION_RESULT(ecr);
+       DECLARE_CRYPTO_WAIT(wait);
        struct scatterlist src_sg, dst_sg;
        struct fscrypt_info *ci = inode->i_crypt_info;
        struct crypto_skcipher *tfm = ci->ci_ctfm;
@@ -131,7 +111,7 @@ static int fname_decrypt(struct inode *inode,
        }
        skcipher_request_set_callback(req,
                CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-               fname_crypt_complete, &ecr);
+               crypto_req_done, &wait);
 
        /* Initialize IV */
        memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
@@ -140,11 +120,7 @@ static int fname_decrypt(struct inode *inode,
        sg_init_one(&src_sg, iname->name, iname->len);
        sg_init_one(&dst_sg, oname->name, oname->len);
        skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
-       res = crypto_skcipher_decrypt(req);
-       if (res == -EINPROGRESS || res == -EBUSY) {
-               wait_for_completion(&ecr.completion);
-               res = ecr.res;
-       }
+       res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
        skcipher_request_free(req);
        if (res < 0) {
                printk_ratelimited(KERN_ERR
index a1d5021c31ef8f494b5ae96cd4e2129976e43ef3..c0f1881f7c3d179b9f5a65ee57dbea63e88da116 100644 (file)
@@ -69,16 +69,6 @@ typedef enum {
 #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL                0x00000001
 #define FS_CTX_HAS_BOUNCE_BUFFER_FL            0x00000002
 
-struct fscrypt_completion_result {
-       struct completion completion;
-       int res;
-};
-
-#define DECLARE_FS_COMPLETION_RESULT(ecr) \
-       struct fscrypt_completion_result ecr = { \
-               COMPLETION_INITIALIZER_ONSTACK((ecr).completion), 0 }
-
-
 /* crypto.c */
 extern int fscrypt_initialize(unsigned int cop_flags);
 extern struct workqueue_struct *fscrypt_read_workqueue;
index 018c588c7ac3b7ac8fd78b4092332f771c6411c0..3c84caca27ebacede5783f74bc54069c35e8be29 100644 (file)
 
 static struct crypto_shash *essiv_hash_tfm;
 
-static void derive_crypt_complete(struct crypto_async_request *req, int rc)
-{
-       struct fscrypt_completion_result *ecr = req->data;
-
-       if (rc == -EINPROGRESS)
-               return;
-
-       ecr->res = rc;
-       complete(&ecr->completion);
-}
-
 /**
  * derive_key_aes() - Derive a key using AES-128-ECB
  * @deriving_key: Encryption key used for derivation.
@@ -42,7 +31,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 {
        int res = 0;
        struct skcipher_request *req = NULL;
-       DECLARE_FS_COMPLETION_RESULT(ecr);
+       DECLARE_CRYPTO_WAIT(wait);
        struct scatterlist src_sg, dst_sg;
        struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
 
@@ -59,7 +48,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
        }
        skcipher_request_set_callback(req,
                        CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-                       derive_crypt_complete, &ecr);
+                       crypto_req_done, &wait);
        res = crypto_skcipher_setkey(tfm, deriving_key,
                                        FS_AES_128_ECB_KEY_SIZE);
        if (res < 0)
@@ -69,11 +58,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
        sg_init_one(&dst_sg, derived_raw_key, source_key->size);
        skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size,
                                   NULL);
-       res = crypto_skcipher_encrypt(req);
-       if (res == -EINPROGRESS || res == -EBUSY) {
-               wait_for_completion(&ecr.completion);
-               res = ecr.res;
-       }
+       res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 out:
        skcipher_request_free(req);
        crypto_free_skcipher(tfm);