diff mbox series

[RFC,09/17] fscrypt: make fscrypt_setup_encryption_info generic for extents

Message ID 2e4743214d5f40664ebb6227f71449015d16a218.1672547582.git.sweettea-kernel@dorminy.me (mailing list archive)
State New, archived
Headers show
Series fscrypt: add per-extent encryption keys | expand

Commit Message

Sweet Tea Dorminy Jan. 1, 2023, 5:06 a.m. UTC
fscrypt_setup_encryption_info() will be used for setting up both inode
and extent fscrypt_infos, so it can't just assume that it should set
inode->i_crypt_info to the new fscrypt_info. Instead, this changes it to
take a pointer to the location to store the new fscrypt_info, which
currently is always &inode->i_crypt_info.  Correspondingly,
fscrypt_setup_encryption_info() currently calls fscrypt_set_inode_info()
to set the inode's info; this renames it to fscrypt_set_info() and
plumbs through the pointer to the location to store the new
fscrypt_info.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 fs/crypto/keysetup.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
index cb3ba4e4f816..04f01da900ca 100644
--- a/fs/crypto/keysetup.c
+++ b/fs/crypto/keysetup.c
@@ -513,22 +513,23 @@  static void put_crypt_info(struct fscrypt_info *ci)
 	kmem_cache_free(fscrypt_info_cachep, ci);
 }
 
-static bool fscrypt_set_inode_info(struct inode *inode,
-				   struct fscrypt_info *ci,
-				   struct fscrypt_master_key *mk)
+static bool fscrypt_set_info(struct fscrypt_info **info_ptr,
+			     struct fscrypt_info *ci,
+			     struct fscrypt_master_key *mk)
 {
 	if (ci == NULL) {
-		inode->i_crypt_info = NULL;
+		*info_ptr = NULL;
 		return true;
 	}
 
 	/*
-	 * For existing inodes, multiple tasks may race to set ->i_crypt_info.
-	 * So use cmpxchg_release().  This pairs with the smp_load_acquire() in
-	 * fscrypt_get_info().  I.e., here we publish ->i_crypt_info with a
-	 * RELEASE barrier so that other tasks can ACQUIRE it.
+	 * For existing objects, multiple tasks may race to set ->i_crypt_info
+	 * or the equivalent. So use cmpxchg_release().  This pairs with the
+	 * smp_load_acquire() in fscrypt_get_info().  I.e., here we publish
+	 * ->i_crypt_info with a RELEASE barrier so that other tasks can
+	 *  ACQUIRE it.
 	 */
-	if (cmpxchg_release(&inode->i_crypt_info, NULL, ci) != NULL)
+	if (cmpxchg_release(info_ptr, NULL, ci) != NULL)
 		return false;
 
 	/*
@@ -549,7 +550,8 @@  static int
 fscrypt_setup_encryption_info(struct inode *inode,
 			      const union fscrypt_policy *policy,
 			      const u8 nonce[FSCRYPT_FILE_NONCE_SIZE],
-			      bool need_dirhash_key)
+			      bool need_dirhash_key,
+			      struct fscrypt_info **info_ptr)
 {
 	struct fscrypt_info *crypt_info;
 	struct fscrypt_mode *mode;
@@ -582,7 +584,7 @@  fscrypt_setup_encryption_info(struct inode *inode,
 	if (res)
 		goto out;
 
-	set_succeeded = fscrypt_set_inode_info(inode, crypt_info, mk);
+	set_succeeded = fscrypt_set_info(info_ptr, crypt_info, mk);
 	res = 0;
 out:
 	if (mk) {
@@ -631,7 +633,7 @@  int fscrypt_get_encryption_info(struct inode *inode, bool allow_unsupported)
 		if (dir_info)
 			mk = dir_info->ci_master_key;
 
-		fscrypt_set_inode_info(inode, dir_info, mk);
+		fscrypt_set_info(&inode->i_crypt_info, dir_info, mk);
 		dput(parent_dentry);
 		dput(dentry);
 		return 0;
@@ -663,7 +665,8 @@  int fscrypt_get_encryption_info(struct inode *inode, bool allow_unsupported)
 	res = fscrypt_setup_encryption_info(inode, &policy,
 					    fscrypt_context_nonce(&ctx),
 					    IS_CASEFOLDED(inode) &&
-					    S_ISDIR(inode->i_mode));
+					    S_ISDIR(inode->i_mode),
+					    &inode->i_crypt_info);
 
 	if (res == -ENOPKG && allow_unsupported) /* Algorithm unavailable? */
 		res = 0;
@@ -722,15 +725,16 @@  int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
 	if (fscrypt_uses_extent_encryption(inode)) {
 		struct fscrypt_info *dir_info = fscrypt_get_inode_info(dir);
 
-		fscrypt_set_inode_info(inode, dir_info,
-				       dir_info->ci_master_key);
+		fscrypt_set_info(&inode->i_crypt_info, dir_info,
+				 dir_info->ci_master_key);
 		return 0;
 	}
 
 	get_random_bytes(nonce, FSCRYPT_FILE_NONCE_SIZE);
 	return fscrypt_setup_encryption_info(inode, policy, nonce,
 					     IS_CASEFOLDED(dir) &&
-					     S_ISDIR(inode->i_mode));
+					     S_ISDIR(inode->i_mode),
+					     &inode->i_crypt_info);
 }
 EXPORT_SYMBOL_GPL(fscrypt_prepare_new_inode);
 
@@ -745,7 +749,7 @@  void fscrypt_put_encryption_info(struct inode *inode)
 {
 	if (!fscrypt_uses_extent_encryption(inode))
 		put_crypt_info(fscrypt_get_inode_info(inode));
-	fscrypt_set_inode_info(inode, NULL, NULL);
+	fscrypt_set_info(&inode->i_crypt_info, NULL, NULL);
 }
 EXPORT_SYMBOL(fscrypt_put_encryption_info);