【操作系统】磁盘空间的分配

磁盘被操作系统抽象成连续的块,一个块通常为512B,那不同大小的文件在磁盘中需要不同个数的块来存储,不同类型的文件在访问时有不同的特征,有的是连续访问,有的是随机访问,有的文件一次写后就不变了,有的会频繁的增加和删除。所以操作系统在选择磁盘空间的分配方法时需要考虑这个问题。

一、连续分配

【操作系统】磁盘空间的分配_第1张图片

上图是一个连续分配的例子,连续分配要求文件在磁盘中以连续的块存储,文件目录记录了文件的起始块和使用的块的个数(长度),这样不论是对连续的访问还是随机的访问都很友好,连续的访问对于磁头来说基本不需要移动,随机的访问也可以根据块的位置来直接移动磁头。

问题1:对于空闲空间的管理会很麻烦,因为连续的存储会产生很多外部碎片。

解决办法:可以把这一片磁盘区域都复制到另一个磁盘区域,这样就创建了一个大量的连续空间,然后再把之前复制走的数据用连续分配的方式复制回来。

仍存在的问题:这样效率极其低下,而且在复制的这段时间服务器需要停机。

问题2:无法预知一个文件会用多少空间,这样等到时候要写的时候发现没地了。

解决方法:

1、可以出现这种情况时终止用户程序,但是这样用户就可能会在申请时申请过多的空间,从而导致浪费。

2、也可以在出现这种情况时再找一片大区域,把旧的和新的要写的复制到新的大区域里,但这样仍旧低效。

问题3:就算可以预知最终文件需要用的空间,但是一个文件可能数年都不会达到这个最后的值,那先前的这段时间都相当于浪费了空间。

解决办法:当空间不够时,可以加一个扩展在别的地方,这样文件块位置的记录就变成首块的地址,块数,下一个扩展的首块地址,这样构成一个类似于链表的结构。

仍存在的问题:如果扩展设置的过大,可能会导致内部碎片;尽管设置了扩展,但本质还是连续的空间,外部碎片仍然存在。

二、链接分配

【操作系统】磁盘空间的分配_第2张图片

 上图是链接分配的一个例子,链接分配维护一个类似于链表的结构,在目录中存文件的起始块和结束块位置。这样做没有外部碎片,而且增长起来也方便,事先也不用知道文件会有多大。

问题1:随机访问很耗时,因为必须从第一块找起。

问题2:因为每个块都要存下一个块的指针,假设521B里就会有4B,那么就是0.78%的空间被用作指针了,会很消耗空间。

解决方法:可以将多个块组成簇(cluster),按簇分配,这样其实相当于是结合了一部分连续分配的思想,可以减少磁头移动(因为有很多块是连续的了);其次在分配时按簇分配,意味着管理空闲空间时也按簇管理,这样空闲空间列表会更短;同时原来是一个块一个指针,现在变成一个簇也就是多个块一个指针了,减少了指针的空间消耗;

仍存在的问题:因为引入了连续分配,所以会有内部碎片,试想一个簇中只用了一部分块,没用完,就产生了内部碎片。

问题3:可靠性问题。试想这样一种情况,其中一个块坏掉了,那这一整条链表的后面就都丢失了。

解决方法:

1、双向链表

2、每个块都各自存储文件的名字和他的相对块号

仍存在的问题:这两种方法显然都增加了开销。

链接分配的一个变种:文件分配表(File-Allocation Table,FAT)

【操作系统】磁盘空间的分配_第3张图片

除开目录条目外,还要每个磁盘存一个FAT表,这个表通常存在磁盘的开头位置。这个表本质是一个长度为磁盘中块数的数组,数组中存的内容是他的文件的下一个块的块号,如果是空闲块,那就填0。也就是数据结构中数组表的思想。这样优化了随机访问,因为可以在FAT中找到要访问的块,然后直接去磁盘中找。

仍存在的问题:这个FAT是在磁盘头的,也就是说,如果不将他缓存,那么顺序访问就要将磁头移到磁盘的开头,在FAT表里找下一块的块号,然后再根据块号去磁盘中找,然后再移回来找块号,然后再去找,如此反复,极大的增加了磁盘的磁头寻道时间。

三、索引分配

【操作系统】磁盘空间的分配_第4张图片

 上图是一个索引分配的例子,每个文件有一个索引块,里面按顺序存放了该文件所有块的块号。目录中存放的是各文件索引块的块号。这样就既解决了内部碎片和外部碎片,又解决了随机访问不便的问题。

问题:只有当索引块完全使用时,指针消耗的空间才和链接分配一样,不然索引块有空余,浪费的空间就比链接分配多,所以这就有一个问题,如何设计索引块。

这里看unix的索引块设计,

【操作系统】磁盘空间的分配_第5张图片

他一共有16个指针,前13个是直接指向数据块的,后三个都是间接索引,第14个指向一个索引块,也就是一级间接索引,第15个指向一个索引块的索引块,也就是二级间接索引,第16个三级间接索引同理。 这样前13个可以指向13个块,第14个可以指向512B/8B=64个块,第15个可以指向64*64=4096=4K个块,第16个可以指向64*64*64=262144=256K个块,加起来大概260K个块,一个块512B,那最大的文件大小就是大概130MB。

每多一层索引就要多一次到磁盘中找,所以这是操作系统中典型的一个以时间换空间的例子。

你可能感兴趣的:(操作系统学习,linux)