428 Star 1.6K Fork 1.6K

GVPopenEuler/kernel

 / 详情

WARNING in _ext4_get_block

已完成
任务
创建于  
2024-06-17 12:34

问题现象:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 5266 at fs/ext4/inode.c:796 _ext4_get_block+0x4ef/0x5e0 fs/ext4/inode.c:796
Modules linked in:
CPU: 1 PID: 5266 Comm: syz-executor.3 Not tainted 6.6.0+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:_ext4_get_block+0x4ef/0x5e0 fs/ext4/inode.c:796
Code: 48 8b 04 24 e9 5c ff ff ff e8 6d d5 55 ff be 08 00 00 00 48 89 ef e8 40 ca b4 ff f0 80 4d 00 10 e9 18 fe ff ff e8 51 d5 55 ff <0f> 0b 41 bd ea ff ff ff e9 25 fc ff ff e8 4f c0 b4 ff e9 18 fd ff
RSP: 0018:ffff88803e8f78e8 EFLAGS: 00010246
RAX: 0000000000040000 RBX: ffff88801b809dc0 RCX: ffffffff9f5e688f
RDX: 0000000000040000 RSI: ffffc900058f1000 RDI: 0000000000000007
RBP: ffff88802e3fac00 R08: 0000000000000000 R09: ffffed100370139d
R10: 0000000000000001 R11: 0000000000000000 R12: 1ffff11007d1ef1f
R13: 0000000000000001 R14: ffff88801b809ce8 R15: 0000000000000010
FS:  00007ffb8c98d6c0(0000) GS:ffff8880be480000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000005a6bf8 CR3: 0000000019a52002 CR4: 0000000000770ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
 <TASK>
 move_extent_per_page.isra.0+0xb71/0x1040 fs/ext4/move_extent.c:389
 ext4_move_extents+0x6e3/0xcd0 fs/ext4/move_extent.c:712
 __ext4_ioctl+0x22e5/0x2820 fs/ext4/ioctl.c:1362
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:871 [inline]
 __se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
 do_syscall_x64 arch/x86/entry/common.c:51 [inline]
 do_syscall_64+0x5b/0x110 arch/x86/entry/common.c:81
 entry_SYSCALL_64_after_hwframe+0x78/0xe2
RIP: 0033:0x4455ad
Code: 48 83 c8 ff c3 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 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:00007ffb8c98d0d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00000000005cbf80 RCX: 00000000004455ad
RDX: 00000000200018c0 RSI: 00000000c028660f RDI: 0000000000000005
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000005cbf8c
R13: 000000000000000b R14: 00000000005cbf80 R15: 00007ffb8c96d000

问题根因:
对于ext4挂载使用了iomap的场景(-obuffered_iomap),ext4_move_extents会先把src和dst的file page全部回写完,然后清除EXT4_STATE_BUFFERED_IOMAP标志,如果回写失败会导致EXT4_STATE_BUFFERED_IOMAP标记不能被清除

ext4_disable_buffered_iomap_aops
 err = filemap_write_and_wait(inode->i_mapping)
 if (err < 0)  // 回写失败会提前返回
   return err;
 ext4_clear_inode_state(inode, EXT4_STATE_BUFFERED_IOMAP)  // 清除iomap标记
导致后续流程触发WARNON

move_extent_per_page
 ext4_get_block
  _ext4_get_block
   WARN_ON(ext4_test_inode_state(inode, EXT4_STATE_BUFFERED_IOMAP)

复现方法:
CONFIG_DEBUG_VM=n
CONFIG_EXT4_FS=y

  1. 合入diff diff
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index f58c0cb4dd76..fadc5a28bf34 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -554,6 +554,7 @@ static int ext4_disable_buffered_iomap_aops(struct inode *inode)
 	 */
 	filemap_invalidate_lock(inode->i_mapping);
 	err = filemap_write_and_wait(inode->i_mapping);
+	err = -EIO;
 	if (err < 0) {
 		filemap_invalidate_unlock(inode->i_mapping);
 		return err;
  1. 编译执行a.c a.c
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mount.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <errno.h>
#include <string.h>
#include <linux/reboot.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <grp.h>
#include <sys/prctl.h>
#include <linux/fs.h>
#include <signal.h>
#include <sched.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <linux/perf_event.h>
#include <linux/bpf.h>
#include <sys/sysinfo.h>
#include <sys/epoll.h>
#include <asm/unistd.h>
#include <sys/time.h>
#include <sys/sendfile.h>
#include <stdarg.h>
#include <assert.h>
#include <linux/aio_abi.h>

struct move_extent {
	__u32 reserved;         /* should be zero */
	__u32 donor_fd;         /* donor file descriptor */
	__u64 orig_start;       /* logical start offset in block for orig */
	__u64 donor_start;      /* logical start offset in block for donor */
	__u64 len;              /* block length to be moved */
	__u64 moved_len;        /* moved block length */
};

#define EXT4_IOC_MOVE_EXT               _IOWR('f', 15, struct move_extent)

int main(void)
{
	struct move_extent me;
	int src, dst;

	system("mkdir /root/temp");
	system("mkfs.ext4 -F /dev/sda");
	system("mount -obuffered_iomap /dev/sda /root/temp");
	system("dd if=/dev/zero of=/root/temp/src bs=8K count=1");
	system("dd if=/dev/zero of=/root/temp/dst bs=8K count=1");
	sync();

	src = open("/root/temp/src", O_RDWR);
	dst = open("/root/temp/dst", O_RDWR);
	if (src < 0 || dst < 0) {
		perror("open fail");
		return -1;
	}
	me.reserved = 0;
	me.donor_fd = dst;
	me.orig_start = 0;
	me.donor_start = 0;
	me.len = 2;
	if (ioctl(src, EXT4_IOC_MOVE_EXT, &me) < 0)
		perror("move fail");
	return 0;
}

复现:

[   22.366477] ------------[ cut here ]------------
[   22.366981] WARNING: CPU: 3 PID: 1046 at fs/ext4/inode.c:796 _ext4_get_block+0x145/0x170
[   22.367764] Modules linked in:
[   22.368120] CPU: 3 PID: 1046 Comm: aa Not tainted 6.6.0-09853-g14e875044e89-dirty #34
[   22.369703] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
[   22.372334] RIP: 0010:_ext4_get_block+0x145/0x170
[   22.373378] Code: ff ff 48 8b 4b 28 8b 54 24 0c 48 83 05 53 a9 35 0c 01 48 0f af 51 18 48 89 55 20 48 83 c4 18 5b 5d c3 48 83 05 db a8 35 0c 01 <0fc
[   22.375123] RSP: 0018:ffffc90000c4bc98 EFLAGS: 00010202
[   22.375617] RAX: 0000102000080000 RBX: ffff88817875c500 RCX: 0000000000000000
[   22.376294] RDX: ffff88817b35fc80 RSI: 0000000000000000 RDI: ffff88817875c500
[   22.376973] RBP: ffff88817b35fc80 R08: 0000000000000000 R09: ffffffff8a46f9d0
[   22.377635] R10: ffffffff8acae618 R11: ffffffff8253f080 R12: ffff88817875c4d8
[   22.378342] R13: 0000000000000000 R14: ffff88817b35fc80 R15: ffff88817875c500
[   22.379027] FS:  00007fda0ca57440(0000) GS:ffff88881fd80000(0000) knlGS:0000000000000000
[   22.379771] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   22.380323] CR2: 00007fda0c4ffe70 CR3: 000000017c7b5000 CR4: 00000000000006e0
[   22.380992] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   22.381645] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   22.382313] Call Trace:
[   22.382549]  <TASK>
[   22.382755]  ? show_regs+0x88/0xa0
[   22.383096]  ? __warn+0xb4/0x250
[   22.383405]  ? _ext4_get_block+0x145/0x170
[   22.383788]  ? report_bug+0x2d1/0x2f0
[   22.384163]  ? handle_bug+0x3c/0x60
[   22.384505]  ? exc_invalid_op+0x18/0x70
[   22.384883]  ? asm_exc_invalid_op+0x1a/0x20
[   22.385284]  ? do_syscall_64+0x70/0x120
[   22.385648]  ? _ext4_get_block+0x145/0x170
[   22.386049]  ? folio_create_empty_buffers+0x144/0x170
[   22.386520]  ext4_get_block+0x1e/0x30
[   22.386889]  ext4_move_extents+0x14a6/0x1840
[   22.387293]  ? do_sys_open+0x50/0x80
[   22.387631]  ? do_filp_open+0xc5/0x130
[   22.387998]  ? call_rcu+0x115/0xa70
[   22.388332]  __ext4_ioctl+0x1ace/0x23c0
[   22.388691]  ? put_object+0x3b/0x80
[   22.389048]  ? __delete_object+0x4d/0x90
[   22.389429]  ? kmemleak_free+0x46/0xa0
[   22.389792]  ? kmem_cache_free+0x2f1/0x730
[   22.390200]  ? ext4_ioctl+0x16/0x20
[   22.390539]  ext4_ioctl+0x16/0x20
[   22.390878]  __se_sys_ioctl+0xb4/0x110
[   22.391245]  __x64_sys_ioctl+0x22/0x30
[   22.391591]  x64_sys_call+0x2af7/0x3e90
[   22.391968]  do_syscall_64+0x70/0x120
[   22.392312]  ? clear_bhb_loop+0x25/0x80
[   22.392692]  entry_SYSCALL_64_after_hwframe+0x68/0xd2
[   22.393189] RIP: 0033:0x7fda0c506577
[   22.393534] Code: b3 66 90 48 8b 05 11 89 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <488
[   22.395271] RSP: 002b:00007ffc6fc93758 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
[   22.396016] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fda0c506577
[   22.396690] RDX: 00007ffc6fc93760 RSI: 00000000c028660f RDI: 0000000000000003
[   22.397365] RBP: 00007ffc6fc93790 R08: 0000000000000000 R09: 00007fda0c811090
[   22.398063] R10: 0000000000000003 R11: 0000000000000202 R12: 0000000000400520
[   22.398739] R13: 00007ffc6fc93870 R14: 0000000000000000 R15: 0000000000000000
[   22.399409]  </TASK>
[   22.399627] ---[ end trace 0000000000000000 ]---

评论 (1)

Hi czh549642238, 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.

chengzhihao 创建了任务 11个月前
openeuler-ci-bot 添加了
 
sig/Kernel
标签
11个月前
ci-robot 通过合并 Pull Request !9101: ext4: Skip moving extents if page writeback failed任务状态待办的 修改为已完成 11个月前
展开全部操作日志

登录 后才可以发表评论

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

搜索帮助