fscrypt: Restore modular support
diff mbox series

Message ID 20191221143020.hbgeixvlmzt7nh54@gondor.apana.org.au
State Superseded
Headers show
Series
  • fscrypt: Restore modular support
Related show

Commit Message

Herbert Xu Dec. 21, 2019, 2:30 p.m. UTC
The commit 643fa9612bf1 ("fscrypt: remove filesystem specific
build config option") removed modular support for fs/crypto.  This
causes the Crypto API to be built-in whenever fscrypt is enabled.
This makes it very difficult for me to test modular builds of
the Crypto API without disabling fscrypt which is a pain.

AFAICS there is no reason why fscrypt has to be built-in.  The
commit above appears to have done this way purely for the sake of
simplicity.  In fact some simple Kconfig tweaking is sufficient
to retain a single FS_ENCRYPTION option while maintaining modularity.

This patch restores modular support to fscrypt by adding a new
hidden FS_ENCRYPTION_TRI tristate option that is selected by all
the FS_ENCRYPTION users.

Subsequent to the above commit, some core code has been introduced
to fs/buffer.c that makes restoring modular support non-trivial.
This patch deals with this by adding a function pointer that defaults
to end_buffer_async_read function until fscrypt is loaded.  When
fscrypt is loaded it modifies the function pointer to its own
function which used to be end_buffer_async_read_io but now resides
in fscrypt.  When it is unloaded the function pointer is restored.

In order for this to be safe with respect to module removal, the
check for whether the host inode is encrypted has been moved into
mark_buffer_async_read.  The assumption is that as long as the
bh is alive the calling filesystem module will be resident.  The
calling filesystem would then guarantee that fscrypt is loaded.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Comments

Eric Biggers Dec. 21, 2019, 11:44 p.m. UTC | #1
On Sat, Dec 21, 2019 at 10:30:20PM +0800, Herbert Xu wrote:
> The commit 643fa9612bf1 ("fscrypt: remove filesystem specific
> build config option") removed modular support for fs/crypto.  This
> causes the Crypto API to be built-in whenever fscrypt is enabled.
> This makes it very difficult for me to test modular builds of
> the Crypto API without disabling fscrypt which is a pain.
> 
> AFAICS there is no reason why fscrypt has to be built-in.  The
> commit above appears to have done this way purely for the sake of
> simplicity.  In fact some simple Kconfig tweaking is sufficient
> to retain a single FS_ENCRYPTION option while maintaining modularity.
> 
> This patch restores modular support to fscrypt by adding a new
> hidden FS_ENCRYPTION_TRI tristate option that is selected by all
> the FS_ENCRYPTION users.
> 
> Subsequent to the above commit, some core code has been introduced
> to fs/buffer.c that makes restoring modular support non-trivial.
> This patch deals with this by adding a function pointer that defaults
> to end_buffer_async_read function until fscrypt is loaded.  When
> fscrypt is loaded it modifies the function pointer to its own
> function which used to be end_buffer_async_read_io but now resides
> in fscrypt.  When it is unloaded the function pointer is restored.
> 
> In order for this to be safe with respect to module removal, the
> check for whether the host inode is encrypted has been moved into
> mark_buffer_async_read.  The assumption is that as long as the
> bh is alive the calling filesystem module will be resident.  The
> calling filesystem would then guarantee that fscrypt is loaded.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

I'm not sure this is a good idea, since there will probably need to be more
places where built-in code calls into fs/crypto/ too.

There's actually already fscrypt_sb_free(), which this patch forgets to handle:

	void fscrypt_sb_free(struct super_block *sb)
	{
		key_put(sb->s_master_keys);
		sb->s_master_keys = NULL;
	}

Though we could make that an inline function.

But there's also a patch under review which adds inline encryption support to
ext4 and f2fs, which requires calling into fs/crypto/ from fs/buffer.c in order
to set an encryption context on bios:

https://lkml.kernel.org/linux-fscrypt/20191218145136.172774-10-satyat@google.com/

If we also add direct I/O support for inline encryption (which is planned), it
would require calling into fs/crypto/ from fs/direct-io.c and
fs/iomap/direct-io.c as well.

Another thing I've been thinking about is adding decryption support to
__block_write_begin(), which would allow us to delete ext4_block_write_begin(),
which was copied from __block_write_begin() to add decryption support.

So more broadly, the issue is that a lot of the filesystem I/O helpers
(fs/buffer.c, fs/iomap/, fs/direct-io.c, fs/mpage.c) are already built-in, and
it can be necessary to call into fs/crypto/ from such places.

Is it really much of an issue to just disable CONFIG_FS_ENCRYPTION when you want
to test building the crypto API as a module?

> diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
> index 3719efa546c6..6bf7f05120bd 100644
> --- a/fs/crypto/crypto.c
> +++ b/fs/crypto/crypto.c
> @@ -20,6 +20,7 @@
>   * Special Publication 800-38E and IEEE P1619/D16.
>   */
>  
> +#include <linux/buffer_head.h>
>  #include <linux/pagemap.h>
>  #include <linux/mempool.h>
>  #include <linux/module.h>
> @@ -286,6 +287,41 @@ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
>  }
>  EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
>  
> +struct decrypt_bh_ctx {
> +	struct work_struct work;
> +	struct buffer_head *bh;
> +};
> +
> +static void decrypt_bh(struct work_struct *work)
> +{
> +	struct decrypt_bh_ctx *ctx =
> +		container_of(work, struct decrypt_bh_ctx, work);
> +	struct buffer_head *bh = ctx->bh;
> +	int err;
> +
> +	err = fscrypt_decrypt_pagecache_blocks(bh->b_page, bh->b_size,
> +					       bh_offset(bh));
> +	end_buffer_async_read(bh, err == 0);
> +	kfree(ctx);
> +}
> +
> +static void fscrypt_end_buffer_async_read(struct buffer_head *bh, int uptodate)
> +{
> +	/* Decrypt if needed */
> +	if (uptodate) {
> +		struct decrypt_bh_ctx *ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
> +
> +		if (ctx) {
> +			INIT_WORK(&ctx->work, decrypt_bh);
> +			ctx->bh = bh;
> +			fscrypt_enqueue_decrypt_work(&ctx->work);
> +			return;
> +		}
> +		uptodate = 0;
> +	}
> +	end_buffer_async_read(bh, uptodate);
> +}
> +
>  /*
>   * Validate dentries in encrypted directories to make sure we aren't potentially
>   * caching stale dentries after a key has been added.
> @@ -418,6 +454,8 @@ static int __init fscrypt_init(void)
>  	if (err)
>  		goto fail_free_info;
>  
> +	end_buffer_async_read_io = fscrypt_end_buffer_async_read;
> +
>  	return 0;

This code would actually need to go into fs/crypto/bio.c because it depends on
CONFIG_BLOCK.  UBIFS uses fs/crypto/ without CONFIG_BLOCK necessarily being set.

> +/**
> + * fscrypt_exit() - Shutdown the fs encryption system
> + */
> +static void __exit fscrypt_exit(void)
> +{
> +	end_buffer_async_read_io = end_buffer_async_read;
> +
> +	kmem_cache_destroy(fscrypt_info_cachep);
> +	destroy_workqueue(fscrypt_read_workqueue);
> +}
> +module_exit(fscrypt_exit);

There's a bit more that would need to be done here:

	mempool_destroy(fscrypt_bounce_page_pool);

and

	fscrypt_exit_keyring()
		=> unregister_key_type(&key_type_fscrypt);
		=> unregister_key_type(&key_type_fscrypt_user);

- Eric
kernel test robot Dec. 24, 2019, 11:44 a.m. UTC | #2
Hi Herbert,

I love your patch! Yet something to improve:

[auto build test ERROR on linux/master]
[also build test ERROR on f2fs/dev-test linus/master v5.5-rc3 next-20191220]
[cannot apply to ext4/dev tytso-fscrypt/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Herbert-Xu/fscrypt-Restore-modular-support/20191224-164226
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1522d9da40bdfe502c91163e6d769332897201fa
config: x86_64-kexec (attached as .config)
compiler: gcc-7 (Debian 7.5.0-3) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: fs/super.o: in function `__put_super':
   fs/super.c:296: undefined reference to `fscrypt_sb_free'
   ld: fs/ext4/dir.o: in function `ext4_dir_open':
   fs/ext4/dir.c:617: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/dir.o: in function `ext4_readdir':
   fs/ext4/dir.c:118: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/dir.c:145: undefined reference to `fscrypt_fname_alloc_buffer'
   ld: fs/ext4/dir.c:263: undefined reference to `fscrypt_fname_disk_to_usr'
   ld: fs/ext4/dir.c:288: undefined reference to `fscrypt_fname_free_buffer'
   ld: fs/ext4/file.o: in function `ext4_file_open':
   fs/ext4/file.c:716: undefined reference to `fscrypt_file_open'
   ld: fs/ext4/ialloc.o: in function `__ext4_new_inode':
   fs/ext4/ialloc.c:772: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/ialloc.c:1145: undefined reference to `fscrypt_inherit_context'
   ld: fs/ext4/inode.o: in function `ext4_block_write_begin':
   fs/ext4/inode.c:1097: undefined reference to `fscrypt_decrypt_pagecache_blocks'
   ld: fs/ext4/inode.o: in function `__ext4_block_zero_page_range':
   fs/ext4/inode.c:3704: undefined reference to `fscrypt_decrypt_pagecache_blocks'
   ld: fs/ext4/inode.o: in function `fscrypt_require_key':
   include/linux/fscrypt.h:548: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/inode.o: in function `ext4_issue_zeroout':
   fs/ext4/inode.c:406: undefined reference to `fscrypt_zeroout_range'
   ld: fs/ext4/ioctl.o: in function `ext4_ioctl':
   fs/ext4/ioctl.c:1141: undefined reference to `fscrypt_ioctl_set_policy'
   ld: fs/ext4/ioctl.c:1186: undefined reference to `fscrypt_ioctl_get_policy'
   ld: fs/ext4/ioctl.c:1191: undefined reference to `fscrypt_ioctl_get_policy_ex'
   ld: fs/ext4/ioctl.c:1196: undefined reference to `fscrypt_ioctl_add_key'
   ld: fs/ext4/ioctl.c:1201: undefined reference to `fscrypt_ioctl_remove_key'
   ld: fs/ext4/ioctl.c:1206: undefined reference to `fscrypt_ioctl_remove_key_all_users'
   ld: fs/ext4/ioctl.c:1211: undefined reference to `fscrypt_ioctl_get_key_status'
   ld: fs/ext4/namei.o: in function `ext4_fname_setup_filename':
   fs/ext4/ext4.h:2380: undefined reference to `fscrypt_setup_filename'
   ld: fs/ext4/namei.o: in function `fscrypt_prepare_lookup':
   include/linux/fscrypt.h:642: undefined reference to `__fscrypt_prepare_lookup'
   ld: fs/ext4/namei.o: in function `htree_dirblock_to_tree':
>> fs/ext4/namei.c:1008: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/namei.c:1013: undefined reference to `fscrypt_fname_alloc_buffer'
   ld: fs/ext4/namei.c:1048: undefined reference to `fscrypt_fname_disk_to_usr'
>> ld: fs/ext4/namei.c:1069: undefined reference to `fscrypt_fname_free_buffer'
   ld: fs/ext4/namei.o: in function `ext4_lookup':
   fs/ext4/namei.c:1709: undefined reference to `fscrypt_has_permitted_context'
   ld: fs/ext4/namei.o: in function `fscrypt_prepare_rename':
   include/linux/fscrypt.h:613: undefined reference to `__fscrypt_prepare_rename'
   ld: fs/ext4/namei.o: in function `fscrypt_prepare_symlink':
   include/linux/fscrypt.h:706: undefined reference to `__fscrypt_prepare_symlink'
   ld: fs/ext4/namei.o: in function `fscrypt_encrypt_symlink':
   include/linux/fscrypt.h:736: undefined reference to `__fscrypt_encrypt_symlink'
   ld: fs/ext4/namei.o: in function `fscrypt_prepare_link':
   include/linux/fscrypt.h:581: undefined reference to `__fscrypt_prepare_link'
   ld: fs/ext4/page-io.o: in function `ext4_finish_bio':
   fs/ext4/page-io.c:147: undefined reference to `fscrypt_free_bounce_page'
   ld: fs/ext4/page-io.o: in function `ext4_bio_write_page':
   fs/ext4/page-io.c:516: undefined reference to `fscrypt_encrypt_pagecache_blocks'
   ld: fs/ext4/readpage.o: in function `decrypt_work':
   fs/ext4/readpage.c:100: undefined reference to `fscrypt_decrypt_bio'
   ld: fs/ext4/readpage.o: in function `bio_post_read_processing':
   fs/ext4/readpage.c:126: undefined reference to `fscrypt_enqueue_decrypt_work'
   ld: fs/ext4/super.o: in function `ext4_drop_inode':
   fs/ext4/super.c:1111: undefined reference to `fscrypt_drop_inode'
   ld: fs/ext4/super.o: in function `ext4_free_in_core_inode':
   fs/ext4/super.c:1119: undefined reference to `fscrypt_free_inode'
   ld: fs/ext4/super.o: in function `ext4_clear_inode':
   fs/ext4/super.c:1184: undefined reference to `fscrypt_put_encryption_info'
   ld: fs/ext4/symlink.o: in function `ext4_encrypted_get_link':
   fs/ext4/symlink.c:49: undefined reference to `fscrypt_get_symlink'

vim +1008 fs/ext4/namei.c

ac27a0ec112a08 Dave Kleikamp           2006-10-11   978  
ac27a0ec112a08 Dave Kleikamp           2006-10-11   979  
ac27a0ec112a08 Dave Kleikamp           2006-10-11   980  /*
ac27a0ec112a08 Dave Kleikamp           2006-10-11   981   * This function fills a red-black tree with information from a
ac27a0ec112a08 Dave Kleikamp           2006-10-11   982   * directory block.  It returns the number directory entries loaded
ac27a0ec112a08 Dave Kleikamp           2006-10-11   983   * into the tree.  If there is an error it is returned in err.
ac27a0ec112a08 Dave Kleikamp           2006-10-11   984   */
ac27a0ec112a08 Dave Kleikamp           2006-10-11   985  static int htree_dirblock_to_tree(struct file *dir_file,
725d26d3f09ccb Aneesh Kumar K.V        2008-01-28   986  				  struct inode *dir, ext4_lblk_t block,
ac27a0ec112a08 Dave Kleikamp           2006-10-11   987  				  struct dx_hash_info *hinfo,
ac27a0ec112a08 Dave Kleikamp           2006-10-11   988  				  __u32 start_hash, __u32 start_minor_hash)
ac27a0ec112a08 Dave Kleikamp           2006-10-11   989  {
ac27a0ec112a08 Dave Kleikamp           2006-10-11   990  	struct buffer_head *bh;
617ba13b31fbf5 Mingming Cao            2006-10-11   991  	struct ext4_dir_entry_2 *de, *top;
90b0a97323f42e Carlos Maiolino         2012-09-17   992  	int err = 0, count = 0;
a7550b30ab709f Jaegeuk Kim             2016-07-10   993  	struct fscrypt_str fname_crypto_str = FSTR_INIT(NULL, 0), tmp_str;
ac27a0ec112a08 Dave Kleikamp           2006-10-11   994  
725d26d3f09ccb Aneesh Kumar K.V        2008-01-28   995  	dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
725d26d3f09ccb Aneesh Kumar K.V        2008-01-28   996  							(unsigned long)block));
4e19d6b65fb4fc Theodore Ts'o           2019-06-20   997  	bh = ext4_read_dirblock(dir, block, DIRENT_HTREE);
dc6982ff4db1f4 Theodore Ts'o           2013-02-14   998  	if (IS_ERR(bh))
dc6982ff4db1f4 Theodore Ts'o           2013-02-14   999  		return PTR_ERR(bh);
b0336e8d2108e6 Darrick J. Wong         2012-04-29  1000  
617ba13b31fbf5 Mingming Cao            2006-10-11  1001  	de = (struct ext4_dir_entry_2 *) bh->b_data;
617ba13b31fbf5 Mingming Cao            2006-10-11  1002  	top = (struct ext4_dir_entry_2 *) ((char *) de +
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1003  					   dir->i_sb->s_blocksize -
617ba13b31fbf5 Mingming Cao            2006-10-11  1004  					   EXT4_DIR_REC_LEN(0));
643fa9612bf1a2 Chandan Rajendra        2018-12-12  1005  #ifdef CONFIG_FS_ENCRYPTION
1f3862b5575b13 Michael Halcrow         2015-04-12  1006  	/* Check if the directory is encrypted */
592ddec7578a33 Chandan Rajendra        2018-12-12  1007  	if (IS_ENCRYPTED(dir)) {
a7550b30ab709f Jaegeuk Kim             2016-07-10 @1008  		err = fscrypt_get_encryption_info(dir);
c936e1ec2879e4 Theodore Ts'o           2015-05-31  1009  		if (err < 0) {
1f3862b5575b13 Michael Halcrow         2015-04-12  1010  			brelse(bh);
1f3862b5575b13 Michael Halcrow         2015-04-12  1011  			return err;
1f3862b5575b13 Michael Halcrow         2015-04-12  1012  		}
a7550b30ab709f Jaegeuk Kim             2016-07-10  1013  		err = fscrypt_fname_alloc_buffer(dir, EXT4_NAME_LEN,
1f3862b5575b13 Michael Halcrow         2015-04-12  1014  						     &fname_crypto_str);
1f3862b5575b13 Michael Halcrow         2015-04-12  1015  		if (err < 0) {
1f3862b5575b13 Michael Halcrow         2015-04-12  1016  			brelse(bh);
1f3862b5575b13 Michael Halcrow         2015-04-12  1017  			return err;
1f3862b5575b13 Michael Halcrow         2015-04-12  1018  		}
1f3862b5575b13 Michael Halcrow         2015-04-12  1019  	}
1f3862b5575b13 Michael Halcrow         2015-04-12  1020  #endif
3d0518f4758eca Wei Yongjun             2009-02-14  1021  	for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
f7c21177af0b32 Theodore Ts'o           2011-01-10  1022  		if (ext4_check_dir_entry(dir, NULL, de, bh,
226ba972b08637 Tao Ma                  2012-12-10  1023  				bh->b_data, bh->b_size,
e6c4021190c828 Eric Sandeen            2006-12-06  1024  				(block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
e6c4021190c828 Eric Sandeen            2006-12-06  1025  					 + ((char *)de - bh->b_data))) {
64cb927371cd2e Al Viro                 2013-07-01  1026  			/* silently ignore the rest of the block */
64cb927371cd2e Al Viro                 2013-07-01  1027  			break;
e6c4021190c828 Eric Sandeen            2006-12-06  1028  		}
b886ee3e778ec2 Gabriel Krisman Bertazi 2019-04-25  1029  		ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1030  		if ((hinfo->hash < start_hash) ||
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1031  		    ((hinfo->hash == start_hash) &&
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1032  		     (hinfo->minor_hash < start_minor_hash)))
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1033  			continue;
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1034  		if (de->inode == 0)
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1035  			continue;
592ddec7578a33 Chandan Rajendra        2018-12-12  1036  		if (!IS_ENCRYPTED(dir)) {
2f61830ae33e29 Theodore Ts'o           2015-04-12  1037  			tmp_str.name = de->name;
2f61830ae33e29 Theodore Ts'o           2015-04-12  1038  			tmp_str.len = de->name_len;
2f61830ae33e29 Theodore Ts'o           2015-04-12  1039  			err = ext4_htree_store_dirent(dir_file,
1f3862b5575b13 Michael Halcrow         2015-04-12  1040  				   hinfo->hash, hinfo->minor_hash, de,
1f3862b5575b13 Michael Halcrow         2015-04-12  1041  				   &tmp_str);
1f3862b5575b13 Michael Halcrow         2015-04-12  1042  		} else {
d229959072eba4 Theodore Ts'o           2015-05-18  1043  			int save_len = fname_crypto_str.len;
a7550b30ab709f Jaegeuk Kim             2016-07-10  1044  			struct fscrypt_str de_name = FSTR_INIT(de->name,
a7550b30ab709f Jaegeuk Kim             2016-07-10  1045  								de->name_len);
d229959072eba4 Theodore Ts'o           2015-05-18  1046  
1f3862b5575b13 Michael Halcrow         2015-04-12  1047  			/* Directory is encrypted */
a7550b30ab709f Jaegeuk Kim             2016-07-10  1048  			err = fscrypt_fname_disk_to_usr(dir, hinfo->hash,
a7550b30ab709f Jaegeuk Kim             2016-07-10  1049  					hinfo->minor_hash, &de_name,
1f3862b5575b13 Michael Halcrow         2015-04-12  1050  					&fname_crypto_str);
ef1eb3aa50930f Eric Biggers            2016-09-15  1051  			if (err) {
1f3862b5575b13 Michael Halcrow         2015-04-12  1052  				count = err;
1f3862b5575b13 Michael Halcrow         2015-04-12  1053  				goto errout;
1f3862b5575b13 Michael Halcrow         2015-04-12  1054  			}
1f3862b5575b13 Michael Halcrow         2015-04-12  1055  			err = ext4_htree_store_dirent(dir_file,
1f3862b5575b13 Michael Halcrow         2015-04-12  1056  				   hinfo->hash, hinfo->minor_hash, de,
1f3862b5575b13 Michael Halcrow         2015-04-12  1057  					&fname_crypto_str);
d229959072eba4 Theodore Ts'o           2015-05-18  1058  			fname_crypto_str.len = save_len;
1f3862b5575b13 Michael Halcrow         2015-04-12  1059  		}
2f61830ae33e29 Theodore Ts'o           2015-04-12  1060  		if (err != 0) {
1f3862b5575b13 Michael Halcrow         2015-04-12  1061  			count = err;
1f3862b5575b13 Michael Halcrow         2015-04-12  1062  			goto errout;
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1063  		}
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1064  		count++;
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1065  	}
1f3862b5575b13 Michael Halcrow         2015-04-12  1066  errout:
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1067  	brelse(bh);
643fa9612bf1a2 Chandan Rajendra        2018-12-12  1068  #ifdef CONFIG_FS_ENCRYPTION
a7550b30ab709f Jaegeuk Kim             2016-07-10 @1069  	fscrypt_fname_free_buffer(&fname_crypto_str);
1f3862b5575b13 Michael Halcrow         2015-04-12  1070  #endif
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1071  	return count;
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1072  }
ac27a0ec112a08 Dave Kleikamp           2006-10-11  1073  

:::::: The code at line 1008 was first introduced by commit
:::::: a7550b30ab709ffb9bbe48669adf7d8556f3698f ext4 crypto: migrate into vfs's crypto engine

:::::: TO: Jaegeuk Kim <jaegeuk@kernel.org>
:::::: CC: Theodore Ts'o <tytso@mit.edu>

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
kernel test robot Dec. 24, 2019, 11:58 a.m. UTC | #3
Hi Herbert,

I love your patch! Yet something to improve:

[auto build test ERROR on linux/master]
[cannot apply to ext4/dev f2fs/dev-test linus/master tytso-fscrypt/master v5.5-rc3 next-20191220]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Herbert-Xu/fscrypt-Restore-modular-support/20191224-164226
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1522d9da40bdfe502c91163e6d769332897201fa
config: x86_64-rhel (attached as .config)
compiler: gcc-7 (Debian 7.5.0-3) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: fs/super.o: in function `__put_super':
   fs/super.c:296: undefined reference to `fscrypt_sb_free'
   ld: fs/ext4/dir.o: in function `ext4_dir_open':
>> fs/ext4/dir.c:617: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/dir.o: in function `ext4_readdir':
   fs/ext4/dir.c:118: undefined reference to `fscrypt_get_encryption_info'
>> ld: fs/ext4/dir.c:263: undefined reference to `fscrypt_fname_disk_to_usr'
>> ld: fs/ext4/dir.c:288: undefined reference to `fscrypt_fname_free_buffer'
>> ld: fs/ext4/dir.c:288: undefined reference to `fscrypt_fname_free_buffer'
>> ld: fs/ext4/dir.c:288: undefined reference to `fscrypt_fname_free_buffer'
>> ld: fs/ext4/dir.c:145: undefined reference to `fscrypt_fname_alloc_buffer'
>> ld: fs/ext4/dir.c:288: undefined reference to `fscrypt_fname_free_buffer'
>> ld: fs/ext4/dir.c:288: undefined reference to `fscrypt_fname_free_buffer'
   ld: fs/ext4/file.o: in function `ext4_file_open':
>> fs/ext4/file.c:716: undefined reference to `fscrypt_file_open'
   ld: fs/ext4/ialloc.o: in function `__ext4_new_inode':
>> fs/ext4/ialloc.c:772: undefined reference to `fscrypt_get_encryption_info'
>> ld: fs/ext4/ialloc.c:1145: undefined reference to `fscrypt_inherit_context'
   ld: fs/ext4/inode.o: in function `ext4_block_write_begin':
>> fs/ext4/inode.c:1097: undefined reference to `fscrypt_decrypt_pagecache_blocks'
   ld: fs/ext4/inode.o: in function `__ext4_block_zero_page_range':
   fs/ext4/inode.c:3704: undefined reference to `fscrypt_decrypt_pagecache_blocks'
   ld: fs/ext4/inode.o: in function `fscrypt_require_key':
>> include/linux/fscrypt.h:548: undefined reference to `fscrypt_get_encryption_info'
   ld: fs/ext4/inode.o: in function `ext4_issue_zeroout':
>> fs/ext4/inode.c:406: undefined reference to `fscrypt_zeroout_range'
   ld: fs/ext4/ioctl.o: in function `ext4_ioctl':
>> fs/ext4/ioctl.c:1141: undefined reference to `fscrypt_ioctl_set_policy'
>> ld: fs/ext4/ioctl.c:1211: undefined reference to `fscrypt_ioctl_get_key_status'
>> ld: fs/ext4/ioctl.c:1186: undefined reference to `fscrypt_ioctl_get_policy'
>> ld: fs/ext4/ioctl.c:1206: undefined reference to `fscrypt_ioctl_remove_key_all_users'
>> ld: fs/ext4/ioctl.c:1201: undefined reference to `fscrypt_ioctl_remove_key'
>> ld: fs/ext4/ioctl.c:1196: undefined reference to `fscrypt_ioctl_add_key'

vim +1097 fs/ext4/inode.c

ac27a0ec112a08 Dave Kleikamp      2006-10-11  1013  
643fa9612bf1a2 Chandan Rajendra   2018-12-12  1014  #ifdef CONFIG_FS_ENCRYPTION
2058f83a728adf Michael Halcrow    2015-04-12  1015  static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
2058f83a728adf Michael Halcrow    2015-04-12  1016  				  get_block_t *get_block)
2058f83a728adf Michael Halcrow    2015-04-12  1017  {
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01  1018  	unsigned from = pos & (PAGE_SIZE - 1);
2058f83a728adf Michael Halcrow    2015-04-12  1019  	unsigned to = from + len;
2058f83a728adf Michael Halcrow    2015-04-12  1020  	struct inode *inode = page->mapping->host;
2058f83a728adf Michael Halcrow    2015-04-12  1021  	unsigned block_start, block_end;
2058f83a728adf Michael Halcrow    2015-04-12  1022  	sector_t block;
2058f83a728adf Michael Halcrow    2015-04-12  1023  	int err = 0;
2058f83a728adf Michael Halcrow    2015-04-12  1024  	unsigned blocksize = inode->i_sb->s_blocksize;
2058f83a728adf Michael Halcrow    2015-04-12  1025  	unsigned bbits;
0b578f358a6a7a Chandan Rajendra   2019-05-20  1026  	struct buffer_head *bh, *head, *wait[2];
0b578f358a6a7a Chandan Rajendra   2019-05-20  1027  	int nr_wait = 0;
0b578f358a6a7a Chandan Rajendra   2019-05-20  1028  	int i;
2058f83a728adf Michael Halcrow    2015-04-12  1029  
2058f83a728adf Michael Halcrow    2015-04-12  1030  	BUG_ON(!PageLocked(page));
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01  1031  	BUG_ON(from > PAGE_SIZE);
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01  1032  	BUG_ON(to > PAGE_SIZE);
2058f83a728adf Michael Halcrow    2015-04-12  1033  	BUG_ON(from > to);
2058f83a728adf Michael Halcrow    2015-04-12  1034  
2058f83a728adf Michael Halcrow    2015-04-12  1035  	if (!page_has_buffers(page))
2058f83a728adf Michael Halcrow    2015-04-12  1036  		create_empty_buffers(page, blocksize, 0);
2058f83a728adf Michael Halcrow    2015-04-12  1037  	head = page_buffers(page);
2058f83a728adf Michael Halcrow    2015-04-12  1038  	bbits = ilog2(blocksize);
09cbfeaf1a5a67 Kirill A. Shutemov 2016-04-01  1039  	block = (sector_t)page->index << (PAGE_SHIFT - bbits);
2058f83a728adf Michael Halcrow    2015-04-12  1040  
2058f83a728adf Michael Halcrow    2015-04-12  1041  	for (bh = head, block_start = 0; bh != head || !block_start;
2058f83a728adf Michael Halcrow    2015-04-12  1042  	    block++, block_start = block_end, bh = bh->b_this_page) {
2058f83a728adf Michael Halcrow    2015-04-12  1043  		block_end = block_start + blocksize;
2058f83a728adf Michael Halcrow    2015-04-12  1044  		if (block_end <= from || block_start >= to) {
2058f83a728adf Michael Halcrow    2015-04-12  1045  			if (PageUptodate(page)) {
2058f83a728adf Michael Halcrow    2015-04-12  1046  				if (!buffer_uptodate(bh))
2058f83a728adf Michael Halcrow    2015-04-12  1047  					set_buffer_uptodate(bh);
2058f83a728adf Michael Halcrow    2015-04-12  1048  			}
2058f83a728adf Michael Halcrow    2015-04-12  1049  			continue;
2058f83a728adf Michael Halcrow    2015-04-12  1050  		}
2058f83a728adf Michael Halcrow    2015-04-12  1051  		if (buffer_new(bh))
2058f83a728adf Michael Halcrow    2015-04-12  1052  			clear_buffer_new(bh);
2058f83a728adf Michael Halcrow    2015-04-12  1053  		if (!buffer_mapped(bh)) {
2058f83a728adf Michael Halcrow    2015-04-12  1054  			WARN_ON(bh->b_size != blocksize);
2058f83a728adf Michael Halcrow    2015-04-12  1055  			err = get_block(inode, block, bh, 1);
2058f83a728adf Michael Halcrow    2015-04-12  1056  			if (err)
2058f83a728adf Michael Halcrow    2015-04-12  1057  				break;
2058f83a728adf Michael Halcrow    2015-04-12  1058  			if (buffer_new(bh)) {
2058f83a728adf Michael Halcrow    2015-04-12  1059  				if (PageUptodate(page)) {
2058f83a728adf Michael Halcrow    2015-04-12  1060  					clear_buffer_new(bh);
2058f83a728adf Michael Halcrow    2015-04-12  1061  					set_buffer_uptodate(bh);
2058f83a728adf Michael Halcrow    2015-04-12  1062  					mark_buffer_dirty(bh);
2058f83a728adf Michael Halcrow    2015-04-12  1063  					continue;
2058f83a728adf Michael Halcrow    2015-04-12  1064  				}
2058f83a728adf Michael Halcrow    2015-04-12  1065  				if (block_end > to || block_start < from)
2058f83a728adf Michael Halcrow    2015-04-12  1066  					zero_user_segments(page, to, block_end,
2058f83a728adf Michael Halcrow    2015-04-12  1067  							   block_start, from);
2058f83a728adf Michael Halcrow    2015-04-12  1068  				continue;
2058f83a728adf Michael Halcrow    2015-04-12  1069  			}
2058f83a728adf Michael Halcrow    2015-04-12  1070  		}
2058f83a728adf Michael Halcrow    2015-04-12  1071  		if (PageUptodate(page)) {
2058f83a728adf Michael Halcrow    2015-04-12  1072  			if (!buffer_uptodate(bh))
2058f83a728adf Michael Halcrow    2015-04-12  1073  				set_buffer_uptodate(bh);
2058f83a728adf Michael Halcrow    2015-04-12  1074  			continue;
2058f83a728adf Michael Halcrow    2015-04-12  1075  		}
2058f83a728adf Michael Halcrow    2015-04-12  1076  		if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
2058f83a728adf Michael Halcrow    2015-04-12  1077  		    !buffer_unwritten(bh) &&
2058f83a728adf Michael Halcrow    2015-04-12  1078  		    (block_start < from || block_end > to)) {
dfec8a14fc9043 Mike Christie      2016-06-05  1079  			ll_rw_block(REQ_OP_READ, 0, 1, &bh);
0b578f358a6a7a Chandan Rajendra   2019-05-20  1080  			wait[nr_wait++] = bh;
2058f83a728adf Michael Halcrow    2015-04-12  1081  		}
2058f83a728adf Michael Halcrow    2015-04-12  1082  	}
2058f83a728adf Michael Halcrow    2015-04-12  1083  	/*
2058f83a728adf Michael Halcrow    2015-04-12  1084  	 * If we issued read requests, let them complete.
2058f83a728adf Michael Halcrow    2015-04-12  1085  	 */
0b578f358a6a7a Chandan Rajendra   2019-05-20  1086  	for (i = 0; i < nr_wait; i++) {
0b578f358a6a7a Chandan Rajendra   2019-05-20  1087  		wait_on_buffer(wait[i]);
0b578f358a6a7a Chandan Rajendra   2019-05-20  1088  		if (!buffer_uptodate(wait[i]))
2058f83a728adf Michael Halcrow    2015-04-12  1089  			err = -EIO;
2058f83a728adf Michael Halcrow    2015-04-12  1090  	}
7e0785fce14f75 Chandan Rajendra   2019-05-20  1091  	if (unlikely(err)) {
2058f83a728adf Michael Halcrow    2015-04-12  1092  		page_zero_new_buffers(page, from, to);
0b578f358a6a7a Chandan Rajendra   2019-05-20  1093  	} else if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) {
0b578f358a6a7a Chandan Rajendra   2019-05-20  1094  		for (i = 0; i < nr_wait; i++) {
0b578f358a6a7a Chandan Rajendra   2019-05-20  1095  			int err2;
0b578f358a6a7a Chandan Rajendra   2019-05-20  1096  
0b578f358a6a7a Chandan Rajendra   2019-05-20 @1097  			err2 = fscrypt_decrypt_pagecache_blocks(page, blocksize,
0b578f358a6a7a Chandan Rajendra   2019-05-20  1098  								bh_offset(wait[i]));
0b578f358a6a7a Chandan Rajendra   2019-05-20  1099  			if (err2) {
0b578f358a6a7a Chandan Rajendra   2019-05-20  1100  				clear_buffer_uptodate(wait[i]);
0b578f358a6a7a Chandan Rajendra   2019-05-20  1101  				err = err2;
0b578f358a6a7a Chandan Rajendra   2019-05-20  1102  			}
0b578f358a6a7a Chandan Rajendra   2019-05-20  1103  		}
7e0785fce14f75 Chandan Rajendra   2019-05-20  1104  	}
7e0785fce14f75 Chandan Rajendra   2019-05-20  1105  
2058f83a728adf Michael Halcrow    2015-04-12  1106  	return err;
2058f83a728adf Michael Halcrow    2015-04-12  1107  }
2058f83a728adf Michael Halcrow    2015-04-12  1108  #endif
2058f83a728adf Michael Halcrow    2015-04-12  1109  

:::::: The code at line 1097 was first introduced by commit
:::::: 0b578f358a6a7afee2ddc48dd39c2972726187de ext4: decrypt only the needed blocks in ext4_block_write_begin()

:::::: TO: Chandan Rajendra <chandan@linux.ibm.com>
:::::: CC: Eric Biggers <ebiggers@google.com>

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation

Patch
diff mbox series

diff --git a/fs/buffer.c b/fs/buffer.c
index d8c7242426bb..eb3553fb5877 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -47,10 +47,13 @@ 
 #include <linux/pagevec.h>
 #include <linux/sched/mm.h>
 #include <trace/events/block.h>
-#include <linux/fscrypt.h>
 
 #include "internal.h"
 
+void (*end_buffer_async_read_io)(struct buffer_head *bh, int uptodate) =
+	end_buffer_async_read;
+EXPORT_SYMBOL_GPL(end_buffer_async_read_io);
+
 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
 static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
 			 enum rw_hint hint, struct writeback_control *wbc);
@@ -249,7 +252,11 @@  __find_get_block_slow(struct block_device *bdev, sector_t block)
 	return ret;
 }
 
-static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
+/*
+ * I/O completion handler for block_read_full_page() - pages
+ * which come unlocked at the end of I/O.
+ */
+void end_buffer_async_read(struct buffer_head *bh, int uptodate)
 {
 	unsigned long flags;
 	struct buffer_head *first;
@@ -305,47 +312,7 @@  static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
 	local_irq_restore(flags);
 	return;
 }
-
-struct decrypt_bh_ctx {
-	struct work_struct work;
-	struct buffer_head *bh;
-};
-
-static void decrypt_bh(struct work_struct *work)
-{
-	struct decrypt_bh_ctx *ctx =
-		container_of(work, struct decrypt_bh_ctx, work);
-	struct buffer_head *bh = ctx->bh;
-	int err;
-
-	err = fscrypt_decrypt_pagecache_blocks(bh->b_page, bh->b_size,
-					       bh_offset(bh));
-	end_buffer_async_read(bh, err == 0);
-	kfree(ctx);
-}
-
-/*
- * I/O completion handler for block_read_full_page() - pages
- * which come unlocked at the end of I/O.
- */
-static void end_buffer_async_read_io(struct buffer_head *bh, int uptodate)
-{
-	/* Decrypt if needed */
-	if (uptodate && IS_ENABLED(CONFIG_FS_ENCRYPTION) &&
-	    IS_ENCRYPTED(bh->b_page->mapping->host) &&
-	    S_ISREG(bh->b_page->mapping->host->i_mode)) {
-		struct decrypt_bh_ctx *ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
-
-		if (ctx) {
-			INIT_WORK(&ctx->work, decrypt_bh);
-			ctx->bh = bh;
-			fscrypt_enqueue_decrypt_work(&ctx->work);
-			return;
-		}
-		uptodate = 0;
-	}
-	end_buffer_async_read(bh, uptodate);
-}
+EXPORT_SYMBOL_GPL(end_buffer_async_read);
 
 /*
  * Completion handler for block_write_full_page() - pages which are unlocked
@@ -419,7 +386,11 @@  EXPORT_SYMBOL(end_buffer_async_write);
  */
 static void mark_buffer_async_read(struct buffer_head *bh)
 {
-	bh->b_end_io = end_buffer_async_read_io;
+	bh->b_end_io = end_buffer_async_read;
+	if (IS_ENABLED(CONFIG_FS_ENCRYPTION) &&
+	    IS_ENCRYPTED(bh->b_page->mapping->host) &&
+	    S_ISREG(bh->b_page->mapping->host->i_mode))
+		bh->b_end_io = end_buffer_async_read_io;
 	set_buffer_async_read(bh);
 }
 
diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig
index ff5a1746cbae..5c32902ed50f 100644
--- a/fs/crypto/Kconfig
+++ b/fs/crypto/Kconfig
@@ -1,6 +1,16 @@ 
 # SPDX-License-Identifier: GPL-2.0-only
 config FS_ENCRYPTION
 	bool "FS Encryption (Per-file encryption)"
+	select KEYS
+	help
+	  Enable encryption of files and directories.  This
+	  feature is similar to ecryptfs, but it is more memory
+	  efficient since it avoids caching the encrypted and
+	  decrypted pages in the page cache.  Currently Ext4,
+	  F2FS and UBIFS make use of this feature.
+
+config FS_ENCRYPTION_TRI
+	tristate
 	select CRYPTO
 	select CRYPTO_AES
 	select CRYPTO_CBC
@@ -9,10 +19,3 @@  config FS_ENCRYPTION
 	select CRYPTO_CTS
 	select CRYPTO_SHA512
 	select CRYPTO_HMAC
-	select KEYS
-	help
-	  Enable encryption of files and directories.  This
-	  feature is similar to ecryptfs, but it is more memory
-	  efficient since it avoids caching the encrypted and
-	  decrypted pages in the page cache.  Currently Ext4,
-	  F2FS and UBIFS make use of this feature.
diff --git a/fs/crypto/Makefile b/fs/crypto/Makefile
index 232e2bb5a337..9e0513e8626f 100644
--- a/fs/crypto/Makefile
+++ b/fs/crypto/Makefile
@@ -1,5 +1,5 @@ 
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_FS_ENCRYPTION)	+= fscrypto.o
+obj-$(CONFIG_FS_ENCRYPTION_TRI)	+= fscrypto.o
 
 fscrypto-y := crypto.o \
 	      fname.o \
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 3719efa546c6..6bf7f05120bd 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -20,6 +20,7 @@ 
  * Special Publication 800-38E and IEEE P1619/D16.
  */
 
+#include <linux/buffer_head.h>
 #include <linux/pagemap.h>
 #include <linux/mempool.h>
 #include <linux/module.h>
@@ -286,6 +287,41 @@  int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
 }
 EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
 
+struct decrypt_bh_ctx {
+	struct work_struct work;
+	struct buffer_head *bh;
+};
+
+static void decrypt_bh(struct work_struct *work)
+{
+	struct decrypt_bh_ctx *ctx =
+		container_of(work, struct decrypt_bh_ctx, work);
+	struct buffer_head *bh = ctx->bh;
+	int err;
+
+	err = fscrypt_decrypt_pagecache_blocks(bh->b_page, bh->b_size,
+					       bh_offset(bh));
+	end_buffer_async_read(bh, err == 0);
+	kfree(ctx);
+}
+
+static void fscrypt_end_buffer_async_read(struct buffer_head *bh, int uptodate)
+{
+	/* Decrypt if needed */
+	if (uptodate) {
+		struct decrypt_bh_ctx *ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+
+		if (ctx) {
+			INIT_WORK(&ctx->work, decrypt_bh);
+			ctx->bh = bh;
+			fscrypt_enqueue_decrypt_work(&ctx->work);
+			return;
+		}
+		uptodate = 0;
+	}
+	end_buffer_async_read(bh, uptodate);
+}
+
 /*
  * Validate dentries in encrypted directories to make sure we aren't potentially
  * caching stale dentries after a key has been added.
@@ -418,6 +454,8 @@  static int __init fscrypt_init(void)
 	if (err)
 		goto fail_free_info;
 
+	end_buffer_async_read_io = fscrypt_end_buffer_async_read;
+
 	return 0;
 
 fail_free_info:
@@ -427,4 +465,18 @@  static int __init fscrypt_init(void)
 fail:
 	return err;
 }
-late_initcall(fscrypt_init)
+module_init(fscrypt_init)
+
+/**
+ * fscrypt_exit() - Shutdown the fs encryption system
+ */
+static void __exit fscrypt_exit(void)
+{
+	end_buffer_async_read_io = end_buffer_async_read;
+
+	kmem_cache_destroy(fscrypt_info_cachep);
+	destroy_workqueue(fscrypt_read_workqueue);
+}
+module_exit(fscrypt_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index ef42ab040905..5de0bcc50d37 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -10,6 +10,7 @@  config EXT3_FS
 	select CRC16
 	select CRYPTO
 	select CRYPTO_CRC32C
+	select FS_ENCRYPTION_TRI if FS_ENCRYPTION
 	help
 	  This config option is here only for backward compatibility. ext3
 	  filesystem is now handled by the ext4 driver.
diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index 652fd2e2b23d..9ccaec60af47 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -6,6 +6,7 @@  config F2FS_FS
 	select CRYPTO
 	select CRYPTO_CRC32
 	select F2FS_FS_XATTR if FS_ENCRYPTION
+	select FS_ENCRYPTION_TRI if FS_ENCRYPTION
 	help
 	  F2FS is based on Log-structured File System (LFS), which supports
 	  versatile "flash-friendly" features. The design has been focused on
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 69932bcfa920..ea2d43829c18 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -12,6 +12,7 @@  config UBIFS_FS
 	select CRYPTO_ZSTD if UBIFS_FS_ZSTD
 	select CRYPTO_HASH_INFO
 	select UBIFS_FS_XATTR if FS_ENCRYPTION
+	select FS_ENCRYPTION_TRI if FS_ENCRYPTION
 	depends on MTD_UBI
 	help
 	  UBIFS is a file system for flash devices which works on top of UBI.
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 7b73ef7f902d..66249a98e003 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -164,6 +164,8 @@  void create_empty_buffers(struct page *, unsigned long,
 			unsigned long b_state);
 void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
 void end_buffer_write_sync(struct buffer_head *bh, int uptodate);
+extern void (*end_buffer_async_read_io)(struct buffer_head *bh, int uptodate);
+void end_buffer_async_read(struct buffer_head *bh, int uptodate);
 void end_buffer_async_write(struct buffer_head *bh, int uptodate);
 
 /* Things to do with buffers at mapping->private_list */