hulk inclusion category: bugfix bugzilla: 189317, https://gitee.com/openeuler/kernel/issues/I76JSK CVE: NA
--------------------------------
When fsstress + drop cache test, we get following warning:
CPU: 2 PID: 42297 Comm: fsstress Not tainted 5.10.0-09150-gd7277a187bfc #33 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 RIP: 0010:xfs_iomap_write_delalloc_release fs/xfs/xfs_iomap.c:1272 [inline] RIP: 0010:xfs_iomap_file_buffered_write_punch_delalloc fs/xfs/xfs_iomap.c:1357 [inline] RIP: 0010:xfs_buffered_write_iomap_end+0xa39/0x11b0 fs/xfs/xfs_iomap.c:1373 Code: 08 01 e8 a2 42 9a 02 e8 35 db 13 ff 49 8d 6d ff 48 83 05 c9 1c df 08 01 e9 f7 fb ff ff e8 1f db 13 ff 48 83 05 e7 2f df 08 01 <0f> 0b 48 83 05 e5 2f df 08 01 4c 8b 7c 24 18 4c 89 e6 48 83 05 dd RSP: 0000:ffff88811ab27550 EFLAGS: 00010202 RAX: ffff888110941bc0 RBX: 00000000002cd000 RCX: ffffffff8b454f41 RDX: 0000000000000000 RSI: 00000000002cd000 RDI: 0000000000000006 RBP: 000000000000001f R08: ffff888110941bc0 R09: 0000000000000001 R10: ffffea0004838877 R11: fffff9400090710e R12: 00000000002cd000 R13: ffff88812318fa88 R14: 00000000002c7000 R15: 00000000002d0000 FS: 00007f9474a86740(0000) GS:ffff8881f6900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f09f84c88e0 CR3: 0000000101b32001 CR4: 0000000000370ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: iomap_apply+0xff/0xdf0 fs/iomap/apply.c:98 iomap_file_buffered_write+0x164/0x230 fs/iomap/buffered-io.c:852 xfs_file_buffered_aio_write+0x34a/0xc90 fs/xfs/xfs_file.c:736 xfs_file_write_iter+0x375/0x4b0 fs/xfs/xfs_file.c:816 call_write_iter include/linux/fs.h:1970 [inline] do_iter_readv_writev+0x735/0x8b0 fs/read_write.c:735 do_iter_write+0x19d/0x4b0 fs/read_write.c:861 vfs_iter_write+0x7c/0xd0 fs/read_write.c:902 ovl_write_iter+0xcdd/0x1d40 fs/overlayfs/file.c:380 call_write_iter include/linux/fs.h:1970 [inline] do_iter_readv_writev+0x735/0x8b0 fs/read_write.c:735 do_iter_write+0x19d/0x4b0 fs/read_write.c:861 vfs_writev+0x191/0x820 fs/read_write.c:934 do_writev+0x149/0x3c0 fs/read_write.c:977 __do_sys_writev fs/read_write.c:1050 [inline] __se_sys_writev fs/read_write.c:1047 [inline] __x64_sys_writev+0x79/0xc0 fs/read_write.c:1047 do_syscall_64+0x4b/0x80 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x62/0xc7 RIP: 0033:0x7f94741a1c08 Code: ff eb b6 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 f3 0f 1e fa 48 8d 05 15 eb 29 00 8b 00 85 c0 75 17 b8 14 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 41 54 41 89 d4 55 RSP: 002b:00007ffdf2165ee8 EFLAGS: 00000246 ORIG_RAX: 0000000000000014 RAX: ffffffffffffffda RBX: 0000000000000079 RCX: 00007f94741a1c08 RDX: 0000000000000266 RSI: 0000000001b3f8a0 RDI: 0000000000000003 RBP: 0000000000000003 R08: 0000000001b3f87a R09: 0000000000000003 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000001b3f8a0 R13: 0000000001b2c7e0 R14: 0000000000000266 R15: 000000000000007f
The warning occurred in the following code of iomap_write_delalloc_release(). After analyzing vmcore, I found that the reason for the warning was that data_end was equal to start_byte.
WARN_ON_ONCE(data_end <= start_byte);
If some delay is added between seeking for data and seeking for hole in xfs_iomap_write_delalloc_release(), the problem can be reproduced quickly. The root cause of the problem is that clean data page was dropped between two seeking in the page cache. As a result, data_end equal to start_byte.
buffer write drop cache --------------------------- --------------------------- xfs_buffered_write_iomap_end xfs_iomap_file_buffered_write_punch_delalloc xfs_iomap_write_delalloc_release xfs_ilock(ip, XFS_MMAPLOCK_EXCL) start_byte = mapping_seek_hole_data(SEEK_DATA)
drop_pagecache_sb invalidate_mapping_pages invalidate_inode_page invalidate_complete_page remove_mapping <remove clean page>
data_end = mapping_seek_hole_data(SEEK_HOLE) xfs_iunlock(ip, XFS_MMAPLOCK_EXCL)
Although there is race between punch delalloc and drop cache, it does not affect the original punch logic for non-dirty data pages, so the warning can be eliminated directly.
Fixes: c515b6a4c619 ("iomap: buffered write failure should not truncate the page cache") Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_iomap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index ae96ac52c974..76285db4aaec 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1269,7 +1269,7 @@ xfs_iomap_write_delalloc_release( error = data_end; goto out_unlock; } - WARN_ON_ONCE(data_end <= start_byte); + WARN_ON_ONCE(data_end < start_byte); WARN_ON_ONCE(data_end > scan_end_byte);
error = xfs_iomap_write_delalloc_scan(inode, &punch_start_byte,