kernel_optimize_test/fs/ext4
Eric Biggers 547c556f4d ext4: fix deadlock allocating crypto bounce page from mempool
ext4_writepages() on an encrypted file has to encrypt the data, but it
can't modify the pagecache pages in-place, so it encrypts the data into
bounce pages and writes those instead.  All bounce pages are allocated
from a mempool using GFP_NOFS.

This is not correct use of a mempool, and it can deadlock.  This is
because GFP_NOFS includes __GFP_DIRECT_RECLAIM, which enables the "never
fail" mode for mempool_alloc() where a failed allocation will fall back
to waiting for one of the preallocated elements in the pool.

But since this mode is used for all a bio's pages and not just the
first, it can deadlock waiting for pages already in the bio to be freed.

This deadlock can be reproduced by patching mempool_alloc() to pretend
that pool->alloc() always fails (so that it always falls back to the
preallocations), and then creating an encrypted file of size > 128 KiB.

Fix it by only using GFP_NOFS for the first page in the bio.  For
subsequent pages just use GFP_NOWAIT, and if any of those fail, just
submit the bio and start a new one.

This will need to be fixed in f2fs too, but that's less straightforward.

Fixes: c9af28fdd4 ("ext4 crypto: don't let data integrity writebacks fail with ENOMEM")
Cc: stable@vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20191231181149.47619-1-ebiggers@kernel.org
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2020-01-17 16:24:54 -05:00
..
acl.c
acl.h
balloc.c ext4: simulate various I/O and checksum errors when reading metadata 2019-12-26 11:28:31 -05:00
bitmap.c
block_validity.c ext4: use RCU API in debug_print_tree 2019-12-15 21:41:04 -05:00
dir.c ext4: remove unnecessary assignment in ext4_htree_store_dirent() 2020-01-17 16:24:52 -05:00
ext4_extents.h
ext4_jbd2.c ext4: uninline ext4_inode_journal_mode() 2020-01-17 16:24:52 -05:00
ext4_jbd2.h ext4: uninline ext4_inode_journal_mode() 2020-01-17 16:24:52 -05:00
ext4.h ext4: Delete ext4_kvzvalloc() 2020-01-17 16:24:53 -05:00
extents_status.c
extents_status.h
extents.c ext4: re-enable extent zeroout optimization on encrypted files 2020-01-17 16:24:53 -05:00
file.c ext4: Optimize ext4 DIO overwrites 2019-12-26 11:57:18 -05:00
fsmap.c
fsmap.h
fsync.c
hash.c
ialloc.c ext4: simulate various I/O and checksum errors when reading metadata 2019-12-26 11:28:31 -05:00
indirect.c
inline.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
inode-test.c
inode.c ext4: only use fscrypt_zeroout_range() on regular files 2020-01-17 16:24:53 -05:00
ioctl.c
Kconfig ext4: remove unnecessary selections from EXT3_FS 2020-01-17 16:24:53 -05:00
Makefile
mballoc.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
mballoc.h
migrate.c
mmp.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
move_extent.c
namei.c ext4: remove unnecessary ifdefs in htree_dirblock_to_tree() 2020-01-17 16:24:52 -05:00
page-io.c ext4: fix deadlock allocating crypto bounce page from mempool 2020-01-17 16:24:54 -05:00
readpage.c
resize.c
super.c ext4: Delete ext4_kvzvalloc() 2020-01-17 16:24:53 -05:00
symlink.c
sysfs.c ext4: export information about first/last errors via /sys/fs/ext4/<dev> 2019-12-26 11:29:10 -05:00
truncate.h
verity.c
xattr_security.c
xattr_trusted.c
xattr_user.c
xattr.c ext4: save the error code which triggered an ext4_error() in the superblock 2019-12-26 11:28:23 -05:00
xattr.h