第12章 虚拟文件系统
1 简介
VFS:Virtual Filesystem Switch,虚拟文件系统转换,VFS
2 VFS支持的文件系统
2.1 磁盘文件系统
Linux使用的文件系统:Ext2(Linux的根文件系统通常是Ex2或Ex3)
微软公司的文件系统:MS-DOS、VFAT、NTFS
……
2.2 网络文件系统
这些文件系统允许我们访问其他网络计算机的文件系统所包含的文件,也就是“映射网络驱动器”
2.3 特殊文件系统
/proc 文件系统
3 通用文件模型
VFS隐含的思想就是引入了一个通用文件模型,Linux需要将文件的物理组织结构转换为VFS的通用文件模型;
3.1 通用文件模型的组成
① 超级块对象(superblock object)
对基于磁盘的文件系统,这类对象对应的就是存放在磁盘上的文件系统控制块(filesystem control block);
存储一个已安装的文件系统的控制信息(文件系统的状态、文件系统类型、块大小、区块数、索引节点数、脏标志、操作方法),它代表一个已安装的文件系统;每次一个实际的文件系统被安装时,内核会从磁盘的特定位置(磁盘的超级块位置)读取一些控制信息来填充内存中的超级块对象。一个安装实例和一个超级块对象一一对应。;超级块对象用双向循环链表连接在一起。
② 索引节点对象(inode object)
用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等;
对应于关于存放在磁盘上的文件控制块(file control block);
每个索引节点对象都有一个索引节点号,这个节点号唯一地标识文件系统中的文件;
软链接和原文件对应不同的inode,如果A是B的软链接,则A里面的内容只是B的路径,删除B之后A还存在,但是A已经没有意义。
③ 文件对象(file object)
存放打开文件与进程之间进行交互的有关信息;仅当进程访问文件期间存在于内核内存中;
文件对象在磁盘中没有对应的映像,因此file结构中没有设置“脏字段”来标识文件对象是否已经被修改。
关于脏字段,超级块对象和索引节点对象都有这个标识,注意脏指的是上述结构体脏,然后要把信息同步到文件中,而不是文件脏。
④ 目录项对象(dentry object)
用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系;
多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存;
最近最常使用的目录项被放入目录项高速缓存中,用于加速文件名->文件索引节点的转换过程;
目录项对象在磁盘上没有对应的映像,存放在名为dentry_cache()的slab分配器高速缓存中。
3.2 举例说明

三个进程打开一个文件,其中两个进程使用同一个硬链接,则有:
- 每个进程都会创建自己的文件对象
- 每个硬链接对应一个目录项对象,可以认为是文件副本
- 实际文件只有一份,所以索引节点对象inode也只有一个
- 索引节点对象包含超级块对象和磁盘文件的信息
4 VFS的系统调用
mount(),umount(),umount2():安装/卸载文件系统
sysfs()
statfs(),fstatfs()等:获取文件信息
mkdir(),rmdir()
chown()等
open(),close(),creat()等
VFS是应用程序和具体文件系统之间的一层,但是在某些情况下一个文件操作由VFS本身执行,并不调用底层函数;
比如进行close(),lseek()等只涉及到对进程文件对象这一中间层属性的操作时。
5 与进程相关的文件
① 内核用来标识进程与文件系统互相作用所必须维护的数据结构:fs_struct
- count:共享这个表(结构体)的进程个数
- root:根目录的目录项
- pwd:当前工作目录的目录项
- xxx
② 当前进程打开的文件,存放于进程描述符的成员files_struct files中
- count:共享该表(结构体)的进程数目
- max_fds:当前进程打开的文件对象的当前最大数目
- struct file * fd_array[]:文件对象(struct file)指针数组,文件描述符fd就是fd_array数组的索引
- struct file **fd:指向文件对象指针数组的指针
- fd_array数组的前三个元素分别为0:标准输入stdin,1:标准输出stdout,2:标准错误stderr
6 文件系统目录树
6.1 通识
- 每个文件系统都有自己的根目录
- 安装文件系统的这个目录称为文件系统的安装点 —— 安装点不是根目录,比如/mnt/media_rw/sdcard0的根目录是/,安装点是sdcard0
- 已安装的文件系统属于该安装点目录的一个子系统
- 已安装文件系统目录隐藏了父文件系统原来的目录
6.2 安装是什么意思?
比如“存放在/dev/fd0软件磁盘上的Ext2文件系统安装在/flp:mount -t ext2 /dev/fd0 /flp
根目录是/,安装点是/flp,已安装的文件系统都是磁盘中的一些文件,安装后可以在/flp中找到;ext2标识安装类型,必须是已注册的文件系统的名称。
“隐藏”的意思在之前的文件系统中,如果/flp已经被安装,那么新安装后/flp目录下之前所有文件都会被隐藏!
如果卸载最新的文件系统,被隐藏的文件又变为可见了。
可以堆叠安装,一个文件系统的目录可能是另外一个文件系统的安装点:
mount -t ext2 /dev/fd0 /flp
touch flp/foo
mkdir /flp/mnt
mount -t ext2 /dev/fd0 /flp/mnt
flp(fd0)
foo
mnt(fd0)
则可以通过/flp/foo和/flp/mnt/foo来访问foo文件
6.3 安装根文件系统
安装根文件系统是系统初始化的关键部分。Linux内核允许根文件系统存放在很多不同的地方,最常见的地方是硬盘分区。以此为例,当内核启动时,内核在ROOT_DEV中寻找包含根文件系统的磁盘主设备号;或者在编译内核时,指定根文件系统为/dev目录下的设备文件。
一个发布版的初始启动光盘,把具有最小驱动程序的内核装入RAM中,内核把存放在ramdisk(内存来模拟磁盘)中的一个最小文件系统作为根安装;然后在这个初始根文件系统的程序探测系统硬件(磁盘或硬盘),装入所有必须的内核模块,并从物理块设备重新安装根文件系统。
本文来自博客园,作者:moonのsun,转载请注明原文链接:https://www.cnblogs.com/moon-sun-blog/p/18819973

浙公网安备 33010602011771号