概述
文件和文件系统
-
文件的优点:
- 持久化:可以长期存在于辅存之中,用户退出系统不会丢失文件;
- 共享性:文件可允许进程间受控共享;
- 结构化:取决于具体的文件系统和物理结构,一个文件具有针对特定应用的内部结构,并且文件间可以组织成复杂的层次结构。
-
文件系统需要提供的文件操作:
- 创建;
- 删除;
- 打开:将文件声明为“打开”状态,获得文件描述符,以便允许该进程对文件进行操作;
- 关闭;
- 读;
- 写;
- 维护文件属性:所有者、访问权限、创建时间、最后修改时间等;
文件结构
域 field
- 基本数据单元,一个域包含一个值;
- 可通过长度和数据类型进行描述。长度可以定长或变长,变长域中要有子域声明域长度;
- 域之间的分隔符也暗示了域长度。
- 如雇员的名字、年龄、工号各是一个域;
记录 record
- 域的集合,一条记录可能是包含了雇员所有信息域的集合。
- 记录可以定长或变长,若其中的域是变长或域数量可变,则记录是变长;
- 变长记录需要长度域;
文件 file
- 相似记录的集合,被用户和应用视为实体,访问的基本单位;
- 具有唯一文件名,可被创建和删除,可通过文件名访问、查找;
- 访问控制在文件级实施,在更复杂系统中也可以设置在记录或域一级;
数据库 database
- 一组相关数据的集合,本质特征是数据元素间存在明确关系,可供不同的应用程序使用;
- 本身由一种或多种类型文件组成,包含一个组织或项目相关的所有信息;
- 数据库管理程序是独立于操作系统的,只是使用 OS 提供的文件管理接口,是另一种系统软件;
补充
- 要使用文件,OS 必须提供增删改查的各项接口,这些对文件执行的操作会影响文件的组织方式。
- Unix 系统中文件的基本结构是字节流,而没有域、记录之分。
文件管理系统
文件管理系统是用户或应用程序访问文件的唯一方式,
-
为系统提供控制重要空间资源的方法,需要满足以下目标:
- 提供对文件基本操作:满足数据管理的要求和用户的需求,存储数据和执行文件操作;
- 保证数据可用:最大限度保证文件中的数据有效;
- 优化性能:系统角度上提升总体吞吐量,用户角度上提升响应时间;
- 提供与硬件设备的 I/O 支持;
- 多用户系统中提供权限控制;
-
对于交互式系统,最少应该满足以下需求:
- 文件基本操作:增删改查;
- 用户能够受控访问其他用户的文件;
- 用户能够控制对其文件进行的访问的类型:读、写、执行等;
- 每个用户都能在文件间移动数据;
- 能够备份用户文件,并在文件损坏时能够恢复;
- 能够通过文件名访问文件;
文件系统架构
从下到上:
- 设备驱动:直接与外围设备 (控制器或通道)进行通信
- 负责启动设备上的 I/O 操作,处理 I/O 请求的完成;
- 对文件操作,典型的控制设备是磁盘或磁带;
- 基本文件系统:又称物理 I/O 层,是与计算机系统外部环境的基本接口
- 处理在磁盘间交换的数据块;
- 关注数据块在辅存和内存缓冲区中的位置,而非数据的内容或涉及的文件结构;
- 基本 I/O 管理程序:负责所有文件 I/O 的初始化和终止
- 需要一定的控制结构来维护设备的输入输出、调度和文件状态;
- 根据所选文件来选择执行文件 I/O 的设备,为优化性能,还参与调度对磁盘的访问;
- 实现指定 I/O 缓冲区和分配辅存;
- 逻辑 I/O:使用户和应用程序能够访问记录
- 较基本文件系统处理数据块“得而不知”,逻辑 I/O 处理文件记录,
- 提供通用的记录 I/O 能力,维护关于文件的基本数据;
- 访问方法:在应用程序和文件系统以及数据存储设备之间提供了标准接口
- 不同的访问方法反映了不同的文件结构及访问和处理数据的不同方法;
文件管理功能
从左到右:
- 用户和应用通过命令进行文件创建、删除、执行等操作;
- 执行操作之前,文件系统需要确认和定位所选择的文件;
- 可以使用树形目录描述所有文件的位置及属性,
- 对共享系统实行用户访问控制:被授权用户才得以特定方式访问特定文件;
- 应用程序可以在文件上执行的基本操作是在记录级执行,
- 将文件视为具有组织记录的特殊结构;
- 采用适合于该文件结构的访问方法,将用户命令转换为特定的文件操作命令;
- I/O 在物理上以块为基础完成,因此文件中的记录必须组块,以块序列输出、输入。为支持块 I/O,需要
- 管理辅存,包括把文件分配到辅存中的空闲块;
- 需要管理空闲存储空间;
- 响应单个块 I/O 的请求;
- 考虑磁盘调度和文件分配对性能优化的影响;
文件组织和访问
- 文件组织方式与考虑原则
- 文件组织指文件中记录的逻辑结构,由用户访问记录的方式确定。
- 选择文件组织有以下考虑原则:快速访问、易于修改、节约存储空间、维护简单、可靠性高;要根据文件用途综合考虑;
- 文件在辅存中的物理组织取决于分块策略和文件分配策略。
堆
- 数据按照到达的顺序收集,每条记录由一串数据组成;
- 记录可以有不同的域、长度、域顺序,
- 每个域都应能自我描述,包含域名和域值,
- 域长度由分隔符隐式指定,或者明确在子域中,或者域类型的默认长度;
- 堆仅仅是积累大量数据并保存,没有结构,对记录的访问是通过穷举查找进行;
- 仅适合于数据快速收集而不进行处理,或者数据类型多变难以组织。
顺序文件
- 每条记录都使用固定格式,所有记录都具有相同长度,由相同数量、长度固定的域按特定顺序组织。每个域只需保存值,其名称、位置、长度表明了类型和属性;
- 关键域:唯一标识一条记录,同一文件中不可重复;
- 通常用于批处理应用,性能很好,是唯一可以容易地存储在磁盘中的文件组织;
- 对于查询或更新记录的交互式应用,性能很差,仍是穷举查找法;
- 文件的物理组织直接对应于逻辑组织;
- 遇到新记录时,将其放到单独堆文件 (称为日志文件或事物文件),周期性地执行成批更新,将日志文件合并到主文件中的正确位置;
- 还可以将顺序文件组织成链表,每个块都含有指向下一块的指针。这种形式操作简便,但是额外增加了处理和空间开销。
索引顺序文件
- 记录按照关键域的顺序组织,有用于支持随机访问的文件索引和溢出文件。
- 索引提供快速接近目标记录的查找能力,
- 溢出文件类似日志文件,但其中记录可以根据前面记录的指针进行定位;
- 一级索引中的索引是简单的顺序文件,索引文件中每条记录由关键域、指向主文件的指针组成;
- 索引方法降低了多少开销?考虑一个 100 万记录的顺序文件:
- 顺序查找,期望访问数是 50 万次;
- 建立包含 1000 条索引,每条索引指向 1000 条记录,则期望访问数是 500+500=1000 次
- 主文件中每条记录都包含一个附加域,附加域对应用程序透明,而是指向溢出文件的一个指针。
- 向文件中插入一条新纪录时,先被添加到溢出文件中,
- 然后修改主文件中逻辑顺序在新纪录之前的记录指针,以从溢出文件中归并到主文件;
- 索引顺序文件保留了文件的顺序特性——基于文件的关键域进行处理,且极大减少了访问单条记录的时间;
- 可以通过使用多级索引降低期望查找数,但是同样会增加复杂度;
索引文件
- 允许通过其它域进行查找,因为每个域都可能有一个索引;
- 摒弃了顺序性和关键字,只通过索引访问记录,对记录的放置位置不再有限制;
- 完全索引:包含主文件中每条记录的索引项。索引组织成顺序文件以便于查找;
- 部分索引:只包含感兴趣的域的索引项;
- 向主文件中添加新纪录时,索引文件必须全部更新;
- 多用于对信息及时性要求严格、很少对所有数据进行处理的应用程序。
直接或散列文件
- 拥有直接访问磁盘中任一地址已知的块的能力;
- 在要求快速访问时使用,记录长度固定,且每条记录都需要关键域。
B 树
特征
- 每个节点至少有一个关键码,且包含多于一个指向子节点的指针;
- 每个节点关键码的数量不能超过最大关键码数量;
- 节点内的关键码按非减次序存放,每个关键码都有一个指针域指向子节点,该子节点所在子树的所有关键码均小于等于当前关键码,且均大于前一个关键码;
- 节点最右侧(关键码最大一侧)有一个额外指针域指向子节点,最右子节点为根的子树中所有关键码都大于该节点包含的任意关键码;
性质
对于最小度数为 d (阶数)的 B 树,具有以下性质:
- 每个节点最多 2d-1 个关键码,2d 个子女,2d 个指针;
- 除根节点,每个节点都至少有 d-1 个关键码和 d 个指针;
- 根节点最少有 1 个关键码、2 个指针;
- 所有叶子都在同一层,不包含任何信息,是用来终止树的逻辑结构,通常是底层节点指针域为 NULL;
搜索
- 从根节点出发,在节点内顺序查找或二分查找,若所需关键码在该节点中,则搜索结束,否则去树的下一层;
- 若所需关键码小于该节点的最小关键码,则沿最左边指针去下一层;
- 若所需关键码大于该节点的最大关键码,则沿最右边指针去下一层;
- 若所需关键码在该节点的某两个关键码之间,则沿两关键码中间指针去下一层;
插入与复平衡
- 在树中搜索指定关键码,若关键码不在树中,则需要插入,此时位于底层的一个节点;
- 若该节点关键码数量少于 ,则将新关键码插入适当位置;
- 若节点已满,则以该节点的中间关键码 为界将其分为两个新节点,每个新节点都包含 个关键码,而中间关键码则上升到上一层;
- 若新关键码的值小于中间关键码,则插入左边的新节点,否则插入右边的新节点;
- 若提升层级的中间关键码导致父节点溢出 (大于 2d-1),则父节点继续分裂、父节点的中间关键码上溢;
- 若提升过程中导致根节点溢出,则中间关键码变成新的根节点,树的高度+1;
删除与复平衡
case 1: delete leaf
case 2: delete internals
case 3: shrink height
复杂度分析
-
Best case Time complexity:
Θ(log n)
-
Average case Space complexity:
Θ(n)
-
Worst case Space complexity:
Θ(n)
文件目录
- 文件目录是关联文件管理系统和文件集合的桥梁;
- 目录包含关于文件的信息,如属性、位置、所有权等,这些信息都由 OS 管理;
- 目录本身是一个文件,可被文件管理例程访问;
内容
目录包含信息有:
- 基本信息:文件名、文件类型、文件组织;
- 地址信息:卷名、起始地址、文件使用大小、分配大小;
- 访问控制信息:所有者、访问信息、许可行为;
- 使用信息:创建时间、创建者身份、最后读访问时间、最后读者、最后修改时间、最后修改者、最后备份时间、当前使用信息;
结构
命名
- 树状结构目录降低了提供唯一名称方面的难度。
- 文件路径:从根目录或指定目录开始,向下到达各个分支直到指定文件,一系列目录名+文件名构成了文件的路径名,
- 绝对路径:从根目录
/
开始的路径名; - 相对路径:将进程的当前路径作为工作目录,以此基准寻找对应文件,按照相对于基准的方式访问;
- 绝对路径:从根目录
- 交互式用户登录或创建一个进程时,默认工作目录是用户目录 (
/home/user_name/
);
文件共享与保护
访问权限
-
访问权限从低到高依次为:
- 无 none:用户不知道文件是否存在,即不允许读取包含该文件的目录;
- 知道 knowledge:可以确定文件位置及所有者,因此可以向所有者申请访问权限;
- 执行 execution:可加载并执行一个程序,但不能复制;
- 读 read:用户能以任何目的读取文件,包括复制、执行;
- 追加 append:只能在文件末尾添加数据,而不能修改或删除文件的其他内容;
- 更新 update:用户可修改、删除、增加文件中的数据;
- 改变保护权限 change protection:可改变已授给其他用户的访问权限,通常只有文件所有者有这一权力,还可以由所有者继续向下授权;
- 删除 delete;
-
访问权限可以限定用户:
- 特定用户:指定用户 ID;
- 用户组:指定用户所属组的 groupID;
- 所有:有权访问该系统的所有用户;
同时访问
多个用户操作统一文件时,
- 为避免共享冲突,需要互斥访问:
- 蛮力法是用户修改文件时,对整个文件加锁;
- 更好的控制粒度是为单个记录加锁;即读写者问题。
记录组块
记录是访问结构化文件的逻辑单元,块是与辅存进行 I/O 操作的基本单位,因而记录必须组织成块。
- 块的大小的考量:
- 块越大,一次 I/O 传送的记录越多,越适合顺序查找、处理,减少了 I/O 操作,处理速度更快;
- 大块对随机访问不好,因为访问不具有局部性,大块的不必要传输反而浪费了空间;
- 大块需要更大的 I/O 缓冲区、更复杂的缓冲区管理;
定长组块
- 定长记录,且若干完整记录保存在一个块,每个块的末尾可能有未使用碎片(内部碎片)
- 记录之间有 gap 区作为分隔;
变长跨越式组块
- 记录是变长,紧缩在块中,使得块中不存在未使用空间;
- 某些记录可能跨越两个块,两个块通过指针连接;
- 效率更高,更适合大文件,但难以实现,因为跨越两个块的文件需要两次 I/O;
变长非跨越式组块
- 记录是变长,但并不采用跨越式,若下一条记录比块中剩余未使用空间更大,则无法使用这一部分;
- 导致块的内碎片更大、更频繁出现;
- 利用率低,且文件大小不能超过块大小;
辅存管理
- 辅存管理问题:
- 辅存中的空间如何分配给文件;
- 必须知道哪些空间可用于分配;
文件分配
- 分配空间需要做的考量:
- 创建新文件时是否一次性分配所需的最大空间?
- 给文件分配的分区大小应该多少?(分区:文件分配得到的一个或连续的块)
- 为跟踪分配给文件的分区,应当选择何种数据结构?DOS 中使用 FAT (文件分配表)
预分配与动态分配
- 预分配策略要求在发出创建文件的请求时,声明该文件的最大尺寸。但估计必然不准确,也不易实现,空间利用率也不高;
- 动态分配只在需要时分配空间,这样利用率较高。
分区大小
-
两种极端:
- 分配大到足够保存整个文件的分区;
- 一次只分配一个块。
-
需要考量的因素:
- 使用临近空间可以提高性能;
- 数量较多的小分区会增加用于管理分配信息的表的大小;
- 固定大小的分区可以简化空间的再分配;
- 可变大小的分区可以减少超额分配导致的未使用存储空间的浪费;
-
两种选择:
- 大小可变的大规模连续分区:性能较好,大小可变避免浪费,且文件分配表较小,缺点是空间难以再利用;
- 大小固定小规模连续分区:小的固定分区灵活性较高,但导致更大、更复杂的管理表;
- 临近性不再是目的,主要根据需要进行块分配;
-
分配策略:
- 首次适配:空闲块列表中选择第一个大小足够的连续块组;
- 最佳适配
- 最近适配:局部性好;
文件分配方法
- 连续分配:
- 创建文件时,给文件分配一组连续的块;
- 大小可变的分区策略,文件分配表中只需要一个表项,说明起始块地址和文件长度;
- 对单个顺序文件,性能最好;I/O 时可以同时读取多个块提高性能;
- 缺点:外部碎片,时常需要紧缩算法收拢碎片;预分配不够灵活且难以实现;
- 链式分配:
- 链式分配基于单个块,链中每个块都包含指向下个块的指针;
- FAT 中只需要一个表项,声明起始块和文件长度;
- 动态分配,不必考虑外碎片;
- 也适合顺序处理的文件;
- 后果是破坏了磁盘中的局部性,若要读取一个文件的连续多个块,需要在磁盘中不同部分访问,寻道时间、旋转延迟不可忽视;对于单用户系统影响较大,因此需要周期性合并文件:
- 索引分配:
- 每个文件都在 FAT 中有一级索引,分配给该文件的每个分区都在索引表中有一个表项;
- 文件索引保存在单独的块,FAT 中该文件的表项指向这个块;
- 分配可以块大小固定,也可以大小可变,两种情况都需要周期性整理文件分块;
空闲空间管理
磁盘分配表 DAT 用于管理磁盘中块的分配情况。有 4 中实现方法:
- 位图:bitmap 向量中每一位对应于磁盘中每一块,0 为空闲 1 为占用;
- 优点是:寻找连续的空闲块比较简单,适合连续、链式、索引所有分配方法,占用空间较小;
- 缺点是:占用内存,且穷举式查找依然耗用开销较大;改进方法是对位图分块,每个子表有一个汇总表,则查询时只需要看汇总表;
- 链接空闲区:使用指向每个空闲区的指针和其长度值,将空闲区连接在一起
- 仅需要一个指向链开始处的指针和第一块空闲区的长度,因而空间开销可以忽略不计;
- 缺点是使用一段时间后会出现磁盘外碎片,很多分区都变得只有一个块那么大;在分配块时,要先读这个块以便找到下一个块的指针,这拖慢了创建文件的速度;
- 索引:使用索引表管理整个空闲空间,相对来说高效、易实现;
- 空闲块列表:为每个块指定序号,所有空闲块的序号保存在磁盘的保留区中
- 大小是块号长度 ✖️ 相应位图大小;
- 尽管空闲块列表大到保存不到内存中,但可以通过两种技术保存一小部分到内存:
- 将表视为下推栈,其中靠前的若干元素保存在内存中,分配新块时弹出栈,解除分配时压入栈;
- 将表视为 FIFO 队列,分配块时从队头取走第一项,解除分配时添加到队尾;
- 后台线程可以对内存中的空闲块列表排序;
- 综合考虑这种策略非常让人满意;
卷
- 一组在辅存上可寻址的扇区集合,OS 或应用程序用来存储数据;
- 是逻辑磁盘,卷的扇区不需要在物理存储设备上连续;
可靠性
当用户为了提高效率而在内存中保存磁盘分配表和文件分配表的副本时,若仅在内存中更新而未及时写回磁盘,当发生系统崩溃时这些更新就会丢失。因此
- 请求文件分配时,应当:
- 在磁盘中对磁盘分配表 DAT 加锁,防止在分配完成前另一用户修改这个表;
- 读入 DAT 到内存,查找 DAT,获知可用空间;
- 分配空间,更新 DAT,并同时写回 DAT 到磁盘,维持数据一致;
- 更新 FAT 和对应磁盘;
- 解锁 DAT;
上述方案对频繁分配的小块性能不佳,可以
- 改进为批存储分配方案:
- 先获得磁盘上一批空闲块,将其标记为“已用”;
- 使用这批块的分配在内存中进行,当这批块用完后更新磁盘上的 DAT,并获得新的一批块;
- 若出现系统崩溃,则磁盘上被标记为“已用”的部分在被重新分配前,须通过文件系统提供的接口清空;
Unix 文件管理
Unix 文件类型
Unix 中“一切皆文件”,共有 6 类文件:
- 普通文件:用户、应用程序、系统实用程序写入的信息,
- Unix 不对其强加任何内部结构,只是视为字节流;
- 目录文件:包含文件名列表和指向对应文件索引节点的指针,
- 目录按树状的层次结构组织;
- 实际上是具有特殊写保护权限的普通文件,只有文件系统才能写,而其他所有用户程序都只能读访问;
- 特殊文件:不包含数据,是物理设备映射到逻辑文件名的机制,
- 文件名用于访问物理设备;
- 每个 I/O 设备都有一个特殊文件与之相关联;
- 命名管道:管道是进程间通信的基础设施
- 管道缓存输入端接收的数据,以便在管道输出端读数据的进程能以 FIFO 的方式接收数据;
- 链接文件:一个文件的另一个可选文件名;
- 符号链接:一种数据文件,包含所链接的文件的文件名。
索引节点
-
索引节点是一个控制结构,包含 OS 所需要的关于某个文件的关键信息;
-
多个文件名能与一个索引节点关联,但一个活跃的索引节点只能与一个文件相关联,每个文件都只能由一个索引节点控制;
-
包含的数据元素有:
- 文件类型、访问模式;
- 文件所有者和组访问标识符;
- 文件创建时间、最后一次读时间、最后一次写时间、最后一次索引节点被系统更新时间;
- 文件大小,以字节表示;
- 一系列块指针,包含直接块、一级间接块、二级间接块等;
- 文件所用磁盘块的个数,包括用于存储间接指针和属性的块;
- 引用该文件的目录项数:软链接会直接复制引用计数,硬链接会导致引用计数增加;
- 内核与用户设置的用于描述文件特征的标志位;
- 文件生成编号:分配索引节点时的随机生成编号,用于监视指向被删除文件的引用;
- 索引节点引用的块大小;
- 扩展属性信息的大小;
- 扩展属性条目;
磁盘上有一个索引节点表,包含了文件系统中所有文件的索引节点。打开文件时,其索引节点会被加载到主存的驻留索引节点表中。
文件分配
文件分配是以块为基础的动态分配,并非预定义的连续分配,因此 Unix 采用索引方法管理分配的磁盘块,其中索引存放在 inode 中。
多级索引块的存储空间计算
- FreeBSD 的 inode 中有 120 字节的地址信息,即被组织为 15 个 64 位指针,
- 前 12 个地址指向文件前 12 个数据块,
- 之后三个地址分别是一级索引块、二级索引块、三级索引块:
FreeBSD 中最小块为 4KB,则每块最多保存 512 个块地址,最多可以超过 500GB 的文件:
- 优点
- 索引节点大小固定,且相对较小,能在内存中保存较长时间;
- 访问小文件时,直接块就能满足需求,能够减少处理时间和磁盘访问时间;
- 支持的存储空间足够大;
目录
- 目录以层次树的形式组织,每个目录都包含文件和其他目录;
- 每个目录项都包含一个相关的文件名或目录录,以及索引节点号。索引节点号用于访问文件或目录时作索引节点表的索引。
卷结构
Unix 文件系统驻留在单个逻辑磁盘或磁盘分区上,有以下元素:
- 引导块 boot block:引导 BIOS 找到操作系统启动入口;
- 超级块 super block:包含文件系统的属性和信息,如分区大小和索引节点表的大小;
- 索引节点表:系统中所有文件的索引节点集;
- 数据块:数据文件和子目录所需的存储空间;
Linux 虚拟文件系统
VFS
- 功能:
- VFS 向用户进程提供一个简单且统一的文件系统接口,定义了一个能代表任何文件系统的通用特征和行为的通用文件系统;
- VFS 通过特定文件系统的一个映射函数,将该系统调用转换为内部某个特定文件系统的功能调用;
- 实现步骤:
- 当进程发起一个面向文件的系统调用时,内核调用 VFS 中的一个函数,
- 该函数处理完与具体文件系统无关的操作后,通过映射函数转换 VFS 调用到目标文件系统的调用,调用目标文件系统中的相应函数,
- 目标文件系统将请求转换到面向具体设备的指令;
VFS 使用 C 的结构体实现面向对象,其中每个对象都包含数据和函数指针,函数指针指向操作这些数据的文件系统的实现函数。
- VFS 主要有 4 个对象:
- 超级块对象:表示一个已挂载的特定文件系统;
- 索引节点对象:表示一个特定的文件;
- 目录项对象:表示特定的目录项;
- 文件对象:表示一个与进程相关的已打开文件。
超级块对象
- 存储了描述特定文件系统的信息,通常对应于磁盘特定扇区的文件系统超级块或文件系统控制块。
- 包含数据项:
- 文件系统所挂接的设备;
- 文件系统的基本块大小;
- 脏标志,表示超级块已被修改但未写回磁盘;
- 文件系统类型;
- 标志:只读,读写;
- 指向文件系统根目录的指针;
- 打开文件的链表;
- 控制访问文件系统的信号量;
- 操作超级块的函数指针数组的指针:包含操作对象,定义内核可在超级块对象上调用的对象方法,如
alloc_inode
分配一个索引节点、write_inode
写回一个索引节点、put_super
卸载一个给定超级块、statfs
文件系统的挂载信息、remount_fs
重新挂载文件系统;
索引节点对象
- 与文件一一对应,包含命名文件处文件名和实际数据外所有信息,如所有者、组、权限、文件访问时间等;
- 包含描述 VFS 能在该索引节点上调用的文件系统实现函数的索引节点操作对象,如
create
、lookup
、mkdir
;
目录项对象
- 是路径上特定组成,要么是目录名,要么是文件名,为访问文件和目录提供了方便;
- 包括一个指向索引节点的指针和超级块,还包括一个指向父目录的指针和指向子目录的指针;
文件对象
- 代表一个进程打开的文件,==在系统调用
open ()
时创建,在close ()
时销毁==; - 包含以下数据项:
- 与文件关联的目录项对象;
- 包含该文件的文件系统;
- 文件对象使用计数;
- 用户 ID;
- 用户组 ID;
- 文件指针:指向下一个文件操作的位置;
- 包含一个描述 VFS 能在该文件对象上调用的文件系统实现函数的操作对象,其中有函数:
read
、write
、open
、release
、lock
;
缓存
VFS 有三个缓存提高性能:
- 索引节点缓存:存储最近访问过的索引节点;
- 目录缓存:存储完整目录名称和它们索引节点号之间的映射,能够加快列出目录的过程;
- 缓冲区高速缓存:是独立于文件系统的 Linux 内核使用分配和读写数据缓冲区的机制