[PATCH v4 07/15] fs: drop i_crypt_info from struct inode

Christian Brauner
2025-07-23T10:58:25Z

Now that all filesystems store the fscrypt data pointer in their private
inode, drop the data pointer from struct inode itself freeing up 8
bytes.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
fs/crypto/keysetup.c | 9 +++++----
include/linux/fs.h | 5 -----
include/linux/fscrypt.h | 23 +++++++----------------
3 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
index 8fd89ce0b614..352d0cfda17d 100644
--- a/fs/crypto/keysetup.c
+++ b/fs/crypto/keysetup.c
@@ -799,10 +799,11 @@ void fscrypt_put_encryption_info(struct inode *inode)
{
struct fscrypt_inode_info **crypt_info;

- if (inode->i_sb->s_cop->inode_info_offs)
- crypt_info = fscrypt_addr(inode);
- else
- crypt_info = &inode->i_crypt_info;
+ if (!IS_ENCRYPTED(inode))
+ return;
+ VFS_WARN_ON_ONCE(!inode->i_sb->s_cop);
+ VFS_WARN_ON_ONCE(!inode->i_sb->s_cop->inode_info_offs);
+ crypt_info = fscrypt_addr(inode);
put_crypt_info(*crypt_info);
*crypt_info = NULL;
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 96c7925a6551..b76a10fc765b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -72,7 +72,6 @@ struct swap_info_struct;
struct seq_file;
struct workqueue_struct;
struct iov_iter;
-struct fscrypt_inode_info;
struct fscrypt_operations;
struct fsverity_info;
struct fsverity_operations;
@@ -778,10 +777,6 @@ struct inode {
struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
#endif

-#ifdef CONFIG_FS_ENCRYPTION
- struct fscrypt_inode_info *i_crypt_info;
-#endif
-
#ifdef CONFIG_FS_VERITY
struct fsverity_info *i_verity_info;
#endif
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 123871dd394c..a62879456873 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -208,28 +208,21 @@ static inline struct fscrypt_inode_info **fscrypt_addr(const struct inode *inode
static inline bool fscrypt_set_inode_info(struct inode *inode,
struct fscrypt_inode_info *crypt_info)
{
- void *p;
-
/*
* 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_inode_info(). I.e., here we publish ->i_crypt_info with
* a RELEASE barrier so that other tasks can ACQUIRE it.
*/
-
- if (inode->i_sb->s_cop->inode_info_offs)
- p = cmpxchg_release(fscrypt_addr(inode), NULL, crypt_info);
- else
- p = cmpxchg_release(&inode->i_crypt_info, NULL, crypt_info);
- return p == NULL;
+ return cmpxchg_release(fscrypt_addr(inode), NULL, crypt_info) == NULL;
}

static inline struct fscrypt_inode_info *
fscrypt_get_inode_info_raw(const struct inode *inode)
{
- if (inode->i_sb->s_cop->inode_info_offs)
- return *fscrypt_addr(inode);
- return inode->i_crypt_info;
+ VFS_WARN_ON_ONCE(!inode->i_sb->s_cop);
+ VFS_WARN_ON_ONCE(!inode->i_sb->s_cop->inode_info_offs);
+ return *fscrypt_addr(inode);
}

static inline struct fscrypt_inode_info *
@@ -241,11 +234,9 @@ fscrypt_get_inode_info(const struct inode *inode)
* a RELEASE barrier. We need to use smp_load_acquire() here to safely
* ACQUIRE the memory the other task published.
*/
-
- if (inode->i_sb->s_cop->inode_info_offs)
- return smp_load_acquire(fscrypt_addr(inode));
-
- return smp_load_acquire(&inode->i_crypt_info);
+ VFS_WARN_ON_ONCE(!inode->i_sb->s_cop);
+ VFS_WARN_ON_ONCE(!inode->i_sb->s_cop->inode_info_offs);
+ return smp_load_acquire(fscrypt_addr(inode));
}

/**

--
2.47.2