Linux的文件系统可以理解为下面4个层次:第一层,用户所看到的,用到的,暂且称为用户层的文件系统;第二层,就是这篇文章所要介绍VFS,一个虚拟的文件系统,建立在各种不同格式的文件系统上,简化了用户对文件的操作;第三层,具体的文件系统,根据类型不同,可以划分为:磁盘文件系统、网络文件系统、特殊文件系统;第四层,文件系统所在设备的驱动,这层真正实现了文件的访问。
VFS是处于具体的文件系统和用户所看到的/、/root等目录之间的一个特殊的存在,没有具体作用于某种文件系统,是建立在各种文件系统之上的一个抽象。VFS的主要功能是对用户,实现了Linux内核特有的文件管理方式。例如,在某个文件被使用之前,除了必须的对文件是否存在进行判断外,还需要对进行文件调用的用户权限进行判断,这个是在VFS中实现的。而对内核而言,VFS实现了文件系统的统一管理,分离了具体的文件系统和用户层,既方便了APP对文件的调用,同时也方便了内核对文件存储介质的操作。
在每次系统初始化期间,Linux 都首先要在内存当中构造一棵VFS的目录树(在 Linux 的源代码里称之为 namespace)。初始化的过程实际上便是在内存中建立相应的数据结构的过程:使用mnt_init()对文件系统进行注册主要经过了这些步骤:分配hashtable、初始化文件系统、注册rootfs、将rootfs设置成VFS根目录。如果VFS初始化不成功,那么在内核引导时会出现kernel panic错误,无法挂载VFS。
Linux遵循POSIX标准,这样使得移植的应用程序在使用文件时更加规范。当应用程序发送一个文件操作的信号时,通过信号传入内核中执行。以读取一个文件为例:
1、用户态程序中出现open系统调用,编译时被连接到C语言库中
2、C语言库中使用0x80中断或者sysenter进入内核模式。
3、使用 sys_open(),得到用户态传进的文件名
4、当文件名可用时filp_open()初始化nameidata,并返回从dentry_open()中得到的file指针。
接着用户态程序就该调用read对文件进行读取了:
1、调用sys_read()传入在open中得到的文件指针
2、通过fget_light()一个轻量级的文件查找函数,将用户态传入的文件名给转换成内核所使用的file指针
3、file指针不为空时,调用vfs_read()
4、当 rw_verify_area()返回0时,首先检查文件的权限是否合法,如果file->f_op->read不为空,则调用 file->f_op->read对文件进行读取,或者通过do_sync_read()调用 filp->f_op->aio_read()读取文件。
5、返回读取的信息
阅读(2566) | 评论(0) | 转发(0) |