linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC DRAFT DOESNOTBUILD] inode: free up more space
@ 2025-07-15 14:35 Christian Brauner
  2025-07-15 14:52 ` Jeff Layton
                   ` (4 more replies)
  0 siblings, 5 replies; 96+ messages in thread
From: Christian Brauner @ 2025-07-15 14:35 UTC (permalink / raw)
  To: Jeff Layton, Jan Kara, Christoph Hellwig, Jens Axboe, Josef Bacik
  Cc: linux-fsdevel, Christian Brauner

struct inode is bloated as everyone is aware and we should try and
shrink it as that's potentially a lot of memory savings. I've already
freed up around 8 bytes but we can probably do better.

There's a bunch of stuff that got shoved into struct inode that I don't
think deserves a spot in there. There are two members I'm currently
particularly interested in:

(1) #ifdef CONFIG_FS_ENCRYPTION
            struct fscrypt_inode_info *i_crypt_info;
    #endif

    ceph, ext4, f2fs, ubifs

(2) #ifdef CONFIG_FS_VERITY
            struct fsverity_info *i_verity_info;
    #endif

    btrfs, ext4, f2fs

So we have 4 users for fscrypt and 3 users for fsverity with both
features having been around for a decent amount of time.

For all other filesystems the 16 bytes are just wasted bloating inodes
for every pseudo filesystem and most other regular filesystems.

We should be able to move both of these out of struct inode by adding
inode operations and making it the filesystem's responsibility to
accommodate the information in their respective inodes.

Unless there are severe performance penalties for the extra pointer
dereferences getting our hands on 16 bytes is a good reason to at least
consider doing this.

I've drafted one way of doing this using ext4 as my victim^wexample. I'd
like to hear some early feedback whether this is something we would want
to pursue.

Build failures very much expected!

Not-Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/crypto/bio.c             |  2 +-
 fs/crypto/crypto.c          |  8 ++++----
 fs/crypto/fname.c           |  8 ++++----
 fs/crypto/fscrypt_private.h |  3 +--
 fs/crypto/hooks.c           |  2 +-
 fs/crypto/inline_crypt.c    | 10 +++++-----
 fs/crypto/keysetup.c        | 21 ++++----------------
 fs/crypto/policy.c          |  8 ++++----
 fs/ext4/ext4.h              |  9 +++++++++
 fs/ext4/file.c              |  4 ++++
 fs/ext4/namei.c             | 22 +++++++++++++++++++++
 fs/ext4/super.c             |  6 +++++-
 fs/ext4/symlink.c           | 12 ++++++++++++
 include/linux/fs.h          |  9 +++++----
 include/linux/fscrypt.h     | 47 ++++++++++++++++++++++++++++++---------------
 15 files changed, 112 insertions(+), 59 deletions(-)

diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
index 0ad8c30b8fa5..f541e6b3a9cc 100644
--- a/fs/crypto/bio.c
+++ b/fs/crypto/bio.c
@@ -111,7 +111,7 @@ static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,
 int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
 			  sector_t pblk, unsigned int len)
 {
-	const struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	const struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(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;
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index b74b5937e695..c480f6867101 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -181,7 +181,7 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio,
 		size_t len, size_t offs, gfp_t gfp_flags)
 {
 	const struct inode *inode = folio->mapping->host;
-	const struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	const struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 	const unsigned int du_bits = ci->ci_data_unit_bits;
 	const unsigned int du_size = 1U << du_bits;
 	struct page *ciphertext_page;
@@ -241,7 +241,7 @@ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
 {
 	if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
 		return -EOPNOTSUPP;
-	return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_ENCRYPT,
+	return fscrypt_crypt_data_unit(inode->i_op->get_fscrypt(inode), FS_ENCRYPT,
 				       lblk_num, page, page, len, offs,
 				       gfp_flags);
 }
@@ -265,7 +265,7 @@ int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len,
 				     size_t offs)
 {
 	const struct inode *inode = folio->mapping->host;
-	const struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	const struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 	const unsigned int du_bits = ci->ci_data_unit_bits;
 	const unsigned int du_size = 1U << du_bits;
 	u64 index = ((u64)folio->index << (PAGE_SHIFT - du_bits)) +
@@ -316,7 +316,7 @@ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
 {
 	if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
 		return -EOPNOTSUPP;
-	return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_DECRYPT,
+	return fscrypt_crypt_data_unit(inode->i_op->get_fscrypt(inode), FS_DECRYPT,
 				       lblk_num, page, page, len, offs,
 				       GFP_NOFS);
 }
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 010f9c0a4c2f..a0317df113a9 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -94,7 +94,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
 {
 	struct skcipher_request *req = NULL;
 	DECLARE_CRYPTO_WAIT(wait);
-	const struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	const struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 	struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
 	union fscrypt_iv iv;
 	struct scatterlist sg;
@@ -151,7 +151,7 @@ static int fname_decrypt(const struct inode *inode,
 	struct skcipher_request *req = NULL;
 	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src_sg, dst_sg;
-	const struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	const struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 	struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
 	union fscrypt_iv iv;
 	int res;
@@ -293,7 +293,7 @@ bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
 bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
 				  u32 max_len, u32 *encrypted_len_ret)
 {
-	return __fscrypt_fname_encrypted_size(&inode->i_crypt_info->ci_policy,
+	return __fscrypt_fname_encrypted_size(&inode->i_op->get_fscrypt(inode)->ci_policy,
 					      orig_len, max_len,
 					      encrypted_len_ret);
 }
@@ -562,7 +562,7 @@ EXPORT_SYMBOL_GPL(fscrypt_match_name);
  */
 u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name)
 {
-	const struct fscrypt_inode_info *ci = dir->i_crypt_info;
+	const struct fscrypt_inode_info *ci = dir->i_op->get_fscrypt(dir);
 
 	WARN_ON_ONCE(!ci->ci_dirhash_key_initialized);
 
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index c1d92074b65c..ddc3c86494cf 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -231,8 +231,7 @@ struct fscrypt_prepared_key {
  * fscrypt_inode_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.  Once created, it remains until the inode is evicted.
  */
 struct fscrypt_inode_info {
 
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index d8d5049b8fe1..a45763da352e 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -197,7 +197,7 @@ int fscrypt_prepare_setflags(struct inode *inode,
 		err = fscrypt_require_key(inode);
 		if (err)
 			return err;
-		ci = inode->i_crypt_info;
+		ci = inode->i_op->get_fscrypt(inode);
 		if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
 			return -EINVAL;
 		mk = ci->ci_master_key;
diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c
index 1d008c440cb6..f5a6560a9c2e 100644
--- a/fs/crypto/inline_crypt.c
+++ b/fs/crypto/inline_crypt.c
@@ -262,7 +262,7 @@ int fscrypt_derive_sw_secret(struct super_block *sb,
 
 bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
 {
-	return inode->i_crypt_info->ci_inlinecrypt;
+	return inode->i_op->get_fscrypt(inode)->ci_inlinecrypt;
 }
 EXPORT_SYMBOL_GPL(__fscrypt_inode_uses_inline_crypto);
 
@@ -306,7 +306,7 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,
 
 	if (!fscrypt_inode_uses_inline_crypto(inode))
 		return;
-	ci = inode->i_crypt_info;
+	ci = inode->i_op->get_fscrypt(inode);
 
 	fscrypt_generate_dun(ci, first_lblk, dun);
 	bio_crypt_set_ctx(bio, ci->ci_enc_key.blk_key, dun, gfp_mask);
@@ -396,10 +396,10 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
 	 * uses the same pointer.  I.e., there's currently no need to support
 	 * merging requests where the keys are the same but the pointers differ.
 	 */
-	if (bc->bc_key != inode->i_crypt_info->ci_enc_key.blk_key)
+	if (bc->bc_key != inode->i_op->get_fscrypt(inode)->ci_enc_key.blk_key)
 		return false;
 
-	fscrypt_generate_dun(inode->i_crypt_info, next_lblk, next_dun);
+	fscrypt_generate_dun(inode->i_op->get_fscrypt(inode), next_lblk, next_dun);
 	return bio_crypt_dun_is_contiguous(bc, bio->bi_iter.bi_size, next_dun);
 }
 EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio);
@@ -501,7 +501,7 @@ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks)
 	if (nr_blocks <= 1)
 		return nr_blocks;
 
-	ci = inode->i_crypt_info;
+	ci = inode->i_op->get_fscrypt(inode);
 	if (!(fscrypt_policy_flags(&ci->ci_policy) &
 	      FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
 		return nr_blocks;
diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
index 0d71843af946..90e1ea83c573 100644
--- a/fs/crypto/keysetup.c
+++ b/fs/crypto/keysetup.c
@@ -568,7 +568,7 @@ static int setup_file_encryption_key(struct fscrypt_inode_info *ci,
 	return err;
 }
 
-static void put_crypt_info(struct fscrypt_inode_info *ci)
+void put_crypt_info(struct fscrypt_inode_info *ci)
 {
 	struct fscrypt_master_key *mk;
 
@@ -597,6 +597,7 @@ static void put_crypt_info(struct fscrypt_inode_info *ci)
 	memzero_explicit(ci, sizeof(*ci));
 	kmem_cache_free(fscrypt_inode_info_cachep, ci);
 }
+EXPORT_SYMBOL(put_crypt_info);
 
 static int
 fscrypt_setup_encryption_info(struct inode *inode,
@@ -644,7 +645,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
 	 * fscrypt_get_inode_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, crypt_info) == NULL) {
+	if (!inode->i_op->set_fscrypt(crypt_info, inode)) {
 		/*
 		 * We won the race and set ->i_crypt_info to our crypt_info.
 		 * Now link it into the master key's inode list.
@@ -788,20 +789,6 @@ int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
 }
 EXPORT_SYMBOL_GPL(fscrypt_prepare_new_inode);
 
-/**
- * fscrypt_put_encryption_info() - free most of an inode's fscrypt data
- * @inode: an inode being evicted
- *
- * Free the inode's fscrypt_inode_info.  Filesystems must call this when the
- * inode is being evicted.  An RCU grace period need not have elapsed yet.
- */
-void fscrypt_put_encryption_info(struct inode *inode)
-{
-	put_crypt_info(inode->i_crypt_info);
-	inode->i_crypt_info = NULL;
-}
-EXPORT_SYMBOL(fscrypt_put_encryption_info);
-
 /**
  * fscrypt_free_inode() - free an inode's fscrypt data requiring RCU delay
  * @inode: an inode being freed
@@ -830,7 +817,7 @@ EXPORT_SYMBOL(fscrypt_free_inode);
  */
 int fscrypt_drop_inode(struct inode *inode)
 {
-	const struct fscrypt_inode_info *ci = fscrypt_get_inode_info(inode);
+	const struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 
 	/*
 	 * If ci is NULL, then the inode doesn't have an encryption key set up
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
index 701259991277..694d1ed26eeb 100644
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -436,7 +436,7 @@ static int fscrypt_get_policy(struct inode *inode, union fscrypt_policy *policy)
 	union fscrypt_context ctx;
 	int ret;
 
-	ci = fscrypt_get_inode_info(inode);
+	ci = inode->i_op->get_fscrypt(inode);
 	if (ci) {
 		/* key available, use the cached policy */
 		*policy = ci->ci_policy;
@@ -725,7 +725,7 @@ const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir)
 		err = fscrypt_require_key(dir);
 		if (err)
 			return ERR_PTR(err);
-		return &dir->i_crypt_info->ci_policy;
+		return &dir->i_op->get_fscrypt(dir)->ci_policy;
 	}
 
 	return fscrypt_get_dummy_policy(dir->i_sb);
@@ -744,7 +744,7 @@ const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir)
  */
 int fscrypt_context_for_new_inode(void *ctx, struct inode *inode)
 {
-	struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 
 	BUILD_BUG_ON(sizeof(union fscrypt_context) !=
 			FSCRYPT_SET_CONTEXT_MAX_SIZE);
@@ -769,7 +769,7 @@ EXPORT_SYMBOL_GPL(fscrypt_context_for_new_inode);
  */
 int fscrypt_set_context(struct inode *inode, void *fs_data)
 {
-	struct fscrypt_inode_info *ci = inode->i_crypt_info;
+	struct fscrypt_inode_info *ci = inode->i_op->get_fscrypt(inode);
 	union fscrypt_context ctx;
 	int ctxsize;
 
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 18373de980f2..34685eec6245 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1197,6 +1197,10 @@ struct ext4_inode_info {
 	__u32 i_csum_seed;
 
 	kprojid_t i_projid;
+
+#ifdef CONFIG_FS_ENCRYPTION
+	struct fscrypt_inode_info	*i_fscrypt_info;
+#endif
 };
 
 /*
@@ -3904,6 +3908,11 @@ static inline bool ext4_inode_can_atomic_write(struct inode *inode)
 extern int ext4_block_write_begin(handle_t *handle, struct folio *folio,
 				  loff_t pos, unsigned len,
 				  get_block_t *get_block);
+#ifdef CONFIG_FS_ENCRYPTION
+struct fscrypt_inode_info *ext4_get_fscrypt(const struct inode *inode);
+int ext4_set_fscrypt(struct fscrypt_inode_info *fscrypt_info,struct inode *inode);
+#endif
+
 #endif	/* __KERNEL__ */
 
 #define EFSBADCRC	EBADMSG		/* Bad CRC detected */
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 21df81347147..676d33a7d842 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -989,5 +989,9 @@ const struct inode_operations ext4_file_inode_operations = {
 	.fiemap		= ext4_fiemap,
 	.fileattr_get	= ext4_fileattr_get,
 	.fileattr_set	= ext4_fileattr_set,
+#ifdef CONFIG_FS_ENCRYPTION
+	.get_fscrypt	= ext4_get_fscrypt,
+	.set_fscrypt	= ext4_set_fscrypt,
+#endif
 };
 
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index a178ac229489..a27c5925c836 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -4203,6 +4203,20 @@ static int ext4_rename2(struct mnt_idmap *idmap,
 	return ext4_rename(idmap, old_dir, old_dentry, new_dir, new_dentry, flags);
 }
 
+#ifdef CONFIG_FS_ENCRYPTION
+struct fscrypt_inode_info *ext4_get_fscrypt(const struct inode *inode)
+{
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	return fscrypt_inode_info_get(&ei->i_fscrypt_info);
+}
+
+int ext4_set_fscrypt(struct fscrypt_inode_info *fscrypt_info, struct inode *inode)
+{
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	return fscrypt_inode_info_set(fscrypt_info, &ei->i_fscrypt_info);
+}
+#endif
+
 /*
  * directories can handle most operations...
  */
@@ -4225,6 +4239,10 @@ const struct inode_operations ext4_dir_inode_operations = {
 	.fiemap         = ext4_fiemap,
 	.fileattr_get	= ext4_fileattr_get,
 	.fileattr_set	= ext4_fileattr_set,
+#ifdef CONFIG_FS_ENCRYPTION
+	.get_fscrypt	= ext4_get_fscrypt,
+	.set_fscrypt	= ext4_set_fscrypt,
+#endif
 };
 
 const struct inode_operations ext4_special_inode_operations = {
@@ -4233,4 +4251,8 @@ const struct inode_operations ext4_special_inode_operations = {
 	.listxattr	= ext4_listxattr,
 	.get_inode_acl	= ext4_get_acl,
 	.set_acl	= ext4_set_acl,
+#ifdef CONFIG_FS_ENCRYPTION
+	.get_fscrypt	= ext4_get_fscrypt,
+	.set_fscrypt	= ext4_set_fscrypt,
+#endif
 };
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index c7d39da7e733..972b057b0d00 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1412,6 +1412,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
 	INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work);
 	ext4_fc_init_inode(&ei->vfs_inode);
 	spin_lock_init(&ei->i_fc_lock);
+#ifdef CONFIG_FS_ENCRYPTION
+	ei->i_fscrypt_info = NULL;
+#endif
 	return &ei->vfs_inode;
 }
 
@@ -1509,7 +1512,8 @@ void ext4_clear_inode(struct inode *inode)
 		jbd2_free_inode(EXT4_I(inode)->jinode);
 		EXT4_I(inode)->jinode = NULL;
 	}
-	fscrypt_put_encryption_info(inode);
+	put_crypt_info(EXT4_I(inode)->i_fscrypt_info);
+	EXT4_I(inode)->i_fscrypt_info = NULL;
 	fsverity_cleanup_inode(inode);
 }
 
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index 645240cc0229..ee3f71e406ce 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -119,6 +119,10 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.setattr	= ext4_setattr,
 	.getattr	= ext4_encrypted_symlink_getattr,
 	.listxattr	= ext4_listxattr,
+#ifdef CONFIG_FS_ENCRYPTION
+	.get_fscrypt	= ext4_get_fscrypt,
+	.set_fscrypt	= ext4_set_fscrypt,
+#endif
 };
 
 const struct inode_operations ext4_symlink_inode_operations = {
@@ -126,6 +130,10 @@ const struct inode_operations ext4_symlink_inode_operations = {
 	.setattr	= ext4_setattr,
 	.getattr	= ext4_getattr,
 	.listxattr	= ext4_listxattr,
+#ifdef CONFIG_FS_ENCRYPTION
+	.get_fscrypt	= ext4_get_fscrypt,
+	.set_fscrypt	= ext4_set_fscrypt,
+#endif
 };
 
 const struct inode_operations ext4_fast_symlink_inode_operations = {
@@ -133,4 +141,8 @@ const struct inode_operations ext4_fast_symlink_inode_operations = {
 	.setattr	= ext4_setattr,
 	.getattr	= ext4_getattr,
 	.listxattr	= ext4_listxattr,
+#ifdef CONFIG_FS_ENCRYPTION
+	.get_fscrypt	= ext4_get_fscrypt,
+	.set_fscrypt	= ext4_set_fscrypt,
+#endif
 };
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 96c7925a6551..600b878f41ab 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -778,10 +778,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
@@ -2257,6 +2253,11 @@ struct inode_operations {
 			    struct dentry *dentry, struct fileattr *fa);
 	int (*fileattr_get)(struct dentry *dentry, struct fileattr *fa);
 	struct offset_ctx *(*get_offset_ctx)(struct inode *inode);
+#ifdef CONFIG_FS_ENCRYPTION
+	struct fscrypt_inode_info *(*get_fscrypt)(const struct inode *inode);
+	int (*set_fscrypt)(struct fscrypt_inode_info *fscrypt_info,
+			   struct inode *inode);
+#endif
 } ____cacheline_aligned;
 
 /* Did the driver provide valid mmap hook configuration? */
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 56fad33043d5..7ac612fec6bb 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -195,18 +195,6 @@ struct fscrypt_operations {
 int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name,
 			 struct dentry *dentry, unsigned int flags);
 
-static inline struct fscrypt_inode_info *
-fscrypt_get_inode_info(const struct inode *inode)
-{
-	/*
-	 * Pairs with the cmpxchg_release() in fscrypt_setup_encryption_info().
-	 * I.e., another task may publish ->i_crypt_info concurrently, executing
-	 * a RELEASE barrier.  We need to use smp_load_acquire() here to safely
-	 * ACQUIRE the memory the other task published.
-	 */
-	return smp_load_acquire(&inode->i_crypt_info);
-}
-
 /**
  * fscrypt_needs_contents_encryption() - check whether an inode needs
  *					 contents encryption
@@ -385,7 +373,7 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg);
 /* keysetup.c */
 int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
 			      bool *encrypt_ret);
-void fscrypt_put_encryption_info(struct inode *inode);
+void put_crypt_info(struct fscrypt_inode_info *ci);
 void fscrypt_free_inode(struct inode *inode);
 int fscrypt_drop_inode(struct inode *inode);
 
@@ -446,10 +434,37 @@ static inline void fscrypt_set_ops(struct super_block *sb,
 {
 	sb->s_cop = s_cop;
 }
+
+static inline int fscrypt_inode_info_set(struct fscrypt_inode_info *crypt_info,
+					 struct fscrypt_inode_info **p)
+{
+	if (cmpxchg_release(p, NULL, crypt_info) != NULL)
+		return -EEXIST;
+	return 0;
+}
+
+static inline struct fscrypt_inode_info *
+fscrypt_inode_info_get(struct fscrypt_inode_info **crypt_info)
+{
+	/*
+	 * Pairs with the cmpxchg_release() in fscrypt_inode_info_set(). I.e.,
+	 * another task may publish crypt_info concurrently, executing a
+	 * RELEASE barrier.  We need to use smp_load_acquire() here to safely
+	 * ACQUIRE the memory the other task published (could be a READ_ONCE()
+	 * really).
+	 */
+	return smp_load_acquire(crypt_info);
+}
 #else  /* !CONFIG_FS_ENCRYPTION */
 
+static inline int fscrypt_inode_info_set(struct fscrypt_inode_info *crypt_info,
+					 struct fscrypt_inode_info **p)
+{
+	return 0;
+}
+
 static inline struct fscrypt_inode_info *
-fscrypt_get_inode_info(const struct inode *inode)
+fscrypt_inode_info_get(const struct fscrypt_inode_info **crypt_info)
 {
 	return NULL;
 }
@@ -639,7 +654,7 @@ static inline int fscrypt_prepare_new_inode(struct inode *dir,
 	return 0;
 }
 
-static inline void fscrypt_put_encryption_info(struct inode *inode)
+static inline void put_crypt_info(struct fscrypt_inode_info *ci)
 {
 	return;
 }
@@ -930,7 +945,7 @@ static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode)
  */
 static inline bool fscrypt_has_encryption_key(const struct inode *inode)
 {
-	return fscrypt_get_inode_info(inode) != NULL;
+	return inode->i_op->get_fscrypt(inode) != NULL;
 }
 
 /**

---
base-commit: 19272b37aa4f83ca52bdf9c16d5d81bdd1354494
change-id: 20250715-work-inode-fscrypt-2b63b276e793


^ permalink raw reply related	[flat|nested] 96+ messages in thread

end of thread, other threads:[~2025-07-25  8:15 UTC | newest]

Thread overview: 96+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-15 14:35 [PATCH RFC DRAFT DOESNOTBUILD] inode: free up more space Christian Brauner
2025-07-15 14:52 ` Jeff Layton
2025-07-15 16:09 ` Matthew Wilcox
2025-07-16 12:53   ` Christian Brauner
2025-07-16 13:02   ` Christoph Hellwig
2025-07-17  7:48     ` Christian Brauner
2025-07-17  7:51       ` Christoph Hellwig
2025-07-17 15:55         ` Darrick J. Wong
2025-07-16  9:15 ` Jan Kara
2025-07-16  9:50   ` Christian Brauner
2025-07-16 11:21 ` Christoph Hellwig
2025-07-16 12:19   ` Christian Brauner
2025-07-16 12:38     ` Jeff Layton
2025-07-16 14:08       ` Matthew Wilcox
2025-07-16 14:10         ` Christoph Hellwig
2025-07-17  8:32           ` Christian Brauner
2025-07-17 10:54             ` Jan Kara
2025-07-17 11:40               ` Christian Brauner
2025-07-17 11:43                 ` Christoph Hellwig
2025-07-17 12:57     ` Jan Kara
2025-07-18  8:24       ` Christian Brauner
2025-07-18  8:32         ` Christoph Hellwig
2025-07-18  8:58           ` Christian Brauner
2025-07-18 16:04 ` Eric Biggers
2025-07-18 17:11   ` Eric Biggers
2025-07-21  6:14   ` Christoph Hellwig
2025-07-21 23:55     ` Eric Biggers
2025-07-22  5:49       ` Christoph Hellwig
2025-07-22  7:52       ` Jan Kara
2025-07-22 12:57         ` [PATCH RFC DRAFT v2 00/13] Move fscrypt and fsverity out of struct inode Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 01/13] fs: add fscrypt offset Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 02/13] fs/crypto: use accessors Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 03/13] ext4: move fscrypt to filesystem inode Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 04/13] ubifs: " Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 05/13] f2fs: " Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 06/13] ceph: " Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 07/13] fs: drop i_crypt_info from struct inode Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 08/13] fs: add fsverity offset Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 09/13] fs/verity: use accessors Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 10/13] btrfs: move fsverity to filesystem inode Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 11/13] ext4: " Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 12/13] f2fs: " Christian Brauner
2025-07-22 12:57           ` [PATCH RFC DRAFT v2 13/13] fs: drop i_verity_info from struct inode Christian Brauner
2025-07-22 13:09           ` [PATCH RFC DRAFT v2 00/13] Move fscrypt and fsverity out of " Christian Brauner
2025-07-22 19:27             ` [PATCH v3 " Christian Brauner
2025-07-22 19:27               ` [PATCH v3 01/13] fs: add fscrypt offset Christian Brauner
2025-07-22 20:02                 ` Eric Biggers
2025-07-23  7:48                   ` Christian Brauner
2025-07-23  3:49                 ` Al Viro
2025-07-22 19:27               ` [PATCH v3 02/13] fs/crypto: use accessors Christian Brauner
2025-07-22 19:27               ` [PATCH v3 03/13] ext4: move fscrypt to filesystem inode Christian Brauner
2025-07-22 20:07                 ` Eric Biggers
2025-07-23  8:59                   ` Christian Brauner
2025-07-22 19:27               ` [PATCH v3 04/13] ubifs: " Christian Brauner
2025-07-22 19:27               ` [PATCH v3 05/13] f2fs: " Christian Brauner
2025-07-22 19:27               ` [PATCH v3 06/13] ceph: " Christian Brauner
2025-07-22 20:14                 ` Eric Biggers
2025-07-23  8:58                   ` Christian Brauner
2025-07-22 19:27               ` [PATCH v3 07/13] fs: drop i_crypt_info from struct inode Christian Brauner
2025-07-22 20:19                 ` Eric Biggers
2025-07-23  8:52                   ` Christian Brauner
2025-07-22 19:27               ` [PATCH v3 08/13] fs: add fsverity offset Christian Brauner
2025-07-23  3:53                 ` Al Viro
2025-07-22 19:27               ` [PATCH v3 09/13] fs/verity: use accessors Christian Brauner
2025-07-22 20:25                 ` Eric Biggers
2025-07-23  8:55                   ` Christian Brauner
2025-07-22 19:27               ` [PATCH v3 10/13] btrfs: move fsverity to filesystem inode Christian Brauner
2025-07-22 19:27               ` [PATCH v3 11/13] ext4: " Christian Brauner
2025-07-22 19:27               ` [PATCH v3 12/13] f2fs: " Christian Brauner
2025-07-22 19:27               ` [PATCH v3 13/13] fs: drop i_verity_info from struct inode Christian Brauner
2025-07-23 10:57               ` [PATCH v4 00/15] Move fscrypt and fsverity out of " Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 01/15] fs: add fscrypt offset Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 02/15] fs/crypto: use accessors Christian Brauner
2025-07-25  0:29                   ` Eric Biggers
2025-07-25  4:01                   ` Eric Biggers
2025-07-23 10:57                 ` [PATCH v4 03/15] ext4: move fscrypt to filesystem inode Christian Brauner
2025-07-25  0:32                   ` Eric Biggers
2025-07-23 10:57                 ` [PATCH v4 04/15] ubifs: " Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 05/15] f2fs: " Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 06/15] ceph: " Christian Brauner
2025-07-25  0:34                   ` Eric Biggers
2025-07-25  8:15                     ` Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 07/15] fs: drop i_crypt_info from struct inode Christian Brauner
2025-07-25  0:38                   ` Eric Biggers
2025-07-23 10:57                 ` [PATCH v4 08/15] fscrypt: rephrase documentation and comments Christian Brauner
2025-07-25  0:35                   ` Eric Biggers
2025-07-23 10:57                 ` [PATCH v4 09/15] fs: add fsverity offset Christian Brauner
2025-07-25  0:45                   ` Eric Biggers
2025-07-23 10:57                 ` [PATCH v4 10/15] fs/verity: use accessors Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 11/15] btrfs: move fsverity to filesystem inode Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 12/15] ext4: " Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 13/15] f2fs: " Christian Brauner
2025-07-23 10:57                 ` [PATCH v4 14/15] fs: drop i_verity_info from struct inode Christian Brauner
2025-07-25  0:43                   ` Eric Biggers
2025-07-23 10:57                 ` [PATCH v4 15/15] fsverity: rephrase documentation and comments Christian Brauner
2025-07-22 13:50           ` [PATCH RFC DRAFT v2 00/13] Move fscrypt and fsverity out of struct inode Jeff Layton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).