fscrypt: replace raw loads of info pointer with helper function
Add and use a helper function fscrypt_get_inode_info_raw(). It loads an inode's fscrypt info pointer using a raw dereference, which is appropriate when the caller knows the key setup already happened. This eliminates most occurrences of inode::i_crypt_info in the source, in preparation for replacing that with a filesystem-specific field. Co-developed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Eric Biggers <ebiggers@kernel.org> Link: https://lore.kernel.org/20250810075706.172910-2-ebiggers@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>pull/1354/merge
parent
8f5ae30d69
commit
6c9468aad2
|
|
@ -113,7 +113,7 @@ out:
|
||||||
int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
|
int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
|
||||||
sector_t pblk, unsigned int len)
|
sector_t pblk, unsigned int len)
|
||||||
{
|
{
|
||||||
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
|
||||||
const unsigned int du_bits = ci->ci_data_unit_bits;
|
const unsigned int du_bits = ci->ci_data_unit_bits;
|
||||||
const unsigned int du_size = 1U << du_bits;
|
const unsigned int du_size = 1U << du_bits;
|
||||||
const unsigned int du_per_page_bits = PAGE_SHIFT - du_bits;
|
const unsigned int du_per_page_bits = PAGE_SHIFT - du_bits;
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio,
|
||||||
size_t len, size_t offs, gfp_t gfp_flags)
|
size_t len, size_t offs, gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
const struct inode *inode = folio->mapping->host;
|
const struct inode *inode = folio->mapping->host;
|
||||||
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
|
||||||
const unsigned int du_bits = ci->ci_data_unit_bits;
|
const unsigned int du_bits = ci->ci_data_unit_bits;
|
||||||
const unsigned int du_size = 1U << du_bits;
|
const unsigned int du_size = 1U << du_bits;
|
||||||
struct page *ciphertext_page;
|
struct page *ciphertext_page;
|
||||||
|
|
@ -232,8 +232,9 @@ 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))
|
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_ENCRYPT,
|
return fscrypt_crypt_data_unit(fscrypt_get_inode_info_raw(inode),
|
||||||
lblk_num, page, page, len, offs);
|
FS_ENCRYPT, lblk_num, page, page, len,
|
||||||
|
offs);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
|
EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
|
||||||
|
|
||||||
|
|
@ -255,7 +256,7 @@ int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len,
|
||||||
size_t offs)
|
size_t offs)
|
||||||
{
|
{
|
||||||
const struct inode *inode = folio->mapping->host;
|
const struct inode *inode = folio->mapping->host;
|
||||||
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
|
||||||
const unsigned int du_bits = ci->ci_data_unit_bits;
|
const unsigned int du_bits = ci->ci_data_unit_bits;
|
||||||
const unsigned int du_size = 1U << du_bits;
|
const unsigned int du_size = 1U << du_bits;
|
||||||
u64 index = ((u64)folio->index << (PAGE_SHIFT - du_bits)) +
|
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,
|
||||||
{
|
{
|
||||||
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
|
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_DECRYPT,
|
return fscrypt_crypt_data_unit(fscrypt_get_inode_info_raw(inode),
|
||||||
lblk_num, page, page, len, offs);
|
FS_DECRYPT, lblk_num, page, page, len,
|
||||||
|
offs);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
|
EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
|
||||||
int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
|
int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
|
||||||
u8 *out, unsigned int olen)
|
u8 *out, unsigned int olen)
|
||||||
{
|
{
|
||||||
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
|
||||||
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
|
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
|
||||||
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
|
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
|
||||||
union fscrypt_iv iv;
|
union fscrypt_iv iv;
|
||||||
|
|
@ -138,7 +138,7 @@ static int fname_decrypt(const struct inode *inode,
|
||||||
const struct fscrypt_str *iname,
|
const struct fscrypt_str *iname,
|
||||||
struct fscrypt_str *oname)
|
struct fscrypt_str *oname)
|
||||||
{
|
{
|
||||||
const struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
|
||||||
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
|
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
|
||||||
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
|
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
|
||||||
union fscrypt_iv iv;
|
union fscrypt_iv iv;
|
||||||
|
|
@ -274,8 +274,9 @@ bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
|
||||||
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
|
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
|
||||||
u32 max_len, u32 *encrypted_len_ret)
|
u32 max_len, u32 *encrypted_len_ret)
|
||||||
{
|
{
|
||||||
return __fscrypt_fname_encrypted_size(&inode->i_crypt_info->ci_policy,
|
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
|
||||||
orig_len, max_len,
|
|
||||||
|
return __fscrypt_fname_encrypted_size(&ci->ci_policy, orig_len, max_len,
|
||||||
encrypted_len_ret);
|
encrypted_len_ret);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(fscrypt_fname_encrypted_size);
|
EXPORT_SYMBOL_GPL(fscrypt_fname_encrypted_size);
|
||||||
|
|
@ -543,7 +544,7 @@ EXPORT_SYMBOL_GPL(fscrypt_match_name);
|
||||||
*/
|
*/
|
||||||
u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *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 = fscrypt_get_inode_info_raw(dir);
|
||||||
|
|
||||||
WARN_ON_ONCE(!ci->ci_dirhash_key_initialized);
|
WARN_ON_ONCE(!ci->ci_dirhash_key_initialized);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ int fscrypt_prepare_setflags(struct inode *inode,
|
||||||
err = fscrypt_require_key(inode);
|
err = fscrypt_require_key(inode);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
ci = inode->i_crypt_info;
|
ci = fscrypt_get_inode_info_raw(inode);
|
||||||
if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
|
if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mk = ci->ci_master_key;
|
mk = ci->ci_master_key;
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ int fscrypt_derive_sw_secret(struct super_block *sb,
|
||||||
|
|
||||||
bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
|
bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
|
||||||
{
|
{
|
||||||
return inode->i_crypt_info->ci_inlinecrypt;
|
return fscrypt_get_inode_info_raw(inode)->ci_inlinecrypt;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__fscrypt_inode_uses_inline_crypto);
|
EXPORT_SYMBOL_GPL(__fscrypt_inode_uses_inline_crypto);
|
||||||
|
|
||||||
|
|
@ -307,7 +307,7 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,
|
||||||
|
|
||||||
if (!fscrypt_inode_uses_inline_crypto(inode))
|
if (!fscrypt_inode_uses_inline_crypto(inode))
|
||||||
return;
|
return;
|
||||||
ci = inode->i_crypt_info;
|
ci = fscrypt_get_inode_info_raw(inode);
|
||||||
|
|
||||||
fscrypt_generate_dun(ci, first_lblk, dun);
|
fscrypt_generate_dun(ci, first_lblk, dun);
|
||||||
bio_crypt_set_ctx(bio, ci->ci_enc_key.blk_key, dun, gfp_mask);
|
bio_crypt_set_ctx(bio, ci->ci_enc_key.blk_key, dun, gfp_mask);
|
||||||
|
|
@ -385,22 +385,24 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
|
||||||
u64 next_lblk)
|
u64 next_lblk)
|
||||||
{
|
{
|
||||||
const struct bio_crypt_ctx *bc = bio->bi_crypt_context;
|
const struct bio_crypt_ctx *bc = bio->bi_crypt_context;
|
||||||
|
const struct fscrypt_inode_info *ci;
|
||||||
u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
|
u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
|
||||||
|
|
||||||
if (!!bc != fscrypt_inode_uses_inline_crypto(inode))
|
if (!!bc != fscrypt_inode_uses_inline_crypto(inode))
|
||||||
return false;
|
return false;
|
||||||
if (!bc)
|
if (!bc)
|
||||||
return true;
|
return true;
|
||||||
|
ci = fscrypt_get_inode_info_raw(inode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Comparing the key pointers is good enough, as all I/O for each key
|
* Comparing the key pointers is good enough, as all I/O for each key
|
||||||
* uses the same pointer. I.e., there's currently no need to support
|
* 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.
|
* 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 != ci->ci_enc_key.blk_key)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fscrypt_generate_dun(inode->i_crypt_info, next_lblk, next_dun);
|
fscrypt_generate_dun(ci, next_lblk, next_dun);
|
||||||
return bio_crypt_dun_is_contiguous(bc, bio->bi_iter.bi_size, next_dun);
|
return bio_crypt_dun_is_contiguous(bc, bio->bi_iter.bi_size, next_dun);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio);
|
EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio);
|
||||||
|
|
@ -502,7 +504,7 @@ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks)
|
||||||
if (nr_blocks <= 1)
|
if (nr_blocks <= 1)
|
||||||
return nr_blocks;
|
return nr_blocks;
|
||||||
|
|
||||||
ci = inode->i_crypt_info;
|
ci = fscrypt_get_inode_info_raw(inode);
|
||||||
if (!(fscrypt_policy_flags(&ci->ci_policy) &
|
if (!(fscrypt_policy_flags(&ci->ci_policy) &
|
||||||
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
|
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
|
||||||
return nr_blocks;
|
return nr_blocks;
|
||||||
|
|
|
||||||
|
|
@ -727,7 +727,7 @@ const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir)
|
||||||
err = fscrypt_require_key(dir);
|
err = fscrypt_require_key(dir);
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
return &dir->i_crypt_info->ci_policy;
|
return &fscrypt_get_inode_info_raw(dir)->ci_policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fscrypt_get_dummy_policy(dir->i_sb);
|
return fscrypt_get_dummy_policy(dir->i_sb);
|
||||||
|
|
@ -746,7 +746,7 @@ const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir)
|
||||||
*/
|
*/
|
||||||
int fscrypt_context_for_new_inode(void *ctx, struct inode *inode)
|
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 = fscrypt_get_inode_info_raw(inode);
|
||||||
|
|
||||||
BUILD_BUG_ON(sizeof(union fscrypt_context) !=
|
BUILD_BUG_ON(sizeof(union fscrypt_context) !=
|
||||||
FSCRYPT_SET_CONTEXT_MAX_SIZE);
|
FSCRYPT_SET_CONTEXT_MAX_SIZE);
|
||||||
|
|
@ -771,7 +771,7 @@ EXPORT_SYMBOL_GPL(fscrypt_context_for_new_inode);
|
||||||
*/
|
*/
|
||||||
int fscrypt_set_context(struct inode *inode, void *fs_data)
|
int fscrypt_set_context(struct inode *inode, void *fs_data)
|
||||||
{
|
{
|
||||||
struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
struct fscrypt_inode_info *ci;
|
||||||
union fscrypt_context ctx;
|
union fscrypt_context ctx;
|
||||||
int ctxsize;
|
int ctxsize;
|
||||||
|
|
||||||
|
|
@ -783,6 +783,7 @@ int fscrypt_set_context(struct inode *inode, void *fs_data)
|
||||||
* This may be the first time the inode number is available, so do any
|
* This may be the first time the inode number is available, so do any
|
||||||
* delayed key setup that requires the inode number.
|
* delayed key setup that requires the inode number.
|
||||||
*/
|
*/
|
||||||
|
ci = fscrypt_get_inode_info_raw(inode);
|
||||||
if (ci->ci_policy.version == FSCRYPT_POLICY_V2 &&
|
if (ci->ci_policy.version == FSCRYPT_POLICY_V2 &&
|
||||||
(ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
|
(ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
|
||||||
fscrypt_hash_inode_number(ci, ci->ci_master_key);
|
fscrypt_hash_inode_number(ci, ci->ci_master_key);
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,22 @@ struct fscrypt_operations {
|
||||||
int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name,
|
int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name,
|
||||||
struct dentry *dentry, unsigned int flags);
|
struct dentry *dentry, unsigned int flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the inode's fscrypt info pointer, using a raw dereference. Since this
|
||||||
|
* uses a raw dereference with no memory barrier, it is appropriate to use only
|
||||||
|
* when the caller knows the inode's key setup already happened, resulting in
|
||||||
|
* non-NULL fscrypt info. E.g., the file contents en/decryption functions use
|
||||||
|
* this, since fscrypt_file_open() set up the key.
|
||||||
|
*/
|
||||||
|
static inline struct fscrypt_inode_info *
|
||||||
|
fscrypt_get_inode_info_raw(const struct inode *inode)
|
||||||
|
{
|
||||||
|
struct fscrypt_inode_info *ci = inode->i_crypt_info;
|
||||||
|
|
||||||
|
VFS_WARN_ON_ONCE(ci == NULL);
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct fscrypt_inode_info *
|
static inline struct fscrypt_inode_info *
|
||||||
fscrypt_get_inode_info(const struct inode *inode)
|
fscrypt_get_inode_info(const struct inode *inode)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue