虚拟文件系统


VFS使得用户可以直接使用open,read,write这样的系统调用而无需考虑具体的文件系统和实际物理介质
四个主要的对象类型

  • 超级块对象:代表一个具体的已安装的文件系统
  • 索引节点inode对象:代表一个具体文件
  • 目录项对象:代表一个目录项,是路径的一个组成部分
  • 文件对象:代表由进程打开的文件
  • 四个对象的联系:文件可以当作一个有序字节序,通过目录组织起来,目录好比一个文件夹,文件的相关信息放在inode,文件会有特定的属性属于某个文件系统,文件系统的控制信息放在超级块

超级块对象super_block

存储特定文件系统的信息,在磁盘中存在

  • 通常对应存放在磁盘特定扇区中的文件系统超级块,即不同分区两个相同文件系统对应两个超级块
  • 所有超级块对象用双向循环链表形式连接

索引节点对象inode

包含内核在操作文件或目录时需要的全部信息,对文件是唯一的,随文件存在而存在。索引节点是物理意义上的文件,记录的是物理上的属性,在磁盘上有对应的映像

  • 必须在内存创建
  • 在同一文件系统中,每个inode号都是唯一的
  • 记录文件是否为脏

目录项对象dentry

为了方便查找,按名存取,引入了目录项。存放目录项(文件特定名称)和链接有关的信息。目录项是逻辑意义上的文件,描述的是文件逻辑上的属性,在磁盘上没有对应的映像

  • 一个索引节点对象可能对应多个目录项对象

链接

  • 软链接相当于一个快捷方式,是一个新的文件,里面存的是源文件的路径,可以跨文件系统创建,可以链接目录
  • 硬链接是通过索引节点来链接,文件副本不占空间(因为索引节点和磁盘盘块对应,硬链接的文件是使用一个索引节点的),会增加索引节点的引用数,不可以跨文件系统创建,不可以链接目录
  • 命令都是ln,软连接用参数-s
  • 目录问题:硬链接在操作系统遍历目录时会有循环问题,比如/A/C链接/B,/B/E链接/A,因为硬链接都是使用同一索引节点,而操作系统也是利用索引节点遍历,很难防范这种死循环;而软链接是不同的索引节点,同时索引节点是会记录这个文件是符号链接类型的,就能在合适的时候跳出循环

目录项状态

  1. 空闲状态:没有包含有效信息,未被VFS使用,只是slab分配了内存
  2. 未使用状态:还没被内核使用,引用计数器为0,已经和索引结点关联起来。包含有效信息,但必要时会被回收内存
  3. 正在使用状态:正在被内核使用,引用计数器为正数。包含有效信息,不会被丢弃
  4. 负状态:与目录项相关的索引结点被删除,但仍保存在目录项高速缓存,避免查找同名目录时遍历全部目录

目录项高速缓存

  • 出现原因:如果VFS遍历路径名所有元素并把它们逐个解析成目录项对象,会浪费大量时间,因为是需要才创建的。因为程序的局部性,后面可能还需要用到这个目录项对象
  • 实现:三个部分
    • “被使用的”目录项双向链表:一个索引节点可以有多个目录项,这些目录项就用链表连起来,由索引节点中的i_dentry指向
    • “最近被使用的”目录项双向链表:该链表含有未被使用和负状态的目录项对象。链头插新目录项,从链尾删除最久的目录项(LRU)
    • 散列表,文件名对应目录项对象

文件对象file

描述进程怎么和一个打开的文件进行交互,由open创建,close撤销,在磁盘上没有对应的映像

  • 一个文件被多个进程打开,就有多个file对象
  • 主要信息是文件指针,即文件中的当前位置,下一个操作将在这个位置发生。因为多个进程可能同时访问一个文件,所以文件指针放在file而不是inode

和进程相关的数据结构

file_struct

所有与单个进程相关的信息(如打开的文件及文件描述符)都包含其中

  • file对象在其中的静态数组fd_array,超过时可以建立新数组

fs_struct

包含文件系统和进程的信息

  • 如根目录的目录项root,当前正在执行文件,当前目录的目录项pwd

路径名查找

  • 如果路径名的第一个字符是"/",那么为绝对路径,从fs_sturct的root开始搜索
  • 否则就是相对路径,从fs_struct的pwd开始搜索
  • 过程:
    1. 检查和第一个名字匹配的目录项对象,没有就创建
    2. 获得对应的索引节点
    3. 从磁盘读出对应的文件,文件里是目录相关的信息(目录文件:inode+文件名)
    4. 从文件中找到和第二个名字匹配的目录项(不是目录项对象),创建目录项对象或在目录项高速缓存中找到,以此类推
posted @ 2021-02-16 17:35  肥斯大只仔  阅读(112)  评论(0编辑  收藏  举报