summaryrefslogtreecommitdiff
path: root/fs/crypto/hooks.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2022-11-05 02:37:58 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-11-10 20:14:24 +0300
commit092401142b959de39ba3db8425cffd9b30f7dea9 (patch)
tree1336bfae8fe3cf8be27f7051c4b04a7a9eef5f76 /fs/crypto/hooks.c
parent54c13d3520ef5b57f5a11cac883fce05d9ce6b52 (diff)
downloadlinux-092401142b959de39ba3db8425cffd9b30f7dea9.tar.xz
fscrypt: simplify master key locking
commit 4a4b8721f1a5e4b01e45b3153c68d5a1014b25de upstream. The stated reasons for separating fscrypt_master_key::mk_secret_sem from the standard semaphore contained in every 'struct key' no longer apply. First, due to commit a992b20cd4ee ("fscrypt: add fscrypt_prepare_new_inode() and fscrypt_set_context()"), fscrypt_get_encryption_info() is no longer called from within a filesystem transaction. Second, due to commit d3ec10aa9581 ("KEYS: Don't write out to userspace while holding key semaphore"), the semaphore for the "keyring" key type no longer ranks above page faults. That leaves performance as the only possible reason to keep the separate mk_secret_sem. Specifically, having mk_secret_sem reduces the contention between setup_file_encryption_key() and FS_IOC_{ADD,REMOVE}_ENCRYPTION_KEY. However, these ioctls aren't executed often, so this doesn't seem to be worth the extra complexity. Therefore, simplify the locking design by just using key->sem instead of mk_secret_sem. Link: https://lore.kernel.org/r/20201117032626.320275-1-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/crypto/hooks.c')
-rw-r--r--fs/crypto/hooks.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 4180371bf864..0c6fa5c2d6f3 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -139,6 +139,7 @@ int fscrypt_prepare_setflags(struct inode *inode,
unsigned int oldflags, unsigned int flags)
{
struct fscrypt_info *ci;
+ struct key *key;
struct fscrypt_master_key *mk;
int err;
@@ -154,13 +155,14 @@ int fscrypt_prepare_setflags(struct inode *inode,
ci = inode->i_crypt_info;
if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
return -EINVAL;
- mk = ci->ci_master_key->payload.data[0];
- down_read(&mk->mk_secret_sem);
+ key = ci->ci_master_key;
+ mk = key->payload.data[0];
+ down_read(&key->sem);
if (is_master_key_secret_present(&mk->mk_secret))
err = fscrypt_derive_dirhash_key(ci, mk);
else
err = -ENOKEY;
- up_read(&mk->mk_secret_sem);
+ up_read(&key->sem);
return err;
}
return 0;