VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
09c434b8a0047 (Thomas Gleixner  2019-05-19 13:08:20 +0100   1) // SPDX-License-Identifier: GPL-2.0-only
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   2) /*
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   3)  * This contains encryption functions for per-file encryption.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   4)  *
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   5)  * Copyright (C) 2015, Google, Inc.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   6)  * Copyright (C) 2015, Motorola Mobility
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   7)  *
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   8)  * Written by Michael Halcrow, 2014.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700   9)  *
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  10)  * Filename encryption additions
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  11)  *	Uday Savagaonkar, 2014
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  12)  * Encryption policy handling additions
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  13)  *	Ildar Muslukhov, 2014
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  14)  * Add fscrypt_pullback_bio_page()
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  15)  *	Jaegeuk Kim, 2015.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  16)  *
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  17)  * This has not yet undergone a rigorous security audit.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  18)  *
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  19)  * The usage of AES-XTS should conform to recommendations in NIST
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  20)  * Special Publication 800-38E and IEEE P1619/D16.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  21)  */
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  22) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  23) #include <linux/pagemap.h>
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  24) #include <linux/mempool.h>
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  25) #include <linux/module.h>
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  26) #include <linux/scatterlist.h>
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  27) #include <linux/ratelimit.h>
a575784c6c13b (Eric Biggers     2018-01-05 10:45:00 -0800  28) #include <crypto/skcipher.h>
cc4e0df038ddb (Theodore Ts'o    2016-11-26 22:05:18 -0500  29) #include "fscrypt_private.h"
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  30) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  31) static unsigned int num_prealloc_crypto_pages = 32;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  32) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  33) module_param(num_prealloc_crypto_pages, uint, 0444);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  34) MODULE_PARM_DESC(num_prealloc_crypto_pages,
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  35) 		"Number of crypto pages to preallocate");
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  36) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  37) static mempool_t *fscrypt_bounce_page_pool = NULL;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  38) 
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  39) static struct workqueue_struct *fscrypt_read_workqueue;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  40) static DEFINE_MUTEX(fscrypt_init_mutex);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  41) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  42) struct kmem_cache *fscrypt_info_cachep;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  43) 
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  44) void fscrypt_enqueue_decrypt_work(struct work_struct *work)
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  45) {
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  46) 	queue_work(fscrypt_read_workqueue, work);
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  47) }
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  48) EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work);
0cb8dae4a0df2 (Eric Biggers     2018-04-18 11:09:47 -0700  49) 
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  50) struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags)
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  51) {
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  52) 	return mempool_alloc(fscrypt_bounce_page_pool, gfp_flags);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  53) }
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  54) 
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  55) /**
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  56)  * fscrypt_free_bounce_page() - free a ciphertext bounce page
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700  57)  * @bounce_page: the bounce page to free, or NULL
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  58)  *
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700  59)  * Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(),
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700  60)  * or by fscrypt_alloc_bounce_page() directly.
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  61)  */
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  62) void fscrypt_free_bounce_page(struct page *bounce_page)
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  63) {
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  64) 	if (!bounce_page)
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  65) 		return;
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  66) 	set_page_private(bounce_page, (unsigned long)NULL);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  67) 	ClearPagePrivate(bounce_page);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  68) 	mempool_free(bounce_page, fscrypt_bounce_page_pool);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  69) }
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  70) EXPORT_SYMBOL(fscrypt_free_bounce_page);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700  71) 
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  72) void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  73) 			 const struct fscrypt_info *ci)
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  74) {
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  75) 	u8 flags = fscrypt_policy_flags(&ci->ci_policy);
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  76) 
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  77) 	memset(iv, 0, ci->ci_mode->ivsize);
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  78) 
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  79) 	if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) {
e3b1078bedd32 (Eric Biggers     2020-05-15 13:41:41 -0700  80) 		WARN_ON_ONCE(lblk_num > U32_MAX);
e3b1078bedd32 (Eric Biggers     2020-05-15 13:41:41 -0700  81) 		WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX);
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  82) 		lblk_num |= (u64)ci->ci_inode->i_ino << 32;
e3b1078bedd32 (Eric Biggers     2020-05-15 13:41:41 -0700  83) 	} else if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) {
e3b1078bedd32 (Eric Biggers     2020-05-15 13:41:41 -0700  84) 		WARN_ON_ONCE(lblk_num > U32_MAX);
e3b1078bedd32 (Eric Biggers     2020-05-15 13:41:41 -0700  85) 		lblk_num = (u32)(ci->ci_hashed_ino + lblk_num);
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  86) 	} else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) {
1d6217a4f9905 (Eric Biggers     2020-07-08 14:57:22 -0700  87) 		memcpy(iv->nonce, ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE);
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  88) 	}
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700  89) 	iv->lblk_num = cpu_to_le64(lblk_num);
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  90) }
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  91) 
f47fcbb2b578b (Eric Biggers     2019-05-20 09:29:41 -0700  92) /* Encrypt or decrypt a single filesystem block of file contents */
f47fcbb2b578b (Eric Biggers     2019-05-20 09:29:41 -0700  93) int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
f47fcbb2b578b (Eric Biggers     2019-05-20 09:29:41 -0700  94) 			u64 lblk_num, struct page *src_page,
f47fcbb2b578b (Eric Biggers     2019-05-20 09:29:41 -0700  95) 			struct page *dest_page, unsigned int len,
f47fcbb2b578b (Eric Biggers     2019-05-20 09:29:41 -0700  96) 			unsigned int offs, gfp_t gfp_flags)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700  97) {
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500  98) 	union fscrypt_iv iv;
d407574e79482 (Linus Torvalds   2016-03-21 11:03:02 -0700  99) 	struct skcipher_request *req = NULL;
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 100) 	DECLARE_CRYPTO_WAIT(wait);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 101) 	struct scatterlist dst, src;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 102) 	struct fscrypt_info *ci = inode->i_crypt_info;
5fee36095cda4 (Satya Tangirala  2020-07-02 01:56:05 +0000 103) 	struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 104) 	int res = 0;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 105) 
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 106) 	if (WARN_ON_ONCE(len <= 0))
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 107) 		return -EINVAL;
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 108) 	if (WARN_ON_ONCE(len % FS_CRYPTO_BLOCK_SIZE != 0))
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 109) 		return -EINVAL;
1400451f04f2f (David Gstir      2016-12-06 23:53:55 +0100 110) 
8094c3ceb21ad (Eric Biggers     2019-01-06 08:36:21 -0500 111) 	fscrypt_generate_iv(&iv, lblk_num, ci);
b7e7cf7a66a27 (Daniel Walter    2017-06-19 09:27:58 +0200 112) 
b32e4482aadfd (Jaegeuk Kim      2016-04-11 15:51:57 -0700 113) 	req = skcipher_request_alloc(tfm, gfp_flags);
c90fd77562479 (Eric Biggers     2018-04-30 15:51:38 -0700 114) 	if (!req)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 115) 		return -ENOMEM;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 116) 
d407574e79482 (Linus Torvalds   2016-03-21 11:03:02 -0700 117) 	skcipher_request_set_callback(
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 118) 		req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 119) 		crypto_req_done, &wait);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 120) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 121) 	sg_init_table(&dst, 1);
1400451f04f2f (David Gstir      2016-12-06 23:53:55 +0100 122) 	sg_set_page(&dst, dest_page, len, offs);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 123) 	sg_init_table(&src, 1);
1400451f04f2f (David Gstir      2016-12-06 23:53:55 +0100 124) 	sg_set_page(&src, src_page, len, offs);
b7e7cf7a66a27 (Daniel Walter    2017-06-19 09:27:58 +0200 125) 	skcipher_request_set_crypt(req, &src, &dst, len, &iv);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 126) 	if (rw == FS_DECRYPT)
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 127) 		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 128) 	else
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 129) 		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
d407574e79482 (Linus Torvalds   2016-03-21 11:03:02 -0700 130) 	skcipher_request_free(req);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 131) 	if (res) {
886da8b39cf27 (Eric Biggers     2019-07-24 11:07:58 -0700 132) 		fscrypt_err(inode, "%scryption failed for block %llu: %d",
886da8b39cf27 (Eric Biggers     2019-07-24 11:07:58 -0700 133) 			    (rw == FS_DECRYPT ? "De" : "En"), lblk_num, res);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 134) 		return res;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 135) 	}
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 136) 	return 0;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 137) }
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 138) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 139) /**
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700 140)  * fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700 141)  *					pagecache page
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 142)  * @page:      The locked pagecache page containing the block(s) to encrypt
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 143)  * @len:       Total size of the block(s) to encrypt.  Must be a nonzero
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 144)  *		multiple of the filesystem's block size.
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 145)  * @offs:      Byte offset within @page of the first block to encrypt.  Must be
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 146)  *		a multiple of the filesystem's block size.
2d8f7f119b0b2 (Eric Biggers     2019-12-31 12:10:26 -0600 147)  * @gfp_flags: Memory allocation flags.  See details below.
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 148)  *
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 149)  * A new bounce page is allocated, and the specified block(s) are encrypted into
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 150)  * it.  In the bounce page, the ciphertext block(s) will be located at the same
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 151)  * offsets at which the plaintext block(s) were located in the source page; any
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 152)  * other parts of the bounce page will be left uninitialized.  However, normally
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 153)  * blocksize == PAGE_SIZE and the whole page is encrypted at once.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 154)  *
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 155)  * This is for use by the filesystem's ->writepages() method.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 156)  *
2d8f7f119b0b2 (Eric Biggers     2019-12-31 12:10:26 -0600 157)  * The bounce page allocation is mempool-backed, so it will always succeed when
2d8f7f119b0b2 (Eric Biggers     2019-12-31 12:10:26 -0600 158)  * @gfp_flags includes __GFP_DIRECT_RECLAIM, e.g. when it's GFP_NOFS.  However,
2d8f7f119b0b2 (Eric Biggers     2019-12-31 12:10:26 -0600 159)  * only the first page of each bio can be allocated this way.  To prevent
2d8f7f119b0b2 (Eric Biggers     2019-12-31 12:10:26 -0600 160)  * deadlocks, for any additional pages a mask like GFP_NOWAIT must be used.
2d8f7f119b0b2 (Eric Biggers     2019-12-31 12:10:26 -0600 161)  *
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 162)  * Return: the new encrypted bounce page on success; an ERR_PTR() on failure
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 163)  */
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 164) struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 165) 					      unsigned int len,
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 166) 					      unsigned int offs,
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 167) 					      gfp_t gfp_flags)
7821d4dd4589c (David Gstir      2016-11-13 22:20:46 +0100 168) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 169) {
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 170) 	const struct inode *inode = page->mapping->host;
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 171) 	const unsigned int blockbits = inode->i_blkbits;
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 172) 	const unsigned int blocksize = 1 << blockbits;
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 173) 	struct page *ciphertext_page;
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 174) 	u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) +
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 175) 		       (offs >> blockbits);
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 176) 	unsigned int i;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 177) 	int err;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 178) 
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 179) 	if (WARN_ON_ONCE(!PageLocked(page)))
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 180) 		return ERR_PTR(-EINVAL);
bd7b8290388dd (David Gstir      2016-12-06 23:53:56 +0100 181) 
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 182) 	if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize)))
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 183) 		return ERR_PTR(-EINVAL);
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 184) 
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700 185) 	ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700 186) 	if (!ciphertext_page)
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700 187) 		return ERR_PTR(-ENOMEM);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 188) 
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 189) 	for (i = offs; i < offs + len; i += blocksize, lblk_num++) {
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 190) 		err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num,
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 191) 					  page, ciphertext_page,
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 192) 					  blocksize, i, gfp_flags);
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 193) 		if (err) {
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 194) 			fscrypt_free_bounce_page(ciphertext_page);
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 195) 			return ERR_PTR(err);
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 196) 		}
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 197) 	}
9e532772b4e36 (David Gstir      2016-12-06 23:53:54 +0100 198) 	SetPagePrivate(ciphertext_page);
d2d0727b1654e (Eric Biggers     2019-05-20 09:29:39 -0700 199) 	set_page_private(ciphertext_page, (unsigned long)page);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 200) 	return ciphertext_page;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 201) }
53bc1d854c64c (Eric Biggers     2019-05-20 09:29:44 -0700 202) EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 203) 
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 204) /**
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 205)  * fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 206)  * @inode:     The inode to which this block belongs
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 207)  * @page:      The page containing the block to encrypt
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 208)  * @len:       Size of block to encrypt.  Doesn't need to be a multiple of the
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 209)  *		fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 210)  * @offs:      Byte offset within @page at which the block to encrypt begins
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 211)  * @lblk_num:  Filesystem logical block number of the block, i.e. the 0-based
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 212)  *		number of the block within the file
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 213)  * @gfp_flags: Memory allocation flags
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 214)  *
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 215)  * Encrypt a possibly-compressed filesystem block that is located in an
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 216)  * arbitrary page, not necessarily in the original pagecache page.  The @inode
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 217)  * and @lblk_num must be specified, as they can't be determined from @page.
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 218)  *
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 219)  * Return: 0 on success; -errno on failure
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 220)  */
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 221) int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 222) 				  unsigned int len, unsigned int offs,
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 223) 				  u64 lblk_num, gfp_t gfp_flags)
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 224) {
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 225) 	return fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, page,
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 226) 				   len, offs, gfp_flags);
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 227) }
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 228) EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
03569f2fb8e73 (Eric Biggers     2019-05-20 09:29:43 -0700 229) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 230) /**
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700 231)  * fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700 232)  *					pagecache page
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 233)  * @page:      The locked pagecache page containing the block(s) to decrypt
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 234)  * @len:       Total size of the block(s) to decrypt.  Must be a nonzero
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 235)  *		multiple of the filesystem's block size.
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 236)  * @offs:      Byte offset within @page of the first block to decrypt.  Must be
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 237)  *		a multiple of the filesystem's block size.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 238)  *
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 239)  * The specified block(s) are decrypted in-place within the pagecache page,
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 240)  * which must still be locked and not uptodate.  Normally, blocksize ==
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 241)  * PAGE_SIZE and the whole page is decrypted at once.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 242)  *
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 243)  * This is for use by the filesystem's ->readpages() method.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 244)  *
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 245)  * Return: 0 on success; -errno on failure
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 246)  */
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 247) int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len,
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 248) 				     unsigned int offs)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 249) {
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 250) 	const struct inode *inode = page->mapping->host;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 251) 	const unsigned int blockbits = inode->i_blkbits;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 252) 	const unsigned int blocksize = 1 << blockbits;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 253) 	u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) +
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 254) 		       (offs >> blockbits);
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 255) 	unsigned int i;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 256) 	int err;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 257) 
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 258) 	if (WARN_ON_ONCE(!PageLocked(page)))
eeacfdc68a104 (Eric Biggers     2019-05-20 09:29:42 -0700 259) 		return -EINVAL;
bd7b8290388dd (David Gstir      2016-12-06 23:53:56 +0100 260) 
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 261) 	if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize)))
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 262) 		return -EINVAL;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 263) 
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 264) 	for (i = offs; i < offs + len; i += blocksize, lblk_num++) {
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 265) 		err = fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page,
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 266) 					  page, blocksize, i, GFP_NOFS);
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 267) 		if (err)
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 268) 			return err;
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 269) 	}
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 270) 	return 0;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 271) }
aa8bc1ac6ef32 (Eric Biggers     2019-05-20 09:29:47 -0700 272) EXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 273) 
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 274) /**
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 275)  * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 276)  * @inode:     The inode to which this block belongs
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 277)  * @page:      The page containing the block to decrypt
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 278)  * @len:       Size of block to decrypt.  Doesn't need to be a multiple of the
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 279)  *		fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 280)  * @offs:      Byte offset within @page at which the block to decrypt begins
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 281)  * @lblk_num:  Filesystem logical block number of the block, i.e. the 0-based
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 282)  *		number of the block within the file
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 283)  *
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 284)  * Decrypt a possibly-compressed filesystem block that is located in an
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 285)  * arbitrary page, not necessarily in the original pagecache page.  The @inode
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 286)  * and @lblk_num must be specified, as they can't be determined from @page.
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 287)  *
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 288)  * Return: 0 on success; -errno on failure
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 289)  */
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 290) int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 291) 				  unsigned int len, unsigned int offs,
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 292) 				  u64 lblk_num)
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 293) {
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 294) 	return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page,
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 295) 				   len, offs, GFP_NOFS);
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 296) }
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 297) EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
41adbcb7267b0 (Eric Biggers     2019-05-20 09:29:46 -0700 298) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 299) /**
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 300)  * fscrypt_initialize() - allocate major buffers for fs encryption.
f32d7ac20a586 (David Gstir      2016-12-06 23:53:57 +0100 301)  * @cop_flags:  fscrypt operations flags
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 302)  *
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 303)  * We only call this when we start accessing encrypted files, since it
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 304)  * results in memory getting allocated that wouldn't otherwise be used.
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 305)  *
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 306)  * Return: 0 on success; -errno on failure
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 307)  */
f32d7ac20a586 (David Gstir      2016-12-06 23:53:57 +0100 308) int fscrypt_initialize(unsigned int cop_flags)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 309) {
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 310) 	int err = 0;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 311) 
a0b3bc855374c (Eric Biggers     2017-10-29 06:30:19 -0400 312) 	/* No need to allocate a bounce page pool if this FS won't use it. */
a0b3bc855374c (Eric Biggers     2017-10-29 06:30:19 -0400 313) 	if (cop_flags & FS_CFLG_OWN_PAGES)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 314) 		return 0;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 315) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 316) 	mutex_lock(&fscrypt_init_mutex);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 317) 	if (fscrypt_bounce_page_pool)
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 318) 		goto out_unlock;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 319) 
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 320) 	err = -ENOMEM;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 321) 	fscrypt_bounce_page_pool =
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 322) 		mempool_create_page_pool(num_prealloc_crypto_pages, 0);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 323) 	if (!fscrypt_bounce_page_pool)
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 324) 		goto out_unlock;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 325) 
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 326) 	err = 0;
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 327) out_unlock:
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 328) 	mutex_unlock(&fscrypt_init_mutex);
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 329) 	return err;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 330) }
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 331) 
886da8b39cf27 (Eric Biggers     2019-07-24 11:07:58 -0700 332) void fscrypt_msg(const struct inode *inode, const char *level,
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 333) 		 const char *fmt, ...)
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 334) {
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 335) 	static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 336) 				      DEFAULT_RATELIMIT_BURST);
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 337) 	struct va_format vaf;
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 338) 	va_list args;
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 339) 
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 340) 	if (!__ratelimit(&rs))
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 341) 		return;
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 342) 
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 343) 	va_start(args, fmt);
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 344) 	vaf.fmt = fmt;
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 345) 	vaf.va = &args;
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700 346) 	if (inode && inode->i_ino)
886da8b39cf27 (Eric Biggers     2019-07-24 11:07:58 -0700 347) 		printk("%sfscrypt (%s, inode %lu): %pV\n",
886da8b39cf27 (Eric Biggers     2019-07-24 11:07:58 -0700 348) 		       level, inode->i_sb->s_id, inode->i_ino, &vaf);
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700 349) 	else if (inode)
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700 350) 		printk("%sfscrypt (%s): %pV\n", level, inode->i_sb->s_id, &vaf);
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 351) 	else
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 352) 		printk("%sfscrypt: %pV\n", level, &vaf);
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 353) 	va_end(args);
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 354) }
544d08fde258b (Eric Biggers     2018-04-30 15:51:47 -0700 355) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 356) /**
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 357)  * fscrypt_init() - Set up for fs encryption.
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700 358)  *
d2fe97545a1e2 (Eric Biggers     2020-05-11 12:13:56 -0700 359)  * Return: 0 on success; -errno on failure
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 360)  */
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 361) static int __init fscrypt_init(void)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 362) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 363) 	int err = -ENOMEM;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 364) 
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 365) 	/*
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 366) 	 * Use an unbound workqueue to allow bios to be decrypted in parallel
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 367) 	 * even when they happen to complete on the same CPU.  This sacrifices
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 368) 	 * locality, but it's worthwhile since decryption is CPU-intensive.
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 369) 	 *
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 370) 	 * Also use a high-priority workqueue to prioritize decryption work,
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 371) 	 * which blocks reads from completing, over regular application tasks.
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 372) 	 */
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 373) 	fscrypt_read_workqueue = alloc_workqueue("fscrypt_read_queue",
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 374) 						 WQ_UNBOUND | WQ_HIGHPRI,
36dd26e0c8d42 (Eric Biggers     2018-04-20 16:30:02 -0700 375) 						 num_online_cpus());
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 376) 	if (!fscrypt_read_workqueue)
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 377) 		goto fail;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 378) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 379) 	fscrypt_info_cachep = KMEM_CACHE(fscrypt_info, SLAB_RECLAIM_ACCOUNT);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 380) 	if (!fscrypt_info_cachep)
1565bdad59e97 (Eric Biggers     2019-10-09 16:34:17 -0700 381) 		goto fail_free_queue;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 382) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 383) 	err = fscrypt_init_keyring();
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 384) 	if (err)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 385) 		goto fail_free_info;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 386) 
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 387) 	return 0;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 388) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 389) fail_free_info:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 390) 	kmem_cache_destroy(fscrypt_info_cachep);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 391) fail_free_queue:
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 392) 	destroy_workqueue(fscrypt_read_workqueue);
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 393) fail:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 394) 	return err;
0b81d07790726 (Jaegeuk Kim      2015-05-15 16:26:10 -0700 395) }
75798f85f2bad (Eric Biggers     2019-07-24 11:07:57 -0700 396) late_initcall(fscrypt_init)