【标题描述】ext4反复挂载做故障注入可能导致日志部分重演,造成文件系统损坏
【环境信息】
硬件信息:
NA
软件信息:
OLK 510
【问题复现步骤】
具体操作步骤
[ 16.999656] inject
[ 17.000026] JBD2: recovery failed
[ 17.022415] EXT4-fs (sda): error loading journal
[ 17.034967] dump: blocksz 1024 s_first 1 s_start 0 s_max_transaction 0 s_max_trans_data 0
[ 17.036341] Kernel panic - not syncing: check 0
[ 17.037153] CPU: 1 PID: 2568 Comm: mount Not tainted 5.10.0-04729-g5219f1220e43-dirty #726
[ 17.038570] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraprojec4
[ 17.040708] Call Trace:
[ 17.041163] dump_stack+0xa6/0xd5
[ 17.041680] panic+0x17e/0x4ab
[ 17.042139] journal_get_superblock.cold+0x49/0x20c
[ 17.042974] load_superblock+0x16/0x100
[ 17.043554] jbd2_journal_wipe+0x24/0x80
[ 17.044190] ext4_fill_super+0x49b5/0x5480
[ 17.044849] ? pointer+0x31b/0x5a0
[ 17.045354] mount_bdev+0x22e/0x270
[ 17.045909] ? ext4_calculate_overhead+0x660/0x660
[ 17.046628] ext4_mount+0x19/0x30
[ 17.047171] legacy_get_tree+0x2c/0x80
[ 17.047789] vfs_get_tree+0x26/0xf0
[ 17.048333] ? capable+0x1d/0x30
[ 17.048867] path_mount+0x853/0x1000
[ 17.049468] ? __kmalloc_track_caller+0x600/0xa20
[ 17.050174] do_mount+0x8d/0xc0
[ 17.050734] __se_sys_mount+0x127/0x1f0
[ 17.051348] __x64_sys_mount+0x29/0x40
[ 17.052002] do_syscall_64+0x45/0x70
[ 17.052638] entry_SYSCALL_64_after_hwframe+0x61/0xc6
[ 17.053590] RIP: 0033:0x7fb37320923a
[ 17.054164] Code: 48 8b 0d 51 dc 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b88
[ 17.057557] RSP: 002b:00007ffe38035a78 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[ 17.058870] RAX: ffffffffffffffda RBX: 0000000002028240 RCX: 00007fb37320923a
[ 17.060122] RDX: 000000000202ef90 RSI: 00000000020284a0 RDI: 0000000002028480
[ 17.061423] RBP: 0000000000000000 R08: 0000000000000000 R09: 00007ffe380349e8
[ 17.062633] R10: 0000000000000000 R11: 0000000000000206 R12: 0000000002028480
[ 17.063831] R13: 000000000202ef90 R14: 0000000000000001 R15: 0000000002028240
[ 17.065137] Kernel Offset: disabled
[ 17.065588] ---[ end Kernel panic - not syncing: check 0 ]---
内核panic,对应Buffer head的verify被标记,但是没有走verify流程
【附件信息】
test.sh
#!/bin/bash
umount /root/temp
mkfs.ext4 -F -E lazy_itable_init=0 /dev/sda 10M
cat /dev/sda > /dev/null &
mount /dev/sda /root/temp
mount /dev/sda /root/temp
diff
diff --git a/fs/buffer.c b/fs/buffer.c
index a74312b1bb42..853c2ec746e2 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -3345,8 +3345,12 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
}
EXPORT_SYMBOL(alloc_buffer_head);
+extern struct buffer_head *g_bh;
void free_buffer_head(struct buffer_head *bh)
{
+ if (bh == g_bh) {
+ dump_stack();
+ }
BUG_ON(!list_empty(&bh->b_assoc_buffers));
kmem_cache_free(bh_cachep, bh);
preempt_disable();
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 13506e2ae3e8..23b14c35e391 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1795,6 +1795,7 @@ static int journal_revoke_records_per_block(journal_t *journal)
* Read the superblock for a given journal, performing initial
* validation of the format.
*/
+struct buffer_head *g_bh = NULL;
static int journal_get_superblock(journal_t *journal)
{
struct buffer_head *bh;
@@ -1811,8 +1812,16 @@ static int journal_get_superblock(journal_t *journal)
goto out;
}
- if (buffer_verified(bh))
+ if (buffer_verified(bh)) {
+ if (journal->j_check == 0) {
+ pr_err("dump: blocksz %u s_first %u s_start %u s_max_transaction %u s_max_trans_data %u\n", be32_to_cpu(journal->j_superblock->s_blocksize), be32_to_cpu(journal->j_superblock->s_first), be32_to_cpu(journal->j_superblock->s_start), be32_to_cpu(journal->j_superblock->s_max_transaction), be32_to_cpu(journal->j_superblock->s_max_trans_data));
+ panic("check 0");
+ }
return 0;
+ }
+
+ if (!strcmp(journal->j_dev->bd_disk->disk_name, "sda"))
+ g_bh = bh;
sb = journal->j_superblock;
@@ -1898,6 +1907,7 @@ static int journal_get_superblock(journal_t *journal)
journal->j_revoke_records_per_block =
journal_revoke_records_per_block(journal);
+ journal->j_check = 1;
set_buffer_verified(bh);
return 0;
@@ -1986,6 +1996,11 @@ int jbd2_journal_load(journal_t *journal)
/* Let the recovery code check whether it needs to recover any
* data from the journal. */
+ if (!strcmp(journal->j_dev->bd_disk->disk_name, "sda")) {
+ pr_err("inject\n");
+ err = -ENOMEM;
+ goto recovery_error;
+ }
if (jbd2_journal_recover(journal))
goto recovery_error;
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 5fd415c0af98..aae8904cd59a 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1303,6 +1303,7 @@ struct journal_s
struct buffer_head *bh,
enum passtype pass, int off,
tid_t expected_commit_id);
+ int j_check;
KABI_RESERVE(1)
KABI_RESERVE(2)
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: @Xie XiuQi , @YangYingliang , @成坚 (CHENG Jian) , @jiaoff , @AlexGuo , @hanjun-guo , @woqidaideshi , @zhengzengkai , @Jackie Liu , @Zhang Yi , @colyli , @ThunderTown , @htforge , @Chiqijun , @冷嘲啊 , @zhujianwei001 , @kylin-mayukun , @wangxiongfeng , @Kefeng , @SuperSix173 , @WangShaoBo , @Zheng Zucheng , @陈结松 , @刘恺 , @whoisxxx , @吴旭 , @koulihong , @柳歆 , @朱科潜 , @Xu Kuohai , @Lingmingqiang , @juntian , @OSSIM , @郑振鹏 , @刘勇强 , @yuzenghui , @Qiuuuuu , @xiehaocheng , @chen wei , @CTC-Xibo.Wang , @Jason Zeng , @Yuehaibing , @guzitao , @zhanghongchen , @lujialin , @苟浩 , @georgeguo , @毛泓博 , @AllenShi , @DuanqiangWen , @zhangjialin
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
登录 后才可以发表评论