• 磁盘存储器管理
  • 外存的组织方式
    • ">连续组织方式
    • ">链接组织方式
      • ">隐式链接
      • ">显式链接
    • ">索引组织方式
      • ">单级索引组织方式
      • ">多级索引组织方式
      • ">混合索引方式
  • ">文件存储空间管理
    • ">存储空间的划分
    • ">空闲表法
    • ">空闲链表法
      • ">空闲盘块链
      • ">空闲盘区链
    • ">位示图
    • ">成组链接法

    磁盘存储器管理

    磁盘块

    类似于内存分页,在外存管理中为了方便对文件数据的管理,文件的逻辑地址空间也被分为了一个一个的文件“块”。磁盘中的存储单元也称为“块/磁盘块/物理块”,很多操作系统中磁盘块的大小与内存块、页面的大小相同。内存与磁盘之间的数据交换(即读/写操作、磁盘 I/O)都是以“块”为单位进行的,即每次读入一块,或每次写出一块,于是文件的逻辑地址也可以表示为(逻辑块号,块内地址)的形式。
    image.png
    操作系统为文件分配存储空间都是以块为单位的,用户通过逻辑地址来操作自己的文件,操作系统要负责实现从逻辑地址到物理地址的映射。
    image.png

    磁盘管理的任务

    磁盘存储器不仅容量大,存取速度快,而且可以实现随机存取,是当前实现虚拟存储器和存放文件最理想的外存。对磁盘存储器管理的主要任务和要求是:

    1. 有效地利用存储空间:采取合理的文件分配方式,为文件分配必要的存储空间,并能有效地减少磁盘碎片,改善存储空间的利用率;
    2. 提高磁盘的 I/O 速度:通过各种途经来提高磁盘的I/O速度,以增加对文件的访问速度,从而改善文件系统的性能;
    3. 提高磁盘系统的可靠性:采取多种技术来提高磁盘系统的可靠性。

      外存的组织方式

      文件的物理结构直接与外存的组织方式有关,不同的外存组织方式将形成不同的文件物理结构。目前常用的外存组织方式有:
    组织方式 说明
    连续组织方式 为每个文件分配一片连续的磁盘空间,形成顺序式的文件结构
    链接组织方式 为每个文件分配不连续的磁盘空间,通过链接指针将一个文件的所有盘块链接在一起,形成链接式文件结构
    索引组织方式 形成的将是索引式文件结构

    连续组织方式

    连续组织方式又称连续分配方式,要求为每一个文件分配一组相邻接的盘块。例如第一个盘块的地址为 b,则第 i 个盘块的地址为 b + i。通常它们都位于一条磁道上,在进行读/写时不必移动磁头。采用这种方式可把逻辑文件中的记录顺序地存储到邻接的各物理盘块中,这样所形成的文件结构称为顺序文件结构,此时的物理文件称为顺序文件。为使系统能找到文件存放的地址,应在目录项的“文件物理地址”字段中记录该文件第一个记录所在的盘块号和文件长度(以盘块为单位)。
    image.png
    连续组织方式的顺序访问容易,系统可从目录中找到该顺序文件所在的第一个盘块号,逐个盘块地往下读/写。同时顺序访问速度快,由连续分配所装入的文件所占用的盘块可能是位于相同或相邻的磁道上,磁头的移动距离最少。
    但是连续组织方式要求为一个文件分配连续的存储空间,会产生出许多外部碎片。如果是定期地利用紧凑方法来消除碎片,则又需花费大量的机器时间。分配时必须事先知道文件的长度,有时文件的大小只能靠估算,如果估计的文件大小比实际文件小,就会因存储空间不足而中止文件的拷贝,这就促使用户将文件长度估得比实际的大造成浪费。为保持文件的有序性,在删除和插入记录时,都需要对相邻的记录做物理上的移动,不灵活。对于那些动态增长的文件,由于事先很难知道文件的最终大小,因而很难为其分配空间。

    链接组织方式

    如果可以将文件装到多个离散的盘块中,就可消除连续组织方式的缺点。在采用链接组织方式时,可为文件分配多个不连续的盘块,再通过每个盘块上的链接指针,将同属于一个文件的多个离散的盘块链接成一个链表,由此所形成的物理文件称为链接文件。链接组织方式消除了磁盘的外部碎片,对插入、删除和修改记录都非常容易,同时能适应文件的动态增长。链接方式又可分为隐式链接和显式链接两种形式。

    隐式链接

    隐式链接组织是在文件目录的每个目录项中,都须含有指向链接文件第一个盘块和最后一个盘块的指针。隐式链接组织方式只适合于顺序访问,如果要访问文件所在的第 i 个盘块,则必须先读出文件的第 i-1 个盘块。此外只通过链接指针将一大批离散的盘块链接起来的可靠性较差,因为只要其中的任何一个指针出现问题,都会导致整个链的断开。
    image.png
    为了提高检索速度和减小指针所占用的存储空间,可以将几个盘块组成一个簇(cluster)。比如一个簇可包含 4 个盘块,在进行盘块分配时,是以簇为单位进行的。这样将会成倍地减小查找指定块的时间,但却增大了内部碎片。

    显式链接

    显式链接把用于链接文件各物理块的指针显式地存放在一张表中,即文件分配表(FAT,File Allocation Table)。用户给出要访问的逻辑块号 i,OS 找到该文件对应的目录项(FCB)。找到起始块号,若 i > O 则查询内存中的文件分配表 FAT,往后找到 i 号逻辑块对应的物理块号。一个磁盘仅设置一张 FAT,开机时将FAT读入内存并常驻内存。FAT 的各个表项在物理上连续存储,且每一个表项长度相同,因此“物理块号”字段可以是隐含的。
    image.png
    显式链接方式的文件支持随机访问,且逻辑块号转换成物理块号的过程不需要读磁盘操作。查找记录的过程是在内存中进行的,不仅显著地提高了检索速度,而且大大减少了访问磁盘的次数。但是链接方式不能支持高效的直接存取,如果文件较大则要在 FAT 中顺序地查找许多盘块号。同时 FAT 需占用较大的内存空间,只有将整个 FAT 调入内存,才能保证在 FAT 中找到一个文件的所有盘块号。

    索引组织方式

    单级索引组织方式

    在打开某个文件时,只需把该文件占用的盘块的编号调入内存即可。为此应将每个文件所对应的盘块号集中地放在一起,在访问到某个文件时,将该文件所对应的盘块号一起调入内存。索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,记录文件的各个逻辑块对应的物理块。索引表存放的磁盘块称为索引块,文件数据存放的磁盘块称为数据块。在建立一个文件时,只须在为之建立的目录项中填上指向该索引块的指针。
    image.png
    索引组织方式支持直接访问,当要读文件的第 i 个盘块时可以方便地从索引块中找到盘块号。索引分配方式也不会产生外部碎片,支持在在文件较大时使用。它的主要问题是对于中、小型文件,其本身通常只占有数个到数十个盘块,但仍须为之分配索引块。

    多级索引组织方式

    在为一个大文件分配磁盘空间时,如果一个索引块不够记录所有盘块号,OS 须再为该文件分配多个索引块,再通过链指针将各索引块按序链接起来。
    image.png
    显然当文件太大会导致索引块太多,此时应为这些索引块再建立一级索引。使第一层索引块指向第二层的索引块,还可根据文件大小的要求再建立第三层、第四层索引块。
    image.png
    多级索引大大加快了对大型文件的查找速度,但在访问一个盘块时,其所需启动磁盘的次数随着索引级数的增加而增多。

    混合索引方式

    为了能较全面地照顾到小、中、大及特大型作业,可以采取多种组织方式来构成文件的物理结构。混合索引是多种索引分配方式的结合,例如一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)。
    image.png
    对于小文件来说,访问一个数据块所需的读磁盘次数更少。

    文件存储空间管理

    为了实现前面任何一种文件组织方式,都需要为文件分配盘块,因此必须知道磁盘上哪些盘块是可用于分配的。故在为文件分配磁盘时,除了需要文件分配表外,系统还应为可分配存储空间设置相应的数据结构——磁盘分配表(Disk Allocation Table),此外还应提供对盘块进行分配和回收的手段。

    存储空间的划分

    安装操作系统的时候,一个必经步骤是为磁盘分区,存储空间的划分是将物理磁盘划分为一个个文件卷(逻辑卷、逻辑盘),例如 C、D、E 盘等。存储空间的初始化将各个文件卷划分为目录区、文件区,目录区主要存放文件目录信息(FCB)、用于磁盘存储空间管理的信息,文件区用于存放文件数据。
    image.png

    空闲表法

    空闲表法属于连续分配方式,为每个文件分配一块连续的存储空间。系统也为外存上的所有空闲区建立一张空闲表,每个空闲区对应于一个空闲表项,其中包括表项序号、该空闲区的第一个盘块号、该区的空闲盘块数等信息。再将所有空闲区按其起始盘块号递增的次序排列,形成空闲盘块表。
    分配磁盘块与内存管理中的动态分区分配很类似,同样可采用首次适应、最佳适应、最坏适应等算法来决定要为文件分配哪个区间。在系统为某新创建的文件分配空闲盘块时,先顺序地检索空闲表的各表项,直至找到第一个其大小能满足要求的空闲区,再将该盘区分配给用户(进程),同时修改空闲表。系统在对用户所释放的存储空间进行回收时,也采取类似于内存回收的方法,即要考虑回收区是否与空闲表中插入点的前区和后区相邻接,对相邻接者应予以合并。
    image.png
    在内存分配上虽然较少采用连续分配方式,然而在外存的管理中。由于这种分配方式具有较高的分配速度,可减少访问磁盘的 I/O 频率,故它在诸多分配方式中仍然会使用。

    空闲链表法

    空闲链表法是将所有空闲盘区拉成一条空闲链,根据构成链所用基本元素的不同,可把链表分成空闲盘块链和空闲盘区链。

    空闲盘块链

    将磁盘上的所有空闲空间以盘块为单位拉成一条链,其中的每一个盘块都有指向后继盘块的指针。当用户因创建文件而请求分配存储空间时,系统从链首开始,依次摘下适当数目的空闲盘块分配给用户。当用户因删除文件而释放存储空间时,系统将回收的盘块依次挂在空闲盘块链的末尾。
    image.png
    这种方法的用于分配和回收一个盘块的过程非常简单,但在为一个文件分配盘块时,可能要重复操作多次,分配和回收的效率较低。又因为它是以盘块为单位,相应的空闲盘块链会很长。

    空闲盘区链

    空闲盘区链将磁盘上的所有空闲盘区(每个盘区可包含若干个盘块)拉成一条链,在每个盘区上除含有用于指示下一个空闲盘区的指针外,还应有能指明本盘区大小(盘块数)的信息。分配盘区的方法与内存的动态分区分配类似,在回收盘区时同样也要将回收区与相邻接的空闲盘区相合并。
    image.png
    这种方法的优点和缺点刚好与前一种方法的优缺点相反,即分配与回收的过程比较复杂,但分配和会收的效率可能较高,每次为文件分配多个连续的块,且空闲盘区链较短。

    位示图

    位示图是利用二进制的一位来表示磁盘中一个盘块的使用情况,当其值为 0 时表示对应的盘块空闲,为 1 时表示已分配也可以反过来。磁盘上的所有盘块都有一个二进制位与之对应,这样由所有盘块所对应的位构成一个矩阵。通常可用 m x n 个位数来构成位示图,并使 m x n 等于磁盘的总块数,描述为一个二维数组 map[m,n]。
    image.png
    根据位示图进行盘块分配时,可分三步进行:

    1. 顺序扫描位示图,从中找出一个或一组其值为 0 的二进制位(“0”表示空闲时);
    2. 将所找到的一个或一组二进制位转换成与之相应的盘块号,假定位于位示图的第 i 行、第 j 列,则其相应的盘块号应按“b = n × (i-1) + j”计算,其中 n 代表每行的位数;
    3. 修改位示图,令 map[i,j] = 1。

    盘块的回收分两步,首先将回收盘块的盘块号转换成位示图中的行号和列号,转换公式为如下。第二步修改位示图,令 map[i,j] = 0。
    Copy Highlighter-hljsi = (b-1) DIV n + 1 j = (b-1) MOD n + 1
    这种方法的主要优点是从位示图中很容易找到一个或一组相邻接的空闲盘块,例如需要找到 n 个相邻接的空闲盘块,这只需在位示图中找出 n 个其值连续为 0 的位即可。由于位示图很小,占用空间少,因而可将它保存在内存中,进而使在每次进行盘区分配时,无需首先把盘区分配表读入内存。

    成组链接法

    空闲表法、空闲链表法不适用于大型文件系统,因为空闲表或空闲链表可能过大,UNIX 系统中采用了成组链接法对磁盘空闲块进行管理。这是将上述两种方法相结合而形成的一种空闲盘块管理方法,它兼备了上述两种方法的优点而克服了两种方法均有的表太长的缺点。
    文件卷的目录区中专门用一个磁盘块作为“超级块”,当系统启动时需要将超级块读入内存,并且要保证内存与外存中的“超级块”数据一致。超级块的第一个元素是下一组空闲盘块数 n,接下来跟着的是 n 个空闲块号。其中第一个空闲块指向保存下一个超级块的信息,仍然是空闲盘块数 n 和 n 个空闲块号。直到最后一个超级块的信息没有后续的空闲块号,它的第一个空闲块号为特殊值例如 -1。
    image.png
    当需要 i 个空闲块时,检查第一个分组的块数是否足够,如果 1 < n 是足够的,就分配第一个分组中的 i 个空闲块,并修改相应数据。例如上图的成组链接,若需要 5 个空闲块,可以分配 201 ~ 205 号空闲块,并修改超级块的空闲块数量为 95。
    image.png
    如果 i ≥ n 刚好或不足够,则需要分配第一个分组中的全部空闲块,由于第一个空闲块存放了再下一组的信息,因此号块的数据需要复制到超级块中。例如上图的成组链接,若需要 95 个空闲块,可以分配 206 ~ 300 号空闲块,由于 300 号块内存放了再下一组的信息,因此 300 号块的数据需要复制到超级块中。
    image.png
    如果需要回收空闲块,则需要把空闲块号加入超级块中,修改空闲盘块数,并且进行相应的链接。如果回收空闲块后达到了超级块空闲盘块数的上限,需要将超级块中的数据复制到新回收的块中,并修改超级块的内容,让新回收的块成为第一个分组。例如上图的成组链接,若回收 1 个空闲块 300 号,进行修改后的状态如下。
    image.png