本文主要参考《计算机操作系统(第四版)》(西安电子科技大学出版社)以及清华大学操作系统公开课(向勇、陈渝),整理操作系统的基本概念,供自己复习查阅。
文件管理
计算机内存是易失性设备,因此在现代计算机系统中都必须配置外存。操作系统的文件管理功能便是管理外存文件的。
文件系统
文件系统的管理功能是将其管理的程序和数据通过组织为一系列文件的方式实现的。
基本概念
首先是文件系统的一些基本概念。
数据项
数据项是文件系统中最低级的数据组织形式。其中,基本数据项是数据组织中可以命名的最小逻辑数据单位,由称为字段。由若干基本数据项组成的数据项称为组合数据项。此外,数据项还应包含数据类型。
记录(Record)
记录是一组相关数据项的集合,用于描述一个对象的某种属性。在一组记录中能唯一标识每个记录的一个或几个数据项称为本组记录的关键字(Key)(对应关系数据库中的键(Key))。
文件
文件是由创建者定义的、具名的一组相关元素的集合,文件是文件系统中最大的数据单位,一般会包含文件类型,文件长度,文件物理位置、创建时间等文件的基本信息。
文件名
文件名是由文件创建者指定的文件的名字,现代操作系统对文件名的限制较少,一般都区分大小写、对字符限制也有所放宽。
扩展名
扩展名又称后缀名,用于指示文件的类型(文件中数据的形式)。
文件类型
按用途可以把文件分为系统文件、用户文件、库文件;按数据形式可以分为源文件、目标文件(已编译未链接)、可执行文件;按组织形式可以分为普通稳健、目录文件(由文件目录组成的文件)、特殊文件(为了便于管理,系统也把I/O设备视为文件)。
层次结构
文件管理系统一般可以分为三层:中间管理层、上层用户接口、底层对象属性。
底层对象及其属性
对象一般包括文件和目录以及对应的磁盘存储空间。其中目录的组织和管理是影响文件存取速度的关键。
中间管理层
该层是文件管理系统的核心,实质是对对象操纵和管理的软件集合。该层又可以细分为I/O控制层、基本文件层、基本I/O管理程序、逻辑文件系统。
- I/O控制层是文件系统的最底层,主要是磁盘驱动程序,又称为设备驱动层。
- 基本文件层主要处理内存和磁盘的数据块的交换。
- 基本I/O管理程序主要完成块号转换、管理盘块、缓冲管理等功能。
- 逻辑文件系统主要处理与记录、文件有关的操作。
上层用户接口
接口层提供的服务主要是为了方便用户的使用,通常包含两种接口:
- 命令接口:用户与文件系统直接交互的接口。
- 程序接口:用户程序与文件系统的接口,即文件相关的系统调用。
文件操作
基本操作
- 创建文件:为新文件分配外存、在文件目录中新建目录项、在目录项中记录文件属性。
- 删除文件:置空对应的目录项、回收存储空间。
- 读文件:根据文件名查找目录,得到其在外存的位置,同时还有一读/写指针。
- 写文件:根据文件名查找目录,得到其在外存的位置,利用目录中的写指针进行写操作。
- 设置读/写位置:使文件的顺序存取改为随机(random,任意)存取。
打开操作
- 打开文件:对于需要多次读写的文件,多次检索显然是费时的,这时在对文件操作之前先引入打开操作,即先从外存中拷贝该文件到内存,又或者把这个动作描述为:在用户和文件之间建立一个连接,这样就免去了冗余的检索和磁盘I/O。对应地,有关闭操作来断开这种连接,即在“打开文件”表中移除该项。
属性修改
即操作系统允许用户直接获取文件的属性并在可行权限内修改,如修改文件名、修改文件拥有者、改变访问权限等。
文件的逻辑结构
用户视图中的文件均为逻辑文件,它是由一系列逻辑记录构成的。就用户而言,文件的逻辑记录是能够被存取的基本单位。
文件结构的分类
在用户层面看到的是文件的逻辑结构,用户可以直接处理这些逻辑文件,这些文件独立于文件的物理特性。而文件的物理结构是文件的存储结构,是系统对存储在外存上的文件的一种存储组织形式。文件系统的底层设计主要涉及其物理结构,即问题为如何将文件存储在外存上(或:如何在外存中组织文件);而文件系统的高层设计则主要涉及其逻辑结构,即问题为如何把逻辑记录组织为一个逻辑文件。
文件逻辑结构的类型
按是否有结构分类
- 有结构文件:由若干记录构成一个文件,即记录式文件。在记录式文件中,每个记录都描述着一个实体。记录又有定长与不定长之分。
- 无结构文件:即流式文件,在系统中运行的源程序、可执行文件、库函数等均为流式文件。
按文件的组织方式分类
可以分为顺序文件、索引文件、索引顺序文件。
顺序文件
顺序文件即把记录按顺序排列的文件类型。排序的标准可以是由用户指定的关键字,或无关键字(即按记录的存入时间排序)。顺序文件的存取效率是最高的,但其增删改都比较困难,性能也不如人意。
索引文件
定长记录可以通过简单计算实现随机查找,但变长记录的查找就只能遍历记录表。此时可以为变长记录文件建立一张索引表,表项为记录的地址以及记录的长度,索引表按关键字排序,即可实现对变长记录的随机查找。
索引顺序文件
索引顺序文件则结合了索引文件和顺序文件的优点,是对顺序文件的一种改进。既能随机访问,又可以从容进行记录的插入、删除、修改,同时还保留了顺序文件的特征:即记录是按关键字的顺序组织起来的。它通过引入文件索引表实现了随机访问,又引入溢出(overflow)文件实现记录的增删改,这两者的实现代价也在可接受范围内。
索引顺序文件即分块法,具体做法为:把完整的变长记录顺序文件分为若干级若干块,并为每一级的每一个块都设置一个索引表,查找时按级顺序查找即可。
对于一个记录数为N的顺序文件,假设分级数为k,那么其随机访问的平均查找记录数为${ (k+1)\cdot {\root k+1\of {N}} \over 2 }$。对于一个记录数为$10^6$的文件,直接查找平均次数为$5\times 10^5$;若采用一级索引,平均查找次数为$1000$;若采用二级索引,则其平均查找次数为150。
直接文件
前述文件结构存取记录都需要进行检索,而直接文件则可以直接获取记录的物理地址。而直接文件中的哈希文件也是应用最广泛的一种,它利用Hash函数将关键字转换为相应记录的地址。
文件目录
文件目录用于标识系统中的文件及其物理地址,供检索使用。
文件控制块(FCB)
文件控制块是用于描述和控制文件的数据结构,通过文件控制块,文件管理程序可以对文件进行各种操作。文件目录即文件控制块的有序集合。文件控制块通常包括文件的基本信息,如文件名、文件物理位置、文件逻辑结构、文件物理结构等,还有一些存取控制信息以及使用信息。
索引结点
当文件数量很大时,文件目录的占用很大,相应地磁盘I/O也会变多。而显然文件检索只需用到文件名这一信息,即其他信息在检索时并不需要调入内存,使文件描述信息单独形成一个数据结构,这个结构也就是索引结点。在磁盘中,每个文件都有唯一的一个磁盘索引结点,用于存储文件的描述信息,当文件被打开时,磁盘索引结点会被拷贝到内存中成为内存索引结点,同时该结点还会附带一些管理信息,如节点编号、状态、访问计数等。
单级文件目录
这是最简单的文件目录,在整个系统中只有一张目录表,每个文件占一个目录项。
两级文件目录
单级目录虽然简单,但它查找速度慢、不允许重名且不便于实现文件共享。为了克服这些缺点,可以为每个用户单独设置一个用户文件目录(User File Dictionary,UFD),在此目录下均为该用户的文件的FCB。此外,再建立一个主文件目录(Main File Dictionary,MFD),用于存放所有用户的用户名以及对应的UFD。
树形文件目录
树形文件目录是现代OS中最通用也最实用的文件目录,它可以明显提高目录的检索速度以及文件系统的性能。
基本结构
主目录为根目录,每个文件目录中只能有一个根目录,且每个文件或目录都有且只有一个父目录,根目录没有父目录,文件即树叶,其余即树结点。为了系统的灵活性,可以让FCB通用化,即目录文件和数据文件公用一种FCB结构,具体实现只需使用一标志位标识该FCB是哪种FCB即可。
路径
在树形目录中,从根目录到任何数据文件都有且只有一条路径,这也就是文件的绝对路径。
当前目录
每次访问一个文件都需要从树根开始寻找,根据局部性原理,这是非常低效的。由此可以设置一个当前目录,让进程对文件的访问都基于相对路径进行。
目录操作
目录操作主要为创建目录、删除目录、改变目录(重新设置当前目录)、移动目录、链接(让指定文件拥有多个父目录,以实现文件共享)、查找。
目录查询
目录查询一般是按照给定关键字对目录进行文件查找,常用的查找算法有:线性探索法、Hash法。现代操作系统一般都配备了模式匹配功能,即可以使用通配符查询,此时无法使用Hash算法查找。
文件共享
在操作系统层面,文件共享指同一台计算机的不同用户可以共享同一份文件。目前一般有两种方式实现共享:基于DAG实现和利用符号链接实现。
DAG与索引结点
树结构要求每个结点只能有一个父节点,即对某个文件的访问只有一条路径,这就限制了文件的共享。这时,可以在文件树的基础上添加链接实现共享,这时的文件有可能有多个父目录,这破坏了树的特性,但这些用户可以用对称的方式实现共享。加入链接后的树成为一个有向无环图(Directed Acyclic Graph,DAG)。
索引结点
在链接时,可以通过直接拷贝对应的物理地址把共享文件或子目录链接到多个父目录。若文件目录直接包含了文件的物理地址,即对应的磁盘块号,若此时某个用户修改了该文件进而引起盘块号的改变,便会引发错误。这时就可以利用索引结点,即把文件的属性信息存放到索引结点中,文件目录中只保存相应索引的指针。
符号链接
在基于DAG的文件共享方法中,文件的链接是实际存在的。而符号链接的基本思想是,允许一个文件或子目录有多个父目录,但只能有一个主父目录,其余父目录称为链接父目录。加入符号链接并不会破坏树的特性。具体实现方法为:在需要链接另一个文件时,在当前目录下新建一个文件,但该文件只包含被链接文件的路径。此时,只有文件拥有者才拥有索引结点指针。这就可以避免在DAG方式下删除文件导致的悬空指针的问题,但同时在访问共享文件时的读盘次数会增加,且由于链本身也是一种文件,无疑会增加外存开销。
共同问题
不管使用哪种方法,每增加一条链接,系统中就会增加一个文件名,用户访问共享文件,实际上也是在用自己的路径访问。在遍历整个文件系统时可能会多次访问同一个文件,在遍历拷贝整个文件系统时甚至会生成同一个共享文件的多个拷贝。
文件保护
在操作系统内涉及的文件保护主要是针对在存取控制操作中的不安全因素。
访问权
为了实现文件保护,系统应对对象的访问加以控制。访问权的概念由此诞生:它是指一个进程对某对象执行操作的权力范围。如某进程对文件A只有读权限,对文件B有读写权限。
保护域
从访问权的概念中引申出保护域的概念,保护域即进程运行时对一组对象的访问权的集合,即进程只能在保护域内操作。保护域又分为静态和动态。静态保护域即在进程开始时就确定了进程执行全过程中对象的访问权,由局部性原理可知,在某一小段时间内,某些对象的访问权是并不被需要的,这也就对应进程调度中的资源浪费现象。为了改善这一情况,可以为系统增设保护域切换功能,即允许进程在执行过程中根据需要动态切换保护域,这就是动态保护域。
访问矩阵
可以采用访问矩阵实现动态保护域。访问矩阵的行对应保护域,列即保护域中的对象,行和列可以确定一个保护域中对应对象的访问权。访问权通常由资源的拥有者或系统管理者确定。
域切换权
为了实现域的动态切换,同样应将切换也当作一种权力,即在列中增设可切换的域对象。
访问表
访问矩阵在概念上很容易理解,但由于实际运用中,访问矩阵一般是稀疏矩阵,即会造成大量的空间浪费。因此在实现时通常采用访问表形式。
访问控制表(Access Control List)
即对访问矩阵按对象划分而成的表,每张表都对应着一个对象的所有域和权集的对偶。当对象是文件时,还可以把该表作为文件的控制信息挂到文件的FCB或索引结点上。
访问权限(Capabilities)表
即对访问矩阵按行划分而成的表,每一个表项都对应着该域内某对象的访问权限。当对象是文件时,该表描述的是一个用户或进程对每个文件的访问权限。