一、文件系统结构
为了提供对磁盘的高效便捷的访问,操作系统通过文件系统来轻松地存储、定位、提取数据。文件系统有两个不同的设计问题:1、如何定义文件系统对用户的接口,涉及到文件及其属性、文件允许的操作、组织文件的目录结构;2、创建数据结构和算法将逻辑文件系统映射到物理外存设备上。
目前有许多文件系统在使用。绝大多数操作系统都支持多个文件系统。
二、文件系统实现
实现文件系统需要应对多种磁盘和内存结构。
磁盘上,文件系统包括操作系统,总块数,空闲块数及位置,目录结构,具体文件等;
内存则用于进行文件系统管理、缓存以提高性能。打开一个文件,内存中的打开文件表则相应增加一个条目,反之剔除。调用open()返回该文件的指针,windows称之为 文件句柄(file handle)。
磁盘分区分为根分区和其他分区。根分区有操作系统内核或其他系统文件,在开机引导时装入内存。其他分区可以在引导时装入或之后手动装入。引导信息本身有自己的格式,但它并不能解释文件系统。系统的启动装载器首先装入引导信息,而后可以引导磁盘上的操作系统,由操作系统对文件系统进行解释、使用。
也有的分区没有文件系统,即尚未格式化的,此谓生分区(或原始的,raw)。如果有文件系统,那就是熟的(cooked)。生磁盘用于没有合适的文件系统的地方,可以被操作系统作特殊用途;也有的数据库绕过操作系统自己格式化后直接使用,也可以用于RAID。
操作系统同时支持多个文件系统类型。绝大多数操作系统都采取了面向对象技术,对文件系统接口加以不同的实现来达到这个目的。这也包括网络文件系统类型,如NFS。
三、目录实现
目录分配和目录管理算法对文件系统的效率、性能和可靠性有很大影响。
1、线性列表
存储文件名和数据块指针的线性列表。简单,但性能不高。主要是新增或删除该目录下的文件时,需要线性搜索以确定无重名或找到相应文件。当然有许多办法改善,比如缓存、排序,或将条目标记、转移等。
2、哈希表
大大减少目录搜索时间,插入和删除也比较简单。哈希算法其实就是为了解决冲突的。
四、分配方法
一个磁盘可存储多个文件,那么如何为它们分配空间,才能有效使用磁盘空间和快速访问?常用的方法有三个:连续、链接和索引。
1、连续分配
文件在磁盘上占有连续的块,如此访问之时磁头移动最少,寻道数、寻道时间也最小。
但这种分配方式容易引起外部碎片,同时文件尺寸难以扩展。
2、链接
能解决连续分配的所有问题:每个文件是块的链表,块可以分布在磁盘任何地方。目录包含每个文件的第一块和最末块指针。缺点是只能有效地用于文件的顺序访问,不能支持直接访问。同时指针需要额外的空间。另外指针丢失或损坏会导致文件内容无法访问。
应对之道是采用簇代替块,比如4块为一簇;采用文件分配表(FAT)代替指针。
3、索引分配
链接是指针和块分布于磁盘,索引分配将所有指针放在一起。每个文件都有索引块。索引块是一个数组,元素i指向文件的块i,故而凭索引i就可以直接访问文件第i块。
索引分配模式没有碎片,问题是索引块多大合适?一个文件一个索引块,因此应该尽可能小,但太小的话,大文件的指针就不够用。这里有一些机制,比如支持多个索引块链接,或多层索引,或分级索引,如linux的方案。
4、性能
采用哪种磁盘分配方法,在于如何使用系统。一个主要为顺序访问的系统不应该与一个主要为随机访问的系统采用相同的方法。
五、空闲空间管理
空闲空间包括未使用空间及已删除文件的空间。为了记录空闲磁盘空间,分配给文件创建,或文件删除时进行回收,这个空闲表有如下几种形式:
1、位向量
每个磁盘块采用0或1进行表示:0代表已分配,1代表空闲。优点是查找第一个空闲块或者连续空闲块时相对简单和高效。因为计算机有位操作指令。缺点是比较消耗内存。一个40GB,每块1K的磁盘需要超过5M的空间来存储位图。
2、链表
将所有空闲块用链表连接起来,并将指向第一块的指针保存在磁盘的特殊位置,同时也缓存在内存中。每一块指向下一块,如此继续。效率不高,要遍历整个空闲表时,要读入每一块。不过,这种机会不大,通常操作系统只是简单地将一个空闲块分配给一个文件,每次只拿第一块就行了。
3、组
链表的改进型。将整条链表分成若干组,每个组只用一块存储组中其他块的地址,然后再用一块存储下一组的地址,如此继续。这样可以很快找到大量的空闲块。
4、计数
记录第一块的地址以及紧随其后的连续空闲块数量。这样,空闲表的每个条目包含磁盘地址和数量,比原来的条目大,但表总长度会更短,因为连续块的数量很多。适用于多个连续块同时分配或释放的情况。
六、效率与性能
磁盘是计算机主要部件中最慢的部分,常常成为系统性能的瓶颈。
1、效率
磁盘空间的有效使用主要取决于所使用的磁盘分配和目录管理算法。例如预先分配索引,根据文件大小以决定选用大簇或小簇;综合考虑是否内存中的文件条目数据结构;文件指针大小;等等。
2、性能
即使选择了基本文件系统,仍然能从多方面改善性能:磁盘缓存、页面缓存(虚拟内存)、异步写、预读,等等。
七、恢复
文件和目录保存在内存和磁盘上,必须确保系统失败不会引起数据丢失和不一致性。
1、一致性检查
由于缓存和异步写等,计算机崩溃后许多对文件和目录的修改会丢失,从而可能出现不一致状态。一致性检查程序常在系统重启时运行,试图修正。修正程度与文件的分配方法有关。
2、备份和恢复
最保险的办法是备份。
八、基于日志结构的文件系统
采用类似数据库日志的机制, 应对系统崩溃、不一致性等问题。
九、NFS
NFS是一种广泛使用的网络文件系统。它是通过局域网(甚至广域网)访问远程文件的软件实现和规范。
1、概述
NFS将一组互连工作站作为独立文件系统的机器组合,目的是允许透明地共享这些文件系统。共享是client - server模式的,一台机器既可能是客户机,也可能是服务器。共享可在任何两台对等机器之间进行。
一台机器如果要访问远程文件系统,首先要将远程目录安装到本地。一旦安装完成,远程目录与本地文件系统就有机集成起来,取代了原本的本地目录。本地目录成为新安装目录的根。NFS规范分两个:一是安装协议,一是远程文件访问协议。
2、安装协议
安装协议在客户机和服务器之间建立逻辑连接。安装操作包括要安装的远程目录名称和存储服务器名称。服务器维护一个输出列表,列出哪些文件系统允许输出以便安装。其中可能包括权限。
3、NFS协议
NFS协议提供了一组RPC以供远程文件操作。包括:
搜索文件
读取目录条目
操作链接和目录
访问文件属性
读写文件
NFS服务器一个显著特点是无状态,每次请求都要提供完整的参数。还要有序列号。在服务器端,崩溃或恢复对客户机是不可见的,那么客户机传过来的写需要确保同步,因而采用非易失性缓存。
单个NFS写时原子的,但NFS不提供并发控制,NFS上层服务需要提供锁。
NFS通过VFS与操作系统集成,客户机与服务器对等。
4、路径名转换
包括把路径名解析成独立的目录条目或组成部分。解析过程中,对每个组成名称和目录虚拟节点执行独立的NFS lookup调用,一旦遇到安装点,即向服务器发送一个RPC。客户端可缓存远程目录。不过当从服务器返回的属性与缓存内的属性不匹配时,目录缓存就要加以更新。
5、远程操作
NFS坚持远程服务,但采用了缓冲和缓存技术以提高性能。