进入linux驱动开发这行已经一年多了,大多时候在调试各种不同的字符驱动,文件系统虽然一直在用,也一直都知道最经典的那句“linux中一切皆文件”,但是至今却始终雾里看花…。这里对自己的一些浅显理解做个总结。
1、什么是VFS
VFS (Virtual File System),是linux内核文件系统中一个极其重要的基础,VFS为所有的文件系统提供了统一的接口,对每一个具体文件系统的访问要通过VFS定义的接口来实现。其设计目的是对用户层(系统调用)屏蔽底层(各特定文件系统)实现的复杂性,对底层提供统一的接口与数据结构,使得能衔接各个特定文件系统(如ext2、ext3、fat32等)的对接,是用户层与文件系统层之间的抽象层。
VFS定义了几个重要的数据结构:超级块对象super_block、索引节点对象inode、目录项dentry、文件对象file、文件系统类型file_system_type、挂载的文件系统vfsmount等。
简单介绍一下三种文件系统操作的原理。
1.1、格式化磁盘
mkfs.ext3 /dev/sdb
- 功能:格式化磁盘分区,将文件系统信息写入到磁盘超级快,为以特定的文件系统格式读写做铺垫
- 底层流程:格式化时的读写磁盘不需要通过文件系统层,即跨过文件系统,直接写入磁盘(通过块设备驱动写入,与dd指令类似)
- 原理:使用strace跟踪dd命令过程大致流程
fd =open(/dev/sdb1);
write(fd,buf);
格式化磁盘就是不经过文件系统,直接写入磁盘
1.2、加载文件系统
insmod ext3.ko
- 功能:内核装载ext3驱动模块,向内核注册ext3文件系统。
- 底层流程:内核加载该文件系统的驱动,并将该文件系统注册进file_system_type全局链表中
- 原理:提供ext3文件系统各种函数,如填充操作块,索引节点操作函数,如分配ext4_alloc_inode、读写索引节点
1.3、挂载文件系统
mount -t ext3 /dev/sdb1 /mnt
- 功能:建立在内核已经注册ext3文件系统的基础之上,挂载sdb1分区
- 底层流程:建立vfs_mount对象,该对象代表挂载的文件系统(挂载点)
- 原理:file_system_type中的方法get_sb调用alloc_super函数填充内存超级块对象(vfs_mount中相关的超级块对象)
2、文件系统挂载的流程
用户层执行mount
mount -t ext3 /dev/sdb1 /mnt
| 陷入系统调用,进入内核层
|--->_asm_( "int $0x80" .........);
|--->system_call:
|--->sys_call_table[sys_mount]
|--->SYSCALL_DEFINE5
|--->do_mount //曾经挂载过
|--->do_new_mount //未挂载过时
|--->vfs_kernel_mount
|--->type->mount //调用 file_system_type 中的成员mount函数,这个函数由不同文件系统去实现
|--->fill_superblock //创建和填充超级快
static struct file_system_type ext3_fs_type = {
.owner = THIS_MODULE,
.name = "ext3",
.get_sb = ext3_get_sb,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
register_filesystem(&ext3_fs_type );//向内核注册该文件系统
vfs_kern_mount()函数创建的数据结构实例组织关系如下图所示:
各位路过的剑仙,有收获的话,点个赞吧