Commit 83e57e47 authored by Eric Biggers's avatar Eric Biggers
Browse files

fscrypt: optimize fscrypt_initialize()

fscrypt_initialize() is a "one-time init" function that is called
whenever the key is set up for any inode on any filesystem.  Make it
implement "one-time init" more efficiently by not taking a global mutex
in the "already initialized case" and doing fewer pointer dereferences.

Link: https://lore.kernel.org/r/20230406181245.36091-1-ebiggers@kernel.org


Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
parent 41b2ad80
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -308,19 +308,24 @@ EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);

/**
 * fscrypt_initialize() - allocate major buffers for fs encryption.
 * @cop_flags:  fscrypt operations flags
 * @sb: the filesystem superblock
 *
 * We only call this when we start accessing encrypted files, since it
 * results in memory getting allocated that wouldn't otherwise be used.
 *
 * Return: 0 on success; -errno on failure
 */
int fscrypt_initialize(unsigned int cop_flags)
int fscrypt_initialize(struct super_block *sb)
{
	int err = 0;
	mempool_t *pool;

	/* pairs with smp_store_release() below */
	if (likely(smp_load_acquire(&fscrypt_bounce_page_pool)))
		return 0;

	/* No need to allocate a bounce page pool if this FS won't use it. */
	if (cop_flags & FS_CFLG_OWN_PAGES)
	if (sb->s_cop->flags & FS_CFLG_OWN_PAGES)
		return 0;

	mutex_lock(&fscrypt_init_mutex);
@@ -328,11 +333,11 @@ int fscrypt_initialize(unsigned int cop_flags)
		goto out_unlock;

	err = -ENOMEM;
	fscrypt_bounce_page_pool =
		mempool_create_page_pool(num_prealloc_crypto_pages, 0);
	if (!fscrypt_bounce_page_pool)
	pool = mempool_create_page_pool(num_prealloc_crypto_pages, 0);
	if (!pool)
		goto out_unlock;

	/* pairs with smp_load_acquire() above */
	smp_store_release(&fscrypt_bounce_page_pool, pool);
	err = 0;
out_unlock:
	mutex_unlock(&fscrypt_init_mutex);
+1 −1
Original line number Diff line number Diff line
@@ -264,7 +264,7 @@ typedef enum {

/* crypto.c */
extern struct kmem_cache *fscrypt_info_cachep;
int fscrypt_initialize(unsigned int cop_flags);
int fscrypt_initialize(struct super_block *sb);
int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
			u64 lblk_num, struct page *src_page,
			struct page *dest_page, unsigned int len,
+1 −1
Original line number Diff line number Diff line
@@ -560,7 +560,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
	struct fscrypt_master_key *mk = NULL;
	int res;

	res = fscrypt_initialize(inode->i_sb->s_cop->flags);
	res = fscrypt_initialize(inode->i_sb);
	if (res)
		return res;