文件系统抽象层
- 内核在底层文件系统接口上建立了一个抽象层,这个抽象层可以让linux支持各种文件系统
- VFS定义了所有文件系统都支持的基本,概念上的接口和数据结构,实际文件系统在统一的接口和数据结构下隐藏了细节
- 实际文件系统通过编程提供VFS所期望的抽象接口和数据结构
- 用户空间:write() – 》VFS:sys_write() --》文件系统:文件系统的写方法 --》物理介质
UNIX文件系统
- VFS把目录当做文件看待
- 文件本身:
- 文件相关信息:inod(索引结点):关于文件的访问控制权限,大小,拥有者,创建时间。存储在单独的块中
- 文件控制信息:存储在超级快中(包含文件系统信息的数据结构)
- 别的文件系统如果不支持某个概念,如索引结点,也必须在内存中装配索引结构体。。。 但会带来很大开销
VFS对象及数据结构
- 虽然内核纯粹用C语言实现,但是VFS实际采用面向对象的设计思路。内核数据结构使用C语言结构体实现,并且包含了操作数据结构的函数指针。(这点很像redis中数据结构的实现)
4大对象类型
-
超级块对象:代表一个具体已经安装的文件系统
-
索引结点对象:代表一个具体文件
-
目录项对象:代表一个目录项,是路径的一个组成部分。方便路径名查找和对目录进行相关操作。
-
文件对象:代表有进程打开的文件
-
注意目录项不同于目录,但是目录是另一种形式的文件
-
每个对象都有一个操作对象,操作对象描述了内核对文件系统可以调用的方法。
-
这里的对象就是结构体
目录项缓存 感觉用的就是LRU算法
- 未被使用的文件目录项不会被过早的撤销,这样后面需要的时候就不用再重新创建。
- 文件访问呈现空间和时间的局部性,所以对目录项和索引节点进行缓存非常有益
- 每次遍历路径名所有元素逐个解析非常耗时,所以内核吧目录项对象缓存在目录项缓存dcache
*dcache - “被使用的” 目录表项 链表
- “最近被使用的”双向链表。包含未被使用的和负状态的目录项对象,头部插入新的目录项,尾部删除旧的目录项,旧的近期再次使用的概率最小。这点有点像LRU,我猜想EPOLL中内核事件表中rdlist 是否可能也是出于这个原因所以用的双向链表
- 散列表 + 散列函数 快速判断解析出给定文件所在目录项