文件系统结构(File System Structure)
磁盘提供大量的外存空间来维持文件系统。磁盘的下述两个特点使得其成为存储多个文件的方便介质。
- ①能够原地重写。
- ②能够直接訪问磁盘上的随意一块信息。
为了提供对磁盘的高效且便捷的訪问,操作系统通过文件系统来轻松地存储、定位、提取数据。
文件系统有两个设计问题。
- ①定义文件系统对用户的接口
- ②创建数据结构和算法来将逻辑文件系统映射到物理外存设备上。
文件系统本身通常由不同的层组成。例如以下图所看到的的是一个分层设计的简单样例。
- I/O控制
- 由设备驱动程序和中断处理程序组成,实现内存与磁盘之间的信息传递
- 基本文件系统
- 向合适的设备驱动程序发送一般命令就可对磁盘上的物理块进行读写
- 文件组织模块
- 知道文件及其逻辑块和物理块。
- 空暇空间管理器
- 逻辑文件系统
- 管理元数据:文件系统的全部结构数据。而不包含实际数据(或文件内容)
- 依据给定符号文件名称来管理文件夹结构
- 逻辑文件系统通过文件控制块(FCB)来维护文件结构
FCB的典型结构例如以下图所看到的
文件系统实现(File System Implementation )
实现文件系统要使用多个磁盘和内存结构。
尽管这些结构赢操作系统和文件系统而异,可是还是有其规律性的。
实现文件系统的结构和操作例如以下:
- 磁盘结构。
- 内存中的文件系统结构;
- 分区与安装
- 虚拟文件系统
磁盘结构
- 引导控制块(卷)(boot control blockVolume)
- 包含启动OS的控制信息
- UFS 中称为引导块(boot block )
- 通常为分区的第一块。假设该分区没有OS。则为空
- NTFS中称为分区引导扇区(partition boot sector)
卷控制块(卷)( Volume control block (/volume))
- 包含卷的具体信息,包含
- 块数和块的大小;
- 空暇块的数量和指针;
- 空暇FCB的数量和指针。
- UFS称为超级块 Superblock 。 NTFS 称为 主控文件表master file table 。
- 包含卷的具体信息,包含
文件夹结构
- 用来组织文件
- UFS 。包含文件名称和关联的inode 号
- NTFS,主控文件表(master file table );
- 文件控制块(FCB):包含非常多文件信息。如文件许可、拥有者、大小和数据块的位置等,详情见上文演示样例。
- UFS中, 索引节点( inode) ;
- NTFS中,主控文件表;
- 採用关系数据库结构, 记录/文件
内存中的文件系统结构
- 安装表
- 包含全部安装分区的信息
- 文件夹结构快表
- 保存近来訪问过的文件夹信息(对安装分区的文件夹,能够包含一个指向分区表的指针)
- 系统范围的打开文件表
- 包含每一个打开文件的FCB拷贝和其它信息
- 单个进程的打开文件表
- 包含一个指向系统范围内已打开文件表中合适条目和其它信息的指针
- 文件描写叙述符(file descriptor, Linux/UNIX)
- 文件句柄(file handle, Windows)
- 包含一个指向系统范围内已打开文件表中合适条目和其它信息的指针
下图总结了文件系统实现的 操作结构。
分区与安装
磁盘布局赢操作系统而异。一个磁盘可分成多个分区,或者一个卷能够跨越多个磁盘上的数个分区。
分区能够是“生的”(raw)。即没有文件系统,或是“熟的”(cooked)即含有文件系统。
生的分区用于没有合适文件系统的地方。
如:Unix中的交换区,由于它不使用文件系统而是使用自己的磁盘格式。
引导信息能存在各个分区中。而且有自己的格式。由于在引导时,系统并没有文件系统设配驱动程序,所以不能解释文件系统格式。
它通常为一组有序块而且作为二进制镜像文件读入内存。
引导信息除了包含怎样启动一个特定操作系统外。还能够有其它指令。(如BootManager bootstar 8.3,Linux GRUB, GRUB - GRand Unified Bootloader)
根分区(root partition)包含操作系统内核或其它系统文件,在引导时装入内存。
其它分区依据不同操作系统能够在引导时自己主动装入或在此之后手动装入。
- /root, /boot
- 文件系统安装表(file system mount table)
虚拟文件系统
- 虚拟文件系统(VFS)提供了一种面向对象的方法来实现文件系统
- VFS功能
- 通过定义VFS 接口将一般文件系统操作与实现分离;
- 为网络中唯一表示一个文件提供一种机制(by vnode)
- VFS同意在不同类型的文件系统上採用同样的系统调用接口(API)
- API是针对VFS的接口,而非对不论什么特定类型的文件系统
第一层为文件系统接口,包含。open()、read()、write()和close()调用以及文件描写叙述符。
第二层称为虚拟文件系统(VFS)层,它有两个目的:
- VFS层通过定义一个清晰的VFS接口,以将文件系统的通用操作和具体实现分开。多个VFS接口的实现能够共存在同一台机器上,它同意訪问已经装再本地的多个类型的文件系统
- VFS提供了在网络上唯一标示一个文件的机制。
文件夹实现(Directory Implementation)
文件夹分配和文件夹管理算法的选择对文件系统的效率、性能和可靠性有非常大的影响。
线性列表
最为简单的文件夹实现方法是使用存储文件名称和数据块指针(数组、链表等)的线性列表,这样的方法编程简单可是执行时较为费时。
文件夹条目的线性列表的真正缺点是採用线性搜索来查找特定条目。
其实,很多操作系统採用软件缓存来存储近期訪问过的文件夹信息。缓存命中避免了不断地从磁盘读取信息,排序列表能够使用二分搜索。并降低平均搜索时间。
Hash表
採用Hash数据结构的线性表
- 降低了文件夹搜索时间。插入和删除也较为简单。
- 只是须要一些机制来避免碰撞(两个文件名称哈希到同样的位置)
哈希表的最大困难是:其固定的大小和哈希函数对大小的依赖性
分配方法(Allocation Methods)
- 目标
- 有效使用磁盘空间;
- 高速訪问文件。
- 经常使用的分配方法有下面三类
- 连续分配
- 链接分配
- 索引分配
连续分配 (contiguous allocation)
连续分配方法要求每一个文件占领磁盘上的一组连续的块。
特点:
- 简单 - 仅仅须要记录文件的起始位置(块号)及长度。
- 訪问文件非常easy,所需的寻道时间也最少
- 顺序訪问。
- 直接訪问。
- 存在的问题
- 为新文件找空间比較困难
- 首次,最佳,最差
- 文件非常难增长
- 为新文件找空间比較困难
逻辑地址到物理地址的映射方法例如以下:
- 逻辑地址 / 块大小 = 商, 余数
LA512=Q⋅⋅⋅⋅⋅⋅R
訪问的块 = Q + 起始地址(base)
块中的位置 = R
基于扩展的连续分配方法:
- 很多新的文件系统採用一种修正的连续分配方法
- 扩展是一个连续的磁盘块
- 文件分配时,将扩展分配给文件
- 还有一个大的连续空间
- 一个文件包含一个或多个扩展
- 须要一个指向下一个扩展的指针
- 文件块的位置就成为開始地址、块数、加上一个指向下一扩展的指针。
- 分配磁盘块时。在扩展中进行
链接分配 (linked allocation)
链接分配攻克了连续分配的全部问题。
採用链接分配。每一个文件是磁盘块的链表:
- 磁盘块分布在磁盘的不论什么角落。
- 每一个文件夹条目都有一个指向文件第一块的指针。
- 该指针初始化为 nil (表尾指针的值)以标识空文件。
- 长处:
- 简单 - 仅仅需起始位置
- 文件创建与增长easy
- 缺点:
- 不能随机訪问
- 块与块之间的链接指针须要占用空间
- 簇:将多个连续块组成簇。磁盘以簇为单位进行分配
- 存在可靠性问题
文件分配表(FAT)
每一个分区的開始部分用于存储该FAT表。
每一个磁盘块在该表中有一项,该表能够通过块号来索引。
文件夹条目中含有文件首块的块号码。
依据块号码索引的FAT条目包含文件下一块的地号码。
这样的链会一直继续到最后一块,该块相应FAT条目的值为文件结束值。未使用的块用0值来表示。
为文件分配一个新的块仅仅要简单地找到第一个值为0的FAT条目。用新块的地址替换前面文件结束值。用文件结束值替代0。
假设不正确FAT採用缓存,FAT分配方案可能导致大量的磁头寻道时间。但通过读入FAT信息。磁盘能找到不论什么块的位置,从而实现随机訪问。
索引分配(indexed allocation)
- 将全部的数据块指针集中到索引块中
- 索引块中的第i个条目指向文件的第i块。
- 文件夹条目包含索引块的地址
- 每一个文件都有索引块。
- 磁盘块地址的数组
- 索引分配支持直接訪问,且没有外部碎片问题
- 索引块本身可能会浪费空间
- 链接方案:一个索引块通常为一个磁盘块。对于大文件。能够将多个索引块链接起来。
- 多层索引:相似于内存的间接寻址方式(一级、二级间接…)
空暇空间管理(Free-Space Management )
位向量(Bit vector)(n块)
- bit[i] = 1
→ block[i]空暇- bit[i] = 0
→ block[i]被占用
第一个空暇块号:
- 位向量须要额外的空间
- 设块大小为
212 字节 - 磁盘大小为
230 字节 (1GB) - N =
230/212=218 (即32K bytes)
- 设块大小为
- easy得到连续的文件
- 分配与回收过程
- 分配过程
- 回收过程
空暇表法
链表(空暇链表)
将全部空暇磁盘块用链表连接起来,并将指向第一空暇块的指针保存在磁盘的特殊位置,同一时候也缓存在内存中。
不易得到连续空间
没有空间浪费
分组(成组链接)
- 将n个空暇块的地址存在第一个空暇块中;
- 最后一块包含另外n个空暇块的地址。
成组链接图例如以下所看到的
- 分组(成组链接)
- 分配与回收过程
- 分配过程
- 回收过程
- 所需的保护
- 指向空暇表的指针
所需的保护
- 位映射
- 必须保存在磁盘上
- 内存中的副本可能与磁盘上不同样;
- 对于 block[i]不同意出现的情形:在内存中 bit[i] = 1。而在磁盘上 bit[i] = 0 。
- 解决方法
- 设置磁盘上bit[i] = 1
- 分配block[i]
- 设置内存中 bit[i] = 1
效率和性能(Efficiency and Performance)
效率
效率依赖于
- 磁盘分配与文件夹算法
- 预分配,簇
- 文件文件夹项中保存的数据的类型
- 近期写/訪问日期
- 指针大小
212,232,264,2128
性能
性能有例如以下几点:
- 磁盘缓冲 - 将近期使用过的块放在内存的某个地方
- 立即释放与预先读取 - 优化顺序訪问
- 留出一块内存作为虚拟磁盘(或RAM磁盘)来提高个人计算机的性能
页缓存(page cache)
- 页缓存使用虚拟内存技术,以将文件数据作为页而不是面向文件系统的块来缓存。
- 内存映射I/O使用了页缓存
- I/O通过文件系统再使用缓冲缓存
无统一缓冲缓存的I/O例如以下图所看到的
採用了统一缓冲缓存的I/O则变化例如以下
不同的磁盘缓存位置
恢复(Recovery)
- 一致性检查 - 比較文件夹中的数据与磁盘中的数据块,以消除不一致性
- 使用系统程序将数据从磁盘备份到其它存储设备(如磁盘,磁带)
- 增量备份
- 从备份上恢复数据以恢复丢失的文件或磁盘
结构化日志的文件系统(Log-Structured File Systems)
- 每一个更新作为事务记录。
- 全部的事务写到日志中
- 一旦写到日志中,就认定为确认的提交;
- 可是FS能够不更新。
- 事务异步写到FS中
- 当FS改动后,事务从日志中删除
- 假设FS崩溃。在日志中的全部事务都要执行