linux/fs/ext4
Jan Kara ceb5c560e2 ext4: fix data exposure after a crash
commit 06bd3c36a7 upstream.

Huang has reported that in his powerfail testing he is seeing stale
block contents in some of recently allocated blocks although he mounts
ext4 in data=ordered mode. After some investigation I have found out
that indeed when delayed allocation is used, we don't add inode to
transaction's list of inodes needing flushing before commit. Originally
we were doing that but commit f3b59291a6 removed the logic with a
flawed argument that it is not needed.

The problem is that although for delayed allocated blocks we write their
contents immediately after allocating them, there is no guarantee that
the IO scheduler or device doesn't reorder things and thus transaction
allocating blocks and attaching them to inode can reach stable storage
before actual block contents. Actually whenever we attach freshly
allocated blocks to inode using a written extent, we should add inode to
transaction's ordered inode list to make sure we properly wait for block
contents to be written before committing the transaction. So that is
what we do in this patch. This also handles other cases where stale data
exposure was possible - like filling hole via mmap in
data=ordered,nodelalloc mode.

The only exception to the above rule are extending direct IO writes where
blkdev_direct_IO() waits for IO to complete before increasing i_size and
thus stale data exposure is not possible. For now we don't complicate
the code with optimizing this special case since the overhead is pretty
low. In case this is observed to be a performance problem we can always
handle it using a special flag to ext4_map_blocks().

Fixes: f3b59291a6
Reported-by: "HUANG Weller (CM/ESW12-CN)" <Weller.Huang@cn.bosch.com>
Tested-by: "HUANG Weller (CM/ESW12-CN)" <Weller.Huang@cn.bosch.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
[bwh: Backported to 4.4:
 - Drop check for EXT4_GET_BLOCKS_ZERO flag
 - Adjust context]
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-21 09:21:17 +01:00
..
acl.c ext4: Don't clear SGID when inheriting ACLs 2017-10-12 11:27:35 +02:00
acl.h ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
balloc.c ext4: validate s_reserved_gdt_blocks on mount 2016-08-16 09:30:51 +02:00
bitmap.c ext4: remove unused header files 2015-04-02 23:47:42 -04:00
block_validity.c ext4: call out CRC and corruption errors with specific error codes 2015-10-17 16:16:04 -04:00
crypto_fname.c fscrypt: avoid collisions when presenting long encrypted filenames 2017-05-25 14:30:11 +02:00
crypto_key.c fscrypt: fix dereference of NULL user_key_payload 2017-10-27 10:23:18 +02:00
crypto_policy.c fscrypt: fix context consistency check when key(s) unavailable 2017-05-25 14:30:11 +02:00
crypto.c ext4 crypto: don't let data integrity writebacks fail with ENOMEM 2017-05-25 14:30:11 +02:00
dir.c ext4 crypto: revalidate dentry after adding or removing the key 2017-05-08 07:46:02 +02:00
ext4_crypto.h fscrypt: remove broken support for detecting keyring key revocation 2017-03-31 09:49:54 +02:00
ext4_extents.h ext4: teach ext4_ext_find_extent() to realloc path if necessary 2014-09-01 14:40:09 -04:00
ext4_jbd2.c ext4: fix potential use after free in __ext4_journal_stop 2015-10-17 22:57:06 -04:00
ext4_jbd2.h ext4: do not perform data journaling when data is encrypted 2017-01-06 11:16:13 +01:00
ext4.h ext4 crypto: don't let data integrity writebacks fail with ENOMEM 2017-05-25 14:30:11 +02:00
extents_status.c ext4: move procfs registration code to fs/ext4/sysfs.c 2015-09-23 12:46:17 -04:00
extents_status.h ext4: move procfs registration code to fs/ext4/sysfs.c 2015-09-23 12:46:17 -04:00
extents.c ext4: fix fdatasync(2) after extent manipulation operations 2017-06-14 13:16:22 +02:00
file.c ext4: in ext4_seek_{hole,data}, return -ENXIO for negative offsets 2017-10-18 09:20:40 +02:00
fsync.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-04-26 17:22:07 -07:00
hash.c ext4: remove unused header files 2015-04-02 23:47:42 -04:00
ialloc.c ext4: clean up error handling when orphan list is corrupted 2016-06-07 18:14:37 -07:00
indirect.c ext4: clean up feature test macros with predicate functions 2015-10-17 16:18:43 -04:00
inline.c ext4: mark inode dirty after converting inline directory 2017-03-30 09:35:17 +02:00
inode.c ext4: fix data exposure after a crash 2017-11-21 09:21:17 +01:00
ioctl.c ext4: require encryption feature for EXT4_IOC_SET_ENCRYPTION_POLICY 2017-05-08 07:46:02 +02:00
Kconfig ext4: Update EXT4_USE_FOR_EXT2 description 2015-09-24 13:27:47 +02:00
Makefile ext4: move sysfs code from super.c to fs/ext4/sysfs.c 2015-09-23 12:44:17 -04:00
mballoc.c ext4: fix stripe-unaligned allocations 2017-11-08 10:06:29 +01:00
mballoc.h ext4: remove unused ac_ex_scanned 2014-02-20 13:32:10 -05:00
migrate.c ext4: clean up feature test macros with predicate functions 2015-10-17 16:18:43 -04:00
mmp.c ext4: call out CRC and corruption errors with specific error codes 2015-10-17 16:16:04 -04:00
move_extent.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
namei.c ext4: don't allow encrypted operations without keys 2017-10-12 11:27:35 +02:00
page-io.c ext4 crypto: fix some error handling 2017-05-25 14:30:11 +02:00
readpage.c ext4 crypto: don't let data integrity writebacks fail with ENOMEM 2017-05-25 14:30:11 +02:00
resize.c ext4: fix overflow caused by missing cast in ext4_resize_fs() 2017-08-11 09:08:48 -07:00
super.c ext4: do not use stripe_width if it is not set 2017-11-08 10:06:29 +01:00
symlink.c ext4: fix an endianness bug in ext4_encrypted_follow_link() 2015-11-26 15:20:50 -05:00
sysfs.c ext4: check return value of kstrtoull correctly in reserved_clusters_store 2017-07-15 11:57:50 +02:00
truncate.h ext4: fix races between page faults and hole punching 2016-05-04 14:48:53 -07:00
xattr_security.c xattr handlers: Pass handler to operations instead of flags 2015-11-13 20:34:32 -05:00
xattr_trusted.c xattr handlers: Pass handler to operations instead of flags 2015-11-13 20:34:32 -05:00
xattr_user.c xattr handlers: Pass handler to operations instead of flags 2015-11-13 20:34:32 -05:00
xattr.c ext4: check if in-inode xattr is corrupted in ext4_expand_extra_isize_ea() 2017-05-02 21:19:48 -07:00
xattr.h ext4 crypto: add encryption xattr support 2015-04-11 07:47:00 -04:00