]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.11.2/ext4-evict-inline-data-when-writing-to-memory-map.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.11.2 / ext4-evict-inline-data-when-writing-to-memory-map.patch
CommitLineData
5032628c
GKH
1From 7b4cc9787fe35b3ee2dfb1c35e22eafc32e00c33 Mon Sep 17 00:00:00 2001
2From: Eric Biggers <ebiggers@google.com>
3Date: Sun, 30 Apr 2017 00:10:50 -0400
4Subject: ext4: evict inline data when writing to memory map
5
6From: Eric Biggers <ebiggers@google.com>
7
8commit 7b4cc9787fe35b3ee2dfb1c35e22eafc32e00c33 upstream.
9
10Currently the case of writing via mmap to a file with inline data is not
11handled. This is maybe a rare case since it requires a writable memory
12map of a very small file, but it is trivial to trigger with on
13inline_data filesystem, and it causes the
14'BUG_ON(ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA));' in
15ext4_writepages() to be hit:
16
17 mkfs.ext4 -O inline_data /dev/vdb
18 mount /dev/vdb /mnt
19 xfs_io -f /mnt/file \
20 -c 'pwrite 0 1' \
21 -c 'mmap -w 0 1m' \
22 -c 'mwrite 0 1' \
23 -c 'fsync'
24
25 kernel BUG at fs/ext4/inode.c:2723!
26 invalid opcode: 0000 [#1] SMP
27 CPU: 1 PID: 2532 Comm: xfs_io Not tainted 4.11.0-rc1-xfstests-00301-g071d9acf3d1f #633
28 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
29 task: ffff88003d3a8040 task.stack: ffffc90000300000
30 RIP: 0010:ext4_writepages+0xc89/0xf8a
31 RSP: 0018:ffffc90000303ca0 EFLAGS: 00010283
32 RAX: 0000028410000000 RBX: ffff8800383fa3b0 RCX: ffffffff812afcdc
33 RDX: 00000a9d00000246 RSI: ffffffff81e660e0 RDI: 0000000000000246
34 RBP: ffffc90000303dc0 R08: 0000000000000002 R09: 869618e8f99b4fa5
35 R10: 00000000852287a2 R11: 00000000a03b49f4 R12: ffff88003808e698
36 R13: 0000000000000000 R14: 7fffffffffffffff R15: 7fffffffffffffff
37 FS: 00007fd3e53094c0(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000
38 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
39 CR2: 00007fd3e4c51000 CR3: 000000003d554000 CR4: 00000000003406e0
40 Call Trace:
41 ? _raw_spin_unlock+0x27/0x2a
42 ? kvm_clock_read+0x1e/0x20
43 do_writepages+0x23/0x2c
44 ? do_writepages+0x23/0x2c
45 __filemap_fdatawrite_range+0x80/0x87
46 filemap_write_and_wait_range+0x67/0x8c
47 ext4_sync_file+0x20e/0x472
48 vfs_fsync_range+0x8e/0x9f
49 ? syscall_trace_enter+0x25b/0x2d0
50 vfs_fsync+0x1c/0x1e
51 do_fsync+0x31/0x4a
52 SyS_fsync+0x10/0x14
53 do_syscall_64+0x69/0x131
54 entry_SYSCALL64_slow_path+0x25/0x25
55
56We could try to be smart and keep the inline data in this case, or at
57least support delayed allocation when allocating the block, but these
58solutions would be more complicated and don't seem worthwhile given how
59rare this case seems to be. So just fix the bug by calling
60ext4_convert_inline_data() when we're asked to make a page writable, so
61that any inline data gets evicted, with the block allocated immediately.
62
63Reported-by: Nick Alcock <nick.alcock@oracle.com>
64Reviewed-by: Andreas Dilger <adilger@dilger.ca>
65Signed-off-by: Eric Biggers <ebiggers@google.com>
66Signed-off-by: Theodore Ts'o <tytso@mit.edu>
67Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
68
69---
70 fs/ext4/inode.c | 5 +++++
71 1 file changed, 5 insertions(+)
72
73--- a/fs/ext4/inode.c
74+++ b/fs/ext4/inode.c
75@@ -5874,6 +5874,11 @@ int ext4_page_mkwrite(struct vm_fault *v
76 file_update_time(vma->vm_file);
77
78 down_read(&EXT4_I(inode)->i_mmap_sem);
79+
80+ ret = ext4_convert_inline_data(inode);
81+ if (ret)
82+ goto out_ret;
83+
84 /* Delalloc case is easy... */
85 if (test_opt(inode->i_sb, DELALLOC) &&
86 !ext4_should_journal_data(inode) &&