文件系统
前言
文件系统提供了在线存储和访问包括数据和程序在内的文件内容的机制,文件系统(构建在I/O设备上的专有系统)永久地驻留在外存上,外存可以永久存储大量数据。
一、 文件系统结构
- 磁盘提供大量的外存空间来维持文件系统,磁盘的两个特点,使其称为存储多个文件的方便介质:
i. 可以原地重写,可以从磁盘上读一块,修改该块,并将它写回到原来的位置
ii. 可以直接访问磁盘上的任意一块信息。因此可以方便地按顺序或随机地访问文件,从一个文件切换到另一个文件只需要简单地移动读写磁头并等待磁盘转动即可以完成 - 为了改善I/O效率,内存与磁盘之间的I/O转移是以块为单位而不是以字节为单位来进行的。(每块为一个或多个扇区,扇区大小32~4096B,通常为512B)
- 为了提供对磁盘的高效且便捷地访问,操作系统通过文件系统来轻松地存储、定位、提取数据
- 文件系统的两个设计问题:
i. 如何定义文件系统对用户的接口
ii. 创建数据结构和算法来讲逻辑文件系统映射到物理外存设备上 - 文件系统按层来进行组织(从上到下):
采用分层的结构实现文件系统,能够最大限度地减少重复的代码。相同的I/O控制代码可以被多个文件系统采用,每个文件系统有自己的逻辑文件系统和文件组织模块
文件的逻辑空间一定是连续的!进程不一定
文件系统包括硬件实现和软件实现,硬件部分包括设备(磁盘等存储装置)与设备控制器,软件部分包括设备驱动程序、中断处理程序、文件组织模块(即地址转换器)以及目录
i. 应用程序
ii. 逻辑文件系统:
管理元数据。元数据包括文件系统的所有结构数据,而不包括实际数据(或文件内容)。
逻辑文件系统根据给定符号文件名来管理目录结构,并提供给文件组织模块所需要的信息。
逻辑文件系统通过文件控制块来维护文件结构。
逻辑文件系统也负责保护和安全。
文件控制块(FCB)包含文件的信息,如拥有者、权限、文件内容的位置。
iii. 文件组织模块:
知道文件及其逻辑块和物理块。
可以将逻辑块地址转换成基本文件系统所用的物理块地址
文件组织模块也包括空闲空间管理器,用于跟踪未分配的块并根据要求提供给文件组织模块
iv. 基本文件系统:向合适的设备驱动程序发送一般命令就可对磁盘上的物理块进行读写。每个块由其数值磁盘地址来标识
v. I/O控制:
为最底层,由设备驱动程序和中断处理程序组成,实现内存与磁盘之间的信息传输
设备驱动程序用于接受低层命令,对DMA中的寄存器和磁盘控制器中寄存器进行访问
vi. 设备
二、 文件系统实现
(一)概述
- 在磁盘上,文件系统可能包括如下信息:
如何启动所存储的操作系统
总的块数
空闲块的数目和位置
目录结构以及各个具体文件等 - 磁盘结构包括:
i. (每个卷的)引导控制块:包括从该卷引导操作系统所需要的信息。
如果磁盘没有操作系统,那么这块的内容为空。
通常为卷的第一块
UFS称之为引导块,NTFS称之为分区引导扇区
ii. (每个卷的)卷控制块:UFS称之为超级块,在NTFS中它存储在主控文件表中
包括卷(或分区)的详细信息,如分区的块数、块的大小、空闲块的数量和指针、空闲FCB的数量和指针等
iii. 每个文件系统的目录结构用来组织文件
UFS中它包含文件名和相关的索引节点号,NTFS中它存储在主控文件表中
iv. 每个文件的FCB包括很多该文件的详细信息
如文件权限、文件日期(创建、访问、写)、文件所有者、组、访问控制列表(ACL)、文件大小、文件数据块或文件数据块指针
v. 内存中的结构:
内存分区表:包含所有安装分区的信息
内存目录结构:保存近来访问过的目录信息(对安装分区的目录,可以包括一个指向分区表的指针)
系统范围的打开文件表:包括每个打开文件的FCB拷贝和其他信息
单个进程的打开文件表:包括一个指向系统范围内已打开文件表中合适条目和其他信息的指针
访问打开文件表的索引叫做文件描述符或者文件句柄 - 打开文件:
i. 通过文件名在目录中找到文件的位置和相关信息
ii. 通过目录在辅助存储器中找到文件控制块,并对目录结构进行修改 - 读文件:
i. 通过索引(文件句柄)在当前进程打开的文件表中找到逻辑地址块
ii. 通过上文找到的逻辑地址块,通过系统范围打开的文件表找到对应的物理地址块
iii. 在辅助存储器中找到对应的数据块,通过文件控制块进行数据的传递
(二)分区与安装
- 分区可以是“生的”,即没有文件系统,或是“熟的”,即含有文件系统。生的分区用于没有合适文件系统的地方,如Unix中的交换区
- 引导信息能存在各个分区中,并且有自己的格式。它通常为一组有序块,作为二进制文件读入内存。引导信息除了包括如何启动一个特定操作系统外,还可以有其他指令
- 根分区包括操作系统内核或其他系统文件,在引导时装入内存。其他分区根据不同操作系统可以在引导时自动装入或在此之后手动装入
(三)虚拟文件系统
i. 虚拟文件系统(VFS)提供了一种面向对象的方法来实现文件系统
ii. VFS允许在不同类型的文件系统上采用同样的系统调用接口(API)
iii. API是针对VFS的接口,而非对任何特定类型的文件系统
三、 目录实现
- 线性列表(数组、链表等):存储文件名和数据块指针,
i. 编程简单运行费时
ii. 缺点:查找文件需要线性搜索
iii. 可以采用软件缓存来存储最近访问过的目录信息 - 哈希表:使用哈希数据结构的线性表
i. 减少了目录搜索时间
ii. 碰撞:两个文件名哈希到相同的位置
iii. 哈希表最大的困难是通常固定的大小和哈希函数对大小的依赖性
四、 分配方法
(一) 连续分配
- 每个文件占据磁盘上的一组连续的块
- 特点:
i. 简单,只需要记录文件的起始位置以及长度
ii. 访问文件很容易,所需的寻道时间也最少 - 存在的问题:为新文件找空间比较困难(类似于内存分配中的连续内存分配方式);文件很难增长
- 基于扩展的连续分配方案;
i. 许多新的文件系统采用一种修正的连续分配方案
ii. 该方法开始分配一块连续空间,当空间不够时,另一块被称为扩展的连续空间会添加到原来的分配中
iii. 文件块的位置就称为开始地址、块数、加上一个指向下一个扩展的指针
e) 存在外部碎片
(二) 链接分配(无对应的内存分配方案)
- 每个文件是磁盘块的链表;磁盘块分布在磁盘的任何地方。目录包括文件第一块和最后一块的指针
- 特点:
i. 简单,只需要知道起始位置
ii. 文件创建与增长很容易,不会产生外部碎片
iii. 无法随机访问,只能从文件开始处读起,不支持随机访问
iv. 块与块之间链接的指针需要空间
v. 存在可靠性问题,任何一个指针丢失或损坏会出错 - 簇:将多个连续块组成簇,磁盘以簇为单位进行分配
- 链接分配方法的变种——文件分配表FAT:
i. 每个分区的开始部分用于存储该FAT表
ii. 每个磁盘块在该表中有一项,该表可以通过块号来索引
iii. 目录条目中含有文件首块的块号码。根据块号码索引的FAT条目包括文件下一块的块号码。这种链会一直继续到最后一块,该块对应FAT条目的值为文件结束值。未使用的块用0值来表示
iv. 为文件分配一个新的块只要简单地找到第一个值为0的FAT条目,用新块地地址替换前面文件结束值,用文件结束值替代0
v. 如果不对FAT采用缓存,FAT分配方案可能导致大量的磁头寻道时间。但通过读入FAT信息,磁盘能找到任何块的位置,从而实现随机访问
(三) 索引分配
- 将所有数据块指针集中到索引块中
i. 索引块中的第i个条目指向文件的第i块
ii. 目录条目包括索引块的地址 - 索引分配支持直接访问,且没有外部碎片问题
- 索引块本身可能会浪费空间
i. 链接方案:一个索引块通常为一个磁盘块。对于大文件,可以将多个索引块来链接起来
ii. 多层索引:类似于内存的间接寻址方式(一级、二级间接……)
iii. 组合方案:如Unix的inode,实际上就是层次段表,或多级段表
iv. 普通的索引分配与内存分配的分页很像,因为磁盘实际上就是大小确定的块,因为大小确定,所以也会有一个类似于页表的情况。而拓展的索引分配与内存分配中的分段(注意不是分页,分页是分成了大小一致的块,分段式分成了大小不一的段!)有些类似,同样是有一个类似于段表的结构,然后通过段表的指针去找到文件,这是因为拓展的索引分配允许块与块之间进行合并与组合
五、 空闲空间管理
- 为了记录空闲磁盘空间,系统需要维护一个空闲空间链表,它记录了所有空闲磁盘空间,即未分配给文件或目录的空间(不一定以链表的方式实现)
- 位向量(n块):首先放在硬盘中(保证断电之后信息仍在),之后可以缓存到内存中去
i. 空闲空间表实现为位图或位向量,每一块用一位来表示,1表示空闲,0表示已分配
ii. 第一个空闲块的块号码计算:(值为0的字数)x(一个字的位数)+第一个值为1的位的偏移
iii. 位向量需要额外的空间来存储 - 链表(空闲链表):将所有空闲磁盘块用链表连接起来,并将指向第一空闲块的指针保存在磁盘的特殊位置,同时也缓存在内存中
i. 可以找到所有的空闲块,但找连续的空闲块会比较麻烦
ii. 没有浪费空间 - 分组(类似于索引方案):将n个空闲块的地址存在第一个空闲块中。这些块中的前n-1个确实为空,而最后一块包含另外n个空闲块的地址,如此继续。
- 计数(类似于连续的分配方案):通常,有多个连续块需要同时分配或释放。因此,可以记录第一块的地址和紧跟第一块的连续的空闲块的数量n。这样,空闲空间表的每个条目包括磁盘地址和数量
六、 效率与性能
- 效率依赖于:
i. 磁盘分配
ii. 目录管理算法
iii. 保留在文件目录条目(或索引节点)内的数据类型 - 性能:
i. 磁盘缓冲:将最近使用过的块放在内存的某个地方
ii. 优化顺序访问:马上释放与预先读取
iii. 留出一块内存作为虚拟磁盘(或RAM磁盘)来提高个人计算机的性能 - 页缓存:使用虚拟内存技术,以将文件数据作为页而不是面向文件系统的块来缓存
i. 内存映射I/O使用了页缓存
ii. I/O通过文件系统再使用缓冲缓存
七、 恢复
- 一致性检查:比较目录中数据与磁盘中的数据块,以消除不一致性
- 使用系统程序将数据从磁盘备份到其他存储设备(如磁盘、磁带),简单地讲,就是增加备份
- 从备份上恢复数据以恢复丢失的文件或磁盘