操作系统6-文件系统

文件系统

概述

文件

文件中常保存的信息:

  • 基本信息:文件名、文件类型、文件组织
  • 地址信息:卷、起始地址、使用大小、分配大小
  • 访问控制信息:所有者、访问信息、许可的行为
  • 使用信息:数据创建、创建者身份、最后一次读 访问的日期、最后一次读用户的身份、最后一次 修改的日期、最后一次修改者的身份、最后一次 备份的日期、当前使用

文件(file)的属性

  • 长期存在:文件存储在硬盘或其他辅存中,用户退出 系统时文件不会丢失
  • 进程间共享:文件有名字,具有允许受控共享的 相关访问权限
  • 结构化:取决于具体的文件系统,一个文件具有针对某 个特定应用的内部结构

文件系统

文件系统(file system)是操作系统的重要组成部分 ,允许用户创建成为文件的数据集;

文件类型

  • 按用途分类:系统文件/用户文件/库文件
  • 按数据形式分类:源文件/目标文件/可执行文件
  • 按存取控制属性分类:只执行文件/只读文件/读写文件
  • 按组织和处理方式分类:普通文件/目录文件/特殊文件

文件系统模型

  • 管理对象:文件,目录,磁盘存储空间
  • 对象操作和管理的软件集合:实现文件系统的功能
  • 文件系统接口:命令接口/程序接口

文件操作

文件系统不但提供存储数据(组织为文件)的手段,而且 提供一系列对文件进行操作的功能接口。

  • 创建文件
  • 删除文件
  • 打开文件
  • 关闭文件
  • 读文件,写文件
  • 截断文件
  • 设置文件读写位置…

组织结构

文件结构

文件:具有文件名的一组相似记录的集合

  1. 域:基本的数据单元,一个域包含一个值,定长或变长
  2. 记录:一组相关域的集合,定长或变长,通常包含长度域

逻辑结构:从用户观点出发所观察到的文件组织形式,是用户可 以直接处理的数据及其结构,它独立于文件的物理特 性,又称为文件组织。

物理结构:指文件在外存上的存储组织形式。

文件系统架构

  • 设备驱动:程序直接和外围设备或其通道通信,驱动负责启动设备上的IO操作,处理IO请求的完成
  • 基本文件系统:物理IO层,处理磁盘间交换的数据块,操作系统关注这些块在辅存和缓冲区的位置
  • 逻辑IO:使得用户程序能访问记录,记录必须组成块进行IO操作
  • 文件组织:用户访问文件的方法

文件组织

堆是最简单的文件组织形式

  • 数据按它们到达的顺序被收集。
  • 堆的目的仅仅是积累大量的数据并 保存
  • 堆文件没有结构,堆对记录的访问是通过穷举查找方式进行的。

顺序文件

  • 每条记录都使用一种固定的格式
  • 所有记录都具有相同的长度 由相同 ,并且 数量、长度固定的域按特定 顺序组成
  • 每个域的域名和长度是该文件结构 的属性。
  • 关键域是记录的唯一标识,记录按关键域来存储

在顺序文件中,逻辑记录的顺序:

  • 串结构:按照记录录入的时间排序
  • 按关键字排序:有利于提高查询速度

对顺序文件的读写:

  • 定长记录:易于定位,可随机读取
  • 变长记录:不易定位,只能顺序读取
  • 维护一个日志文件log:用于存放将更新到主文件的记录 。

优点:

  • 批处理时效率是所有逻辑文件中最高的
  • 可存在于磁带上

缺点:

  • 交互应用时“效率低”(如要查找单个记录),尤其 是对变长记录的顺序文件。
  • 增加、删除记录涉及到排序问题,开销大。

索引顺序文件

索引顺序文件是克服顺序文件缺点的常用办法

  • 保留顺序文件的关键特征:记录按照关键域的顺序组织
  • 用于支持随机访问的文件索引:提供了快速接近目标 记录的查找能力
  • 溢出文件:类似于顺序文件中使用的日志文件,但溢 出文件中的记录可根据它前面记录的指针进行定位

image-20241208215304798

检索文件:

  1. 利用用户(程序)所提供的关键字以及某种查找 算法去检索索引表
  2. 找到该记录所在记录组中第一个 记录的表项,从中得到该记录组第一个记录在主文件 中的位置。
  3. 再利用顺序查找法去查找主文件,从中找到所要求的 记录。

对于有N条记录的顺序文件中,设定一个M项的索引文件,索引的关键域均匀分布在主文件中,找到某条记录平均需要在索引文件中访问O(M/2)次,在主文件平均访问O(N/2M)次,索引顺序文件组织的开销为O(M/2+N/2M), 顺序文件组织查找某条记录平均开销为O(N/2);

索引文件

顺序文件和索引顺序文件都只允许按记录的唯一关键字检索记 录,这不符合某些应用需要按多个字段检索记录的要求;

采用多索引的结构,成为查找条件的每个域都可能有一个索引;

  • 完全索引:包含主文件中每条记录的索引项
  • 部分索引:只包含那些有感兴趣域的记录的索引项

特点:

  • 建立有序的索引表,查找很快,提高了速度,增加了存储开销(索引文件);
  • 增、删记录时,对索引表作相应的修改

note:有时删除文件可能只是删除了其索引,这也是利用某些软件可以找回删除文件的原因;

image-20241208222417285

直接或散列文件

而对于直接文件,则可根据给定的记录键值,直接获 得指定记录的物理地址。换言之,记录键值本身就决 定了记录的物理地址。

这是目前应用最为广泛的一种直接文件,它利用Hash 函数(或称散列函数),可将记录键值转换为相应记录的 地址。

存储空间管理

文件分配方法

连续分配: 连续分配是指在创建文件时,给文件分配一组连续的块。 以该方式管理的文件称为连续文件,可采用紧缩技术整理;

  • 优点:简单、容易实现,对于顺序文件,能很快检索文件中的数据块,连续读/写 多个数据块内容时,性能较好。
  • 缺点:它不利于文件尺寸的动态增长,该分配方案可能会导致磁盘碎片,严重降低外存空间的 利用率。

链式分配:为文件分配非连续的若干数据块,数据块之间用指针相连,,以该方式管理的文件称为链接 文件,包含隐式链接和显式链接;

  • 隐式链接:在文件目录的每个目录项中都须含有指向链接文件第一 个盘块和最后一个盘块的指针,文件目录表中有start块号,每块中有下一块号;只适合于顺序访问,对随机访问效率低,可靠性差
  • 显式链接:把用于链接文件各物理块的指针,显式地存放在内存 的一张链接表中(整个磁盘仅设置一张)。查找在内存中进行,由于分配给文件的所有盘块号都放在该表中,故把该 表称为文件分配表FAT(File Allocation Table);
  • 优点:链接分配技术不要求文件存储到彼此相邻的数据块中, 消除连续分配引起的碎片,提高了外存空间的利用率。能适应文件尺寸的动态增长
  • 缺点:对于随机存取却相当低效,局部性原理不再适用;

索引分配:每个文件在文件分配表中存在一个一级索引,文件每个分区在索引上都有一个表项

空闲空间管理方法

  1. 位示图法:

    • 每一位对应一个磁盘 块。位的值为0或1,分别表示磁盘块空闲,或磁盘块已分配;

    • 利用位表容易找到一个或一组空闲盘块  位表适合于以上各种文件分配方法 ;

    • 位表很小,可以装入内存;

  2. 链接空闲区

    • 每个空闲分区包含一个指向下一个分区的指针,并 记载分区大小
    • 无空闲分区表空间开销
    • 适合于各种文件分配方法
    • 若每次分配一个磁盘块,则可取空闲分区链的第一 个盘块进行分配,并调整空闲分区链首指针和分区 链大小
    • 若采用可变分区法,可用首次适应算法,从链表头 开始查找,找到的第一个适合的分区则可分配,然 后调整空闲分区链首指针和分区链大小
  3. 索引

    • 将空闲分区视为文件,按文件存储空间分配法为空 闲分区建立索引
    • 索引表中为每一个空闲分区建立一个索引项
    • 为可变分区建立索引比为磁盘块建立索引效率高
    • 适合于各种文件分配法
  4. 空闲块列表

    • 在这种方法中,每块都指定一个序号,所有空闲 块的序号保存在磁盘的一个保留区中。
    • 两种有效技术把该表一小部分保存到内存中:将表看作堆栈/FIFO队列;

文件目录管理

文件目录

有的 系统将其中部分信息保存在文件头部,只将一些 必要信息如文件名、文件大小、外存中的存储位 置等保存在文件目录中;

典型操作: 查找、创建文件、删除 文件、显示目录、修改目录

管理要求:实现“按名存取”,提高对目录的检索速度,文件共享,允许文件重名

文件控制块和索引结点

文件控制块(file control block, FCB):用于描述和控制文件的数据结构,用于记载文件 在内存中的使用情况;

  • 基本信息类:文件名,文件物理位置,文件逻辑结构,文件的 物理结构
  • 存取控制类信息:权限
  • 使用信息:记录信息,如日期等

索引结点:包含文件描述信息,把文件名与文件描述信息分开,在文件目录中的每个 目录项仅由文件名和指向该文件所对应的 i 结点的指 针所构成。目录结构

  • 磁盘索引结点:包含文件主标识,文件类型,文件存取权限,物理地址,文件长度,连接(共享)计数,存取时间等;
  • 内存索引结点:文件打开后,将磁盘索引结点的内容部分或全部子集 拷贝到内存,并增加以下内容:编号,状态,共享计数,逻辑设备号,链接指针

目录结构

  1. 单级目录结构:所有用户的全部文件目录保存在一张目 录表中,每个文件的目录项占用一个表项,目录项中主要记载的信息有:文件名及扩展名,文件 的物理地址,其它属性,如文件长度、建立日期、文 件类型等

    优点:简单且按名存取

    缺点:查找速度慢,不允许重名,不便于实现文件共享;

  2. 两级目录结构:每一个用户建立一个单独的用户文件目录UFD,再 建立一个主文件目录MFD。在主文件目录中,每个用 户目录文件都占有一个目录项,其目录项中包括用户 名和指向该用户目录文件的指针

    优点:提高了检索目录的速度,在不同的用户目录中,可以使用相同的文件名,不同用户还可使用不同的文件名来访问系统中的同 一个共享文件

  3. 树型目录结构:

    主目录在这里被称为根目录,把数据文件称为树叶, 其它的目录均作为树的结点

    路径名:从树的根(即主目录)开始,把全部目录文件名与数 据文件名,依次地用“/”连接起来,即构成该数据文件 的路径名

    工作目录:即当前目录,进程对各文件的访问都相对于“当前目录”而进行, 通常称为相对路径。

增加目录:在用户要创建一个新文件时,只需查看在自己的 UFD及其子目录中,有无与新建文件相同的文件名。 若无,便可在UFD或其某个子目录中增加一个新目 录项。

删除目录:例如Linux中,不删除非空目录rmdir如果该目录内包含文件或子目录,系统会拒绝执行删除操作,可删除非空目录rm -r在尝试删除一个目录时,即使该目录内包含文件或子目录,系统也会允许执行删除操作

目录查询技术

过程:文件名-目录项(FCB)或索引结点-盘块号-启动磁盘-驱动程序

例如查询:/usr/ast/mbox

  • 根中得usr的索引结点号6
  • 6中得usr目录文件为132#
  • 132#中得/usr/ast的索引结点是26
  • 26中的/usr/ast目录文件中406#
  • 406#中得/usr/ast/mbox的索引结点是60
  • 60中得/usr/ast/mbox的物理地址

FAT文件系统

早期的MS-DOS采用FAT12,后演变为FAT16,在windows95和98中升级成FAT32;

FAT12:以盘块为基本分配单位,每个分区设置两张文件分配表FAT1,FAT2,系统设置文件分配表FAT,在 FAT 的每个表项中存放下一个盘块号;当达到文件尾的时候,存入0xFFF,标志结束

  • 为了适应更大容量的磁盘,因而以簇为单位进行分配, 簇越小磁盘浪费的空间就越小;
  • 簇一般由2n个盘块组成,与扇区的数量、磁盘容量的大小 直接有关
  • 对所允许的磁盘容量存在着严重的限制,虽然可以用继续增加簇的大小来提高所允许的最大磁 盘容量,但随着支持的硬盘容量的增加,相应的簇内 碎片也将随之成倍地增加。

image-20241209140316205

FAT16: FAT 表的宽度增至16 位,最大表项数将增至$2^{16}$个 ,此时便能将一个磁盘分区分为$2^{16}$个 簇。可以管理的最大分区空间为(1<<16 )×64 ×512B = 2048 MB

  • 当磁盘容量迅速增加时,如果再继续使用FAT16, 由此所形成的簇内碎片所造成的浪费也越大。(簇越 大,一般磁盘的碎片就越多

FAT32: FAT32保留扇区的数目默认为32个而不是FAT16的1个

  • FAT32的根目录等同于普通的文件;
  • 根目录储在分区内可 寻址的任意簇内,不过通常根目录是最早建立的
  • 根目录下的所有文件及其子目录在根目录的文件目录表 FDT中都有一个“目录项”,系统以32个字节为单位进 行目录文件所占簇的分配,因此32个扇区的根目录FDT 最多可以记录32*512/32=512个文件或子目录。
  • DATA区是实际的文件和目录数据存储的区域,它占据 了分区的绝大部分。 每个簇只能被一个文件占有,因而常常文件的尾部会出 现不可利用的空间,所以簇越大,文件数目越多时,零 头就越多,造成资源浪费,因此簇的大小不应该太大。FAT32采用4KB的簇的大小。
  • 不能采用太小的单位进行分配。如采用大小为512B的 扇区管理会增加FAT表的项数,对大文件存取增加消耗 ,文件系统效率不高

文件系统格式化

  • 格式化程序并没有把DATA区的数据清除,只是重写了 FAT表而已,至于分区硬盘,也只是修改了MBR和 DBR,绝大部分的DATA区的数据并没有被改变;
  • 因而 进行上述操作后,数据仍然可以得到恢复

image-20241209150412186

NTFS文件系统

  • 使用了64 位磁盘地址;
  • 很好地支持长文件名;
  • 具有系统容错功能;
  • 提供了数据的一致性;

磁盘组织:以簇作为磁盘空间分配和回收的基本单位,卷上簇的大小称为“卷因子”(一个簇包含2n个 盘块),对于簇的定位,采用逻辑簇号LCN和虚拟簇号VCN进行的。

文件组织:在NTFS 中,以卷为单位,将一个卷中的所有文件信 息、目录信息以及可用的未分配空间信息,都以文件 记录的方式记录在一张主控文件表MFT中。卷中的每个文件作为一条记录,在MFT 表中占有一行, 其中还包括MFT 自己的这一行。每行大小固定为1 KB,每行称为该行所对应文件的元数据(metadata), 也称为文件控制字。 NTFS 文件不能被FAT 等文件系统所存取,缺乏兼容性。文件通过主文件表(MFT)来确定其在磁盘上的存储 位置。主文件表是一个对应的数据库,由一系列的文 件记录组成–卷中每一个文件都有一个文件记录(对于 大型文件还可能有多个记录与之相对应)。NTFS卷上的每个文件都有一个64位(bit)称为文件引 用号(File Reference Number,也称文件索引号)的 唯一标识。文件引用号由两部分组成:一是文件号, 二是文件顺序号。NTFS使用逻辑簇号(Logical Cluster Number,LCN)和 虚拟簇号(Virtual Cluster Number,VCN)来进行簇的定 位。LCN是对整个卷中所有的簇从头到尾所进行的简单编 号。VCN则是对属于特定文件的簇从头到尾进行编号,以 便于引用文件中的数据。VCN可以映射成LCN,而不必要 求在物理上连续。

文件系统结构:

  • 启动扇区文件$BOOT位于磁盘头部,$BOOT中包含 MFT的位置数据。
  • 主文件表索引的第一个文件为$MFT。主文件的每一个 表项表示一个文件索引,每个文件索引由一系列的属 性组成。

image-20241209151442406

NTFS元文件: MFT的前16个元数据文件非常重要,为了防止数据的丢失, NTFS系统在该卷文件存储部分的正中央对它们进行了备份。

  • MFT中的第1个记录就是MFT自身;
  • 由于MFT文件本身 的重要性,为了确保文件系统结构的可靠性,系统专门 为它准备了一个镜像文件$MftMirr,也就是MFT中 的第2个记录。
  • 第3个记录是日志文件$LogFile。该文件是NTFS为 实现可恢复性和安全性而设计的。当系统运行时NTFS 就会在日志文件中记录所有影响NTFS卷结构的操作, 包括文件的创建和改变目录结构的命令,例如复制,从 而在系统失败时能够恢复NTFS卷。
  • 第4个记录是卷文件$Volume,它包含了卷名、被 格式化的卷的NTFS版本和一个标明该磁盘是否损坏的 标志位。
  • 第5个记录是属性定义表$AttrDef,其中存放了卷所支持的所有文件属性, 并指出它们是否可以被索引和恢复等;
  • 第6个记录是根目录(\),其中保存了存放于该卷根目 录下所有文件和目录的索引。在访问了一个文件后, NTFS就保留该文件的MFT引用,第二次就能够直接进 行对该文件的访问
  • 第7个记录是位图文件$Bitmap。NTFS卷的分配状 态都存放在位图文件中,其中每一位(bit)代表卷中的 一簇,标识该簇是空闲的还是已被分配了的,由于该文 件可以很容易的被扩大,所以NTFS的卷可以很方便的 动态的扩大,而FAT格式的文件系统由于涉及到FAT表 的变化,所以不能随意的对分区大小进行调整。
  • 第8个记录是引导文件$Boot,它是另一个重要的 系统文件。
  • 第9个记录是坏簇文件$BadClus,它记录了磁盘上 该卷中所有的损坏的簇号,防止系统对其进行分配使用。
  • 第10个记录是安全文件$Secure,它存储了整个卷 的安全描述符数据库。NTFS文件和目录都有各自的安 全描述符,为了节省空间,NTFS将具有相同描述符的 文件和目录存放在一个公共文件中。
  • 第11个记录为大写文件$UpCase, 该文件包含一个大小写字符转换表。
  • 第12个记录是扩展元数据目录$Extended metadata directory
  • 第13个记录是重解析点文件$Extend\$Reparse

image-20241209151929072

Linux文件系统

Linux是一个unix类操作系统,用EXT2文件系统结构,以下是查找文件的过程

  1. 当访问一个文件时,通过文件名在“目录表”中查到 其“索引节点号”。
  2. 通过“索引节点号”查“索引节点表”。
  3. 通过“索引节点表”得到其“索引节点”;
  4. 通过索引节点得到文件数据所在位置

EXT2文件系统的物理结构:整个盘卷由多个数据块组构成。一个数据块代表一个 文件系统

  • 超级块:存储着描述文件系统大小和形状的基本信息;
  • 组描述符:描述它的数据结构。(块位图大小、索引节 点位图大小、索引节点表大小、空闲块数、空闲索引节 点数、已用目录数等重要信息);
  • 块位图:描述了该块组中数据块空间的使用情况,在数 据块分配和数据块撤销时使用;
  • 索引节点位图:描述了该块组索引节点表所占空间的信 息,在索引节点的分配和撤销中使用;
  • 索引节点表:记录了本块组中索引节点集合;
  • 数据块:用于存放文件数据;

image-20241209152202486

EXT2的目录

  • 一个文件对应有一个目录项;
  • 目录项包含该文件对应的索引节点号、文件名、名字 长度等信息;
  • 目录是一些特殊的文件,称为目录文件,其中包含了 该目录下所有文件的目录项集合。

image-20241209152534513

EXT2的索引节点

  • Mode:用户拥有的权限r,w,e
  • Owner Information:文件或目录所有者的用户和组标 识符
  • Size:文件大小
  • Timestamps:索引节点建立的时间和索引节点最后修 改的时间
  • Data blocks:描述文件的数据块

image-20241209152648940

文件控制块

  • 当打开一个EXT2文件时,把要打开文件的管理控制信 息从辅存的目录项和索引节点中读到内存,形成FCB, 并将该FCB的地址以一个文件描述符(FD)的形式返 回给用户进程;
  • 根据FD可获得文件的描述信息,通过这些信息用户可对实际物理文件进行操作

linux的虚拟文件系统VFS: 将实际的文件系统 的数据结构转换成统一的内存VFS的数据结构来兼容多种 文件系统类型

  • 数据缓存:任何一个从块设备中读取的数据块或者往块设备中写 入的数据块都要通过缓存,缓存中的数据块是以拥有此数据块的设备的设备标识 符和缓冲区的块号来唯一标识的;

    1. 空闲的缓冲区链表
    2. 非空闲的缓冲区:由指针数组构成的散列表, 散列表中hash值由设备的标识符和数据块的块号产生 的,表中的指针指向具有相同hash值的缓冲区。

    image-20241209153612426

    缓冲区的状态类型:clean,locked,dirty,shared, unshared

    bdflush守护进程: 使用bdflush内核守护进程来完成缓存管理,在系统启动时作为一个系 统的线程运行,在大部分时间中,此守护进程都处 于睡眠状态,等待系统中被改动的数据块缓冲区的 数量增大到一定的值,bdflush守护进程将被唤醒,任务是当缓存中被改动的缓 冲区数量太多时,提供一个管理功能

  • 索引结点缓存:索引节点缓存可以加快对系统中文件的存取,使用散列表实现,表项的hash值是通 过索引节点号和存储文件系统的物理设备号计算出来的, 各表项指向具有相同hash值的VFS索引节点链表的指针。

    操作:如果系统在索引节点缓存中找到索引节点,那么此索 引节点的计数器将加1,表明又有一个进程在使用该 索引节点。否则,系统必须申请一个空闲的VFS索引 节点,系统读取该索引节点到内存缓存。如果系统已经没有可分配的空闲索引节点时,那么必 须查找一个已用的索引节点,将那些用户计数器为0 的索引节点重新分配(说明系统中没有任何进程正在 使用这些索引节点),一些非常重要的索引节点,如文件系统的根目录索引 节点,它们的索引节点计数器总是大于0,以保证永 远不能被重新分配。不论用什么方法找到一个新的索引节点,系统都必须 调用一个特殊的子程序来把实际文件的信息添加到此 索引节点中。当向新的索引节点中写入信息时,锁定此索引节点, 将索引节点计数器置为1,直到索引节点中的信息写完 后,再解锁。如果它被锁定时,则其他需要访问该索引节点必须等 到解锁后才能进行。

  • 目录缓存:为了加速对常用目录的存取, VFS维护一个两层LRU目录 缓存链表。 目录缓存包括一个散列表, 表的hash值由设备号和目录 名来计算,每个表项指向具 有相同hash值的目录缓存链 表的指针。当读取一个目录时,目录的 详细信息将添加到目录缓存 中

    image-20241209153555479