fscrypt: Standardize on blk-crypto
Subsystems (8)
Eric Biggers
maintainerv3 cover fscrypt: Standardize on blk-crypto
This series applies to commit 2d0afaac9137e9 of
https://git.kernel.org/pub/scm/fs/fscrypt/linux.git/log/?h=for-next
It can also be retrieved from:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git/ fscrypt-blk-crypto-v3
Currently, ext4 and f2fs (i.e., the block-based filesystems with fscrypt support) have two file contents encryption implementations:
- Filesystem-layer, where code in fs/crypto/ directly invokes crypto_skcipher to en/decrypt data using the CPU. This implementation requires the management of bounce pages at the filesystem level. It doesn't support direct I/O or large folios.
- blk-crypto (also known as inline encryption), where the filesystem assigns bio_crypt_ctxs to bios, which are then processed either by the CPU using blk-crypto-fallback.c or by inline encryption hardware. This supports direct I/O and is compatible with large folios.
Currently, the latter implementation is enabled only when the "inlinecrypt" mount option is given.
The persistence of the fs-layer implementation is mainly for historical reasons, as it came first. It's becoming increasingly hard to maintain, especially as the filesystems get refactored to use iomap, large folios, etc. It's time to remove it and just rely on the similar code in blk-crypto-fallback. This series does that.
Some fs-layer encryption support remains in fs/crypto/ for non-block based filesystems (UBIFS and CephFS), as well as directories and symlinks. So it's not entirely gone, but it's reduced.
To be clear, this just changes an internal implementation detail. ext4 and f2fs continue to fully support encryption (fscrypt), regardless of the presence of inline encryption hardware on the system.
Changed in v3:
- Fixed bug in mpage_prepare_extent_to_map().
- Updated a couple other places in fscrypt.rst.
- Cleaned up outdated comments in {ext4,f2fs}_getattr().
- Removed an orphaned function prototype.
- Fixed accidental removal of @key_type kerneldoc.
Changed in v2:
- Replaced the allow_hw bool with a flags argument.
- Added patch "Documentation: fscrypt: Update docs for inlinecrypt" which updates the documentation more completely by updating not just fscrypt.rst (which was previously part of another patch), but also the documentation for inlinecrypt in ext4.rst and f2fs.rst.
- Removed extern from declarations of ext4_init_verity_caches() and ext4_exit_verity_caches()
- Remove unused 'inode' argument from ext4_set_verity_work()
- Added Reviewed-by tags
Eric Biggers (17):
blk-crypto: Simplify check for fallback support
blk-crypto: Fold __blk_crypto_cfg_supported() into its caller
blk-crypto: Allow control over whether hardware is used
fscrypt: Fully disallow IV_INO_LBLK_32 with s_blocksize != PAGE_SIZE
fscrypt: Always use blk-crypto for contents on block-based filesystems
Documentation: fscrypt: Update docs for inlinecrypt
ext4: Remove fs-layer file contents en/decryption code
ext4: Make ext4_bio_write_folio() return void
ext4: Further de-generalize the bio postprocessing code
f2fs: Remove fs-layer file contents en/decryption code fs/buffer: Remove fs-layer decryption code
fscrypt: Replace calls to fscrypt_inode_uses_inline_crypto()
fscrypt: Remove fscrypt_dio_supported()
fscrypt: Remove fs-layer zeroout code
fscrypt: Remove unused functions and workqueue
fscrypt: Merge bio.c and inline_crypt.c into block.c
fscrypt: Add safety checks to non-block-based en/decryption
Documentation/admin-guide/ext4.rst | 8 +-
Documentation/filesystems/f2fs.rst | 10 +-
Documentation/filesystems/fscrypt.rst | 58 ++--
arch/loongarch/configs/loongson32_defconfig | 1 -
arch/loongarch/configs/loongson64_defconfig | 1 -
block/blk-crypto-fallback.c | 3 +-
block/blk-crypto-internal.h | 3 -
block/blk-crypto-profile.c | 22 --
block/blk-crypto.c | 34 ++-
drivers/md/dm-inlinecrypt.c | 3 +-
fs/buffer.c | 45 +---
fs/crypto/Kconfig | 8 +-
fs/crypto/Makefile | 3 +-
fs/crypto/bio.c | 216 ---------------
fs/crypto/{inline_crypt.c => block.c} | 284 ++++++++++----------
fs/crypto/crypto.c | 140 ++++------
fs/crypto/fscrypt_private.h | 28 +-
fs/crypto/keysetup.c | 31 +--
fs/crypto/policy.c | 17 ++
fs/ext4/crypto.c | 2 +-
fs/ext4/ext4.h | 6 +-
fs/ext4/inode.c | 71 +----
fs/ext4/page-io.c | 74 +----
fs/ext4/readpage.c | 139 +++-------
fs/ext4/super.c | 6 +-
fs/f2fs/compress.c | 31 +--
fs/f2fs/data.c | 93 +------
fs/f2fs/f2fs.h | 2 -
fs/f2fs/file.c | 6 +-
fs/f2fs/segment.c | 2 -
fs/f2fs/super.c | 2 +-
include/linux/blk-crypto.h | 13 +-
include/linux/fscrypt.h | 96 ++-----
33 files changed, 387 insertions(+), 1071 deletions(-)
delete mode 100644 fs/crypto/bio.c
rename fs/crypto/{inline_crypt.c => block.c} (61%)base-commit: 2d0afaac9137e95e504bd3ad3512a9044745536b
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 1/17 blk-crypto: Simplify check for fallback support
Since blk-crypto-fallback supports all blk_crypto_keys except wrapped keys, just check for that condition directly instead of using __blk_crypto_cfg_supported(). With this done, __blk_crypto_cfg_supported() is now used only for the hardware support.
--- block/blk-crypto-fallback.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
block/blk-crypto-fallback.c +1 -2
@@ -496,8 +496,7 @@ bool blk_crypto_fallback_bio_prep(struct bio *bio)return false; } -if (!__blk_crypto_cfg_supported (blk_crypto_fallback_profile, - &bc->bc_key->crypto_cfg)) { +if (bc->bc_key->crypto_cfg.key_type !=BLK_CRYPTO_KEY_TYPE_RAW ) {bio_endio_status (bio,BLK_STS_NOTSUPP );return false; }
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 2/17 blk-crypto: Fold __blk_crypto_cfg_supported() into its caller
In reply to Eric Biggers__blk_crypto_cfg_supported() is called only by blk_crypto_config_supported_natively(), so fold it in.
--- block/blk-crypto-internal.h | 3 --- block/blk-crypto-profile.c | 22 ---------------------- block/blk-crypto.c | 23 +++++++++++++++++++++-- 3 files changed, 21 insertions(+), 27 deletions(-)
block/blk-crypto-internal.h +0 -3
@@ -80,9 +80,6 @@ void blk_crypto_put_keyslot(struct blk_crypto_keyslot *slot);int __blk_crypto_evict_key (struct blk_crypto_profile *profile,const struct blk_crypto_key *key); -bool __blk_crypto_cfg_supported (struct blk_crypto_profile *profile, -const struct blk_crypto_config *cfg); -int blk_crypto_ioctl (struct block_device *bdev,unsigned int cmd,void __user *argp);
block/blk-crypto-profile.c +0 -22
@@ -335,28 +335,6 @@ void blk_crypto_put_keyslot(struct blk_crypto_keyslot *slot) } } -/** -* __blk_crypto_cfg_supported() - Check whether the given crypto profile -* supports the given crypto configuration. -* @profile: the crypto profile to check -* @cfg: the crypto configuration to check for -* -* Return: %true if @profile supports the given @cfg. -*/ -bool __blk_crypto_cfg_supported (struct blk_crypto_profile *profile, -const struct blk_crypto_config *cfg) -{ -if (!profile) -return false; -if (!(profile->modes_supported[cfg->crypto_mode] & cfg->data_unit_size)) -return false; -if (profile->max_dun_bytes_supported < cfg->dun_bytes) -return false; -if (!(profile->key_types_supported & cfg->key_type)) -return false; -return true; -} -/* * This is an internal function that evicts a key from an inline encryption * device that can be either a real device or the blk-crypto-fallback "device".
block/blk-crypto.c +21 -2
@@ -351,11 +351,30 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, }EXPORT_SYMBOL_GPL (blk_crypto_init_key); +/** +* blk_crypto_config_supported_natively() - Check whether a block device +* supports hardware inline encryption +* with the given configuration. +* @bdev: the block device +* @cfg: the crypto configuration to check for +* +* Return: %true if @bdev supports hardware inline encryption with @cfg. +*/ bool blk_crypto_config_supported_natively (struct block_device *bdev,const struct blk_crypto_config *cfg) { -return __blk_crypto_cfg_supported (bdev_get_queue (bdev)->crypto_profile, - cfg); +struct blk_crypto_profile *profile = +bdev_get_queue (bdev)->crypto_profile; + +if (!profile) +return false; +if (!(profile->modes_supported[cfg->crypto_mode] & cfg->data_unit_size)) +return false; +if (profile->max_dun_bytes_supported < cfg->dun_bytes) +return false; +if (!(profile->key_types_supported & cfg->key_type)) +return false; +return true; }/*
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 3/17 blk-crypto: Allow control over whether hardware is used
In reply to Eric Biggersfscrypt uses inline encryption hardware only when the "inlinecrypt" mount option is given. I'd like to keep that behavior even after standardizing on the blk-crypto API for file contents encryption. That is, the default should continue to be the well-tested CPU-based encryption code, and the use of inline encryption hardware should continue to be an opt-in feature for systems where it's beneficial and has been fully validated (including verifying ciphertext correctness).
To support this use case, extend blk_crypto_config with a new flag BLK_CRYPTO_CFG_ALLOW_HW.
For now it's always set. Later commits will change that.
--- block/blk-crypto.c | 11 ++++++++++- drivers/md/dm-inlinecrypt.c | 3 ++- fs/crypto/inline_crypt.c | 4 +++- include/linux/blk-crypto.h | 13 ++++++++++++- 4 files changed, 27 insertions(+), 4 deletions(-)
block/blk-crypto.c +10 -1
@@ -300,6 +300,7 @@ int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio,* @dun_bytes: number of bytes that will be used to specify the DUN when this * key is used * @data_unit_size: the data unit size to use for en/decryption +* @flags: BLK_CRYPTO_CFG_* flags * * Return: 0 on success, -errno on failure. The caller is responsible for * zeroizing both blk_key and key_bytes when done with them.
@@ -309,7 +310,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key,enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size) + unsigned int data_unit_size, int flags) { const struct blk_crypto_mode *mode;
@@ -318,6 +319,9 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key,if (crypto_mode >=ARRAY_SIZE (blk_crypto_modes))return -EINVAL ; +if (flags & ~BLK_CRYPTO_CFG_ALLOW_HW ) +return -EINVAL ; + mode = &blk_crypto_modes[crypto_mode];switch (key_type) {case BLK_CRYPTO_KEY_TYPE_RAW :
@@ -328,6 +332,8 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key,if (key_size < mode->security_strength || key_size >BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE )return -EINVAL ; +if (!(flags &BLK_CRYPTO_CFG_ALLOW_HW )) +return -EINVAL ;break ;default :return -EINVAL ;
@@ -343,6 +349,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, blk_key->crypto_cfg.dun_bytes = dun_bytes; blk_key->crypto_cfg.data_unit_size = data_unit_size; blk_key->crypto_cfg.key_type = key_type; + blk_key->crypto_cfg.flags = flags; blk_key->data_unit_size_bits =ilog2 (data_unit_size); blk_key->size = key_size;memcpy (blk_key->bytes, key_bytes, key_size);
@@ -368,6 +375,8 @@ bool blk_crypto_config_supported_natively(struct block_device *bdev,if (!profile)return false; +if (!(cfg->flags &BLK_CRYPTO_CFG_ALLOW_HW )) +return false;if (!(profile->modes_supported[cfg->crypto_mode] & cfg->data_unit_size))return false;if (profile->max_dun_bytes_supported < cfg->dun_bytes)
drivers/md/dm-inlinecrypt.c +2 -1
@@ -406,7 +406,8 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) err =blk_crypto_init_key (&ctx->key, key_bytes, ctx->key_size, ctx->key_type, cipher->mode_num, - dun_bytes, ctx->sector_size); + dun_bytes, ctx->sector_size, +BLK_CRYPTO_CFG_ALLOW_HW );if (err) { ti->error ="Error initializing blk-crypto key" ; goto bad;
fs/crypto/inline_crypt.c +3 -1
@@ -134,6 +134,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci, crypto_cfg.dun_bytes =fscrypt_get_dun_bytes (ci); crypto_cfg.key_type = is_hw_wrapped_key ?BLK_CRYPTO_KEY_TYPE_HW_WRAPPED :BLK_CRYPTO_KEY_TYPE_RAW ; + crypto_cfg.flags =BLK_CRYPTO_CFG_ALLOW_HW ; devs =fscrypt_get_devices (sb, &num_devs);if (IS_ERR (devs))
@@ -175,7 +176,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, err =blk_crypto_init_key (blk_key, key_bytes, key_size, key_type, crypto_mode,fscrypt_get_dun_bytes (ci), -1U << ci->ci_data_unit_bits); +1U << ci->ci_data_unit_bits, +BLK_CRYPTO_CFG_ALLOW_HW );if (err) {fscrypt_err (inode,"error %d initializing blk-crypto key" , err); goto fail;
include/linux/blk-crypto.h +12 -1
@@ -68,6 +68,15 @@ enum blk_crypto_key_type {*/ #define BLK_CRYPTO_SW_SECRET_SIZE 32 +/* Flags for blk_crypto_config::flags: */ + +/* +* If set, inline encryption hardware will be used if available. +* If unset, CPU-based encryption will always be used (requires +* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) +*/ +#define BLK_CRYPTO_CFG_ALLOW_HW (1 << 0) +/** * struct blk_crypto_config - an inline encryption key's crypto configuration * @crypto_mode: encryption algorithm this key is for
@@ -77,12 +86,14 @@ enum blk_crypto_key_type {* filesystem block size or the disk sector size. * @dun_bytes: the maximum number of bytes of DUN used when using this key * @key_type: the type of this key -- either raw or hardware-wrapped +* @flags: BLK_CRYPTO_CFG_* flags */ struct blk_crypto_config {enum blk_crypto_mode_num crypto_mode;unsigned int data_unit_size;unsigned int dun_bytes;enum blk_crypto_key_type key_type; +int flags; };/**
@@ -150,7 +161,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key,enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size); + unsigned int data_unit_size, int flags);int blk_crypto_start_using_key (struct block_device *bdev,const struct blk_crypto_key *key);
Signature · 1 line
2.55.0
Re: [PATCH v3 03/17] blk-crypto: Allow control over whether hardware is used
Looks good:
Eric Biggers
maintainerPATCH v3 4/17 fscrypt: Fully disallow IV_INO_LBLK_32 with s_blocksize != PAGE_SIZE
In reply to Eric BiggersFSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 with s_blocksize != PAGE_SIZE works only with the fs-layer implementation of file contents encryption, not blk-crypto. This is a problem for standardizing on blk-crypto.
Fortunately, no one should be using this combination anyway. It doesn't make sense because the entire point of IV_INO_LBLK_32 is to support inline encryption hardware that is limited to 32-bit DUNs.
Thus, fully disallow IV_INO_LBLK_32 with s_blocksize != PAGE_SIZE.
--- Documentation/filesystems/fscrypt.rst | 3 +++ fs/crypto/inline_crypt.c | 13 ------------- fs/crypto/policy.c | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 13 deletions(-)
Documentation/filesystems/fscrypt.rst +3 -0
@@ -336,6 +336,9 @@ per I/O request and may have only a small number of keyslots. This format results in some level of IV reuse, so it should only be used when necessary due to hardware limitations. +IV_INO_LBLK_32 is supported only when the filesystem block size is +equal to the page size. + Key identifiers ---------------
fs/crypto/inline_crypt.c +0 -13
@@ -112,19 +112,6 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci,if (!(sb->s_flags &SB_INLINECRYPT ))return 0 ; -/* -* When a page contains multiple logically contiguous filesystem blocks, -* some filesystem code only calls fscrypt_mergeable_bio() for the first -* block in the page. This is fine for most of fscrypt's IV generation -* strategies, where contiguous blocks imply contiguous IVs. But it -* doesn't work with IV_INO_LBLK_32. For now, simply exclude -* IV_INO_LBLK_32 with blocksize != PAGE_SIZE from inline encryption. -*/ -if ((fscrypt_policy_flags (&ci->ci_policy) & -FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 ) && - sb->s_blocksize !=PAGE_SIZE ) -return 0 ; -/* * On all the filesystem's block devices, blk-crypto must support the * crypto configuration that the file would use.
fs/crypto/policy.c +17 -0
@@ -177,6 +177,23 @@ static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy, type, sb->s_id);return false; } + +/* +* IV_INO_LBLK_32 isn't compatible with inline encryption when +* s_blocksize != PAGE_SIZE. In that case the DUN can wrap around in +* the middle of a page, but sometimes fscrypt_mergeable_bio() is called +* only for the first block per page. Since IV_INO_LBLK_32 exists only +* to support inline encryption hardware that is limited to 32-bit DUNs, +* just disallow IV_INO_LBLK_32 with s_blocksize != PAGE_SIZE entirely. +*/ +if ((policy->flags &FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 ) && + sb->s_blocksize !=PAGE_SIZE ) { +fscrypt_warn (inode, +"Can't use %s policy on filesystem '%s' with block size != PAGE_SIZE" , + type, sb->s_id); +return false; + } +return true; }
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 5/17 fscrypt: Always use blk-crypto for contents on block-based filesystems
In reply to Eric BiggersFor encrypting and decrypting file contents on block-based filesystems (i.e., ext4 and f2fs, but not ceph and ubifs), always use blk-crypto instead of fs-layer crypto (direct use of crypto_skcipher).
Since the blk-crypto API provides a fallback to CPU-based encryption, it's all that's needed on block-based filesystems. The support for two alternative block-based file contents encryption implementations, fs-layer and blk-crypto, existed mainly for historical reasons, as the fs-layer path came first. Some of it is also still needed for the non-block-based filesystems, but a lot of it isn't.
Removing the duplicate fs-layer code paths greatly simplifies the code, most of which is done in later commits.
Specific implementation details:
- SB_INLINECRYPT now controls whether blk_crypto_config::allow_hw is set to true, instead of whether blk-crypto is used at all. The effect is that the semantics are preserved: the inlinecrypt mount option selects the use of inline encryption hardware instead of the CPU.
- Set up a blk_crypto_key iff the file is a regular file on a block-based filesystem. To determine whether the filesystem is block-based, add a bit fscrypt_operations::is_block_based.
- Remove fscrypt_select_encryption_impl(). Move the logging logic that was previously there into fscrypt_prepare_inline_crypt_key(). Note that blk_crypto_config_supported() is no longer needed.
--- arch/loongarch/configs/loongson32_defconfig | 1 - arch/loongarch/configs/loongson64_defconfig | 1 - fs/crypto/Kconfig | 8 +- fs/crypto/fscrypt_private.h | 21 +--- fs/crypto/inline_crypt.c | 110 ++++++-------------- fs/crypto/keysetup.c | 31 +----- fs/ext4/crypto.c | 1 + fs/f2fs/super.c | 1 + include/linux/fscrypt.h | 28 ++--- 9 files changed, 57 insertions(+), 145 deletions(-)
arch/loongarch/configs/loongson32_defconfig +0 -1
@@ -969,7 +969,6 @@ CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_CHECK_FS=y CONFIG_F2FS_FS_COMPRESSION=y CONFIG_FS_ENCRYPTION=y -CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_FS_VERITY=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
arch/loongarch/configs/loongson64_defconfig +0 -1
@@ -1000,7 +1000,6 @@ CONFIG_F2FS_FS_SECURITY=y CONFIG_F2FS_CHECK_FS=y CONFIG_F2FS_FS_COMPRESSION=y CONFIG_FS_ENCRYPTION=y -CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_FS_VERITY=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
fs/crypto/Kconfig +4 -4
@@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only config FS_ENCRYPTION bool "FS Encryption (Per-file encryption)" + select BLK_INLINE_ENCRYPTION if BLOCK + select BLK_INLINE_ENCRYPTION_FALLBACK if BLOCK select CRYPTO select CRYPTO_SKCIPHER select CRYPTO_LIB_AES
@@ -34,7 +36,5 @@ config FS_ENCRYPTION_ALGS select CRYPTO_XTS config FS_ENCRYPTION_INLINE_CRYPT - bool "Enable fscrypt to use inline crypto" - depends on FS_ENCRYPTION && BLK_INLINE_ENCRYPTION - help - Enable fscrypt to use inline encryption hardware if available. + bool + default y if FS_ENCRYPTION && BLOCK
fs/crypto/fscrypt_private.h +3 -18
@@ -266,14 +266,6 @@ struct fscrypt_inode_info {/* True if ci_enc_key should be freed when this struct is freed */ u8 ci_owns_key : 1; -#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT -/* -* True if this inode will use inline encryption (blk-crypto) instead of -* the traditional filesystem-layer encryption. -*/ - u8 ci_inlinecrypt : 1; -#endif -/* True if ci_dirhash_key is initialized */ u8 ci_dirhash_key_initialized : 1;
@@ -410,13 +402,12 @@ void fscrypt_hkdf_expand(const struct hmac_sha512_key *hkdf, u8 context,/* inline_crypt.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT -int fscrypt_select_encryption_impl (struct fscrypt_inode_info *ci, -bool is_hw_wrapped_key); -static inline bool fscrypt_using_inline_encryption (const struct fscrypt_inode_info *ci) { -return ci->ci_inlinecrypt; +const struct inode *inode = ci->ci_inode; + +return S_ISREG (inode->i_mode) && inode->i_sb->s_cop->is_block_based; } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
@@ -446,12 +437,6 @@ fscrypt_is_key_prepared(const struct fscrypt_prepared_key *prep_key,#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ -static inline int fscrypt_select_encryption_impl (struct fscrypt_inode_info *ci, -bool is_hw_wrapped_key) -{ -return 0 ; -} -static inline bool fscrypt_using_inline_encryption (const struct fscrypt_inode_info *ci) {
fs/crypto/inline_crypt.c +33 -77
155 lines not on this page · raw message
fs/crypto/keysetup.c +4 -27
@@ -144,9 +144,9 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key,/* * Prepare the crypto transform object or blk-crypto key in @prep_key, given the -* raw key, encryption mode (@ci->ci_mode), flag indicating which encryption -* implementation (fs-layer or blk-crypto) will be used (@ci->ci_inlinecrypt), -* and IV generation method (@ci->ci_policy.flags). +* raw key, encryption mode (@ci->ci_mode), predicate indicating which style of +* key is needed (fscrypt_using_inline_encryption(ci)), IV generation method +* (@ci->ci_policy.flags), and data unit size (@ci->ci_data_unit_bits). */ int fscrypt_prepare_key (struct fscrypt_prepared_key *prep_key,const u8 *raw_key,const struct fscrypt_inode_info *ci)
@@ -224,23 +224,8 @@ static int setup_per_mode_enc_key(struct fscrypt_inode_info *ci,u8 raw_mode_key[FSCRYPT_MAX_RAW_KEY_SIZE ];u8 hkdf_info[sizeof (mode_num) +sizeof (sb->s_uuid)];unsigned int hkdf_infolen =0 ; -bool use_hw_wrapped_key = false;int err; -if (mk->mk_secret.is_hw_wrapped &&S_ISREG (inode->i_mode)) { -/* Using a hardware-wrapped key for file contents encryption */ -if (!fscrypt_using_inline_encryption (ci)) { -if (sb->s_flags &SB_INLINECRYPT ) -fscrypt_warn (ci->ci_inode, -"Hardware-wrapped key required, but no suitable inline encryption capabilities are available" ); -else -fscrypt_warn (ci->ci_inode, -"Hardware-wrapped keys require inline encryption (-o inlinecrypt)" ); -return -EINVAL ; - } - use_hw_wrapped_key = true; - } - prep_key =fscrypt_find_mode_key (mk, hkdf_context, mode_num, ci);if (prep_key) { ci->ci_enc_key = *prep_key;
@@ -263,7 +248,7 @@ static int setup_per_mode_enc_key(struct fscrypt_inode_info *ci, new_node->data_unit_bits = ci->ci_data_unit_bits; prep_key = &new_node->key; -if (use_hw_wrapped_key) { +if (mk->mk_secret.is_hw_wrapped &&S_ISREG (inode->i_mode)) { err = fscrypt_prepare_inline_crypt_key(prep_key, mk->mk_secret.bytes, mk->mk_secret.size, true,
@@ -509,10 +494,6 @@ static int setup_file_encryption_key(struct fscrypt_inode_info *ci,if (ci->ci_policy.version !=FSCRYPT_POLICY_V1 )return -ENOKEY ; - err =fscrypt_select_encryption_impl (ci, false); -if (err) -return err; -/* * As a legacy fallback for v1 policies, search for the key in * the current task's subscribed keyrings too. Don't move this
@@ -534,10 +515,6 @@ static int setup_file_encryption_key(struct fscrypt_inode_info *ci, goto out_release_key; } - err =fscrypt_select_encryption_impl (ci, mk->mk_secret.is_hw_wrapped); -if (err) - goto out_release_key; -switch (ci->ci_policy.version) {case FSCRYPT_POLICY_V1 :if (WARN_ON_ONCE (mk->mk_secret.is_hw_wrapped)) {
fs/ext4/crypto.c +1 -0
@@ -236,6 +236,7 @@ static bool ext4_has_stable_inodes(struct super_block *sb)const struct fscrypt_operations ext4_cryptops = { .inode_info_offs = (int )offsetof(struct ext4_inode_info , i_crypt_info) - (int )offsetof(struct ext4_inode_info , vfs_inode), + .is_block_based =1 , .needs_bounce_pages =1 , .has_32bit_inodes =1 , .supports_subblock_data_units =1 ,
fs/f2fs/super.c +1 -0
@@ -3772,6 +3772,7 @@ static struct block_device **f2fs_get_devices(struct super_block *sb,static const struct fscrypt_operations f2fs_cryptops = { .inode_info_offs = (int )offsetof(struct f2fs_inode_info , i_crypt_info) - (int )offsetof(struct f2fs_inode_info , vfs_inode), + .is_block_based =1 , .needs_bounce_pages =1 , .has_32bit_inodes =1 , .supports_subblock_data_units =1 ,
include/linux/fscrypt.h +11 -17
@@ -69,14 +69,15 @@ struct fscrypt_operations {ptrdiff_t inode_info_offs;/* -* If set, then fs/crypto/ will allocate a global bounce page pool the -* first time an encryption key is set up for a file. The bounce page -* pool is required by the following functions: -* -* - fscrypt_encrypt_pagecache_blocks() -* - fscrypt_zeroout_range() for files not using inline crypto -* -* If the filesystem doesn't use those, it doesn't need to set this. +* Set to 1 if the filesystem is block-based. This causes fs/crypto/ to +* set up the key for regular files as a blk_crypto_key. The filesystem +* then uses fscrypt_set_bio_crypt_ctx() and similar functions. +*/ + unsigned int is_block_based : 1; + +/* +* Set to 1 if the filesystem uses fscrypt_encrypt_pagecache_blocks(). +* This enables the allocation of the bounce page pool it requires. */ unsigned int needs_bounce_pages : 1;
@@ -863,8 +864,6 @@ static inline void fscrypt_set_ops(struct super_block *sb,/* inline_crypt.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT -bool __fscrypt_inode_uses_inline_crypto (const struct inode *inode); -void fscrypt_set_bio_crypt_ctx (struct bio *bio,const struct inode *inode,loff_t pos,gfp_t gfp_mask);
@@ -877,11 +876,6 @@ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks);#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ -static inline bool __fscrypt_inode_uses_inline_crypto (const struct inode *inode) -{ -return false; -} -static inline void fscrypt_set_bio_crypt_ctx (struct bio *bio,const struct inode *inode,loff_t pos,gfp_t gfp_mask) { }
@@ -917,7 +911,7 @@ static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk,static inline bool fscrypt_inode_uses_inline_crypto (const struct inode *inode) {return fscrypt_needs_contents_encryption (inode) && -__fscrypt_inode_uses_inline_crypto (inode); + inode->i_sb->s_cop->is_block_based; }/**
@@ -932,7 +926,7 @@ static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode)static inline bool fscrypt_inode_uses_fs_layer_crypto (const struct inode *inode) {return fscrypt_needs_contents_encryption (inode) && - !__fscrypt_inode_uses_inline_crypto (inode); + !inode->i_sb->s_cop->is_block_based; }/**
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 6/17 Documentation: fscrypt: Update docs for inlinecrypt
In reply to Eric BiggersUpdate the documentation for the inlinecrypt mount option to reflect that it's now just about the choice of whether to use inline encryption hardware, not whether the blk-crypto framework is used.
Also remove an outdated statement about the data unit size, and make the ext4 and f2fs docs reference the fscrypt docs rather than the block layer docs directly.
--- Documentation/admin-guide/ext4.rst | 8 ++-- Documentation/filesystems/f2fs.rst | 10 ++--- Documentation/filesystems/fscrypt.rst | 55 ++++++++++----------------- 3 files changed, 28 insertions(+), 45 deletions(-)
Documentation/admin-guide/ext4.rst +3 -5
@@ -385,11 +385,9 @@ When mounting an ext4 filesystem, the following option are accepted: incompatible with data=journal. inlinecrypt - When possible, encrypt/decrypt the contents of encrypted files using the - blk-crypto framework rather than filesystem-layer encryption. This - allows the use of inline encryption hardware. The on-disk format is - unaffected. For more details, see - Documentation/block/inline-encryption.rst. + When possible, encrypt/decrypt the contents of encrypted files using + inline encryption hardware rather than the CPU. For more details, see + Documentation/filesystems/fscrypt.rst. Data Mode =========
Documentation/filesystems/f2fs.rst +4 -6
@@ -351,12 +351,10 @@ compress_mode=%s Control file compression mode. This supports "fs" and "user" compress_cache Support to use address space of a filesystem managed inode to cache compressed block, in order to improve cache hit ratio of random read. -inlinecrypt When possible, encrypt/decrypt the contents of encrypted - files using the blk-crypto framework rather than - filesystem-layer encryption. This allows the use of - inline encryption hardware. The on-disk format is - unaffected. For more details, see - Documentation/block/inline-encryption.rst. +inlinecrypt When possible, encrypt/decrypt the contents of + encrypted files using inline encryption hardware rather + than the CPU. For more details, see + Documentation/filesystems/fscrypt.rst. atgc Enable age-threshold garbage collection, it provides high effectiveness and efficiency on background GC. discard_unit=%s Control discard unit, the argument can be "block", "segment"
Documentation/filesystems/fscrypt.rst +21 -34
88 lines not on this page · raw message
Signature · 1 line
2.55.0
Re: [PATCH v3 06/17] Documentation: fscrypt: Update docs for inlinecrypt
Looks good:
Eric Biggers
maintainerPATCH v3 7/17 ext4: Remove fs-layer file contents en/decryption code
In reply to Eric BiggersNow that fscrypt's file contents en/decryption is always implemented using blk-crypto when the filesystem is block-based, the fs-layer en/decryption code in ext4 is unused code. Remove it.
Note that this makes possible some additional cleanups, but they're left to later commits:
- Making ext4_bio_write_folio() return void
- Renaming bio_post_read_ctx to fsverity_ctx or similar, and allocating the pool only when fsverity support is needed
--- fs/ext4/crypto.c | 1 - fs/ext4/inode.c | 28 ++-------------- fs/ext4/page-io.c | 68 ++------------------------------------- fs/ext4/readpage.c | 80 ++++------------------------------------------ 4 files changed, 13 insertions(+), 164 deletions(-)
fs/ext4/crypto.c +0 -1
@@ -237,7 +237,6 @@ const struct fscrypt_operations ext4_cryptops = { .inode_info_offs = (int)offsetof(struct ext4_inode_info, i_crypt_info) - (int)offsetof(struct ext4_inode_info, vfs_inode), .is_block_based = 1, - .needs_bounce_pages = 1, .has_32bit_inodes = 1, .supports_subblock_data_units = 1, .legacy_key_prefix = "ext4:",
fs/ext4/inode.c +3 -25
@@ -1262,17 +1262,6 @@ int ext4_block_write_begin(handle_t *handle, struct folio *folio, from, to); elsefolio_zero_new_buffers (folio ,from ,to ); - }else if (fscrypt_inode_uses_fs_layer_crypto (inode)) { -for (i =0 ; i < nr_wait; i++) { -int err2; - - err2 =fscrypt_decrypt_pagecache_blocks (folio, - blocksize,bh_offset (wait[i])); -if (err2) { -clear_buffer_uptodate (wait[i]); - err = err2; - } - } }return err;
@@ -3829,9 +3818,9 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,return ret; out:/* -* When inline encryption is enabled, sometimes I/O to an encrypted file -* has to be broken up to guarantee DUN contiguity. Handle this by -* limiting the length of the mapping returned. +* Sometimes I/O to an encrypted file has to be broken up to guarantee +* DUN contiguity. Handle this by limiting the length of the mapping +* returned. */ map.m_len =fscrypt_limit_io_blocks (inode, map.m_lblk, map.m_len);
@@ -4081,17 +4070,6 @@ static struct buffer_head *ext4_load_tail_bh(struct inode *inode, loff_t from) err =ext4_read_bh_lock (bh,0 , true);if (err) goto unlock; -if (fscrypt_inode_uses_fs_layer_crypto (inode)) { -/* We expect the key to be set. */ -BUG_ON (!fscrypt_has_encryption_key (inode)); - err =fscrypt_decrypt_pagecache_blocks (folio, - blocksize, -bh_offset (bh)); -if (err) { -clear_buffer_uptodate (bh); - goto unlock; - } - } }return bh;
fs/ext4/page-io.c +3 -65
120 lines not on this page · raw message
fs/ext4/readpage.c +7 -73
129 lines not on this page · raw message
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 8/17 ext4: Make ext4_bio_write_folio() return void
In reply to Eric BiggersSince the fs-layer file contents encryption implementation was removed, ext4_bio_write_folio() now always returns 0. Change it to return void, and likewise for its caller mpage_submit_folio().
--- fs/ext4/ext4.h | 2 +- fs/ext4/inode.c | 32 +++++++++----------------------- fs/ext4/page-io.c | 6 ++---- 3 files changed, 12 insertions(+), 28 deletions(-)
fs/ext4/ext4.h +1 -1
@@ -3945,7 +3945,7 @@ extern void ext4_io_submit_init(struct ext4_io_submit *io, struct writeback_control *wbc);extern void ext4_end_io_rsv_work (struct work_struct *work);extern void ext4_io_submit (struct ext4_io_submit *io); -int ext4_bio_write_folio (struct ext4_io_submit *io,struct folio *page, +void ext4_bio_write_folio (struct ext4_io_submit *io,struct folio *page,size_t len);extern struct ext4_io_end_vec *ext4_alloc_io_end_vec (ext4_io_end_t *io_end);extern struct ext4_io_end_vec *ext4_last_io_end_vec (ext4_io_end_t *io_end);
fs/ext4/inode.c +9 -23
@@ -2064,11 +2064,10 @@ static void mpage_folio_done(struct mpage_da_data *mpd, struct folio *folio)folio_unlock (folio); } -static int mpage_submit_folio (struct mpage_da_data *mpd,struct folio *folio) +static void mpage_submit_folio (struct mpage_da_data *mpd,struct folio *folio) {size_t len;loff_t size; -int err;WARN_ON_ONCE (folio_pos (folio) != mpd->start_pos);folio_clear_dirty_for_io (folio);
@@ -2090,9 +2089,7 @@ static int mpage_submit_folio(struct mpage_da_data *mpd, struct folio *folio)if (folio_pos (folio) + len > size && !ext4_verity_in_progress (mpd->inode)) len = size & (len -1 ); - err =ext4_bio_write_folio (&mpd->io_submit, folio, len); - -return err; +ext4_bio_write_folio (&mpd->io_submit, folio, len); }#define BH_FLAGS (BIT(BH_Unwritten) | BIT(BH_Delay))
@@ -2169,8 +2166,7 @@ static bool mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk,* accumulated extent of buffers to map or add buffers in the page to the * extent of buffers to map. The function returns 1 if the caller can continue * by processing the next page, 0 if it should stop adding buffers to the -* extent to map because we cannot extend it anymore. It can also return value -* < 0 in case of error during IO submission. +* extent to map because we cannot extend it anymore. */ static int mpage_process_page_bufs(struct mpage_da_data *mpd, struct buffer_head *head,
@@ -2178,7 +2174,6 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd, ext4_lblk_t lblk) {struct inode *inode = mpd->inode; -int err;ext4_lblk_t blocks = (i_size_read (inode) +i_blocksize (inode) -1 ) >> inode->i_blkbits;
@@ -2201,9 +2196,7 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd, }while (lblk++, (bh = bh->b_this_page) != head);/* So far everything mapped? Submit the page for IO. */ if (mpd->map.m_len ==0 ) { - err =mpage_submit_folio (mpd, head->b_folio); -if (err <0 ) -return err; +mpage_submit_folio (mpd, head->b_folio);mpage_folio_done (mpd, head->b_folio); }if (lblk >= blocks) {
@@ -2333,9 +2326,7 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)if (err <0 || map_bh) goto out;/* Page fully mapped - let IO run! */ - err =mpage_submit_folio (mpd, folio); -if (err <0 ) - goto out; +mpage_submit_folio (mpd, folio);mpage_folio_done (mpd, folio); }folio_batch_release (&fbatch);
@@ -2408,7 +2399,6 @@ static int mpage_submit_partial_folio(struct mpage_da_data *mpd)struct inode *inode = mpd->inode;struct folio *folio;loff_t pos; -int ret; folio =filemap_get_folio (inode->i_mapping, mpd->start_pos >>PAGE_SHIFT );
@@ -2423,9 +2413,7 @@ static int mpage_submit_partial_folio(struct mpage_da_data *mpd) !folio_contains(folio, pos >> PAGE_SHIFT)))return -EINVAL ; - ret =mpage_submit_folio (mpd, folio); -if (ret) - goto out; +mpage_submit_folio (mpd, folio);/* * Update start_pos to prevent this folio from being released in * mpage_release_unused_pages(), it will be reset to the aligned folio
@@ -2434,10 +2422,9 @@ static int mpage_submit_partial_folio(struct mpage_da_data *mpd)* entire folio has finished processing. */ mpd->start_pos = pos; -out:folio_unlock (folio);folio_put (folio); -return ret; +return 0 ; }/*
@@ -2724,9 +2711,8 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)* through a pin. */ if (!mpd->can_map) { - err =mpage_submit_folio (mpd, folio); -if (err <0 ) - goto out; +mpage_submit_folio (mpd, folio); + err =0 ;/* Pending dirtying of journalled data? */ if (folio_test_checked (folio)) { err = mpage_journal_page_buffers(handle,
fs/ext4/page-io.c +2 -4
@@ -459,7 +459,7 @@ static void io_submit_add_bh(struct ext4_io_submit *io, io->io_next_block++; } -int ext4_bio_write_folio (struct ext4_io_submit *io,struct folio *folio, +void ext4_bio_write_folio (struct ext4_io_submit *io,struct folio *folio,size_t len) {struct inode *inode = folio->mapping->host;
@@ -533,7 +533,7 @@ int ext4_bio_write_folio(struct ext4_io_submit *io, struct folio *folio,*/ __folio_start_writeback (folio, keep_towrite);folio_end_writeback (folio); -return 0 ; +return ; } bh = head =folio_buffers (folio);
@@ -546,6 +546,4 @@ int ext4_bio_write_folio(struct ext4_io_submit *io, struct folio *folio,continue ;io_submit_add_bh (io, inode, folio, bh); }while ((bh = bh->b_this_page) != head); - -return 0 ; }
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 9/17 ext4: Further de-generalize the bio postprocessing code
In reply to Eric BiggersSince the bio postprocessing code in fs/ext4/readpage.c is now used only for fsverity, rename things accordingly.
Also:
- Don't create the caches at all when !CONFIG_FS_VERITY.
- Remove the unused inode argument from ext4_set_verity_work().
--- fs/ext4/ext4.h | 4 +-- fs/ext4/readpage.c | 65 ++++++++++++++++++++++------------------------ fs/ext4/super.c | 6 ++--- 3 files changed, 36 insertions(+), 39 deletions(-)
fs/ext4/ext4.h +2 -2
@@ -3829,8 +3829,8 @@ static inline void ext4_set_de_type(struct super_block *sb,/* readpages.c */ int ext4_read_folio (struct file *file,struct folio *folio);void ext4_readahead (struct readahead_control *rac); -extern int __init ext4_init_post_read_processing (void ); -extern void ext4_exit_post_read_processing (void ); +int __init ext4_init_verity_caches (void ); +void ext4_exit_verity_caches (void );/* symlink.c */ extern const struct inode_operations ext4_encrypted_symlink_inode_operations;
fs/ext4/readpage.c +31 -34
133 lines not on this page · raw message
fs/ext4/super.c +3 -3
@@ -7531,7 +7531,7 @@ static int __init ext4_init_fs(void)if (err) goto out7; - err =ext4_init_post_read_processing (); + err =ext4_init_verity_caches ();if (err) goto out6;
@@ -7580,7 +7580,7 @@ static int __init ext4_init_fs(void) out4:ext4_exit_pageio (); out5: -ext4_exit_post_read_processing (); +ext4_exit_verity_caches (); out6:ext4_exit_pending (); out7:
@@ -7601,7 +7601,7 @@ static void __exit ext4_exit_fs(void)ext4_exit_sysfs ();ext4_exit_system_zone ();ext4_exit_pageio (); -ext4_exit_post_read_processing (); +ext4_exit_verity_caches ();ext4_exit_es ();ext4_exit_pending (); }
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 10/17 f2fs: Remove fs-layer file contents en/decryption code
In reply to Eric BiggersNow that fscrypt's file contents en/decryption is always implemented using blk-crypto when the filesystem is block-based, the fs-layer en/decryption code in f2fs is unused code. Remove it.
Note that the struct f2fs_io_info field encrypted_page is kept because it is still used by the garbage collection path to relocate encrypted blocks using raw meta pages from META_MAPPING.
--- fs/f2fs/compress.c | 31 ++-------------- fs/f2fs/data.c | 93 +++++----------------------------------------- fs/f2fs/f2fs.h | 2 - fs/f2fs/segment.c | 2 - fs/f2fs/super.c | 1 - 5 files changed, 12 insertions(+), 117 deletions(-)
fs/f2fs/compress.c +3 -28
@@ -1286,8 +1286,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, .compressed_page = NULL, .io_type = io_type, .io_wbc = wbc, - .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ? - 1 : 0, };struct folio *folio;struct dnode_of_data dn;
@@ -1361,14 +1359,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,/* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback (inode, fio.old_blkaddr); - -if (fio.encrypted) { - fio.page = cc->rpages[i +1 ]; - err =f2fs_encrypt_one_page (&fio); -if (err) - goto out_destroy_crypt; - cc->cpages[i] = fio.encrypted_page; - } }set_cluster_writeback (cc);
@@ -1406,21 +1396,15 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,f2fs_bug_on (fio.sbi, blkaddr ==NULL_ADDR ); -if (fio.encrypted) - fio.encrypted_page = cc->cpages[i -1 ]; -else - fio.compressed_page = cc->cpages[i -1 ]; + fio.compressed_page = cc->cpages[i -1 ]; cc->cpages[i -1 ] =NULL ; fio.submitted =0 ;f2fs_outplace_write_data (&dn, &fio);if (unlikely (!fio.submitted)) {cancel_cluster_writeback (cc, cic, i); - -/* To call fscrypt_finalize_bounce_page */ - i = cc->valid_nr_cpages; *submitted =0 ; - goto out_destroy_crypt; + goto out_free_page_array; } (*submitted)++; unlock_continue:
@@ -1452,17 +1436,8 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,f2fs_destroy_compress_ctx (cc, false);return 0 ; -out_destroy_crypt: +out_free_page_array:page_array_free (sbi, cic->rpages, cc->cluster_size); - -if (!fio.encrypted) - goto out_put_cic; - -for (--i; i >=0 ; i--) { -if (!cc->cpages[i]) -continue ; -fscrypt_finalize_bounce_page (&cc->cpages[i]); - } out_put_cic:kmem_cache_free (cic_entry_slab, cic); out_put_dnode:
fs/f2fs/data.c +9 -84
167 lines not on this page · raw message
fs/f2fs/f2fs.h +0 -2
@@ -1364,7 +1364,6 @@ struct f2fs_io_info { unsigned int submitted:1; /* indicate IO submission */ unsigned int in_list:1; /* indicate fio is in io_list */ unsigned int is_por:1; /* indicate IO is from recovery or not */ - unsigned int encrypted:1; /* indicate file is encrypted */ unsigned int meta_gc:1; /* require meta inode GC */enum iostat_type io_type;/* io type */ struct writeback_control *io_wbc;/* writeback control */
@@ -4199,7 +4198,6 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio);int f2fs_map_blocks (struct inode *inode,struct f2fs_map_blocks *map,int flag);int f2fs_fiemap (struct inode *inode,struct fiemap_extent_info *fieinfo,u64 start,u64 len); -int f2fs_encrypt_one_page (struct f2fs_io_info *fio);bool f2fs_should_update_inplace (struct inode *inode,struct f2fs_io_info *fio);bool f2fs_should_update_outplace (struct inode *inode,struct f2fs_io_info *fio); int f2fs_write_single_data_page(struct folio *folio, int *submitted,
fs/f2fs/segment.c +0 -2
@@ -3986,8 +3986,6 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)"%s Failed to allocate data block, ino:%u, index:%lu, type:%d, old_blkaddr:0x%x, new_blkaddr:0x%x, err:%d" , __func__, fio->ino, folio->index, type, fio->old_blkaddr, fio->new_blkaddr, err); -if (fscrypt_inode_uses_fs_layer_crypto (folio->mapping->host)) -fscrypt_finalize_bounce_page (&fio->encrypted_page);folio_end_writeback (folio);if (f2fs_in_warm_node_list (folio))f2fs_del_fsync_node_entry (fio->sbi, folio);
fs/f2fs/super.c +0 -1
@@ -3773,7 +3773,6 @@ static const struct fscrypt_operations f2fs_cryptops = { .inode_info_offs = (int)offsetof(struct f2fs_inode_info, i_crypt_info) - (int)offsetof(struct f2fs_inode_info, vfs_inode), .is_block_based = 1, - .needs_bounce_pages = 1, .has_32bit_inodes = 1, .supports_subblock_data_units = 1, .legacy_key_prefix = "f2fs:",
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 11/17 fs/buffer: Remove fs-layer decryption code
In reply to Eric BiggersNow that fscrypt's file contents en/decryption is always implemented using blk-crypto when the filesystem is block-based, the fs-layer decryption code in fs/buffer.c is unused code. Remove it.
--- fs/buffer.c | 45 ++++++++------------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-)
fs/buffer.c +8 -37
@@ -336,7 +336,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)spin_unlock_irqrestore (&first->b_uptodate_lock, flags); } -struct postprocess_bh_ctx { +struct verify_bh_ctx {struct work_struct work;struct buffer_head *bh;struct fsverity_info *vi;
@@ -344,8 +344,8 @@ struct postprocess_bh_ctx {static void verify_bh (struct work_struct *work) { -struct postprocess_bh_ctx *ctx = - container_of(work, struct postprocess_bh_ctx, work); +struct verify_bh_ctx *ctx = + container_of(work, struct verify_bh_ctx, work);struct buffer_head *bh = ctx->bh;bool valid;
@@ -355,29 +355,6 @@ static void verify_bh(struct work_struct *work)kfree (ctx); } -static void decrypt_bh (struct work_struct *work) -{ -struct postprocess_bh_ctx *ctx = - container_of(work, struct postprocess_bh_ctx, work); -struct buffer_head *bh = ctx->bh; -int err; - - err =fscrypt_decrypt_pagecache_blocks (bh->b_folio, bh->b_size, -bh_offset (bh)); -if (err ==0 && ctx->vi) { -/* -* We use different work queues for decryption and for verity -* because verity may require reading metadata pages that need -* decryption, and we shouldn't recurse to the same workqueue. -*/ -INIT_WORK (&ctx->work, verify_bh); -fsverity_enqueue_verify_work (&ctx->work); -return ; - } -end_buffer_async_read (bh, err ==0 ); -kfree (ctx); -} -/* * I/O completion handler for block_read_full_folio() - folios * which come unlocked at the end of I/O.
@@ -387,27 +364,21 @@ static void bh_end_async_read(struct bio *bio)struct buffer_head *bh;bool uptodate =bio_endio_bh (bio, &bh);struct inode *inode = bh->b_folio->mapping->host; -bool decrypt =fscrypt_inode_uses_fs_layer_crypto (inode);struct fsverity_info *vi =NULL ;/* needed by ext4 */ if (bh->b_folio->index <DIV_ROUND_UP (inode->i_size,PAGE_SIZE )) vi =fsverity_get_info (inode); -/* Decrypt (with fscrypt) and/or verify (with fsverity) if needed. */ -if (uptodate && (decrypt || vi)) { -struct postprocess_bh_ctx *ctx =kmalloc_obj (*ctx,GFP_ATOMIC ); +/* Verify (with fsverity) if needed. */ +if (vi && uptodate) { +struct verify_bh_ctx *ctx =kmalloc_obj (*ctx,GFP_ATOMIC );if (ctx) { ctx->bh = bh; ctx->vi = vi; -if (decrypt) { -INIT_WORK (&ctx->work, decrypt_bh); -fscrypt_enqueue_decrypt_work (&ctx->work); - }else { -INIT_WORK (&ctx->work, verify_bh); -fsverity_enqueue_verify_work (&ctx->work); - } +INIT_WORK (&ctx->work, verify_bh); +fsverity_enqueue_verify_work (&ctx->work);return ; } uptodate = false;
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 12/17 fscrypt: Replace calls to fscrypt_inode_uses_inline_crypto()
In reply to Eric BiggersNow that fscrypt's file contents en/decryption is always implemented using blk-crypto when the filesystem is block-based, the calls to fscrypt_inode_uses_inline_crypto() in fs/crypto/inline_crypt.c (which contains functions that are called only from block-based filesystems) are equivalent to checking whether the file is an encrypted regular file, i.e. fscrypt_needs_contents_encryption(). Use that instead.
--- fs/crypto/inline_crypt.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
fs/crypto/inline_crypt.c +12 -12
@@ -228,8 +228,8 @@ static void fscrypt_generate_dun(const struct fscrypt_inode_info *ci,* @gfp_mask: memory allocation flags - these must be a waiting mask so that * bio_crypt_set_ctx can't fail. * -* If the contents of the file should be encrypted (or decrypted) with inline -* encryption, then assign the appropriate encryption context to the bio. +* If the contents of the file should be encrypted (or decrypted), then assign +* the appropriate encryption context to the bio. * * Normally the bio should be newly allocated (i.e. no pages added yet), as * otherwise fscrypt_mergeable_bio() won't work as intended.
@@ -242,7 +242,7 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,const struct fscrypt_inode_info *ci;u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE ]; -if (!fscrypt_inode_uses_inline_crypto (inode)) +if (!fscrypt_needs_contents_encryption (inode))return ; ci =fscrypt_get_inode_info_raw (inode);
@@ -257,12 +257,12 @@ EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx);* @inode: the inode for the next part of the I/O * @pos: the next file position (in bytes) in the I/O * -* When building a bio which may contain data which should undergo inline -* encryption (or decryption) via fscrypt, filesystems should call this function -* to ensure that the resulting bio contains only contiguous data unit numbers. -* This will return false if the next part of the I/O cannot be merged with the -* bio because either the encryption key would be different or the encryption -* data unit numbers would be discontiguous. +* When building a bio which may contain data which should undergo encryption +* (or decryption) via fscrypt, filesystems should call this function to ensure +* that the resulting bio contains only contiguous data unit numbers. This will +* return false if the next part of the I/O cannot be merged with the bio +* because either the encryption key would be different or the encryption data +* unit numbers would be discontiguous. * * fscrypt_set_bio_crypt_ctx() must have already been called on the bio. *
@@ -279,7 +279,7 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,const struct fscrypt_inode_info *ci;u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE ]; -if (!!bc !=fscrypt_inode_uses_inline_crypto (inode)) +if (!!bc !=fscrypt_needs_contents_encryption (inode))return false;if (!bc)return true;
@@ -337,7 +337,7 @@ bool fscrypt_dio_supported(struct inode *inode)*/ return false; } -return fscrypt_inode_uses_inline_crypto (inode); +return true; }EXPORT_SYMBOL_GPL (fscrypt_dio_supported);
@@ -366,7 +366,7 @@ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks)const struct fscrypt_inode_info *ci;u32 dun; -if (!fscrypt_inode_uses_inline_crypto (inode)) +if (!fscrypt_needs_contents_encryption (inode))return nr_blocks;if (nr_blocks <=1 )
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 13/17 fscrypt: Remove fscrypt_dio_supported()
In reply to Eric BiggersOn block-based filesystems, fscrypt file contents encryption is now always implemented using blk-crypto. This implementation supports direct I/O.
Therefore, fscrypt_dio_supported() now always returns true, except in the edge case where statx(STATX_DIOALIGN) is called on an encrypted regular file that hasn't had its key set up. But that was really a workaround rather than the desired behavior, so we can disregard it.
Thus, fscrypt_dio_supported() is no longer needed. Remove it.
--- fs/crypto/inline_crypt.c | 43 ---------------------------------------- fs/ext4/inode.c | 11 ++-------- fs/f2fs/file.c | 6 +----- include/linux/fscrypt.h | 7 ------- 4 files changed, 3 insertions(+), 64 deletions(-)
fs/crypto/inline_crypt.c +0 -43
@@ -298,49 +298,6 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, }EXPORT_SYMBOL_GPL (fscrypt_mergeable_bio); -/** -* fscrypt_dio_supported() - check whether DIO (direct I/O) is supported on an -* inode, as far as encryption is concerned -* @inode: the inode in question -* -* Return: %true if there are no encryption constraints that prevent DIO from -* being supported; %false if DIO is unsupported. (Note that in the -* %true case, the filesystem might have other, non-encryption-related -* constraints that prevent DIO from actually being supported. Also, on -* encrypted files the filesystem is still responsible for only allowing -* DIO when requests are filesystem-block-aligned.) -*/ -bool fscrypt_dio_supported (struct inode *inode) -{ -int err; - -/* If the file is unencrypted, no veto from us. */ -if (!fscrypt_needs_contents_encryption (inode)) -return true; - -/* -* We only support DIO with inline crypto, not fs-layer crypto. -* -* To determine whether the inode is using inline crypto, we have to set -* up the key if it wasn't already done. This is because in the current -* design of fscrypt, the decision of whether to use inline crypto or -* not isn't made until the inode's encryption key is being set up. In -* the DIO read/write case, the key will always be set up already, since -* the file will be open. But in the case of statx(), the key might not -* be set up yet, as the file might not have been opened yet. -*/ - err =fscrypt_require_key (inode); -if (err) { -/* -* Key unavailable or couldn't be set up. This edge case isn't -* worth worrying about; just report that DIO is unsupported. -*/ -return false; - } -return true; -} -EXPORT_SYMBOL_GPL (fscrypt_dio_supported); -/** * fscrypt_limit_io_blocks() - limit I/O blocks to avoid discontiguous DUNs * @inode: the file on which I/O is being done
fs/ext4/inode.c +2 -9
@@ -6147,11 +6147,8 @@ u32 ext4_dio_alignment(struct inode *inode)return 0 ;if (ext4_has_inline_data (inode))return 0 ; -if (IS_ENCRYPTED (inode)) { -if (!fscrypt_dio_supported (inode)) -return 0 ; +if (IS_ENCRYPTED (inode))return i_blocksize (inode); - }return 1 ;/* use the iomap defaults */ }
@@ -6170,11 +6167,7 @@ int ext4_getattr(struct mnt_idmap *idmap, const struct path *path, stat->btime.tv_nsec = ei->i_crtime.tv_nsec; } -/* -* Return the DIO alignment restrictions if requested. We only return -* this information when requested, since on encrypted files it might -* take a fair bit of work to get if the file wasn't opened recently. -*/ +/* Return the DIO alignment restrictions if requested. */ if ((request_mask &STATX_DIOALIGN ) &&S_ISREG (inode->i_mode)) {u32 dio_align =ext4_dio_alignment (inode);
fs/f2fs/file.c +1 -5
@@ -950,8 +950,6 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -if (!fscrypt_dio_supported (inode)) -return true;if (fsverity_active (inode))return true;if (f2fs_compressed_file (inode))
@@ -996,9 +994,7 @@ int f2fs_getattr(struct mnt_idmap *idmap, const struct path *path, }/* -* Return the DIO alignment restrictions if requested. We only return -* this information when requested, since on encrypted files it might -* take a fair bit of work to get if the file wasn't opened recently. +* Return the DIO alignment restrictions if requested. * * f2fs sometimes supports DIO reads but not DIO writes. STATX_DIOALIGN * cannot represent that, so in that case we report no DIO support.
include/linux/fscrypt.h +0 -7
@@ -870,8 +870,6 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,bool fscrypt_mergeable_bio (struct bio *bio,const struct inode *inode,loff_t pos); -bool fscrypt_dio_supported (struct inode *inode); -u64 fscrypt_limit_io_blocks (const struct inode *inode,u64 lblk,u64 nr_blocks);#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
@@ -887,11 +885,6 @@ static inline bool fscrypt_mergeable_bio(struct bio *bio,return true; } -static inline bool fscrypt_dio_supported (struct inode *inode) -{ -return !fscrypt_needs_contents_encryption (inode); -} -static inline u64 fscrypt_limit_io_blocks (const struct inode *inode,u64 lblk,u64 nr_blocks) {
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 14/17 fscrypt: Remove fs-layer zeroout code
In reply to Eric BiggersNow that fscrypt's file contents en/decryption is always implemented using blk-crypto when the filesystem is block-based, the fs-layer zeroout code in fs/crypto/bio.c is unused code. Remove it, then fold fscrypt_zeroout_range_inline_crypt() into fscrypt_zeroout_range().
Then make fscrypt_alloc_bounce_page() and fscrypt_crypt_data_unit() static, since they're no longer called from any other file.
--- fs/crypto/bio.c | 134 +++++++----------------------------- fs/crypto/crypto.c | 14 ++-- fs/crypto/fscrypt_private.h | 5 -- 3 files changed, 32 insertions(+), 121 deletions(-)
fs/crypto/bio.c +25 -109
@@ -69,16 +69,36 @@ static void fscrypt_zeroout_range_end_io(struct bio *bio)bio_put (bio); } -static int fscrypt_zeroout_range_inline_crypt (const struct inode *inode, -loff_t pos,sector_t sector, -u64 len) +/** +* fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file +* @inode: the file's inode +* @pos: the first file position (in bytes) to zero out +* @sector: the first sector to zero out +* @len: bytes to zero out +* +* Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write +* ciphertext blocks which decrypt to the all-zeroes block. The blocks must be +* both logically and physically contiguous. It's also assumed that the +* filesystem only uses a single block device, ->s_bdev. @len must be a +* multiple of the file system logical block size. +* +* Note that since each block uses a different IV, this involves writing a +* different ciphertext to each block; we can't simply reuse the same one. +* +* Return: 0 on success; -errno on failure. +*/ +int fscrypt_zeroout_range (const struct inode *inode,loff_t pos, +sector_t sector,u64 len) {struct fscrypt_zero_done done = { .pending =ATOMIC_INIT (1 ), .done =COMPLETION_INITIALIZER_ONSTACK (done.done), }; -while (len) { +if (len ==0 ) +return 0 ; + + do { struct bio *bio; unsigned int n;
@@ -102,115 +122,11 @@ static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,atomic_inc (&done.pending);blk_crypto_submit_bio (bio); - } + }while (len);fscrypt_zeroout_range_done (&done);wait_for_completion (&done.done);return blk_status_to_errno (done.status); } - -/** -* fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file -* @inode: the file's inode -* @pos: the first file position (in bytes) to zero out -* @sector: the first sector to zero out -* @len: bytes to zero out -* -* Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write -* ciphertext blocks which decrypt to the all-zeroes block. The blocks must be -* both logically and physically contiguous. It's also assumed that the -* filesystem only uses a single block device, ->s_bdev. @len must be a -* multiple of the file system logical block size. -* -* Note that since each block uses a different IV, this involves writing a -* different ciphertext to each block; we can't simply reuse the same one. -* -* Return: 0 on success; -errno on failure. -*/ -int fscrypt_zeroout_range (const struct inode *inode,loff_t pos, -sector_t sector,u64 len) -{ -const struct fscrypt_inode_info *ci =fscrypt_get_inode_info_raw (inode); -const unsigned int du_bits = ci->ci_data_unit_bits; -const unsigned int du_size =1U << du_bits; -const unsigned int du_per_page_bits =PAGE_SHIFT - du_bits; -const unsigned int du_per_page =1U << du_per_page_bits; -u64 du_index = pos >> du_bits; -u64 du_remaining = len >> du_bits; -struct page *pages[16 ];/* write up to 16 pages at a time */ -unsigned int nr_pages; -unsigned int i; -unsigned int offset; -struct bio *bio; -int ret, err; - -if (len ==0 ) -return 0 ; - -if (fscrypt_inode_uses_inline_crypto (inode)) -return fscrypt_zeroout_range_inline_crypt (inode, pos, sector, - len); - -BUILD_BUG_ON (ARRAY_SIZE (pages) >BIO_MAX_VECS ); - nr_pages =min_t (u64,ARRAY_SIZE (pages), - (du_remaining + du_per_page -1 ) >> du_per_page_bits); - -/* -* We need at least one page for ciphertext. Allocate the first one -* from a mempool, with __GFP_DIRECT_RECLAIM set so that it can't fail. -* -* Any additional page allocations are allowed to fail, as they only -* help performance, and waiting on the mempool for them could deadlock. -*/ -for (i =0 ; i < nr_pages; i++) { - pages[i] =fscrypt_alloc_bounce_page (i ==0 ?GFP_NOFS : -GFP_NOWAIT ); -if (!pages[i]) -break ; - } - nr_pages = i; -if (WARN_ON_ONCE (nr_pages <=0 )) -return -EINVAL ; - -/* This always succeeds since __GFP_DIRECT_RECLAIM is set. */ - bio =bio_alloc (inode->i_sb->s_bdev, nr_pages,REQ_OP_WRITE ,GFP_NOFS ); - -do { - bio->bi_iter.bi_sector = sector; - - i =0 ; - offset =0 ; -do { - err =fscrypt_crypt_data_unit (ci,FS_ENCRYPT , du_index, -ZERO_PAGE (0 ), pages[i], - du_size, offset); -if (err) - goto out; - du_index++; - sector +=1U << (du_bits -SECTOR_SHIFT ); - du_remaining--; - offset += du_size; -if (offset ==PAGE_SIZE || du_remaining ==0 ) { - ret =bio_add_page (bio, pages[i++], offset,0 ); -if (WARN_ON_ONCE (ret != offset)) { - err = -EIO ; - goto out; - } - offset =0 ; - } - }while (i != nr_pages && du_remaining !=0 ); - - err =submit_bio_wait (bio); -if (err) - goto out; -bio_reset (bio, inode->i_sb->s_bdev,REQ_OP_WRITE ); - }while (du_remaining !=0 ); - err =0 ; -out: -bio_put (bio); -for (i =0 ; i < nr_pages; i++) -fscrypt_free_bounce_page (pages[i]); -return err; -}EXPORT_SYMBOL (fscrypt_zeroout_range);
fs/crypto/crypto.c +7 -7
@@ -49,7 +49,7 @@ void fscrypt_enqueue_decrypt_work(struct work_struct *work) }EXPORT_SYMBOL (fscrypt_enqueue_decrypt_work); -struct page *fscrypt_alloc_bounce_page (gfp_t gfp_flags) +static struct page *fscrypt_alloc_bounce_page (gfp_t gfp_flags) {if (WARN_ON_ONCE (!fscrypt_bounce_page_pool)) {/*
@@ -65,8 +65,7 @@ struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags)* fscrypt_free_bounce_page() - free a ciphertext bounce page * @bounce_page: the bounce page to free, or NULL * -* Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(), -* or by fscrypt_alloc_bounce_page() directly. +* Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(). */ void fscrypt_free_bounce_page (struct page *bounce_page) {
@@ -107,10 +106,11 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 index, }/* Encrypt or decrypt a single "data unit" of file contents. */ -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) +static 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) {struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;SYNC_SKCIPHER_REQUEST_ON_STACK (req, tfm);
fs/crypto/fscrypt_private.h +0 -5
@@ -329,11 +329,6 @@ typedef enum {/* crypto.c */ extern struct kmem_cache *fscrypt_inode_info_cachep;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); -struct page *fscrypt_alloc_bounce_page (gfp_t gfp_flags); void __printf(3, 4) __cold fscrypt_msg(const struct inode *inode, const char *level, const char *fmt, ...);
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 15/17 fscrypt: Remove unused functions and workqueue
In reply to Eric BiggersRemove functions that are no longer used:
- fscrypt_decrypt_bio()
- fscrypt_decrypt_pagecache_blocks()
- fscrypt_inode_uses_fs_layer_crypto()
- fscrypt_inode_uses_inline_crypto()
- fscrypt_enqueue_decrypt_work()
This makes the decryption workqueue unused, so remove it too.
--- fs/crypto/bio.c | 32 -------------------- fs/crypto/crypto.c | 65 ----------------------------------------- include/linux/fscrypt.h | 47 ----------------------------- 3 files changed, 144 deletions(-)
fs/crypto/bio.c +0 -32
@@ -15,38 +15,6 @@#include "fscrypt_private.h" -/** -* fscrypt_decrypt_bio() - decrypt the contents of a bio -* @bio: the bio to decrypt -* -* Decrypt the contents of a "read" bio following successful completion of the -* underlying disk read. The bio must be reading a whole number of blocks of an -* encrypted file directly into the page cache. If the bio is reading the -* ciphertext into bounce pages instead of the page cache (for example, because -* the file is also compressed, so decompression is required after decryption), -* then this function isn't applicable. This function may sleep, so it must be -* called from a workqueue rather than from the bio's bi_end_io callback. -* -* Return: %true on success; %false on failure. On failure, bio->bi_status is -* also set to an error status. -*/ -bool fscrypt_decrypt_bio (struct bio *bio) -{ -struct folio_iter fi; - -bio_for_each_folio_all (fi, bio) { -int err =fscrypt_decrypt_pagecache_blocks (fi.folio, fi.length, - fi.offset); - -if (err) { - bio->bi_status =errno_to_blk_status (err); -return false; - } - } -return true; -} -EXPORT_SYMBOL (fscrypt_decrypt_bio); -struct fscrypt_zero_done {atomic_t pending;blk_status_t status;
fs/crypto/crypto.c +0 -65
87 lines not on this page · raw message
include/linux/fscrypt.h +0 -47
89 lines not on this page · raw message
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 16/17 fscrypt: Merge bio.c and inline_crypt.c into block.c
In reply to Eric BiggersNow that fscrypt always uses blk-crypto on block-based filesystems, there's no meaningful difference between bio.c and inline_crypt.c. Therefore merge the two files into one named block.c.
Note: I didn't carry over bio.c's "Copyright (C) 2015, Motorola Mobility", as none of the code that applied to remained.
---
fs/crypto/Makefile | 3 +-
fs/crypto/bio.c | 100 --------------------------
fs/crypto/{inline_crypt.c => block.c} | 96 +++++++++++++++++++++++--
fs/crypto/fscrypt_private.h | 2 +-
include/linux/fscrypt.h | 22 +++---
5 files changed, 101 insertions(+), 122 deletions(-)
delete mode 100644 fs/crypto/bio.c
rename fs/crypto/{inline_crypt.c => block.c} (79%)fs/crypto/Makefile +1 -2
@@ -10,5 +10,4 @@ fscrypto-y := crypto.o \ keysetup_v1.o \ policy.o -fscrypto-$(CONFIG_BLOCK) += bio.o -fscrypto-$(CONFIG_FS_ENCRYPTION_INLINE_CRYPT) += inline_crypt.o +fscrypto-$(CONFIG_BLOCK) += block.o
fs/crypto/bio.c deleted +0 -100
100 lines not on this page · raw message
fs/crypto/block.c renamed from fs/crypto/inline_crypt.c +90 -6
113 lines not on this page · raw message
fs/crypto/fscrypt_private.h +1 -1
@@ -395,7 +395,7 @@ void fscrypt_hkdf_expand(const struct hmac_sha512_key *hkdf, u8 context, const u8 *info, unsigned int infolen, u8 *okm, unsigned int okmlen); -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT static inline bool fscrypt_using_inline_encryption (const struct fscrypt_inode_info *ci)
include/linux/fscrypt.h +9 -13
@@ -446,10 +446,6 @@ bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len);u64 fscrypt_fname_siphash (const struct inode *dir,const struct qstr *name); -/* bio.c */ -int fscrypt_zeroout_range (const struct inode *inode,loff_t pos, -sector_t sector,u64 len); -/* hooks.c */ int fscrypt_file_open (struct inode *inode,struct file *filp); int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
@@ -737,14 +733,6 @@ static inline int fscrypt_d_revalidate(struct inode *dir, const struct qstr *namreturn 1 ; } -/* bio.c */ - -static inline int fscrypt_zeroout_range (const struct inode *inode,loff_t pos, -sector_t sector,u64 len) -{ -return -EOPNOTSUPP ; -} -/* hooks.c */ static inline int fscrypt_file_open (struct inode *inode,struct file *filp)
@@ -844,7 +832,7 @@ static inline void fscrypt_set_ops(struct super_block *sb,#endif /* !CONFIG_FS_ENCRYPTION */ -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,
@@ -854,6 +842,8 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, loff_t pos);u64 fscrypt_limit_io_blocks (const struct inode *inode,u64 lblk,u64 nr_blocks); +int fscrypt_zeroout_range (const struct inode *inode,loff_t pos, +sector_t sector,u64 len);#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
@@ -873,6 +863,12 @@ static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, {return nr_blocks; } + +static inline int fscrypt_zeroout_range (const struct inode *inode,loff_t pos, +sector_t sector,u64 len) +{ +return -EOPNOTSUPP ; +}#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ /**
Signature · 1 line
2.55.0
Eric Biggers
maintainerPATCH v3 17/17 fscrypt: Add safety checks to non-block-based en/decryption
In reply to Eric Biggersfscrypt_encrypt_pagecache_blocks(), fscrypt_encrypt_block_inplace(), fscrypt_decrypt_block_inplace() would dereference a NULL fscrypt_inode_info pointer if they were to be called on a file that hasn't been opened yet or on a block-based filesystem. Since they have the ability to report errors anyway, add WARN_ON_ONCE checks for this.
--- fs/crypto/crypto.c | 61 +++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 22 deletions(-)
fs/crypto/crypto.c +39 -22
@@ -105,12 +105,17 @@ static int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, struct page *dest_page, unsigned int len, unsigned int offs) { - struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm; -SYNC_SKCIPHER_REQUEST_ON_STACK (req, tfm); + struct crypto_sync_skcipher *tfm;union fscrypt_iv iv;struct scatterlist dst, src;int err; +if (WARN_ON_ONCE (ci ==NULL ))/* File hasn't been opened yet? */ +return -ENOKEY ; + tfm = ci->ci_enc_key.tfm; +if (WARN_ON_ONCE (tfm ==NULL ))/* Called on block-based filesystem? */ +return -ENOKEY ; +if (WARN_ON_ONCE (len <=0 ))return -EINVAL ;if (WARN_ON_ONCE (len %FSCRYPT_CONTENTS_ALIGNMENT !=0 ))
@@ -118,18 +123,22 @@ static int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci,fscrypt_generate_iv (&iv, index, ci); -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 ) - err =crypto_skcipher_decrypt (req); -else - err =crypto_skcipher_encrypt (req); + { +SYNC_SKCIPHER_REQUEST_ON_STACK (req, tfm); +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 ) + err =crypto_skcipher_decrypt (req); +else + err =crypto_skcipher_encrypt (req); + }if (err) fscrypt_err(ci->ci_inode, "%scryption failed for data unit %llu: %d",
@@ -153,7 +162,7 @@ static int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci,* which the plaintext data was located in the source page. Any other parts of * the bounce page will be left uninitialized. * -* This is for use by the filesystem's ->writepages() method. +* This is for use by the ->writepages() method of non-block-based filesystems. * * The bounce page allocation is mempool-backed, so it will always succeed when * @gfp_flags includes __GFP_DIRECT_RECLAIM, e.g. when it's GFP_NOFS. However,
@@ -167,14 +176,20 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, {const struct inode *inode = folio->mapping->host;const struct fscrypt_inode_info *ci =fscrypt_get_inode_info_raw (inode); -const unsigned int du_bits = ci->ci_data_unit_bits; -const unsigned int du_size =1U << du_bits; +unsigned int du_bits; +unsigned int du_size;struct page *ciphertext_page; -u64 index = ((u64 )folio->index << (PAGE_SHIFT - du_bits)) + - (offs >> du_bits); +u64 index;unsigned int i;int err; +if (WARN_ON_ONCE (ci ==NULL ))/* File hasn't been opened yet? */ +return ERR_PTR (-ENOKEY ); + + du_bits = ci->ci_data_unit_bits; + du_size =1U << du_bits; + index = (folio_pos (folio) + offs) >> du_bits; +VM_BUG_ON_FOLIO (folio_test_large (folio), folio);if (WARN_ON_ONCE (!folio_test_locked (folio)))return ERR_PTR (-EINVAL );
@@ -215,7 +230,8 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);* arbitrary page, not necessarily in the original pagecache page. The @inode * and @lblk_num must be specified, as they can't be determined from @page. * -* This is not compatible with fscrypt_operations::supports_subblock_data_units. +* This function only supports non-block-based filesystems that don't support +* sub-block data units (as indicated by the fscrypt_operations fields). * * Return: 0 on success; -errno on failure */
@@ -245,7 +261,8 @@ EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);* arbitrary page, not necessarily in the original pagecache page. The @inode * and @lblk_num must be specified, as they can't be determined from @page. * -* This is not compatible with fscrypt_operations::supports_subblock_data_units. +* This function only supports non-block-based filesystems that don't support +* sub-block data units (as indicated by the fscrypt_operations fields). * * Return: 0 on success; -errno on failure */
@@ -275,7 +292,7 @@ int fscrypt_initialize(struct super_block *sb)mempool_t *pool;/* pairs with smp_store_release() below */ -if (likely (smp_load_acquire (&fscrypt_bounce_page_pool))) +if (smp_load_acquire (&fscrypt_bounce_page_pool))return 0 ;/* No need to allocate a bounce page pool if this FS won't use it. */
Signature · 1 line
2.55.0
Eric Biggers
maintainerQuoted 5 lines · Eric Biggers
ext4: Remove fs-layer file contents en/decryption code
ext4: Makeext4_bio_write_folio()return void
ext4: Further de-generalize the bio postprocessing code
f2fs: Remove fs-layer file contents en/decryption code fs/buffer: Remove fs-layer decryption code
Could we get acks from the ext4 and f2fs maintainers on these?
- Eric
Quoted 10 lines · Eric Biggers
Eric Biggers (17):
blk-crypto: Simplify check for fallback support
blk-crypto: Fold__blk_crypto_cfg_supported()into its caller
blk-crypto: Allow control over whether hardware is used
fscrypt: Fully disallowIV_INO_LBLK_32withs_blocksize!=PAGE_SIZE
fscrypt: Always use blk-crypto for contents on block-based filesystems
Documentation: fscrypt: Update docs for inlinecrypt
ext4: Remove fs-layer file contents en/decryption code
ext4: Makeext4_bio_write_folio()return void
ext4: Further de-generalize the bio postprocessing code
Quoted 8 lines
f2fs: Remove fs-layer file contents en/decryption code fs/buffer: Remove fs-layer decryption code
fscrypt: Replace calls tofscrypt_inode_uses_inline_crypto()
fscrypt: Removefscrypt_dio_supported()
fscrypt: Remove fs-layer zeroout code
fscrypt: Remove unused functions and workqueue
fscrypt: Mergebio.candinline_crypt.cintoblock.c
fscrypt: Add safety checks to non-block-based en/decryption
Applied to https://git.kernel.org/pub/scm/fs/fscrypt/linux.git/log/?h=for-next
But I'd still like acks on the ext4 and f2fs patches.
- Eric
Eric Biggers
maintainerQuoted 20 lines · Eric Biggers
Quoted 10 lines · Eric Biggers
Eric Biggers (17):
blk-crypto: Simplify check for fallback support
blk-crypto: Fold__blk_crypto_cfg_supported()into its caller
blk-crypto: Allow control over whether hardware is used
fscrypt: Fully disallowIV_INO_LBLK_32withs_blocksize!=PAGE_SIZE
fscrypt: Always use blk-crypto for contents on block-based filesystems
Documentation: fscrypt: Update docs for inlinecrypt
ext4: Remove fs-layer file contents en/decryption code
ext4: Makeext4_bio_write_folio()return void
ext4: Further de-generalize the bio postprocessing codeQuoted 8 lines
f2fs: Remove fs-layer file contents en/decryption code fs/buffer: Remove fs-layer decryption code
fscrypt: Replace calls tofscrypt_inode_uses_inline_crypto()
fscrypt: Removefscrypt_dio_supported()
fscrypt: Remove fs-layer zeroout code
fscrypt: Remove unused functions and workqueue
fscrypt: Mergebio.candinline_crypt.cintoblock.c
fscrypt: Add safety checks to non-block-based en/decryption
Quoted 3 lines
Applied to https://git.kernel.org/pub/scm/fs/fscrypt/linux.git/log/?h=for-next
But I'd still like acks on the ext4 and f2fs patches.
Ted and Jaegeuk, any chance for Acks on the ext4 and f2fs patches?
- Eric