记一次内核打印 VFS: Can‘t find ext4 filesystem 错误信息的定位和解决过程

本文记录了一次排查内核打印出'VFS: Can't find ext4 filesystem'错误的过程。问题源自新加入的硬盘未分区和格式化就被尝试挂载。通过分析内核代码和调用栈,发现是用户态bug,具体为/home目录挂载前未创建文件系统。解决方案是在mount时添加MS_SILENT标志,并调整硬件盒子的mkfs与mount顺序。新内核将ext3,ext4代码合并,使错误信息从info级别提升到error级别,因此问题暴露。" 100163468,8517903,UI设计技巧:Sketch与PS背景模糊效果实现,"['设计工具', 'UI设计', 'Sketch教程', 'PS教程', '视觉效果']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

内核打印
VFS: Can't find ext4 filesystem
只有第一次启动才会出问题

定位思路:
1,由于刚升级了内核,很有可能是内核导致的
查看内核代码,定位到打印出错信息的位置为函数ext4_fill_super,该函数是一个回调函数,由函数mount_bdev 调用
加入printk打印详细信息,看为什么会出现这种错误,定位到问题代码在
if (sb->s_magic != EXT4_SUPER_MAGIC) {
    printk(KERN_ERR, "invalid magic number:0x%x", sb->s_magic);
    goto cantfind_ext4;
}
直接原因是magic number不对
于是打印super_block结构,发现全是0,于是想到,设备第一次启动,对于新加入的硬盘,这个盘应该还没有分区,还没有文件系统,所以mount当然失败
问题又出现了,为什么这块盘还没有初始化就被使用了呢?
在内核打印调用栈
dump_stack+0x66/0x90
ext4_fill_super.cold+0x135/0x33fd
? vsnprintf+0x239/0x5b0
? snprintf+0x49/0x60
mount_bdev+0x171/0x1a0
? ext4_calculate_overhead+0x470/0x470
legacy_get_tree+0x22/0x40
vfs_get_tree+0x1b/0x80
? ns_capable_common+0x29/0x50
do_mount+0x72a/0x920
? memdup_user+0x33/0x70
ksys_mount+0x79/0xc0
__x64_sys_mount+0x1c/0x20
do_syscall_64+0x52/0x2f0
entry_SYSCALL_64_aft

### 回答1: Ext4文件系统是一种支持日志操作的Linux文件系统。它支持分层目录结构,以及支持更大文件分区的大小。要挂载Ext4文件系统,首先需要格式化分区,然后将其挂载到VFS(虚拟文件系统)。格式化分区可以使用以下命令:sudo mkfs -t ext4 /dev/<disk-name>。接下来,可以使用以下命令挂载到VFS:sudo mount -t ext4 /dev/<disk-name> /mnt/<mount-point>。这些命令将Ext4文件系统挂载到VFS,以便可以访问分区内的文件文件夹。 ### 回答2: ext4文件系统是Linux中最常用的文件系统之一。当我们要将ext4文件系统挂载到VFS(Virtual File System,虚拟文件系统)时,需要经过以下步骤: 1. 首先,需要通过系统调用(syscall)打开ext4文件系统的设备。在打开设备后,系统会为设备创建一个file对象,用于描述该设备。可以在Linux内核的文件`fs/ext4/super.c`中找到相关源代码。 2. 接下来,需要通过调用`mount_bdev()`函数来进行文件系统的挂载。该函数的作用是将设备与文件系统关联起来,创建超级块对象,并将其添加到全局的超级块链表中。详细代码可以在`fs/ext4/super.c`文件中的`ext4_fill_super()`函数中找到。 3. 在`ext4_fill_super()`函数中,还需要解析设备上的ext4文件系统的超级块信息,并进行一系列的初始化操作,如加载块组描述符表、inode表等。相关代码可以在`fs/ext4/super.c`文件中的`ext4_parse_sb()`函数中找到。 4. 通过调用`get_sb_bdev()`函数,将ext4的超级块对象与设备对象(在第一步中创建的file对象)关联起来。该函数会调用`ext4_fill_super()`函数,从而完成挂载过程。相关代码可以在`fs/ext4/super.c`文件中找到。 5. 挂载完成后,VFS会通过将ext4文件系统挂载点与超级块对象关联起来,并维护一系列的内存数据结构,如VFS的super_block结构等。这些数据结构用于管理操作ext4文件系统的各种操作。 总结起来,ext4文件系统的挂载过程主要涉及打开设备、创建超级块对象、解析超级块信息以及与VFS的关联操作。在源码的层面上,主要通过调用相关的函数完成这些操作,涉及的源代码位于`fs/ext4/super.c`文件中。 ### 回答3: ext4是一种常用的文件系统,在Linux内核中有自己的实现。VFS(Virtual File System)是Linux内核提供的抽象层,用于统一不同文件系统的接口。 源码角度解释ext4文件系统如何挂载到VFS需要了解以下主要步骤: 1. 初始化ext4文件系统:在Linux内核中,ext4的初始化由文件系统对象super_block的填充注册函数init_ext4_fs()完成。这些函数会设置文件系统的相关参数,并创建并初始化超级块(super_block)对象。 2. 注册ext4文件系统:通过调用register_filesystem()函数,将ext4的文件系统类型注册到VFS中。此时,Linux内核就能够识别ext4文件系统。 3. 挂载ext4文件系统:在内核中,挂载操作由mount()函数实现。当用户使用mount命令挂载ext4文件系统时,该命令会调用mount()函数完成挂载过程。在函数中,首先会检查是否具有挂载权限,并调用find_filesystem()函数查找ext4文件系统类型。如果找到,则会调用ext4_mount()函数对具体的ext4文件系统进行挂载。 4. ext4文件系统挂载过程:在ext4_mount()函数中,首先会调用ext4_fill_super()函数填充文件系统的超级块信息。然后,会调用read_super()函数读取磁盘上的超级块,并对文件系统进行一些初始化操作。最后,将文件系统的根目录(root)设置为当前进程的工作目录,并返回挂载成功的信息。 通过以上步骤,ext4文件系统就成功挂载到VFS中了。在挂载完成后,用户可以通过与其他文件系统相同的接口进行文件目录的访问操作。 总结一下,ext4文件系统的挂载到VFS主要包括初始化ext4文件系统、注册ext4文件系统、挂载ext4文件系统这三个主要步骤。这些步骤通过相应的函数调用参数设置来实现,在源码层面上保证了ext4文件系统与VFS的兼容性良好的交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值