linux/fs/ext4
Eric Biggers 7b4cc9787f ext4: evict inline data when writing to memory map
Currently the case of writing via mmap to a file with inline data is not
handled.  This is maybe a rare case since it requires a writable memory
map of a very small file, but it is trivial to trigger with on
inline_data filesystem, and it causes the
'BUG_ON(ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA));' in
ext4_writepages() to be hit:

    mkfs.ext4 -O inline_data /dev/vdb
    mount /dev/vdb /mnt
    xfs_io -f /mnt/file \
	-c 'pwrite 0 1' \
	-c 'mmap -w 0 1m' \
	-c 'mwrite 0 1' \
	-c 'fsync'

	kernel BUG at fs/ext4/inode.c:2723!
	invalid opcode: 0000 [#1] SMP
	CPU: 1 PID: 2532 Comm: xfs_io Not tainted 4.11.0-rc1-xfstests-00301-g071d9acf3d1f #633
	Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
	task: ffff88003d3a8040 task.stack: ffffc90000300000
	RIP: 0010:ext4_writepages+0xc89/0xf8a
	RSP: 0018:ffffc90000303ca0 EFLAGS: 00010283
	RAX: 0000028410000000 RBX: ffff8800383fa3b0 RCX: ffffffff812afcdc
	RDX: 00000a9d00000246 RSI: ffffffff81e660e0 RDI: 0000000000000246
	RBP: ffffc90000303dc0 R08: 0000000000000002 R09: 869618e8f99b4fa5
	R10: 00000000852287a2 R11: 00000000a03b49f4 R12: ffff88003808e698
	R13: 0000000000000000 R14: 7fffffffffffffff R15: 7fffffffffffffff
	FS:  00007fd3e53094c0(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
	CR2: 00007fd3e4c51000 CR3: 000000003d554000 CR4: 00000000003406e0
	Call Trace:
	 ? _raw_spin_unlock+0x27/0x2a
	 ? kvm_clock_read+0x1e/0x20
	 do_writepages+0x23/0x2c
	 ? do_writepages+0x23/0x2c
	 __filemap_fdatawrite_range+0x80/0x87
	 filemap_write_and_wait_range+0x67/0x8c
	 ext4_sync_file+0x20e/0x472
	 vfs_fsync_range+0x8e/0x9f
	 ? syscall_trace_enter+0x25b/0x2d0
	 vfs_fsync+0x1c/0x1e
	 do_fsync+0x31/0x4a
	 SyS_fsync+0x10/0x14
	 do_syscall_64+0x69/0x131
	 entry_SYSCALL64_slow_path+0x25/0x25

We could try to be smart and keep the inline data in this case, or at
least support delayed allocation when allocating the block, but these
solutions would be more complicated and don't seem worthwhile given how
rare this case seems to be.  So just fix the bug by calling
ext4_convert_inline_data() when we're asked to make a page writable, so
that any inline data gets evicted, with the block allocated immediately.

Reported-by: Nick Alcock <nick.alcock@oracle.com>
Cc: stable@vger.kernel.org
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2017-04-30 00:10:50 -04:00
..
acl.c ext4: use current_time() for inode timestamps 2016-11-14 21:40:10 -05:00
acl.h ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
balloc.c The major change this cycle is deleting ext4's copy of the file system 2016-07-26 18:35:55 -07:00
bitmap.c ext4: remove unused header files 2015-04-02 23:47:42 -04:00
block_validity.c ext4: add missing KERN_CONT to a few more debugging uses 2016-10-15 09:57:31 -04:00
dir.c ext4: remove unused variable 2016-09-30 02:14:56 -04:00
ext4_extents.h ext4: fix misspellings in comments. 2016-03-09 23:49:05 -05:00
ext4_jbd2.c ext4: add shutdown bit and check for it 2017-02-05 01:28:48 -05:00
ext4_jbd2.h ext4: do not perform data journaling when data is encrypted 2016-12-10 17:54:58 -05:00
ext4.h ext4: constify static data that is never modified 2017-04-29 23:47:50 -04:00
extents_status.c scripts/spelling.txt: add "comsume(r)" pattern and fix typo instances 2017-02-27 18:43:47 -08: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: do not polute the extents cache while shifting extents 2017-01-08 21:00:35 -05:00
file.c ext4: Add statx support 2017-04-03 01:05:58 -04:00
fsync.c ext4: add shutdown bit and check for it 2017-02-05 01:28:48 -05:00
hash.c ext4: move halfmd4 into hash.c directly 2017-02-02 11:52:14 -05:00
ialloc.c sched/headers: Prepare to remove <linux/cred.h> inclusion from <linux/sched.h> 2017-03-02 08:42:31 +01:00
indirect.c ext4: refactor direct IO code 2016-05-13 00:44:16 -04:00
inline.c ext4: trim return value and 'dir' argument from ext4_insert_dentry() 2017-04-29 23:27:26 -04:00
inode.c ext4: evict inline data when writing to memory map 2017-04-30 00:10:50 -04:00
ioctl.c ext4: rename EXT4_IOC_GOINGDOWN to EXT4_IOC_SHUTDOWN 2017-02-20 15:34:59 -05:00
Kconfig dax: fix build warnings with FS_DAX and !FS_IOMAP 2017-01-24 16:26:14 -08:00
Makefile ext4 crypto: migrate into vfs's crypto engine 2016-07-10 14:01:03 -04:00
mballoc.c ext4: constify static data that is never modified 2017-04-29 23:47:50 -04:00
mballoc.h ext4: add missing KERN_CONT to a few more debugging uses 2016-10-15 09:57:31 -04:00
migrate.c ext4: fix misspellings in comments. 2016-03-09 23:49:05 -05:00
mmp.c block,fs: use REQ_* flags directly 2016-11-01 09:43:26 -06:00
move_extent.c Fix a memory leak on an error path, and two races when modifying 2017-03-26 10:29:21 -07:00
namei.c ext4: trim return value and 'dir' argument from ext4_insert_dentry() 2017-04-29 23:27:26 -04:00
page-io.c For this cycle we add support for the shutdown ioctl, which is 2017-02-20 18:24:39 -08:00
readpage.c Merge branch 'akpm' (patches from Andrew) 2016-07-26 19:55:54 -07:00
resize.c ext4: rename s_resize_flags to s_ext4_flags 2017-02-05 01:27:48 -05:00
super.c ext4: constify static data that is never modified 2017-04-29 23:47:50 -04:00
symlink.c ext4: Add statx support 2017-04-03 01:05:58 -04:00
sysfs.c ext4: constify static data that is never modified 2017-04-29 23:47:50 -04:00
truncate.h ext4: fix races between page faults and hole punching 2015-12-07 14:28:03 -05:00
xattr_security.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00
xattr_trusted.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00
xattr_user.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00
xattr.c ext4: remove ext4_xattr_check_entry() 2017-04-30 00:01:02 -04:00
xattr.h ext4: fix deadlock between inline_data and ext4_expand_extra_isize_ea() 2017-01-11 21:50:46 -05:00