162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * This contains encryption functions for per-file encryption. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015, Google, Inc. 662306a36Sopenharmony_ci * Copyright (C) 2015, Motorola Mobility 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Written by Michael Halcrow, 2014. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Filename encryption additions 1162306a36Sopenharmony_ci * Uday Savagaonkar, 2014 1262306a36Sopenharmony_ci * Encryption policy handling additions 1362306a36Sopenharmony_ci * Ildar Muslukhov, 2014 1462306a36Sopenharmony_ci * Add fscrypt_pullback_bio_page() 1562306a36Sopenharmony_ci * Jaegeuk Kim, 2015. 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * This has not yet undergone a rigorous security audit. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * The usage of AES-XTS should conform to recommendations in NIST 2062306a36Sopenharmony_ci * Special Publication 800-38E and IEEE P1619/D16. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include <linux/pagemap.h> 2462306a36Sopenharmony_ci#include <linux/mempool.h> 2562306a36Sopenharmony_ci#include <linux/module.h> 2662306a36Sopenharmony_ci#include <linux/scatterlist.h> 2762306a36Sopenharmony_ci#include <linux/ratelimit.h> 2862306a36Sopenharmony_ci#include <crypto/skcipher.h> 2962306a36Sopenharmony_ci#include "fscrypt_private.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic unsigned int num_prealloc_crypto_pages = 32; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cimodule_param(num_prealloc_crypto_pages, uint, 0444); 3462306a36Sopenharmony_ciMODULE_PARM_DESC(num_prealloc_crypto_pages, 3562306a36Sopenharmony_ci "Number of crypto pages to preallocate"); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic mempool_t *fscrypt_bounce_page_pool = NULL; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic struct workqueue_struct *fscrypt_read_workqueue; 4062306a36Sopenharmony_cistatic DEFINE_MUTEX(fscrypt_init_mutex); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistruct kmem_cache *fscrypt_info_cachep; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_civoid fscrypt_enqueue_decrypt_work(struct work_struct *work) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci queue_work(fscrypt_read_workqueue, work); 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_enqueue_decrypt_work); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistruct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci return mempool_alloc(fscrypt_bounce_page_pool, gfp_flags); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/** 5662306a36Sopenharmony_ci * fscrypt_free_bounce_page() - free a ciphertext bounce page 5762306a36Sopenharmony_ci * @bounce_page: the bounce page to free, or NULL 5862306a36Sopenharmony_ci * 5962306a36Sopenharmony_ci * Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(), 6062306a36Sopenharmony_ci * or by fscrypt_alloc_bounce_page() directly. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_civoid fscrypt_free_bounce_page(struct page *bounce_page) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci if (!bounce_page) 6562306a36Sopenharmony_ci return; 6662306a36Sopenharmony_ci set_page_private(bounce_page, (unsigned long)NULL); 6762306a36Sopenharmony_ci ClearPagePrivate(bounce_page); 6862306a36Sopenharmony_ci mempool_free(bounce_page, fscrypt_bounce_page_pool); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_free_bounce_page); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* 7362306a36Sopenharmony_ci * Generate the IV for the given logical block number within the given file. 7462306a36Sopenharmony_ci * For filenames encryption, lblk_num == 0. 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * Keep this in sync with fscrypt_limit_io_blocks(). fscrypt_limit_io_blocks() 7762306a36Sopenharmony_ci * needs to know about any IV generation methods where the low bits of IV don't 7862306a36Sopenharmony_ci * simply contain the lblk_num (e.g., IV_INO_LBLK_32). 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_civoid fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, 8162306a36Sopenharmony_ci const struct fscrypt_info *ci) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci u8 flags = fscrypt_policy_flags(&ci->ci_policy); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci memset(iv, 0, ci->ci_mode->ivsize); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) { 8862306a36Sopenharmony_ci WARN_ON_ONCE(lblk_num > U32_MAX); 8962306a36Sopenharmony_ci WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX); 9062306a36Sopenharmony_ci lblk_num |= (u64)ci->ci_inode->i_ino << 32; 9162306a36Sopenharmony_ci } else if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) { 9262306a36Sopenharmony_ci WARN_ON_ONCE(lblk_num > U32_MAX); 9362306a36Sopenharmony_ci lblk_num = (u32)(ci->ci_hashed_ino + lblk_num); 9462306a36Sopenharmony_ci } else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { 9562306a36Sopenharmony_ci memcpy(iv->nonce, ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE); 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci iv->lblk_num = cpu_to_le64(lblk_num); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/* Encrypt or decrypt a single filesystem block of file contents */ 10162306a36Sopenharmony_ciint fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, 10262306a36Sopenharmony_ci u64 lblk_num, struct page *src_page, 10362306a36Sopenharmony_ci struct page *dest_page, unsigned int len, 10462306a36Sopenharmony_ci unsigned int offs, gfp_t gfp_flags) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci union fscrypt_iv iv; 10762306a36Sopenharmony_ci struct skcipher_request *req = NULL; 10862306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 10962306a36Sopenharmony_ci struct scatterlist dst, src; 11062306a36Sopenharmony_ci struct fscrypt_info *ci = inode->i_crypt_info; 11162306a36Sopenharmony_ci struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; 11262306a36Sopenharmony_ci int res = 0; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci if (WARN_ON_ONCE(len <= 0)) 11562306a36Sopenharmony_ci return -EINVAL; 11662306a36Sopenharmony_ci if (WARN_ON_ONCE(len % FSCRYPT_CONTENTS_ALIGNMENT != 0)) 11762306a36Sopenharmony_ci return -EINVAL; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci fscrypt_generate_iv(&iv, lblk_num, ci); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci req = skcipher_request_alloc(tfm, gfp_flags); 12262306a36Sopenharmony_ci if (!req) 12362306a36Sopenharmony_ci return -ENOMEM; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci skcipher_request_set_callback( 12662306a36Sopenharmony_ci req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 12762306a36Sopenharmony_ci crypto_req_done, &wait); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci sg_init_table(&dst, 1); 13062306a36Sopenharmony_ci sg_set_page(&dst, dest_page, len, offs); 13162306a36Sopenharmony_ci sg_init_table(&src, 1); 13262306a36Sopenharmony_ci sg_set_page(&src, src_page, len, offs); 13362306a36Sopenharmony_ci skcipher_request_set_crypt(req, &src, &dst, len, &iv); 13462306a36Sopenharmony_ci if (rw == FS_DECRYPT) 13562306a36Sopenharmony_ci res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); 13662306a36Sopenharmony_ci else 13762306a36Sopenharmony_ci res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 13862306a36Sopenharmony_ci skcipher_request_free(req); 13962306a36Sopenharmony_ci if (res) { 14062306a36Sopenharmony_ci fscrypt_err(inode, "%scryption failed for block %llu: %d", 14162306a36Sopenharmony_ci (rw == FS_DECRYPT ? "De" : "En"), lblk_num, res); 14262306a36Sopenharmony_ci return res; 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci return 0; 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/** 14862306a36Sopenharmony_ci * fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a 14962306a36Sopenharmony_ci * pagecache page 15062306a36Sopenharmony_ci * @page: The locked pagecache page containing the block(s) to encrypt 15162306a36Sopenharmony_ci * @len: Total size of the block(s) to encrypt. Must be a nonzero 15262306a36Sopenharmony_ci * multiple of the filesystem's block size. 15362306a36Sopenharmony_ci * @offs: Byte offset within @page of the first block to encrypt. Must be 15462306a36Sopenharmony_ci * a multiple of the filesystem's block size. 15562306a36Sopenharmony_ci * @gfp_flags: Memory allocation flags. See details below. 15662306a36Sopenharmony_ci * 15762306a36Sopenharmony_ci * A new bounce page is allocated, and the specified block(s) are encrypted into 15862306a36Sopenharmony_ci * it. In the bounce page, the ciphertext block(s) will be located at the same 15962306a36Sopenharmony_ci * offsets at which the plaintext block(s) were located in the source page; any 16062306a36Sopenharmony_ci * other parts of the bounce page will be left uninitialized. However, normally 16162306a36Sopenharmony_ci * blocksize == PAGE_SIZE and the whole page is encrypted at once. 16262306a36Sopenharmony_ci * 16362306a36Sopenharmony_ci * This is for use by the filesystem's ->writepages() method. 16462306a36Sopenharmony_ci * 16562306a36Sopenharmony_ci * The bounce page allocation is mempool-backed, so it will always succeed when 16662306a36Sopenharmony_ci * @gfp_flags includes __GFP_DIRECT_RECLAIM, e.g. when it's GFP_NOFS. However, 16762306a36Sopenharmony_ci * only the first page of each bio can be allocated this way. To prevent 16862306a36Sopenharmony_ci * deadlocks, for any additional pages a mask like GFP_NOWAIT must be used. 16962306a36Sopenharmony_ci * 17062306a36Sopenharmony_ci * Return: the new encrypted bounce page on success; an ERR_PTR() on failure 17162306a36Sopenharmony_ci */ 17262306a36Sopenharmony_cistruct page *fscrypt_encrypt_pagecache_blocks(struct page *page, 17362306a36Sopenharmony_ci unsigned int len, 17462306a36Sopenharmony_ci unsigned int offs, 17562306a36Sopenharmony_ci gfp_t gfp_flags) 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci const struct inode *inode = page->mapping->host; 17962306a36Sopenharmony_ci const unsigned int blockbits = inode->i_blkbits; 18062306a36Sopenharmony_ci const unsigned int blocksize = 1 << blockbits; 18162306a36Sopenharmony_ci struct page *ciphertext_page; 18262306a36Sopenharmony_ci u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) + 18362306a36Sopenharmony_ci (offs >> blockbits); 18462306a36Sopenharmony_ci unsigned int i; 18562306a36Sopenharmony_ci int err; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci if (WARN_ON_ONCE(!PageLocked(page))) 18862306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize))) 19162306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags); 19462306a36Sopenharmony_ci if (!ciphertext_page) 19562306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci for (i = offs; i < offs + len; i += blocksize, lblk_num++) { 19862306a36Sopenharmony_ci err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, 19962306a36Sopenharmony_ci page, ciphertext_page, 20062306a36Sopenharmony_ci blocksize, i, gfp_flags); 20162306a36Sopenharmony_ci if (err) { 20262306a36Sopenharmony_ci fscrypt_free_bounce_page(ciphertext_page); 20362306a36Sopenharmony_ci return ERR_PTR(err); 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci SetPagePrivate(ciphertext_page); 20762306a36Sopenharmony_ci set_page_private(ciphertext_page, (unsigned long)page); 20862306a36Sopenharmony_ci return ciphertext_page; 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/** 21362306a36Sopenharmony_ci * fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place 21462306a36Sopenharmony_ci * @inode: The inode to which this block belongs 21562306a36Sopenharmony_ci * @page: The page containing the block to encrypt 21662306a36Sopenharmony_ci * @len: Size of block to encrypt. This must be a multiple of 21762306a36Sopenharmony_ci * FSCRYPT_CONTENTS_ALIGNMENT. 21862306a36Sopenharmony_ci * @offs: Byte offset within @page at which the block to encrypt begins 21962306a36Sopenharmony_ci * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based 22062306a36Sopenharmony_ci * number of the block within the file 22162306a36Sopenharmony_ci * @gfp_flags: Memory allocation flags 22262306a36Sopenharmony_ci * 22362306a36Sopenharmony_ci * Encrypt a possibly-compressed filesystem block that is located in an 22462306a36Sopenharmony_ci * arbitrary page, not necessarily in the original pagecache page. The @inode 22562306a36Sopenharmony_ci * and @lblk_num must be specified, as they can't be determined from @page. 22662306a36Sopenharmony_ci * 22762306a36Sopenharmony_ci * Return: 0 on success; -errno on failure 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_ciint fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, 23062306a36Sopenharmony_ci unsigned int len, unsigned int offs, 23162306a36Sopenharmony_ci u64 lblk_num, gfp_t gfp_flags) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci return fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, page, 23462306a36Sopenharmony_ci len, offs, gfp_flags); 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_encrypt_block_inplace); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/** 23962306a36Sopenharmony_ci * fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a 24062306a36Sopenharmony_ci * pagecache folio 24162306a36Sopenharmony_ci * @folio: The locked pagecache folio containing the block(s) to decrypt 24262306a36Sopenharmony_ci * @len: Total size of the block(s) to decrypt. Must be a nonzero 24362306a36Sopenharmony_ci * multiple of the filesystem's block size. 24462306a36Sopenharmony_ci * @offs: Byte offset within @folio of the first block to decrypt. Must be 24562306a36Sopenharmony_ci * a multiple of the filesystem's block size. 24662306a36Sopenharmony_ci * 24762306a36Sopenharmony_ci * The specified block(s) are decrypted in-place within the pagecache folio, 24862306a36Sopenharmony_ci * which must still be locked and not uptodate. 24962306a36Sopenharmony_ci * 25062306a36Sopenharmony_ci * This is for use by the filesystem's ->readahead() method. 25162306a36Sopenharmony_ci * 25262306a36Sopenharmony_ci * Return: 0 on success; -errno on failure 25362306a36Sopenharmony_ci */ 25462306a36Sopenharmony_ciint fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len, 25562306a36Sopenharmony_ci size_t offs) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci const struct inode *inode = folio->mapping->host; 25862306a36Sopenharmony_ci const unsigned int blockbits = inode->i_blkbits; 25962306a36Sopenharmony_ci const unsigned int blocksize = 1 << blockbits; 26062306a36Sopenharmony_ci u64 lblk_num = ((u64)folio->index << (PAGE_SHIFT - blockbits)) + 26162306a36Sopenharmony_ci (offs >> blockbits); 26262306a36Sopenharmony_ci size_t i; 26362306a36Sopenharmony_ci int err; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci if (WARN_ON_ONCE(!folio_test_locked(folio))) 26662306a36Sopenharmony_ci return -EINVAL; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize))) 26962306a36Sopenharmony_ci return -EINVAL; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci for (i = offs; i < offs + len; i += blocksize, lblk_num++) { 27262306a36Sopenharmony_ci struct page *page = folio_page(folio, i >> PAGE_SHIFT); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci err = fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, 27562306a36Sopenharmony_ci page, blocksize, i & ~PAGE_MASK, 27662306a36Sopenharmony_ci GFP_NOFS); 27762306a36Sopenharmony_ci if (err) 27862306a36Sopenharmony_ci return err; 27962306a36Sopenharmony_ci } 28062306a36Sopenharmony_ci return 0; 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci/** 28562306a36Sopenharmony_ci * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place 28662306a36Sopenharmony_ci * @inode: The inode to which this block belongs 28762306a36Sopenharmony_ci * @page: The page containing the block to decrypt 28862306a36Sopenharmony_ci * @len: Size of block to decrypt. This must be a multiple of 28962306a36Sopenharmony_ci * FSCRYPT_CONTENTS_ALIGNMENT. 29062306a36Sopenharmony_ci * @offs: Byte offset within @page at which the block to decrypt begins 29162306a36Sopenharmony_ci * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based 29262306a36Sopenharmony_ci * number of the block within the file 29362306a36Sopenharmony_ci * 29462306a36Sopenharmony_ci * Decrypt a possibly-compressed filesystem block that is located in an 29562306a36Sopenharmony_ci * arbitrary page, not necessarily in the original pagecache page. The @inode 29662306a36Sopenharmony_ci * and @lblk_num must be specified, as they can't be determined from @page. 29762306a36Sopenharmony_ci * 29862306a36Sopenharmony_ci * Return: 0 on success; -errno on failure 29962306a36Sopenharmony_ci */ 30062306a36Sopenharmony_ciint fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, 30162306a36Sopenharmony_ci unsigned int len, unsigned int offs, 30262306a36Sopenharmony_ci u64 lblk_num) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, 30562306a36Sopenharmony_ci len, offs, GFP_NOFS); 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_decrypt_block_inplace); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci/** 31062306a36Sopenharmony_ci * fscrypt_initialize() - allocate major buffers for fs encryption. 31162306a36Sopenharmony_ci * @sb: the filesystem superblock 31262306a36Sopenharmony_ci * 31362306a36Sopenharmony_ci * We only call this when we start accessing encrypted files, since it 31462306a36Sopenharmony_ci * results in memory getting allocated that wouldn't otherwise be used. 31562306a36Sopenharmony_ci * 31662306a36Sopenharmony_ci * Return: 0 on success; -errno on failure 31762306a36Sopenharmony_ci */ 31862306a36Sopenharmony_ciint fscrypt_initialize(struct super_block *sb) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci int err = 0; 32162306a36Sopenharmony_ci mempool_t *pool; 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci /* pairs with smp_store_release() below */ 32462306a36Sopenharmony_ci if (likely(smp_load_acquire(&fscrypt_bounce_page_pool))) 32562306a36Sopenharmony_ci return 0; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* No need to allocate a bounce page pool if this FS won't use it. */ 32862306a36Sopenharmony_ci if (sb->s_cop->flags & FS_CFLG_OWN_PAGES) 32962306a36Sopenharmony_ci return 0; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci mutex_lock(&fscrypt_init_mutex); 33262306a36Sopenharmony_ci if (fscrypt_bounce_page_pool) 33362306a36Sopenharmony_ci goto out_unlock; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci err = -ENOMEM; 33662306a36Sopenharmony_ci pool = mempool_create_page_pool(num_prealloc_crypto_pages, 0); 33762306a36Sopenharmony_ci if (!pool) 33862306a36Sopenharmony_ci goto out_unlock; 33962306a36Sopenharmony_ci /* pairs with smp_load_acquire() above */ 34062306a36Sopenharmony_ci smp_store_release(&fscrypt_bounce_page_pool, pool); 34162306a36Sopenharmony_ci err = 0; 34262306a36Sopenharmony_ciout_unlock: 34362306a36Sopenharmony_ci mutex_unlock(&fscrypt_init_mutex); 34462306a36Sopenharmony_ci return err; 34562306a36Sopenharmony_ci} 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_civoid fscrypt_msg(const struct inode *inode, const char *level, 34862306a36Sopenharmony_ci const char *fmt, ...) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, 35162306a36Sopenharmony_ci DEFAULT_RATELIMIT_BURST); 35262306a36Sopenharmony_ci struct va_format vaf; 35362306a36Sopenharmony_ci va_list args; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci if (!__ratelimit(&rs)) 35662306a36Sopenharmony_ci return; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci va_start(args, fmt); 35962306a36Sopenharmony_ci vaf.fmt = fmt; 36062306a36Sopenharmony_ci vaf.va = &args; 36162306a36Sopenharmony_ci if (inode && inode->i_ino) 36262306a36Sopenharmony_ci printk("%sfscrypt (%s, inode %lu): %pV\n", 36362306a36Sopenharmony_ci level, inode->i_sb->s_id, inode->i_ino, &vaf); 36462306a36Sopenharmony_ci else if (inode) 36562306a36Sopenharmony_ci printk("%sfscrypt (%s): %pV\n", level, inode->i_sb->s_id, &vaf); 36662306a36Sopenharmony_ci else 36762306a36Sopenharmony_ci printk("%sfscrypt: %pV\n", level, &vaf); 36862306a36Sopenharmony_ci va_end(args); 36962306a36Sopenharmony_ci} 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci/** 37262306a36Sopenharmony_ci * fscrypt_init() - Set up for fs encryption. 37362306a36Sopenharmony_ci * 37462306a36Sopenharmony_ci * Return: 0 on success; -errno on failure 37562306a36Sopenharmony_ci */ 37662306a36Sopenharmony_cistatic int __init fscrypt_init(void) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci int err = -ENOMEM; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci /* 38162306a36Sopenharmony_ci * Use an unbound workqueue to allow bios to be decrypted in parallel 38262306a36Sopenharmony_ci * even when they happen to complete on the same CPU. This sacrifices 38362306a36Sopenharmony_ci * locality, but it's worthwhile since decryption is CPU-intensive. 38462306a36Sopenharmony_ci * 38562306a36Sopenharmony_ci * Also use a high-priority workqueue to prioritize decryption work, 38662306a36Sopenharmony_ci * which blocks reads from completing, over regular application tasks. 38762306a36Sopenharmony_ci */ 38862306a36Sopenharmony_ci fscrypt_read_workqueue = alloc_workqueue("fscrypt_read_queue", 38962306a36Sopenharmony_ci WQ_UNBOUND | WQ_HIGHPRI, 39062306a36Sopenharmony_ci num_online_cpus()); 39162306a36Sopenharmony_ci if (!fscrypt_read_workqueue) 39262306a36Sopenharmony_ci goto fail; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci fscrypt_info_cachep = KMEM_CACHE(fscrypt_info, SLAB_RECLAIM_ACCOUNT); 39562306a36Sopenharmony_ci if (!fscrypt_info_cachep) 39662306a36Sopenharmony_ci goto fail_free_queue; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci err = fscrypt_init_keyring(); 39962306a36Sopenharmony_ci if (err) 40062306a36Sopenharmony_ci goto fail_free_info; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci return 0; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cifail_free_info: 40562306a36Sopenharmony_ci kmem_cache_destroy(fscrypt_info_cachep); 40662306a36Sopenharmony_cifail_free_queue: 40762306a36Sopenharmony_ci destroy_workqueue(fscrypt_read_workqueue); 40862306a36Sopenharmony_cifail: 40962306a36Sopenharmony_ci return err; 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_cilate_initcall(fscrypt_init) 412