Skip to content

Commit f0883b9

Browse files
committed
Merge patch series "Move fscrypt and fsverity info out of struct inode"
Eric Biggers <ebiggers@kernel.org> says: This is a cleaned-up implementation of moving the i_crypt_info and i_verity_info pointers out of 'struct inode' and into the fs-specific part of the inode, as proposed previously by Christian at https://lore.kernel.org/r/20250723-work-inode-fscrypt-v4-0-c8e11488a0e6@kernel.org/ The high-level concept is still the same: fs/crypto/ and fs/verity/ locate the pointer by adding an offset to the address of struct inode. The offset is retrieved from fscrypt_operations or fsverity_operations. I've cleaned up a lot of the details, including: - Grouped changes into patches differently - Rewrote commit messages and comments to be clearer - Adjusted code formatting to be consistent with existing code - Removed unneeded #ifdefs - Improved choice and location of VFS_WARN_ON_ONCE() statements - Added missing kerneldoc for ubifs_inode::i_crypt_info - Moved field initialization to init_once functions when they exist - Improved ceph offset calculation and removed unneeded static_asserts - fsverity_get_info() now checks IS_VERITY() instead of v_ops - fscrypt_put_encryption_info() no longer checks IS_ENCRYPTED(), since I no longer think it's actually correct there. - verity_data_blocks() now keeps doing a raw dereference - Dropped fscrypt_set_inode_info() - Renamed some functions - Do offset calculation using int, so we don't rely on unsigned overflow - And more. * patches from https://lore.kernel.org/20250810075706.172910-1-ebiggers@kernel.org: fsverity: check IS_VERITY() in fsverity_cleanup_inode() fs: remove inode::i_verity_info btrfs: move verity info pointer to fs-specific part of inode f2fs: move verity info pointer to fs-specific part of inode ext4: move verity info pointer to fs-specific part of inode fsverity: add support for info in fs-specific part of inode fs: remove inode::i_crypt_info ceph: move crypt info pointer to fs-specific part of inode ubifs: move crypt info pointer to fs-specific part of inode f2fs: move crypt info pointer to fs-specific part of inode ext4: move crypt info pointer to fs-specific part of inode fscrypt: add support for info in fs-specific part of inode fscrypt: replace raw loads of info pointer with helper function Link: https://lore.kernel.org/20250810075706.172910-1-ebiggers@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents 8f5ae30 + 8a3d00d commit f0883b9

30 files changed

Lines changed: 215 additions & 83 deletions

fs/btrfs/btrfs_inode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,11 @@ struct btrfs_inode {
338338
struct list_head delayed_iput;
339339

340340
struct rw_semaphore i_mmap_lock;
341+
342+
#ifdef CONFIG_FS_VERITY
343+
struct fsverity_info *i_verity_info;
344+
#endif
345+
341346
struct inode vfs_inode;
342347
};
343348

fs/btrfs/inode.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7961,6 +7961,9 @@ static void init_once(void *foo)
79617961
struct btrfs_inode *ei = foo;
79627962

79637963
inode_init_once(&ei->vfs_inode);
7964+
#ifdef CONFIG_FS_VERITY
7965+
ei->i_verity_info = NULL;
7966+
#endif
79647967
}
79657968

79667969
void __cold btrfs_destroy_cachep(void)

fs/btrfs/verity.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ static int btrfs_write_merkle_tree_block(struct inode *inode, const void *buf,
802802
}
803803

804804
const struct fsverity_operations btrfs_verityops = {
805+
.inode_info_offs = (int)offsetof(struct btrfs_inode, i_verity_info) -
806+
(int)offsetof(struct btrfs_inode, vfs_inode),
805807
.begin_enable_verity = btrfs_begin_enable_verity,
806808
.end_enable_verity = btrfs_end_enable_verity,
807809
.get_verity_descriptor = btrfs_get_verity_descriptor,

fs/ceph/crypto.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ static const union fscrypt_policy *ceph_get_dummy_policy(struct super_block *sb)
133133
}
134134

135135
static struct fscrypt_operations ceph_fscrypt_ops = {
136+
.inode_info_offs = (int)offsetof(struct ceph_inode_info, i_crypt_info) -
137+
(int)offsetof(struct ceph_inode_info, netfs.inode),
136138
.needs_bounce_pages = 1,
137139
.get_context = ceph_crypt_get_context,
138140
.set_context = ceph_crypt_set_context,

fs/ceph/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
665665
ci->i_work_mask = 0;
666666
memset(&ci->i_btime, '\0', sizeof(ci->i_btime));
667667
#ifdef CONFIG_FS_ENCRYPTION
668+
ci->i_crypt_info = NULL;
668669
ci->fscrypt_auth = NULL;
669670
ci->fscrypt_auth_len = 0;
670671
#endif

fs/ceph/super.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ struct ceph_inode_info {
463463
unsigned long i_work_mask;
464464

465465
#ifdef CONFIG_FS_ENCRYPTION
466+
struct fscrypt_inode_info *i_crypt_info;
466467
u32 fscrypt_auth_len;
467468
u32 fscrypt_file_len;
468469
u8 *fscrypt_auth;

fs/crypto/bio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,
113113
int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
114114
sector_t pblk, unsigned int len)
115115
{
116-
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
116+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
117117
const unsigned int du_bits = ci->ci_data_unit_bits;
118118
const unsigned int du_size = 1U << du_bits;
119119
const unsigned int du_per_page_bits = PAGE_SHIFT - du_bits;

fs/crypto/crypto.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio,
173173
size_t len, size_t offs, gfp_t gfp_flags)
174174
{
175175
const struct inode *inode = folio->mapping->host;
176-
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
176+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
177177
const unsigned int du_bits = ci->ci_data_unit_bits;
178178
const unsigned int du_size = 1U << du_bits;
179179
struct page *ciphertext_page;
@@ -232,8 +232,9 @@ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
232232
{
233233
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
234234
return -EOPNOTSUPP;
235-
return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_ENCRYPT,
236-
lblk_num, page, page, len, offs);
235+
return fscrypt_crypt_data_unit(fscrypt_get_inode_info_raw(inode),
236+
FS_ENCRYPT, lblk_num, page, page, len,
237+
offs);
237238
}
238239
EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
239240

@@ -255,7 +256,7 @@ int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len,
255256
size_t offs)
256257
{
257258
const struct inode *inode = folio->mapping->host;
258-
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
259+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
259260
const unsigned int du_bits = ci->ci_data_unit_bits;
260261
const unsigned int du_size = 1U << du_bits;
261262
u64 index = ((u64)folio->index << (PAGE_SHIFT - du_bits)) +
@@ -305,8 +306,9 @@ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
305306
{
306307
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
307308
return -EOPNOTSUPP;
308-
return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_DECRYPT,
309-
lblk_num, page, page, len, offs);
309+
return fscrypt_crypt_data_unit(fscrypt_get_inode_info_raw(inode),
310+
FS_DECRYPT, lblk_num, page, page, len,
311+
offs);
310312
}
311313
EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
312314

fs/crypto/fname.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
9494
int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
9595
u8 *out, unsigned int olen)
9696
{
97-
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
97+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
9898
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
9999
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
100100
union fscrypt_iv iv;
@@ -138,7 +138,7 @@ static int fname_decrypt(const struct inode *inode,
138138
const struct fscrypt_str *iname,
139139
struct fscrypt_str *oname)
140140
{
141-
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
141+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
142142
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
143143
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
144144
union fscrypt_iv iv;
@@ -274,8 +274,9 @@ bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
274274
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
275275
u32 max_len, u32 *encrypted_len_ret)
276276
{
277-
return __fscrypt_fname_encrypted_size(&inode->i_crypt_info->ci_policy,
278-
orig_len, max_len,
277+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
278+
279+
return __fscrypt_fname_encrypted_size(&ci->ci_policy, orig_len, max_len,
279280
encrypted_len_ret);
280281
}
281282
EXPORT_SYMBOL_GPL(fscrypt_fname_encrypted_size);
@@ -543,7 +544,7 @@ EXPORT_SYMBOL_GPL(fscrypt_match_name);
543544
*/
544545
u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name)
545546
{
546-
const struct fscrypt_inode_info *ci = dir->i_crypt_info;
547+
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(dir);
547548

548549
WARN_ON_ONCE(!ci->ci_dirhash_key_initialized);
549550

fs/crypto/fscrypt_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ struct fscrypt_prepared_key {
249249
* fscrypt_inode_info - the "encryption key" for an inode
250250
*
251251
* When an encrypted file's key is made available, an instance of this struct is
252-
* allocated and stored in ->i_crypt_info. Once created, it remains until the
253-
* inode is evicted.
252+
* allocated and a pointer to it is stored in the file's in-memory inode. Once
253+
* created, it remains until the inode is evicted.
254254
*/
255255
struct fscrypt_inode_info {
256256

0 commit comments

Comments
 (0)