From c6a14b32c9ba041fbe043aa30ebd5c6b467d6518 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 14 Jun 2025 15:13:01 -0700 Subject: [PATCH 1/9] fscrypt: Explicitly include Fix build warnings with W=1 that started appearing after commit a934a57a42f6 ("scripts/misc-check: check missing #include when W=1"). While at it, also sort the include lists alphabetically. Link: https://lore.kernel.org/r/20250614221301.100803-1-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 6 ++++-- fs/crypto/crypto.c | 8 +++++--- fs/crypto/fname.c | 6 ++++-- fs/crypto/hkdf.c | 2 +- fs/crypto/hooks.c | 2 ++ fs/crypto/inline_crypt.c | 1 + fs/crypto/keyring.c | 5 +++-- fs/crypto/keysetup.c | 1 + fs/crypto/policy.c | 4 +++- 9 files changed, 24 insertions(+), 11 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 0ad8c30b8fa5..13ad2dd771b6 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -7,10 +7,12 @@ * Copyright (C) 2015, Motorola Mobility */ -#include -#include #include +#include +#include #include +#include + #include "fscrypt_private.h" /** diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index b74b5937e695..ddf6991d46da 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -20,12 +20,14 @@ * Special Publication 800-38E and IEEE P1619/D16. */ -#include +#include +#include #include #include -#include +#include #include -#include +#include + #include "fscrypt_private.h" static unsigned int num_prealloc_crypto_pages = 32; diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 010f9c0a4c2f..fb01dde0f2e5 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -11,11 +11,13 @@ * This has not yet undergone a rigorous security audit. */ -#include -#include #include #include #include +#include +#include +#include + #include "fscrypt_private.h" /* diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c index 0f3028adc9c7..5c095c8aa3b5 100644 --- a/fs/crypto/hkdf.c +++ b/fs/crypto/hkdf.c @@ -8,8 +8,8 @@ */ #include -#include #include +#include #include "fscrypt_private.h" diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index d8d5049b8fe1..e0b32ac841f7 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c @@ -5,6 +5,8 @@ * Encryption hooks for higher-level filesystem operations. */ +#include + #include "fscrypt_private.h" /** diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 1d008c440cb6..caaff809765b 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index ace369f13068..7557f6a88b8f 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -18,12 +18,13 @@ * information about these ioctls. */ -#include #include +#include #include -#include #include +#include #include +#include #include "fscrypt_private.h" diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 0d71843af946..a67e20d126c9 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -9,6 +9,7 @@ */ #include +#include #include #include "fscrypt_private.h" diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 701259991277..6ad30ae07c06 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -10,11 +10,13 @@ * Modified by Eric Biggers, 2019 for v2 policy support. */ +#include #include +#include #include #include #include -#include + #include "fscrypt_private.h" /** From 66271c155d88e9e3a6ad92df946efde6645ec851 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 19 Jun 2025 12:31:49 -0700 Subject: [PATCH 2/9] fscrypt: Drop obsolete recommendation to enable optimized SHA-512 Since the crypto kconfig options are being fixed to enable optimized SHA-512 automatically (https://lore.kernel.org/linux-crypto/20250616014019.415791-1-ebiggers@kernel.org/), it is no longer necessary to give a recommendation to enable it. Link: https://lore.kernel.org/r/20250619193149.138315-1-ebiggers@kernel.org Signed-off-by: Eric Biggers --- Documentation/filesystems/fscrypt.rst | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 29e84d125e02..f63791641c1d 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -468,14 +468,6 @@ API, but the filenames mode still does. - Recommended: - AES-CBC acceleration -fscrypt also uses HMAC-SHA512 for key derivation, so enabling SHA-512 -acceleration is recommended: - -- SHA-512 - - Recommended: - - arm64: CONFIG_CRYPTO_SHA512_ARM64_CE - - x86: CONFIG_CRYPTO_SHA512_SSSE3 - Contents encryption ------------------- From b41c1d8d07906786c60893980d52688f31d114a6 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 4 Jul 2025 00:03:22 -0700 Subject: [PATCH 3/9] fscrypt: Don't use problematic non-inline crypto engines Make fscrypt no longer use Crypto API drivers for non-inline crypto engines, even when the Crypto API prioritizes them over CPU-based code (which unfortunately it often does). These drivers tend to be really problematic, especially for fscrypt's workload. This commit has no effect on inline crypto engines, which are different and do work well. Specifically, exclude drivers that have CRYPTO_ALG_KERN_DRIVER_ONLY or CRYPTO_ALG_ALLOCATES_MEMORY set. (Later, CRYPTO_ALG_ASYNC should be excluded too. That's omitted for now to keep this commit backportable, since until recently some CPU-based code had CRYPTO_ALG_ASYNC set.) There are two major issues with these drivers: bugs and performance. First, these drivers tend to be buggy. They're fundamentally much more error-prone and harder to test than the CPU-based code. They often don't get tested before kernel releases, and even if they do, the crypto self-tests don't properly test these drivers. Released drivers have en/decrypted or hashed data incorrectly. These bugs cause issues for fscrypt users who often didn't even want to use these drivers, e.g.: - https://github.com/google/fscryptctl/issues/32 - https://github.com/google/fscryptctl/issues/9 - https://lore.kernel.org/r/PH0PR02MB731916ECDB6C613665863B6CFFAA2@PH0PR02MB7319.namprd02.prod.outlook.com These drivers have also similarly caused issues for dm-crypt users, including data corruption and deadlocks. Since Linux v5.10, dm-crypt has disabled most of them by excluding CRYPTO_ALG_ALLOCATES_MEMORY. Second, these drivers tend to be *much* slower than the CPU-based code. This may seem counterintuitive, but benchmarks clearly show it. There's a *lot* of overhead associated with going to a hardware driver, off the CPU, and back again. To prove this, I gathered as many systems with this type of crypto engine as I could, and I measured synchronous encryption of 4096-byte messages (which matches fscrypt's workload): Intel Emerald Rapids server: AES-256-XTS: xts-aes-vaes-avx512 16171 MB/s [CPU-based, Vector AES] qat_aes_xts 289 MB/s [Offload, Intel QuickAssist] Qualcomm SM8650 HDK: AES-256-XTS: xts-aes-ce 4301 MB/s [CPU-based, ARMv8 Crypto Extensions] xts-aes-qce 73 MB/s [Offload, Qualcomm Crypto Engine] i.MX 8M Nano LPDDR4 EVK: AES-256-XTS: xts-aes-ce 647 MB/s [CPU-based, ARMv8 Crypto Extensions] xts(ecb-aes-caam) 20 MB/s [Offload, CAAM] AES-128-CBC-ESSIV: essiv(cbc-aes-caam,sha256-lib) 23 MB/s [Offload, CAAM] STM32MP157F-DK2: AES-256-XTS: xts-aes-neonbs 13.2 MB/s [CPU-based, ARM NEON] xts(stm32-ecb-aes) 3.1 MB/s [Offload, STM32 crypto engine] AES-128-CBC-ESSIV: essiv(cbc-aes-neonbs,sha256-lib) 14.7 MB/s [CPU-based, ARM NEON] essiv(stm32-cbc-aes,sha256-lib) 3.2 MB/s [Offload, STM32 crypto engine] Adiantum: adiantum(xchacha12-arm,aes-arm,nhpoly1305-neon) 52.8 MB/s [CPU-based, ARM scalar + NEON] So, there was no case in which the crypto engine was even *close* to being faster. On the first three, which have AES instructions in the CPU, the CPU was 30 to 55 times faster (!). Even on STM32MP157F-DK2 which has a Cortex-A7 CPU that doesn't have AES instructions, AES was over 4 times faster on the CPU. And Adiantum encryption, which is what actually should be used on CPUs like that, was over 17 times faster. Other justifications that have been given for these non-inline crypto engines (almost always coming from the hardware vendors, not actual users) don't seem very plausible either: - The crypto engine throughput could be improved by processing multiple requests concurrently. Currently irrelevant to fscrypt, since it doesn't do that. This would also be complex, and unhelpful in many cases. 2 of the 4 engines I tested even had only one queue. - Some of the engines, e.g. STM32, support hardware keys. Also currently irrelevant to fscrypt, since it doesn't support these. Interestingly, the STM32 driver itself doesn't support this either. - Free up CPU for other tasks and/or reduce energy usage. Not very plausible considering the "short" message length, driver overhead, and scheduling overhead. There's just very little time for the CPU to do something else like run another task or enter low-power state, before the message finishes and it's time to process the next one. - Some of these engines resist power analysis and electromagnetic attacks, while the CPU-based crypto generally does not. In theory, this sounds great. In practice, if this benefit requires the use of an off-CPU offload that massively regresses performance and has a low-quality, buggy driver, the price for this hardening (which is not relevant to most fscrypt users, and tends to be incomplete) is just too high. Inline crypto engines are much more promising here, as are on-CPU solutions like RISC-V High Assurance Cryptography. Fixes: b30ab0e03407 ("ext4 crypto: add ext4 encryption facilities") Cc: stable@vger.kernel.org Acked-by: Ard Biesheuvel Link: https://lore.kernel.org/r/20250704070322.20692-1-ebiggers@kernel.org Signed-off-by: Eric Biggers --- Documentation/filesystems/fscrypt.rst | 37 +++++++++++---------------- fs/crypto/fscrypt_private.h | 17 ++++++++++++ fs/crypto/hkdf.c | 2 +- fs/crypto/keysetup.c | 3 ++- fs/crypto/keysetup_v1.c | 3 ++- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index f63791641c1d..696a5844bfa3 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -147,9 +147,8 @@ However, these ioctls have some limitations: were wiped. To partially solve this, you can add init_on_free=1 to your kernel command line. However, this has a performance cost. -- Secret keys might still exist in CPU registers, in crypto - accelerator hardware (if used by the crypto API to implement any of - the algorithms), or in other places not explicitly considered here. +- Secret keys might still exist in CPU registers or in other places + not explicitly considered here. Full system compromise ~~~~~~~~~~~~~~~~~~~~~~ @@ -406,9 +405,12 @@ the work is done by XChaCha12, which is much faster than AES when AES acceleration is unavailable. For more information about Adiantum, see `the Adiantum paper `_. -The (AES-128-CBC-ESSIV, AES-128-CBC-CTS) pair exists only to support -systems whose only form of AES acceleration is an off-CPU crypto -accelerator such as CAAM or CESA that does not support XTS. +The (AES-128-CBC-ESSIV, AES-128-CBC-CTS) pair was added to try to +provide a more efficient option for systems that lack AES instructions +in the CPU but do have a non-inline crypto engine such as CAAM or CESA +that supports AES-CBC (and not AES-XTS). This is deprecated. It has +been shown that just doing AES on the CPU is actually faster. +Moreover, Adiantum is faster still and is recommended on such systems. The remaining mode pairs are the "national pride ciphers": @@ -1318,22 +1320,13 @@ this by validating all top-level encryption policies prior to access. Inline encryption support ========================= -By default, fscrypt uses the kernel crypto API for all cryptographic -operations (other than HKDF, which fscrypt partially implements -itself). The kernel crypto API supports hardware crypto accelerators, -but only ones that work in the traditional way where all inputs and -outputs (e.g. plaintexts and ciphertexts) are in memory. fscrypt can -take advantage of such hardware, but the traditional acceleration -model isn't particularly efficient and fscrypt hasn't been optimized -for it. - -Instead, many newer systems (especially mobile SoCs) have *inline -encryption hardware* that can encrypt/decrypt data while it is on its -way to/from the storage device. Linux supports inline encryption -through a set of extensions to the block layer called *blk-crypto*. -blk-crypto allows filesystems to attach encryption contexts to bios -(I/O requests) to specify how the data will be encrypted or decrypted -in-line. For more information about blk-crypto, see +Many newer systems (especially mobile SoCs) have *inline encryption +hardware* that can encrypt/decrypt data while it is on its way to/from +the storage device. Linux supports inline encryption through a set of +extensions to the block layer called *blk-crypto*. blk-crypto allows +filesystems to attach encryption contexts to bios (I/O requests) to +specify how the data will be encrypted or decrypted in-line. For more +information about blk-crypto, see :ref:`Documentation/block/inline-encryption.rst `. On supported filesystems (currently ext4 and f2fs), fscrypt can use diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index c1d92074b65c..6e7164530a1e 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -45,6 +45,23 @@ */ #undef FSCRYPT_MAX_KEY_SIZE +/* + * This mask is passed as the third argument to the crypto_alloc_*() functions + * to prevent fscrypt from using the Crypto API drivers for non-inline crypto + * engines. Those drivers have been problematic for fscrypt. fscrypt users + * have reported hangs and even incorrect en/decryption with these drivers. + * Since going to the driver, off CPU, and back again is really slow, such + * drivers can be over 50 times slower than the CPU-based code for fscrypt's + * workload. Even on platforms that lack AES instructions on the CPU, using the + * offloads has been shown to be slower, even staying with AES. (Of course, + * Adiantum is faster still, and is the recommended option on such platforms...) + * + * Note that fscrypt also supports inline crypto engines. Those don't use the + * Crypto API and work much better than the old-style (non-inline) engines. + */ +#define FSCRYPT_CRYPTOAPI_MASK \ + (CRYPTO_ALG_ALLOCATES_MEMORY | CRYPTO_ALG_KERN_DRIVER_ONLY) + #define FSCRYPT_CONTEXT_V1 1 #define FSCRYPT_CONTEXT_V2 2 diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c index 5c095c8aa3b5..b1ef506cd341 100644 --- a/fs/crypto/hkdf.c +++ b/fs/crypto/hkdf.c @@ -58,7 +58,7 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key, u8 prk[HKDF_HASHLEN]; int err; - hmac_tfm = crypto_alloc_shash(HKDF_HMAC_ALG, 0, 0); + hmac_tfm = crypto_alloc_shash(HKDF_HMAC_ALG, 0, FSCRYPT_CRYPTOAPI_MASK); if (IS_ERR(hmac_tfm)) { fscrypt_err(NULL, "Error allocating " HKDF_HMAC_ALG ": %ld", PTR_ERR(hmac_tfm)); diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index a67e20d126c9..74d4a2e1ad23 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -104,7 +104,8 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key, struct crypto_skcipher *tfm; int err; - tfm = crypto_alloc_skcipher(mode->cipher_str, 0, 0); + tfm = crypto_alloc_skcipher(mode->cipher_str, 0, + FSCRYPT_CRYPTOAPI_MASK); if (IS_ERR(tfm)) { if (PTR_ERR(tfm) == -ENOENT) { fscrypt_warn(inode, diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index b70521c55132..158ceae8a5bc 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -52,7 +52,8 @@ static int derive_key_aes(const u8 *master_key, struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); struct scatterlist src_sg, dst_sg; - struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0); + struct crypto_skcipher *tfm = + crypto_alloc_skcipher("ecb(aes)", 0, FSCRYPT_CRYPTOAPI_MASK); if (IS_ERR(tfm)) { res = PTR_ERR(tfm); From 71ffd1dc5234f522a7647dd30ca8fc9eefe8da1b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Jul 2025 23:07:48 -0700 Subject: [PATCH 4/9] fscrypt: Don't use asynchronous CryptoAPI algorithms Now that fscrypt's incomplete support for non-inline crypto engines has been removed, and none of the CPU-based algorithms have the CRYPTO_ALG_ASYNC flag set anymore, there is no need to accommodate asynchronous algorithms. Therefore, explicitly allocate only synchronous algorithms. Then, remove the code that handled waiting for asynchronous en/decryption operations to complete. This commit should *not* be backported to kernels that lack commit 0ba6ec5b2972 ("crypto: x86/aes - stop using the SIMD helper"), as then it would disable the use of the optimized AES code on x86. Link: https://lore.kernel.org/r/20250710060754.637098-2-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/crypto/crypto.c | 7 +++---- fs/crypto/fname.c | 18 ++++++++---------- fs/crypto/fscrypt_private.h | 5 +++-- fs/crypto/keysetup_v1.c | 9 ++++----- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index ddf6991d46da..43d1658e07ce 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -115,7 +115,6 @@ int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, { union fscrypt_iv iv; struct skcipher_request *req = NULL; - DECLARE_CRYPTO_WAIT(wait); struct scatterlist dst, src; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; int res = 0; @@ -133,7 +132,7 @@ int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, skcipher_request_set_callback( req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, - crypto_req_done, &wait); + NULL, NULL); sg_init_table(&dst, 1); sg_set_page(&dst, dest_page, len, offs); @@ -141,9 +140,9 @@ int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, sg_set_page(&src, src_page, len, offs); skcipher_request_set_crypt(req, &src, &dst, len, &iv); if (rw == FS_DECRYPT) - res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); + res = crypto_skcipher_decrypt(req); else - res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); + res = crypto_skcipher_encrypt(req); skcipher_request_free(req); if (res) { fscrypt_err(ci->ci_inode, diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index fb01dde0f2e5..17edc24ccd42 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -95,7 +95,6 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, u8 *out, unsigned int olen) { struct skcipher_request *req = NULL; - DECLARE_CRYPTO_WAIT(wait); const struct fscrypt_inode_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; union fscrypt_iv iv; @@ -118,14 +117,14 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, req = skcipher_request_alloc(tfm, GFP_NOFS); if (!req) return -ENOMEM; - skcipher_request_set_callback(req, - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, - crypto_req_done, &wait); + skcipher_request_set_callback( + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); sg_init_one(&sg, out, olen); skcipher_request_set_crypt(req, &sg, &sg, olen, &iv); /* Do the encryption */ - res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); + res = crypto_skcipher_encrypt(req); skcipher_request_free(req); if (res < 0) { fscrypt_err(inode, "Filename encryption failed: %d", res); @@ -151,7 +150,6 @@ static int fname_decrypt(const struct inode *inode, struct fscrypt_str *oname) { struct skcipher_request *req = NULL; - DECLARE_CRYPTO_WAIT(wait); struct scatterlist src_sg, dst_sg; const struct fscrypt_inode_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; @@ -162,9 +160,9 @@ static int fname_decrypt(const struct inode *inode, req = skcipher_request_alloc(tfm, GFP_NOFS); if (!req) return -ENOMEM; - skcipher_request_set_callback(req, - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, - crypto_req_done, &wait); + skcipher_request_set_callback( + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); /* Initialize IV */ fscrypt_generate_iv(&iv, 0, ci); @@ -173,7 +171,7 @@ static int fname_decrypt(const 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_wait_req(crypto_skcipher_decrypt(req), &wait); + res = crypto_skcipher_decrypt(req); skcipher_request_free(req); if (res < 0) { fscrypt_err(inode, "Filename decryption failed: %d", res); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 6e7164530a1e..06fa8f2b2d08 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -59,8 +59,9 @@ * Note that fscrypt also supports inline crypto engines. Those don't use the * Crypto API and work much better than the old-style (non-inline) engines. */ -#define FSCRYPT_CRYPTOAPI_MASK \ - (CRYPTO_ALG_ALLOCATES_MEMORY | CRYPTO_ALG_KERN_DRIVER_ONLY) +#define FSCRYPT_CRYPTOAPI_MASK \ + (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | \ + CRYPTO_ALG_KERN_DRIVER_ONLY) #define FSCRYPT_CONTEXT_V1 1 #define FSCRYPT_CONTEXT_V2 2 diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index 158ceae8a5bc..3fdf174384f3 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -50,7 +50,6 @@ static int derive_key_aes(const u8 *master_key, { int res = 0; struct skcipher_request *req = NULL; - DECLARE_CRYPTO_WAIT(wait); struct scatterlist src_sg, dst_sg; struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, FSCRYPT_CRYPTOAPI_MASK); @@ -66,9 +65,9 @@ static int derive_key_aes(const u8 *master_key, res = -ENOMEM; goto out; } - skcipher_request_set_callback(req, - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, - crypto_req_done, &wait); + skcipher_request_set_callback( + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); res = crypto_skcipher_setkey(tfm, nonce, FSCRYPT_FILE_NONCE_SIZE); if (res < 0) goto out; @@ -77,7 +76,7 @@ static int derive_key_aes(const u8 *master_key, sg_init_one(&dst_sg, derived_key, derived_keysize); skcipher_request_set_crypt(req, &src_sg, &dst_sg, derived_keysize, NULL); - res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); + res = crypto_skcipher_encrypt(req); out: skcipher_request_free(req); crypto_free_skcipher(tfm); From 53d9218d8d38cd33e065cc46db996608adec6687 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Jul 2025 23:07:49 -0700 Subject: [PATCH 5/9] fscrypt: Drop FORBID_WEAK_KEYS flag for AES-ECB This flag only has an effect for DES, 3DES, and XTS mode. It does nothing for AES-ECB, as there is no concept of weak keys for AES. Link: https://lore.kernel.org/r/20250710060754.637098-3-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/crypto/keysetup_v1.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index 3fdf174384f3..75b0f1211a1e 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -59,7 +59,6 @@ static int derive_key_aes(const u8 *master_key, tfm = NULL; goto out; } - crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); req = skcipher_request_alloc(tfm, GFP_KERNEL); if (!req) { res = -ENOMEM; From 52e7e0d8893327ea83373c02b597ec809b94db76 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Jul 2025 23:07:50 -0700 Subject: [PATCH 6/9] fscrypt: Switch to sync_skcipher and on-stack requests Now that fscrypt uses only synchronous skciphers, switch to the actual sync_skcipher API and the corresponding on-stack requests. This eliminates a heap allocation per en/decryption operation. Link: https://lore.kernel.org/r/20250710060754.637098-4-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/crypto/crypto.c | 24 ++++++----------- fs/crypto/fname.c | 53 ++++++++++++------------------------- fs/crypto/fscrypt_private.h | 2 +- fs/crypto/keysetup.c | 23 ++++++++-------- fs/crypto/keysetup_v1.c | 52 +++++++++++++++--------------------- 5 files changed, 60 insertions(+), 94 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 43d1658e07ce..646b1831e683 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -113,11 +113,11 @@ int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, unsigned int len, unsigned int offs, gfp_t gfp_flags) { + struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm; + SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); union fscrypt_iv iv; - struct skcipher_request *req = NULL; struct scatterlist dst, src; - struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; - int res = 0; + int err; if (WARN_ON_ONCE(len <= 0)) return -EINVAL; @@ -126,31 +126,23 @@ int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, fscrypt_generate_iv(&iv, index, ci); - req = skcipher_request_alloc(tfm, gfp_flags); - if (!req) - return -ENOMEM; - skcipher_request_set_callback( req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); - sg_init_table(&dst, 1); sg_set_page(&dst, dest_page, len, offs); sg_init_table(&src, 1); 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); + err = crypto_skcipher_decrypt(req); else - res = crypto_skcipher_encrypt(req); - skcipher_request_free(req); - if (res) { + err = crypto_skcipher_encrypt(req); + if (err) fscrypt_err(ci->ci_inode, "%scryption failed for data unit %llu: %d", - (rw == FS_DECRYPT ? "De" : "En"), index, res); - return res; - } - return 0; + (rw == FS_DECRYPT ? "De" : "En"), index, err); + return err; } /** diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 17edc24ccd42..f9f6713e144f 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -94,12 +94,12 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str) int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, u8 *out, unsigned int olen) { - struct skcipher_request *req = NULL; const struct fscrypt_inode_info *ci = inode->i_crypt_info; - struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; + struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm; + SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); union fscrypt_iv iv; struct scatterlist sg; - int res; + int err; /* * Copy the filename to the output buffer for encrypting in-place and @@ -110,28 +110,17 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, memcpy(out, iname->name, iname->len); memset(out + iname->len, 0, olen - iname->len); - /* Initialize the IV */ fscrypt_generate_iv(&iv, 0, ci); - /* Set up the encryption request */ - req = skcipher_request_alloc(tfm, GFP_NOFS); - if (!req) - return -ENOMEM; skcipher_request_set_callback( req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); sg_init_one(&sg, out, olen); skcipher_request_set_crypt(req, &sg, &sg, olen, &iv); - - /* Do the encryption */ - res = crypto_skcipher_encrypt(req); - skcipher_request_free(req); - if (res < 0) { - fscrypt_err(inode, "Filename encryption failed: %d", res); - return res; - } - - return 0; + err = crypto_skcipher_encrypt(req); + if (err) + fscrypt_err(inode, "Filename encryption failed: %d", err); + return err; } EXPORT_SYMBOL_GPL(fscrypt_fname_encrypt); @@ -149,33 +138,25 @@ static int fname_decrypt(const struct inode *inode, const struct fscrypt_str *iname, struct fscrypt_str *oname) { - struct skcipher_request *req = NULL; - struct scatterlist src_sg, dst_sg; const struct fscrypt_inode_info *ci = inode->i_crypt_info; - struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; + struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm; + SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); union fscrypt_iv iv; - int res; + struct scatterlist src_sg, dst_sg; + int err; + + fscrypt_generate_iv(&iv, 0, ci); - /* Allocate request */ - req = skcipher_request_alloc(tfm, GFP_NOFS); - if (!req) - return -ENOMEM; skcipher_request_set_callback( req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); - - /* Initialize IV */ - fscrypt_generate_iv(&iv, 0, ci); - - /* Create decryption request */ 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); - skcipher_request_free(req); - if (res < 0) { - fscrypt_err(inode, "Filename decryption failed: %d", res); - return res; + err = crypto_skcipher_decrypt(req); + if (err) { + fscrypt_err(inode, "Filename decryption failed: %d", err); + return err; } oname->len = strnlen(oname->name, iname->len); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 06fa8f2b2d08..bffeb14501fd 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -239,7 +239,7 @@ struct fscrypt_symlink_data { * Normally only one of the fields will be non-NULL. */ struct fscrypt_prepared_key { - struct crypto_skcipher *tfm; + struct crypto_sync_skcipher *tfm; #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT struct blk_crypto_key *blk_key; #endif diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 74d4a2e1ad23..4f3b9ecbfe4e 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -97,15 +97,15 @@ select_encryption_mode(const union fscrypt_policy *policy, } /* Create a symmetric cipher object for the given encryption mode and key */ -static struct crypto_skcipher * +static struct crypto_sync_skcipher * fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key, const struct inode *inode) { - struct crypto_skcipher *tfm; + struct crypto_sync_skcipher *tfm; int err; - tfm = crypto_alloc_skcipher(mode->cipher_str, 0, - FSCRYPT_CRYPTOAPI_MASK); + tfm = crypto_alloc_sync_skcipher(mode->cipher_str, 0, + FSCRYPT_CRYPTOAPI_MASK); if (IS_ERR(tfm)) { if (PTR_ERR(tfm) == -ENOENT) { fscrypt_warn(inode, @@ -125,21 +125,22 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key, * first time a mode is used. */ pr_info("fscrypt: %s using implementation \"%s\"\n", - mode->friendly_name, crypto_skcipher_driver_name(tfm)); + mode->friendly_name, + crypto_skcipher_driver_name(&tfm->base)); } - if (WARN_ON_ONCE(crypto_skcipher_ivsize(tfm) != mode->ivsize)) { + if (WARN_ON_ONCE(crypto_sync_skcipher_ivsize(tfm) != mode->ivsize)) { err = -EINVAL; goto err_free_tfm; } - crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); - err = crypto_skcipher_setkey(tfm, raw_key, mode->keysize); + crypto_sync_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); + err = crypto_sync_skcipher_setkey(tfm, raw_key, mode->keysize); if (err) goto err_free_tfm; return tfm; err_free_tfm: - crypto_free_skcipher(tfm); + crypto_free_sync_skcipher(tfm); return ERR_PTR(err); } @@ -152,7 +153,7 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key, int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, const u8 *raw_key, const struct fscrypt_inode_info *ci) { - struct crypto_skcipher *tfm; + struct crypto_sync_skcipher *tfm; if (fscrypt_using_inline_encryption(ci)) return fscrypt_prepare_inline_crypt_key(prep_key, raw_key, @@ -176,7 +177,7 @@ int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, void fscrypt_destroy_prepared_key(struct super_block *sb, struct fscrypt_prepared_key *prep_key) { - crypto_free_skcipher(prep_key->tfm); + crypto_free_sync_skcipher(prep_key->tfm); fscrypt_destroy_inline_crypt_key(sb, prep_key); memzero_explicit(prep_key, sizeof(*prep_key)); } diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index 75b0f1211a1e..c4d05168522b 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -48,38 +48,30 @@ static int derive_key_aes(const u8 *master_key, const u8 nonce[FSCRYPT_FILE_NONCE_SIZE], u8 *derived_key, unsigned int derived_keysize) { - int res = 0; - struct skcipher_request *req = NULL; - struct scatterlist src_sg, dst_sg; - struct crypto_skcipher *tfm = - crypto_alloc_skcipher("ecb(aes)", 0, FSCRYPT_CRYPTOAPI_MASK); + struct crypto_sync_skcipher *tfm; + int err; - if (IS_ERR(tfm)) { - res = PTR_ERR(tfm); - tfm = NULL; - goto out; - } - req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (!req) { - res = -ENOMEM; - goto out; - } - skcipher_request_set_callback( - req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, - NULL, NULL); - res = crypto_skcipher_setkey(tfm, nonce, FSCRYPT_FILE_NONCE_SIZE); - if (res < 0) - goto out; + tfm = crypto_alloc_sync_skcipher("ecb(aes)", 0, FSCRYPT_CRYPTOAPI_MASK); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - sg_init_one(&src_sg, master_key, derived_keysize); - sg_init_one(&dst_sg, derived_key, derived_keysize); - skcipher_request_set_crypt(req, &src_sg, &dst_sg, derived_keysize, - NULL); - res = crypto_skcipher_encrypt(req); -out: - skcipher_request_free(req); - crypto_free_skcipher(tfm); - return res; + err = crypto_sync_skcipher_setkey(tfm, nonce, FSCRYPT_FILE_NONCE_SIZE); + if (err == 0) { + SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); + struct scatterlist src_sg, dst_sg; + + skcipher_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + sg_init_one(&src_sg, master_key, derived_keysize); + sg_init_one(&dst_sg, derived_key, derived_keysize); + skcipher_request_set_crypt(req, &src_sg, &dst_sg, + derived_keysize, NULL); + err = crypto_skcipher_encrypt(req); + } + crypto_free_sync_skcipher(tfm); + return err; } /* From a9a95ecd9d3a24402a302595ee12029772a9f593 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Jul 2025 23:07:51 -0700 Subject: [PATCH 7/9] fscrypt: Remove gfp_t argument from fscrypt_crypt_data_unit() This argument is no longer used, so remove it. Link: https://lore.kernel.org/r/20250710060754.637098-5-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 3 +-- fs/crypto/crypto.c | 14 +++++--------- fs/crypto/fscrypt_private.h | 3 +-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 13ad2dd771b6..486fcb2ecf13 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -167,8 +167,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, do { err = fscrypt_crypt_data_unit(ci, FS_ENCRYPT, du_index, ZERO_PAGE(0), pages[i], - du_size, offset, - GFP_NOFS); + du_size, offset); if (err) goto out; du_index++; diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 646b1831e683..bab0aacd4da3 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -110,8 +110,7 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 index, int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, fscrypt_direction_t rw, u64 index, struct page *src_page, struct page *dest_page, - unsigned int len, unsigned int offs, - gfp_t gfp_flags) + unsigned int len, unsigned int offs) { struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm; SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm); @@ -197,7 +196,7 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, for (i = offs; i < offs + len; i += du_size, index++) { err = fscrypt_crypt_data_unit(ci, FS_ENCRYPT, index, &folio->page, ciphertext_page, - du_size, i, gfp_flags); + du_size, i); if (err) { fscrypt_free_bounce_page(ciphertext_page); return ERR_PTR(err); @@ -235,8 +234,7 @@ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units)) return -EOPNOTSUPP; return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_ENCRYPT, - lblk_num, page, page, len, offs, - gfp_flags); + lblk_num, page, page, len, offs); } EXPORT_SYMBOL(fscrypt_encrypt_block_inplace); @@ -276,8 +274,7 @@ int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len, struct page *page = folio_page(folio, i >> PAGE_SHIFT); err = fscrypt_crypt_data_unit(ci, FS_DECRYPT, index, page, - page, du_size, i & ~PAGE_MASK, - GFP_NOFS); + page, du_size, i & ~PAGE_MASK); if (err) return err; } @@ -310,8 +307,7 @@ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units)) return -EOPNOTSUPP; return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_DECRYPT, - lblk_num, page, page, len, offs, - GFP_NOFS); + lblk_num, page, page, len, offs); } EXPORT_SYMBOL(fscrypt_decrypt_block_inplace); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index bffeb14501fd..d8b485b9881c 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -337,8 +337,7 @@ int fscrypt_initialize(struct super_block *sb); int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, fscrypt_direction_t rw, u64 index, struct page *src_page, struct page *dest_page, - unsigned int len, unsigned int offs, - gfp_t gfp_flags); + unsigned int len, unsigned int offs); struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags); void __printf(3, 4) __cold From 47462586f91358499897fddb20f6bb9cec5f4213 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Jul 2025 23:07:52 -0700 Subject: [PATCH 8/9] fscrypt: Remove gfp_t argument from fscrypt_encrypt_block_inplace() This argument is no longer used, so remove it. Reviewed-by: Alex Markuze Link: https://lore.kernel.org/r/20250710060754.637098-6-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/ceph/crypto.c | 3 +-- fs/crypto/crypto.c | 3 +-- fs/ubifs/crypto.c | 2 +- include/linux/fscrypt.h | 5 ++--- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 3b3c4d8d401e..6d04d528ed03 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -523,8 +523,7 @@ int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, doutc(cl, "%p %llx.%llx len %u offs %u blk %llu\n", inode, ceph_vinop(inode), len, offs, lblk_num); - return fscrypt_encrypt_block_inplace(inode, page, len, offs, lblk_num, - gfp_flags); + return fscrypt_encrypt_block_inplace(inode, page, len, offs, lblk_num); } /** diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index bab0aacd4da3..b6ccab524fde 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -217,7 +217,6 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks); * @offs: Byte offset within @page at which the block to encrypt begins * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based * number of the block within the file - * @gfp_flags: Memory allocation flags * * Encrypt a possibly-compressed filesystem block that is located in an * arbitrary page, not necessarily in the original pagecache page. The @inode @@ -229,7 +228,7 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks); */ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, - u64 lblk_num, gfp_t gfp_flags) + u64 lblk_num) { if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units)) return -EOPNOTSUPP; diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c index 921f9033d0d2..fb5ac358077b 100644 --- a/fs/ubifs/crypto.c +++ b/fs/ubifs/crypto.c @@ -51,7 +51,7 @@ int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn, memset(p + in_len, 0, pad_len - in_len); err = fscrypt_encrypt_block_inplace(inode, virt_to_page(p), pad_len, - offset_in_page(p), block, GFP_NOFS); + offset_in_page(p), block); if (err) { ubifs_err(c, "fscrypt_encrypt_block_inplace() failed: %d", err); return err; diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 56fad33043d5..8d0e3ad89b94 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -314,7 +314,7 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs, gfp_t gfp_flags); int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, - u64 lblk_num, gfp_t gfp_flags); + u64 lblk_num); int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs); @@ -487,8 +487,7 @@ static inline struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, static inline int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, - unsigned int offs, u64 lblk_num, - gfp_t gfp_flags) + unsigned int offs, u64 lblk_num) { return -EOPNOTSUPP; } From fa65058063cbaba6e519b5291a7e2e9e0fa24ae3 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Jul 2025 23:07:53 -0700 Subject: [PATCH 9/9] ceph: Remove gfp_t argument from ceph_fscrypt_encrypt_*() This argument is no longer used, so remove it. Reviewed-by: Alex Markuze Link: https://lore.kernel.org/r/20250710060754.637098-7-ebiggers@kernel.org Signed-off-by: Eric Biggers --- fs/ceph/crypto.c | 10 ++++------ fs/ceph/crypto.h | 10 ++++------ fs/ceph/file.c | 3 +-- fs/ceph/inode.c | 3 +-- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 6d04d528ed03..91e62db0c205 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -516,8 +516,7 @@ int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, - unsigned int offs, u64 lblk_num, - gfp_t gfp_flags) + unsigned int offs, u64 lblk_num) { struct ceph_client *cl = ceph_inode_to_client(inode); @@ -641,9 +640,8 @@ int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page, * @page: pointer to page array * @off: offset into the file that the data starts * @len: max length to encrypt - * @gfp: gfp flags to use for allocation * - * Decrypt an array of cleartext pages and return the amount of + * Encrypt an array of cleartext pages and return the amount of * data encrypted. Any data in the page prior to the start of the * first complete block in the read is ignored. Any incomplete * crypto blocks at the end of the array are ignored. @@ -651,7 +649,7 @@ int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page, * Returns the length of the encrypted data or a negative errno. */ int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, - int len, gfp_t gfp) + int len) { int i, num_blocks; u64 baseblk = off >> CEPH_FSCRYPT_BLOCK_SHIFT; @@ -672,7 +670,7 @@ int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, fret = ceph_fscrypt_encrypt_block_inplace(inode, page[pgidx], CEPH_FSCRYPT_BLOCK_SIZE, pgoffs, - baseblk + i, gfp); + baseblk + i); if (fret < 0) { if (ret == 0) ret = fret; diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h index d0768239a1c9..6db28464ff80 100644 --- a/fs/ceph/crypto.h +++ b/fs/ceph/crypto.h @@ -155,15 +155,14 @@ int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, unsigned int offs, u64 lblk_num); int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, - unsigned int offs, u64 lblk_num, - gfp_t gfp_flags); + unsigned int offs, u64 lblk_num); int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page, u64 off, int len); int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page, u64 off, struct ceph_sparse_extent *map, u32 ext_cnt); int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, - int len, gfp_t gfp); + int len); static inline struct page *ceph_fscrypt_pagecache_page(struct page *page) { @@ -246,8 +245,7 @@ static inline int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode, static inline int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, - unsigned int offs, u64 lblk_num, - gfp_t gfp_flags) + unsigned int offs, u64 lblk_num) { return 0; } @@ -269,7 +267,7 @@ static inline int ceph_fscrypt_decrypt_extents(struct inode *inode, static inline int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off, - int len, gfp_t gfp) + int len) { return 0; } diff --git a/fs/ceph/file.c b/fs/ceph/file.c index a7254cab44cc..9b79da6d1aee 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1992,8 +1992,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, if (IS_ENCRYPTED(inode)) { ret = ceph_fscrypt_encrypt_pages(inode, pages, - write_pos, write_len, - GFP_KERNEL); + write_pos, write_len); if (ret < 0) { doutc(cl, "encryption failed with %d\n", ret); ceph_release_page_vector(pages, num_pages); diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 06cd2963e41e..fc543075b827 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -2436,8 +2436,7 @@ static int fill_fscrypt_truncate(struct inode *inode, /* encrypt the last block */ ret = ceph_fscrypt_encrypt_block_inplace(inode, page, CEPH_FSCRYPT_BLOCK_SIZE, - 0, block, - GFP_KERNEL); + 0, block); if (ret) goto out; }