394 Star 1.4K Fork 1.3K

GVPopenEuler / kernel

 / 详情

[OLK5.10][Syzkaller] kernel BUG in __ext4_journal_stop

已完成
任务
创建于  
2022-05-16 21:16

EXT4-fs error (device loop3): ext4_mb_generate_buddy:805: group 0, block bitmap and bg descriptor inconsistent: 25 vs 31513 free clusters
------------[ cut here ]------------
kernel BUG at fs/ext4/ext4_jbd2.c:53!
invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 0 PID: 25371 Comm: syz-executor.3 Not tainted 5.10.0+ #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:ext4_put_nojournal fs/ext4/ext4_jbd2.c:53 [inline]
RIP: 0010:__ext4_journal_stop+0x10e/0x110 fs/ext4/ext4_jbd2.c:116
Code: 31 ff 44 89 e6 e8 e2 eb cb ff 45 85 e4 41 0f 45 ec eb 05 e8 44 e7 cb ff 89 e8 5b 41 5c 41 5d 41 5e 41 5f 5d c3 e8 32 e7 cb ff <0f> 0b 55 41 57 41 56 41 55 41 54 53 50 41 89 d6 41 89 f4 48 89 fb
RSP: 0018:ffff88811563fa50 EFLAGS: 00010293
RAX: ffffffff907ad4ce RBX: 0000000000000039 RCX: ffff888113920000
RDX: 0000000000000000 RSI: 000000000000031b RDI: ffffffff92782c88
RBP: 0000000000000000 R08: ffffffff907de78c R09: ffffed1022bbb9db
R10: ffffed1022bbb9db R11: 1ffff11022bbb9da R12: ffff8880143e6998
R13: 0000000000000000 R14: 000000000000031b R15: ffffffff92782c88
FS: 00007ff883c31700(0000) GS:ffff88811b200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ff99b1ed16b CR3: 0000000113016006 CR4: 00000000003706f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
ext4_write_inline_data_end+0x59a/0x730 fs/ext4/inline.c:795
generic_perform_write+0x279/0x3c0 mm/filemap.c:3344
ext4_buffered_write_iter+0x2e3/0x3d0 fs/ext4/file.c:270
ext4_file_write_iter+0x30a/0x11c0 fs/ext4/file.c:520
do_iter_readv_writev+0x339/0x3c0 fs/read_write.c:732
do_iter_write+0x107/0x430 fs/read_write.c:861
vfs_writev fs/read_write.c:934 [inline]
do_pwritev+0x1e5/0x380 fs/read_write.c:1031
do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x478399
Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ff883c30be8 EFLAGS: 00000246 ORIG_RAX: 0000000000000128
RAX: ffffffffffffffda RBX: 000000000077bf60 RCX: 0000000000478399
RDX: 0000000000000001 RSI: 0000000020000b80 RDI: 0000000000000003
RBP: 000000000077bf60 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 000000000077bf60 R15: 00007fffd760eac0
Modules linked in:
---[ end trace 43677bfb6b6544b5 ]---
RIP: 0010:ext4_put_nojournal fs/ext4/ext4_jbd2.c:53 [inline]
RIP: 0010:__ext4_journal_stop+0x10e/0x110 fs/ext4/ext4_jbd2.c:116
Code: 31 ff 44 89 e6 e8 e2 eb cb ff 45 85 e4 41 0f 45 ec eb 05 e8 44 e7 cb ff 89 e8 5b 41 5c 41 5d 41 5e 41 5f 5d c3 e8 32 e7 cb ff <0f> 0b 55 41 57 41 56 41 55 41 54 53 50 41 89 d6 41 89 f4 48 89 fb
RSP: 0018:ffff88811563fa50 EFLAGS: 00010293
RAX: ffffffff907ad4ce RBX: 0000000000000039 RCX: ffff888113920000
RDX: 0000000000000000 RSI: 000000000000031b RDI: ffffffff92782c88
RBP: 0000000000000000 R08: ffffffff907de78c R09: ffffed1022bbb9db
R10: ffffed1022bbb9db R11: 1ffff11022bbb9da R12: ffff8880143e6998
R13: 0000000000000000 R14: 000000000000031b R15: ffffffff92782c88
FS: 00007ff883c31700(0000) GS:ffff88811b200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ff99b1ed16b CR3: 0000000113016006 CR4: 00000000003706f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400

评论 (6)

LiBaokun 创建了任务

Hi cool-water, welcome to the openEuler Community.
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here.
If you have any questions, please contact the SIG: Kernel, and any of the maintainers: @YangYingliang , @pi3orama , @成坚 (CHENG Jian) , @jiaoff , @zhengzengkai , @刘勇强 , @Qiuuuuu , @Xie XiuQi

openeuler-ci-bot 添加了
 
sig/Kernel
标签

【报错位置代码】

49 static void ext4_put_nojournal(handle_t *handle)                                
 50 {                                                                               
 51         unsigned long ref_cnt = (unsigned long)handle;                          
 52                                                                                 
 53         BUG_ON(ref_cnt == 0);                           

报错是因为在 ext4_put_nojournal 中 ref_cnt 为0,导致 BUG_ON
具体 handle 如何导致 ref_cnt 为 0 尚不清楚
尝试通过 syzkaller 复现进行分析

【复现程序】
截取 log 后8个程序进行复现拆分,得到 syzkaller 复现程序如下,无法将其转换为C程序

14:25:12 executing program 3:
r0 = syz_mount_image$ext4(&(0x7f0000000080)='ext4\x00', &(0x7f0000000000)='./file0\x00', 0x200000, 0x9, &(0x7f0000000200)=[{&(0x7f0000010000)="200000000002000019000000900100000f000000000000000200000006000000000008000080000020000000d6f4655fd6f4655f0100ffff53ef010001000000d5f4655f000000000000000001000000000000000b0000000001000018000000c28500002b02", 0x66, 0x400}, {&(0x7f0000010100)="00000000000000000000000028305c8a835f4f4da440baa59e2884cb010040", 0x1f, 0x4e0}, {&(0x7f0000010200)="0000000000000000000000000000000000000000000000000000000020002000010000000000050040", 0x29, 0x540}, {&(0x7f0000000400)="020000000300000004000000197b63", 0xf, 0x1000}, {&(0x7f0000010400)="7f000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0x1002, 0x2000}, {&(0x7f0000012500)="ed41000000100000d5f4655fd6f4655fd6f4655f00000000000004008000000000000800050000000af301000400000000000000000000000100000010", 0x3d, 0x4100}, {&(0x7f0000012a00)="ed4100003c000000d6f4655fd6f4655fd6f4655f0000000000000200000000000000001003000000020000000d0000001000050166696c65300000000e0000002800050766696c65310000000000000000000000000000000000000000000000000000003ba2b893000000000000000000000000000000000000000000000000200000003413ec503413ec503413ec50d6f4655f3413ec500000000000000000000002ea0407000000000000000000000000000064617461", 0xb8, 0x4b00}, {&(0x7f0000013000)="020000000c0001022e000000020000000c0002022e2e00000b00000014000a026c6f73742b666f756e6400000c0000001000050266696c6530", 0x39, 0x10000}, {&(0x7f0000013400)="504d4d00504d4dff", 0x8, 0x40000}], 0x0, &(0x7f0000000180)=ANY=[])
r1 = openat(r0, &(0x7f0000000100)='./file0\x00', 0x9aa10a2d6bd99fa2, 0x0)
pwritev(r1, &(0x7f0000000b80)=[{&(0x7f00000007c0)="1d", 0x1}], 0x1, 0x0, 0x0) (async, rerun: 64)
r2 = syz_open_dev$evdev(&(0x7f0000000240), 0x0, 0x0) (rerun: 64)
ioctl$EVIOCSMASK(r2, 0x40104593, &(0x7f0000000100)={0x0, 0x0, 0x0})
ioctl$AUTOFS_DEV_IOCTL_TIMEOUT(r1, 0xc018937a, &(0x7f0000000040)={{0x1, 0x1, 0x18, r2, {0x4}}, './file0\x00'}) (async)
ioctl$FS_IOC_RESVSP(r1, 0x40305828, &(0x7f00000000c0)={0x0, 0x0, 0x0, 0x70f4})
pwritev(r1, &(0x7f0000000640)=[{&(0x7f0000000300)='\t', 0x1}], 0x1, 0x8db5, 0x0)

通过复现程序发现 handle 为 NULL 导致 BUG_ON

同时发现在 ext4_block_write_begin 中调用的函数为 ext4_block_write_begin
而在 ext4_da_write_end 中调用的函数为 ext4_write_inline_data_end
这两个函数不匹配

在 ext4_write_inline_data_end 调用 ext4_journal_stop(handle)
而在 ext4_block_write_begin 没有调用 ext4_journal_start 进行初始化

具体查看造成匹配的原因是在 begin 时 ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) 失败了,没有该标志位。而在end时该判断又成功了。

排查所有设置 EXT4_STATE_MAY_INLINE_DATA 的地方,发现是在begin和end之间执行了一个 vfs_fallocate,这个通过调用 ext4_restore_inline_data 设置上了标志位,这几个操作的inode 都是 <17>

确认问题发生时序并构造复现

do_pwritev
  vfs_writev
    do_iter_write
      ext4_file_write_iter
        ext4_buffered_write_iter
          generic_perform_write
            ext4_da_write_begin
                                    vfs_fallocate
                                      ext4_fallocate
                                        ext4_convert_inline_data
                                          ext4_convert_inline_data_nolock
                                            ext4_destroy_inline_data_nolock
                                              ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
                                            ext4_map_blocks
                                              ext4_ext_map_blocks
                                                ext4_mb_new_blocks
                                                  ext4_mb_regular_allocator
                                                    ext4_mb_good_group_nolock
                                                      ext4_mb_init_group
                                                        ext4_mb_init_cache
                                                          ext4_mb_generate_buddy  --> ext4_grp_locked_error
              ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)
                                            ext4_restore_inline_data
                                              ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
              ext4_block_write_begin
            ext4_da_write_end
              ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)
              ext4_write_inline_data_end
                handle=NULL
                ext4_journal_stop(handle)
                  __ext4_journal_stop
                    ext4_put_nojournal(handle)
                      ref_cnt = (unsigned long)handle
                      BUG_ON(ref_cnt == 0)            ---> BUG_ON
复现 ext4_write_inline_data_begin + generic_write_end
fallocate -l4G disk
mkfs.ext4 -F -O inline_data disk
mount disk /mnt
touch /mnt/test
echo test > /mnt/test
setfattr -n user.pet1 -v dog /mnt/test
setfattr -n user.pet2 -v cat /mnt/test

echo testtesttesttesttesttesttesttesttesttesttesttesttesttest > /mnt/test
fallocate -l16k /mnt/test
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 9c076262770d..1eacdb6d3b3d 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -2003,6 +2003,7 @@ int ext4_convert_inline_data(struct inode *inode)
 	struct ext4_iloc iloc;
 
 	if (!ext4_has_inline_data(inode)) {
+		pr_err(">>> ext4 not has_inline_data! inode: %lu\n", inode->i_ino);
 		ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
 		return 0;
 	}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 646ece9b3455..d8a5b9f46180 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -42,6 +42,7 @@
 #include <linux/iomap.h>
 #include <linux/iversion.h>
 #include <linux/dax.h>
+#include <linux/delay.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -2957,6 +2958,9 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
 		ret = ext4_da_write_inline_data_begin(mapping, inode,
 						      pos, len, flags,
 						      pagep, fsdata);
+		pr_err(">>> write_begin mdelay 3s for clear flag!\n");
+		mdelay(3000);
+		pr_err(">>> write_begin mdelay done!\n");
 		if (ret < 0)
 			return ret;
 		if (ret == 1)
[  175.237980] EXT4-fs (loop0): mounted filesystem with ordered data mode. Quota mode: none.
[  192.592367] >>> write_begin mdelay 3s for clear flag!
[  195.592837] >>> write_begin mdelay done!
[  195.592886] ------------[ cut here ]------------
[  195.592888] kernel BUG at fs/ext4/inode.c:3017!
[  195.592917] invalid opcode: 0000 [#1] PREEMPT SMP KASAN
[  195.594701] CPU: 2 PID: 651 Comm: bash Not tainted 5.18.0-rc4-next-20220426-dirty #190
[  195.595438] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-
[  195.596666] RIP: 0010:ext4_da_write_end+0x6d1/0x9a0
[  195.597139] Code: 01 4d 89 46 d0 4c 89 df e8 2c 65 56 ff 48 83 05 e4 a4 6b 0e 01 48 83 05 34 e3 6b
[  195.598877] RSP: 0018:ffff88816c5e7a10 EFLAGS: 00010202
[  195.599364] RAX: 002fffff80000005 RBX: ffffea0005785e40 RCX: 0000000000000039
[  195.600034] RDX: 1ffffd4000af0bc8 RSI: 0000000000000008 RDI: ffffea0005785e40
[  195.600703] RBP: ffff888168fe9218 R08: 0000000000000039 R09: 0000000000000001
[  195.601368] R10: ffffea0005785e47 R11: ffff888168fe90a8 R12: 0000000000000039
[  195.602036] R13: 0000000000000039 R14: ffff888168fe90a8 R15: 0000000000000000
[  195.602707] FS:  00007fdf893cc700(0000) GS:ffff88839c100000(0000) knlGS:0000000000000000
[  195.603457] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  195.604002] CR2: 00005589ce92f080 CR3: 000000010661f000 CR4: 00000000000006e0
[  195.604675] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  195.605346] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[  195.606026] Call Trace:
[  195.606272]  <TASK>
[  195.606480]  generic_perform_write+0x300/0x570
[  195.606911]  ? folio_unlock+0xe0/0xe0
[  195.607257]  ? inode_update_time+0xd0/0xd0
[  195.607644]  ? down_write_killable+0x1d0/0x1d0
[  195.608061]  ? kasan_set_track+0x29/0x40
[  195.608427]  ext4_buffered_write_iter+0x168/0x370
[  195.608868]  ext4_file_write_iter+0x3ac/0x1a30
[  195.609286]  ? __kasan_check_write+0x20/0x30
[  195.609695]  ? page_cpupid_xchg_last+0xd9/0x180
[  195.610116]  ? lruvec_init+0x230/0x230
[  195.610472]  ? getname_flags+0xe2/0x610
[  195.610838]  ? ext4_dio_supported.isra.0+0x220/0x220
[  195.611300]  ? _raw_spin_unlock+0x59/0xb0
[  195.611678]  ? wp_page_reuse+0x201/0x420
[  195.612052]  new_sync_write+0x33e/0x540
[  195.612414]  ? __kasan_check_write+0x20/0x30
[  195.612820]  ? new_sync_read+0x5c0/0x5c0
[  195.613193]  ? copy_page_range+0x13b0/0x13b0
[  195.613595]  ? _raw_spin_lock_irqsave+0x160/0x160
[  195.614033]  ? __kasan_check_read+0x1d/0x30
[  195.614426]  vfs_write+0x675/0x9f0
[  195.614753]  ksys_write+0xfd/0x250
[  195.615078]  ? __x64_sys_read+0xc0/0xc0
[  195.615438]  ? up_read+0x25/0x100
[  195.615756]  ? do_user_addr_fault+0x4b3/0x14a0
[  195.616173]  __x64_sys_write+0x77/0xc0
[  195.616525]  do_syscall_64+0x35/0x80
[  195.616870]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[  195.617338] RIP: 0033:0x7fdf88500130
[  195.617682] Code: 73 01 c3 48 8b 0d 58 ed 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83
[  195.619362] RSP: 002b:00007ffd63161418 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[  195.620063] RAX: ffffffffffffffda RBX: 0000000000000039 RCX: 00007fdf88500130
[  195.620714] RDX: 0000000000000039 RSI: 00005589ce92f080 RDI: 0000000000000001
[  195.621366] RBP: 00005589ce92f080 R08: 000000000000000a R09: 00007fdf893cc700
[  195.622019] R10: 00005589ceca8040 R11: 0000000000000246 R12: 0000000000000039
[  195.622676] R13: 0000000000000001 R14: 00007fdf887d05e0 R15: 00007fdf887cb8c0
[  195.623325]  </TASK>
[  195.623537] Modules linked in:
[  195.623876] ---[ end trace 0000000000000000 ]---
[  195.623884] RIP: 0010:ext4_da_write_end+0x6d1/0x9a0
[  195.623904] Code: 01 4d 89 46 d0 4c 89 df e8 2c 65 56 ff 48 83 05 e4 a4 6b 0e 01 48 83 05 34 e3 6b
[  195.623916] RSP: 0018:ffff88816c5e7a10 EFLAGS: 00010202
[  195.623925] RAX: 002fffff80000005 RBX: ffffea0005785e40 RCX: 0000000000000039
[  195.623933] RDX: 1ffffd4000af0bc8 RSI: 0000000000000008 RDI: ffffea0005785e40
[  195.623941] RBP: ffff888168fe9218 R08: 0000000000000039 R09: 0000000000000001
[  195.623951] R10: ffffea0005785e47 R11: ffff888168fe90a8 R12: 0000000000000039
[  195.623954] R13: 0000000000000039 R14: ffff888168fe90a8 R15: 0000000000000000
[  195.623956] FS:  00007fdf893cc700(0000) GS:ffff88839c100000(0000) knlGS:0000000000000000
[  195.623960] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  195.623962] CR2: 00005589ce92f080 CR3: 000000010661f000 CR4: 00000000000006e0
[  195.623964] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  195.623966] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index cb42b2245c21..55f2d524c6b8 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -7,6 +7,7 @@
 #include <linux/iomap.h>
 #include <linux/fiemap.h>
 #include <linux/iversion.h>
+#include <linux/delay.h>
 
 #include "ext4_jbd2.h"
 #include "ext4.h"
@@ -155,6 +156,7 @@ int ext4_find_inline_data_nolock(struct inode *inode)
 		EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
 				le32_to_cpu(is.s.here->e_value_size);
 		ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+		pr_err(">>> EXT4_STATE_MAY_INLINE_DATA in ext4_find_inline_data_nolock! inode: %lu\n", inode->i_ino);
 	}
 out:
 	brelse(is.iloc.bh);
@@ -366,6 +368,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
 				      (void *)ext4_raw_inode(&is.iloc));
 	EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +
 				le32_to_cpu(is.s.here->e_value_size);
+	pr_err(">>> EXT4_STATE_MAY_INLINE_DATA in ext4_update_inline_data! inode: %lu\n", inode->i_ino);
 	ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
 	get_bh(is.iloc.bh);
 	error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
@@ -454,6 +457,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle,
 	EXT4_I(inode)->i_inline_off = 0;
 	EXT4_I(inode)->i_inline_size = 0;
 	ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+	pr_err(">>> clear EXT4_STATE_MAY_INLINE_DATA in ext4_destroy_inline_data_nolock!\n");
 out:
 	brelse(is.iloc.bh);
 	if (error == -ENODATA)
@@ -735,6 +739,12 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
 	struct ext4_iloc iloc;
 	int ret = 0, ret2;
 
+	if (!handle) {
+		pr_err(">>> error  handle in ext4_write_inline_data_end\n");
+		if (handle==NULL)
+			pr_err(">>> handle is NULL in ext4_write_inline_data_end\n");
+	}
+
 	if (unlikely(copied < len) && !PageUptodate(page))
 		copied = 0;
 
@@ -1128,7 +1138,10 @@ static void ext4_restore_inline_data(handle_t *handle, struct inode *inode,
 {
 	ext4_create_inline_data(handle, inode, inline_size);
 	ext4_write_inline_data(inode, iloc, buf, 0, inline_size);
+	pr_err(">>> convert_inline mdelay 2s for write begin!\n");
+	mdelay(3500);
 	ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+	pr_err(">>>> set EXT4_STATE_MAY_INLINE_DATA in ext4_restore_inline_data! inode: %lu\n", inode->i_ino);
 }
 
 static int ext4_finish_convert_inline_dir(handle_t *handle,
@@ -1215,7 +1228,8 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
 	map.m_lblk = 0;
 	map.m_len = 1;
 	map.m_flags = 0;
-	error = ext4_map_blocks(handle, inode, &map, EXT4_GET_BLOCKS_CREATE);
+	// error = ext4_map_blocks(handle, inode, &map, EXT4_GET_BLOCKS_CREATE);
+	error = -EIO;
 	if (error < 0)
 		goto out_restore;
 	if (!(map.m_flags & EXT4_MAP_MAPPED)) {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 164161e4c144..d26a87d3356e 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -40,6 +40,7 @@
 #include <linux/bitops.h>
 #include <linux/iomap.h>
 #include <linux/iversion.h>
+#include <linux/delay.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -1052,6 +1053,8 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
 	int nr_wait = 0;
 	int i;
 
+	pr_err(">>> In ext4_block_write_begin!\n");
+
 	BUG_ON(!PageLocked(page));
 	BUG_ON(from > PAGE_SIZE);
 	BUG_ON(to > PAGE_SIZE);
@@ -1185,6 +1188,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
 		put_page(page);
 		return PTR_ERR(handle);
 	}
+	pr_err(">>> get handle: %lu in ext4 write begin!\n", (unsigned long)handle);
 
 	lock_page(page);
 	if (page->mapping != mapping) {
@@ -2954,8 +2958,11 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
 	pgoff_t index;
 	struct inode *inode = mapping->host;
 
+	pr_err(">>> In ext4_da_write_begin!i\n");
+
 	if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 		return -EIO;
+	pr_err(">>> ext4_da_write_begin Point A!\n");
 
 	index = pos >> PAGE_SHIFT;
 
@@ -2965,23 +2972,35 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
 		return ext4_write_begin(file, mapping, pos,
 					len, flags, pagep, fsdata);
 	}
+	pr_err(">>> ext4_da_write_begin Point B!\n");
+
 	*fsdata = (void *)0;
 	trace_ext4_da_write_begin(inode, pos, len, flags);
 
+	if (ext4_has_inline_data(inode))
+		pr_err(">>> ext4_has_inline_data in ext4_da_write_begin!\n");
+	pr_err(">>> write_begin mdelay 3s for clear flag!\n");
+	mdelay(3000);
+	pr_err(">>> write_begin mdelay done!\n");
+	if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+		pr_err(">>> test inline in ext4_da_write_begin ! inode: %lu \n", inode->i_ino);
 	if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
 		ret = ext4_da_write_inline_data_begin(mapping, inode,
 						      pos, len, flags,
 						      pagep, fsdata);
 		if (ret < 0)
 			return ret;
+		pr_err(">>> ext4_da_write_begin Point C!\n");
 		if (ret == 1)
 			return 0;
+		pr_err(">>> ext4_da_write_begin Point D!\n");
 	}
 
 retry:
 	page = grab_cache_page_write_begin(mapping, index, flags);
 	if (!page)
 		return -ENOMEM;
+	pr_err(">>> ext4_da_write_begin Point E!\n");
 
 	/* In case writeback began while the page was unlocked */
 	wait_for_stable_page(page);
@@ -3006,9 +3025,14 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
 		if (ret == -ENOSPC &&
 		    ext4_should_retry_alloc(inode->i_sb, &retries))
 			goto retry;
+		pr_err(">>> ext4_da_write_begin Point F!\n");
 		return ret;
 	}
-
+	
+	pr_err(">>> write_begin mdelay 2s for set flag!\n");
+	mdelay(2000);
+	pr_err(">>> write_begin delay set flag done!\n");
+	pr_err(">>> ext4_da_write_begin Point end!\n");
 	*pagep = page;
 	return ret;
 }
@@ -3046,12 +3070,19 @@ static int ext4_da_write_end(struct file *file,
 	unsigned long start, end;
 	int write_mode = (int)(unsigned long)fsdata;
 
+	pr_err(">>>> ext4_da_write_end begin!\n");
 	if (write_mode == FALL_BACK_TO_NONDELALLOC)
 		return ext4_write_end(file, mapping, pos,
 				      len, copied, page, fsdata);
 
 	trace_ext4_da_write_end(inode, pos, len, copied);
 
+	if (write_mode != CONVERT_INLINE_DATA)
+		pr_err(">>>> !CONVERT_INLINE_DATA in ext4_da_write_end\n");
+	if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+		pr_err(">>>> get EXT4_STATE_MAY_INLINE_DATA in ext4_da_write_end! inode: %lu\n", inode->i_ino);
+	if (ext4_has_inline_data(inode))
+		pr_err(">>>> ext4_has_inline_data in ext4_da_write_end!\n");
 	if (write_mode != CONVERT_INLINE_DATA &&
 	    ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) &&
 	    ext4_has_inline_data(inode))
@@ -3079,7 +3110,7 @@ static int ext4_da_write_end(struct file *file,
 	if (copied && new_i_size > inode->i_size &&
 	    ext4_da_should_update_i_disksize(page, end))
 		ext4_update_i_disksize(inode, new_i_size);
-
+	pr_err(">>>> ext4_da_write_end end!\n");
 	return generic_write_end(file, mapping, pos, len, copied, page, fsdata);
 }

【构造复现】

  1. 注入延时和故障,打上附件中的diff git apply test_inline_write_delay.diff
    基于 hulk-5.10-next 2f4a66db5c90643d68f831bad006862296ef6949
    重新编译内核启动

  2. 执行

fallocate -l4G disk
mkfs.ext4 -F -O inline_data disk
mount disk /mnt
touch /mnt/test
echo test > /mnt/test
setfattr -n user.pet1 -v dog /mnt/test
setfattr -n user.pet2 -v cat /mnt/test
  1. 执行 echo testtesttesttesttesttesttesttesttesttesttesttesttesttest > /mnt/test, 看到 write_begin mdelay 3s for clear flag 执行 fallocate -l16k /mnt/test 数秒后问题复现

【复现栈】

[root@localhost ~]# [  135.133012] >>> In ext4_da_write_begin!i
[  135.145013] >>> ext4_da_write_begin Point A!
[  135.145615] >>> ext4_da_write_begin Point B!
[  135.146198] >>> ext4_has_inline_data in ext4_da_write_begin!
[  135.146936] >>> write_begin mdelay 3s for clear flag!
[  136.161011] >>> clear EXT4_STATE_MAY_INLINE_DATA in ext4_destroy_inline_data_nolock!
[  136.162748] >>> convert_inline mdelay 2s for write begin!
[  138.148313] >>> write_begin mdelay done!
[  138.151343] >>> test inline in ext4_da_write_begin ! inode: 12 
[  138.152232] >>> ext4_da_write_begin Point E!
[  138.153653] >>> In ext4_block_write_begin!
[  138.155164] >>> write_begin mdelay 2s for set flag!
[  139.665218] >>>> set EXT4_STATE_MAY_INLINE_DATA in ext4_restore_inline_data! inode: 12
[  140.157200] >>> write_begin delay set flag done!
[  140.159870] >>> ext4_da_write_begin Point end!
[  140.160459] >>>> ext4_da_write_end begin!
[  140.160956] >>>> !CONVERT_INLINE_DATA in ext4_da_write_end
[  140.161640] >>>> get EXT4_STATE_MAY_INLINE_DATA in ext4_da_write_end! inode: 12
[  140.162563] >>>> ext4_has_inline_data in ext4_da_write_end!
[  140.163296] >>> error  handle in ext4_write_inline_data_end
[  140.163976] >>> handle is NULL in ext4_write_inline_data_end
[  140.164777] >>> EXT4_STATE_MAY_INLINE_DATA in ext4_find_inline_data_nolock! inode: 12
[  140.167356] ------------[ cut here ]------------
[  140.168983] kernel BUG at fs/ext4/ext4_jbd2.c:53!
[  140.170545] invalid opcode: 0000 [#1] SMP KASAN
[  140.171945] CPU: 7 PID: 633 Comm: bash Not tainted 5.10.0-11654-g2f4a66db5c90-dirty #136
[  140.174382] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-p4
[  140.178388] RIP: 0010:__ext4_journal_stop+0x1bb/0x210
[  140.179578] Code: ff 75 0d 48 83 05 e4 22 0d 0e 01 e9 45 ff ff ff 44 89 f8 e9 3d ff ff ff e8 72 b8 b
[  140.181989] RSP: 0018:ffff88810634f8f0 EFLAGS: 00010202
[  140.182670] RAX: dffffc0000000000 RBX: 0000000000000039 RCX: 0000000000000000
[  140.183597] RDX: 0000000000000000 RSI: 0000000000000325 RDI: ffffffff8db87240
[  140.184516] RBP: 0000000000000000 R08: 0000000000000202 R09: 0000000000000001
[  140.185438] R10: 0000000000000003 R11: ffffed1020c69e8a R12: 0000000000000039
[  140.186359] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88812a79f390
[  140.187282] FS:  00007fe375c25700(0000) GS:ffff88839c380000(0000) knlGS:0000000000000000
[  140.188333] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  140.189090] CR2: 00007f4688447770 CR3: 000000011d335000 CR4: 00000000000006e0
[  140.190023] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  140.190943] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[  140.191865] Call Trace:
[  140.192204]  ext4_write_inline_data_end+0x22f/0xd80
[  140.192838]  ? ext4_try_to_write_inline_data+0x1660/0x1660
[  140.193565]  ? ext4_da_write_begin+0x8ea/0x973
[  140.194159]  ext4_da_write_end+0x3c9/0x7e6
[  140.194697]  ? current_time+0xc4/0x130
[  140.195199]  generic_perform_write+0x298/0x4d0
[  140.195776]  ? filemap_page_mkwrite+0x4c0/0x4c0
[  140.196372]  ext4_buffered_write_iter+0x1e2/0x480
[  140.196987]  ext4_file_write_iter+0x3db/0x1540
[  140.197567]  ? do_filp_open+0x1bc/0x2b0
[  140.198069]  ? may_open_dev+0xf0/0xf0
[  140.198550]  ? ext4_buffered_write_iter+0x480/0x480
[  140.199189]  ? do_dup2+0x5c0/0x5c0
[  140.199634]  new_sync_write+0x3ad/0x610
[  140.200160]  ? do_iter_readv_writev+0x7c0/0x7c0
[  140.200753]  vfs_write+0x556/0x800
[  140.201205]  ksys_write+0xfd/0x230
[  140.201646]  ? __x64_sys_read+0xc0/0xc0
[  140.202163]  ? irqentry_exit_to_user_mode+0xd/0xa0
[  140.202777]  __x64_sys_write+0x77/0xc0
[  140.203270]  do_syscall_64+0x45/0x70
[  140.203730]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  140.204392] RIP: 0033:0x7fe375313130
[  140.204855] Code: 73 01 c3 48 8b 0d 58 ed 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 4
[  140.207227] RSP: 002b:00007ffe1c6cd6c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[  140.208201] RAX: ffffffffffffffda RBX: 0000000000000039 RCX: 00007fe375313130
[  140.209138] RDX: 0000000000000039 RSI: 000055eaf9fda080 RDI: 0000000000000001
[  140.210077] RBP: 000055eaf9fda080 R08: 000000000000000a R09: 00007fe375c25700
[  140.210998] R10: 000055eafa352180 R11: 0000000000000246 R12: 0000000000000039
[  140.211919] R13: 0000000000000001 R14: 00007fe3755e35e0 R15: 00007fe3755de8c0
[  140.212840] Modules linked in:
[  140.213291] ---[ end trace 3151f7dd1aba07c7 ]---
[  140.214008] RIP: 0010:__ext4_journal_stop+0x1bb/0x210
[  140.214693] Code: ff 75 0d 48 83 05 e4 22 0d 0e 01 e9 45 ff ff ff 44 89 f8 e9 3d ff ff ff e8 72 b8 b
[  140.217138] RSP: 0018:ffff88810634f8f0 EFLAGS: 00010202
[  140.217842] RAX: dffffc0000000000 RBX: 0000000000000039 RCX: 0000000000000000
[  140.218776] RDX: 0000000000000000 RSI: 0000000000000325 RDI: ffffffff8db87240
[  140.219708] RBP: 0000000000000000 R08: 0000000000000202 R09: 0000000000000001
[  140.220643] R10: 0000000000000003 R11: ffffed1020c69e8a R12: 0000000000000039
[  140.221577] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88812a79f390
[  140.222516] FS:  00007fe375c25700(0000) GS:ffff88839c380000(0000) knlGS:0000000000000000
[  140.223573] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  140.224337] CR2: 00007f4688447770 CR3: 000000011d335000 CR4: 00000000000006e0
[  140.225339] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  140.226304] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(2)
5329419 openeuler ci bot 1632792936
C
1
https://gitee.com/openeuler/kernel.git
git@gitee.com:openeuler/kernel.git
openeuler
kernel
kernel

搜索帮助