Viewing: 0010_llcrypt_info.patch

Replace use of inode->i_crypt_info with inode->i_private, cast as a struct llcrypt_info.
This is required in order to be able to support encryption on kernels that lack
inode->i_crypt_info field.

--- a/libcfs/include/libcfs/crypto/llcrypt.h
+++ b/libcfs/include/libcfs/crypto/llcrypt.h
@@ -81,11 +81,7 @@ struct llcrypt_ctx {
 	u8 flags;				/* Flags */
 };
 
-static inline bool llcrypt_has_encryption_key(const struct inode *inode)
-{
-	/* pairs with cmpxchg_release() in llcrypt_get_encryption_info() */
-	return READ_ONCE(inode->i_crypt_info) != NULL;
-}
+extern bool llcrypt_has_encryption_key(const struct inode *inode);
 
 static inline bool llcrypt_dummy_context_enabled(struct inode *inode)
 {
--- a/libcfs/libcfs/crypto/crypto.c
+++ b/libcfs/libcfs/crypto/crypto.c
@@ -158,7 +158,7 @@ int llcrypt_crypt_block(const struct ino
 	struct skcipher_request *req = NULL;
 	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist dst, src;
-	struct llcrypt_info *ci = inode->i_crypt_info;
+	struct llcrypt_info *ci = llcrypt_info(inode);
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
 	int res = 0;
 
--- a/libcfs/libcfs/crypto/fname.c
+++ b/libcfs/libcfs/crypto/fname.c
@@ -39,7 +39,7 @@ int fname_encrypt(struct inode *inode, c
 {
 	struct skcipher_request *req = NULL;
 	DECLARE_CRYPTO_WAIT(wait);
-	struct llcrypt_info *ci = inode->i_crypt_info;
+	struct llcrypt_info *ci = llcrypt_info(inode);
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
 	union llcrypt_iv iv;
 	struct scatterlist sg;
@@ -92,7 +92,7 @@ static int fname_decrypt(struct inode *i
 	struct skcipher_request *req = NULL;
 	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src_sg, dst_sg;
-	struct llcrypt_info *ci = inode->i_crypt_info;
+	struct llcrypt_info *ci = llcrypt_info(inode);
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
 	union llcrypt_iv iv;
 	int res;
@@ -181,7 +181,7 @@ static int base64_decode(const char *src
 bool llcrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
 				  u32 max_len, u32 *encrypted_len_ret)
 {
-	const struct llcrypt_info *ci = inode->i_crypt_info;
+	const struct llcrypt_info *ci = llcrypt_info(inode);
 	int padding = 4 << (llcrypt_policy_flags(&ci->ci_policy) &
 			    LLCRYPT_POLICY_FLAGS_PAD_MASK);
 	u32 encrypted_len;
--- a/libcfs/libcfs/crypto/keysetup.c
+++ b/libcfs/libcfs/crypto/keysetup.c
@@ -501,7 +501,8 @@ int llcrypt_get_encryption_info(struct i
 	if (res)
 		goto out;
 
-	if (cmpxchg_release(&inode->i_crypt_info, NULL, crypt_info) == NULL) {
+	if (cmpxchg_release(&(llcrypt_info_nocast(inode)), NULL,
+			    crypt_info) == NULL) {
 		if (master_key) {
 			struct llcrypt_master_key *mk =
 				master_key->payload.data[0];
@@ -538,8 +539,8 @@ EXPORT_SYMBOL(llcrypt_get_encryption_inf
  */
 void llcrypt_put_encryption_info(struct inode *inode)
 {
-	put_crypt_info(inode->i_crypt_info);
-	inode->i_crypt_info = NULL;
+	put_crypt_info(llcrypt_info(inode));
+	llcrypt_info_nocast(inode) = NULL;
 }
 EXPORT_SYMBOL(llcrypt_put_encryption_info);
 
@@ -569,9 +570,10 @@ EXPORT_SYMBOL(llcrypt_free_inode);
  */
 int llcrypt_drop_inode(struct inode *inode)
 {
-	const struct llcrypt_info *ci = READ_ONCE(inode->i_crypt_info);
+	const struct llcrypt_info *ci;
 	const struct llcrypt_master_key *mk;
 
+	ci = (struct llcrypt_info *)READ_ONCE(llcrypt_info_nocast(inode));
 	/*
 	 * If ci is NULL, then the inode doesn't have an encryption key set up
 	 * so it's irrelevant.  If ci_master_key is NULL, then the master key
@@ -593,3 +595,10 @@ int llcrypt_drop_inode(struct inode *ino
 	return !is_master_key_secret_present(&mk->mk_secret);
 }
 EXPORT_SYMBOL_GPL(llcrypt_drop_inode);
+
+inline bool llcrypt_has_encryption_key(const struct inode *inode)
+{
+	/* pairs with cmpxchg_release() in llcrypt_get_encryption_info() */
+	return READ_ONCE(llcrypt_info_nocast(inode)) != NULL;
+}
+EXPORT_SYMBOL_GPL(llcrypt_has_encryption_key);
--- a/libcfs/libcfs/crypto/llcrypt_private.h
+++ b/libcfs/libcfs/crypto/llcrypt_private.h
@@ -19,6 +19,9 @@
 #define CRYPTO_TFM_REQ_FORBID_WEAK_KEYS CRYPTO_TFM_REQ_WEAK_KEY
 #endif
 
+#define llcrypt_info(inode)	     ((struct llcrypt_info *)(inode)->i_private)
+#define llcrypt_info_nocast(inode)   ((inode)->i_private)
+
 #define CONST_STRLEN(str)	(sizeof(str) - 1)
 
 #define FS_KEY_DERIVATION_NONCE_SIZE	16
@@ -160,8 +163,8 @@ struct llcrypt_symlink_data {
  * llcrypt_info - the "encryption key" for an inode
  *
  * When an encrypted file's key is made available, an instance of this struct is
- * allocated and stored in ->i_crypt_info.  Once created, it remains until the
- * inode is evicted.
+ * allocated and stored in '(struct llcrypt_info *)inode->i_private'.
+ * Once created, it remains until the inode is evicted.
  */
 struct llcrypt_info {
 
--- a/libcfs/libcfs/crypto/policy.c
+++ b/libcfs/libcfs/crypto/policy.c
@@ -212,7 +212,7 @@ static int llcrypt_get_policy(struct ino
 	struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
 	int ret;
 
-	ci = READ_ONCE(inode->i_crypt_info);
+	ci = (struct llcrypt_info *)READ_ONCE(llcrypt_info_nocast(inode));
 	if (ci) {
 		/* key available, use the cached policy */
 		*policy = ci->ci_policy;
@@ -472,7 +472,7 @@ EXPORT_SYMBOL(llcrypt_has_permitted_cont
  * @parent: Parent inode from which the context is inherited.
  * @child:  Child inode that inherits the context from @parent.
  * @fs_data:  private data given by FS.
- * @preload:  preload child i_crypt_info if true
+ * @preload:  preload child crypt info if true
  *
  * Return: 0 on success, -errno on failure
  */
@@ -489,7 +489,7 @@ int llcrypt_inherit_context(struct inode
 	if (res < 0)
 		return res;
 
-	ci = READ_ONCE(parent->i_crypt_info);
+	ci = (struct llcrypt_info *)READ_ONCE(llcrypt_info_nocast(parent));
 	if (ci == NULL)
 		return -ENOKEY;