前言
操作系统需要对磁盘块进行管理,这涉及两个方面,一方面是对非空闲磁盘块的管理(存放了文件数据的磁盘块),这是文件物理结构/文件分配方式需要探讨的问题。另一方面是对空闲磁盘块的管理,这是文件存储空间管理需要探讨的问题。本文介绍第一个问题,即文件的物理结构,即文件数据应该怎么样存放在外存中。
本文内容
类似于内存分页,磁盘中的存储单元也会别分为一个个块/物理块/磁盘块,在很多操作系统中,磁盘块的大小与内存块、页面的大小相同。
1 文件块、磁盘块
在内存管理中,进程的逻辑地址地址空间被分为了一个个页面。同样的,在外存管理中,为了方便对文件数据的管理,文件的逻辑地址空间被分为了一个个文件“块”。
于是文件的逻辑地址页可以表示为(逻辑块号,块内地址)的形式。
操作系统为文件分配的存储空间是以块为单位的。如果一个块的大小是1KB,那么即使一个文件大小是10B,操作系统也会为该文件分配一个块进行存储。同时操作系统需要实现从逻辑地址到物理地址的映射。
2 文件分配方式
2.1 连续分配
连续分配方式要求每个文件在磁盘上占有一组连续的块。
用户通过逻辑地址操作自己的文件,操作系统如何实现从逻辑地址到物理地址的映射?
用户给出要访问的逻辑块号,操作系统会找到该文件对应的目录项(FCB),文件目录项(FCB)中记录存放的起始块号和长度。所以物理块号 = 起始块号 + 逻辑块号。
当然,还需哟啊检查用户提供的逻辑块号是否合法(逻辑块号 >= 长度 就是不合法)。
连续分配方式可以直接算出逻辑块号对应的物理块号,因此连续分配支持顺序访问和直接访问(即随机访问)。
读取某个磁盘时,需要移动磁头。访问的两个磁盘块相隔越远,移动磁头锁的时间就越长。
优点:连续分配的文件在顺序读/写时速度最快。
缺点:物理上采用连续分配的文件不方便拓展。
如下图所示,如果此时A文件想要拓展,由于连续分配要求在物理上占用的磁盘块必须是连续的,而此时A后面的物理块都被占用,所以A只能全部移动到后面没有被占用且空间足够的区域。
缺点:物理上采用连续分配,存储空空间利用率低,会产生难以利用的磁盘碎片。
可以使用紧凑来处理碎片问题,但是需要耗费很大的时间代价。
连续分配的优缺点
优点:支持顺序访问和直接访问(随机访问);连续分配的文件在顺序访问时速度最快。
缺点:不方便文件拓展;存储空间利用率低,会产生磁盘碎片。
2.2 链接分配
链接分配采用离散分配的方式,可以为文件分配离散的磁盘块。分为隐式链接和显示链接。
2.2.1 隐式链接
逻辑块号到物理块号转换:用户给出要访问的逻辑块号i,操作系统找到该文件对应的FCB,FCB中记录了起始块号和结束块号,从FCB中找到起始块号(即0号逻辑块对应的物理块),将0号逻辑块读入内存(除了结束块号,每个物理块都保存了指向下一个物理块的指针),由此知道1号逻辑块的物理内存,于是读入1号逻辑块,再找到2号逻辑块的存放位置..........以此类推。因此,读入i号逻辑块,总共需要 i + 1 次磁盘I/O。
结论:(1) 采用链式分配(隐式链接)方式的文件,只支持顺序访问,不支持随机访问,查找效率低。另外,指向下一个磁盘块的指针也需要耗费少量的存储空间。
隐式链接:除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针。文件目录包括文件第一块的指针和最后一块的指针。
隐式链接的优缺点
(1) 优点:方便文件的拓展,不会有碎片问题,外存利用高。
(2) 缺点:只支持顺序访问,不支持随机访问,查找效率低。指向下一个盘块的指针也需要耗费一定的存储空间。
2.2.2 显式链接
显示链接:把用于链接文件的各物理块的指针存放在一张表中,即文件分配表(FAT,File Allocation Table)。
例如,假设某个新创建的文件“aaa”依次存放的磁盘块为2-->5-->0-->1。新创建的文件“bbb”一次存放在磁盘块4-->23-->3。那么文件分配表如下图
注:一个磁盘仅设置一张FAT。开机时将FAT读入内存,并常驻内存。FAT的各个表项在物理上连续存储,且每一个表项长度相同,因此物理块号字段可以是隐含的。
如何实现文件的逻辑块号到物理块号的转换?
用户想访问逻辑块号i,操作系统找到找到该文件对应的目录项(FCB),从FCB中找到起始块号,若i > 0,则查询内存中的文件分配表,往后找到i号逻辑块对应的物理块号。逻辑块号转换成物理块号过程不需要读磁盘操作。都是直接在内存中直接读取FAT表即可找到逻辑块号与物理块号的对应关系。
如用户想要访问aaa文件的2号逻辑块,根据页目录项的起始块号2号块(0号逻辑块),查询FAT表,得到1号逻辑块对应的物理块为5号块,再查5号物理块的下一块即为2号逻辑块所对应的物理块,整个查询过程都是在内存中进行的,没有访问过磁盘。
结论:采用链式分配(显示链接)方式的文件,支持顺序访问,也支持随机访问(想访问第i号块不需要依次访问之前的0~i-1号逻辑块),由于块号转换过程不需要访问磁盘,所以相比于隐式链接来说,访问速度快很多。
显示链接不会产生外部碎片,页可以很方便地对文件拓展。
2.3 索引分配
索引分配:允许文件离散的分配在各个磁盘中,系统会为每个文件建立一张索引表,索引表只记录了文件的各个逻辑块所对应的物理块(索引表功能类似内存管理中的页面——建立逻辑页面到物理页之间的映射关系)。索引表存放的磁盘称为索引块。文件数据存放的磁盘块称为数据块。
例如,假设某个新创建的文件“aaa”依次存放的磁盘块为2-->5-->13-->9。7号磁盘作为“aaa”的索引块,索引块中保存了索引表的内容。如下图所示
注:链接分配的显示链接中,文件分配表FAT是一个磁盘对应一张。而索引分配方式中,索引表是一个文件对应一张。
可以用固定长度表示物理块号(如假设磁盘总容量为1TB = 240B,磁盘块大小为1KB,则共有230个磁盘块,则可用4个字节表示磁盘号,即可用4B表是索引表的表项),因此,索引表中的逻辑块号可以是隐含的。
如何实现文件的逻辑块号到物理块号的转换?
用户给出要访问的逻辑块号i,操作系统找到该文件对应的目录项(FCB),从目录项中找到索引表的存放位置,将索引表读入内存,并查找索引表即可知道i号逻辑块在外存中存放的位置。
索引分配可以支持随机访问。文件扩展也很容易实现(只需要给文件分配一个空闲块,并增加一个索引表项即可),但是索引表需要占用一定的存储空间。
下面考虑这样一个问题,若一个磁盘块1KB,一个索引项4B,则一个磁盘只能放下256个索引项(逻辑块号隐含),如果文件大小超过了256个索引块,那么一个磁盘块就装不下整张索引表了,如何解决这个问题?
通常有以下三种解决方案:链接方案、多层索引、混合索引。
2.3.1 链接方案
链接方案:如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。
若一个文件的大小为256 * 256KB = 65535KB = 64MB。一个磁盘块1KB,所以有256 * 256个块,也就共有256 * 256个索引项,也就需要256个索引块来存储,这些索引块用链接方案连起来。如果要向访问最后一个索引块,而各个索引索引块是用指针链接起来的,因此必须顺序地读入前255个索引块。
显然,这种方案的效率是很低的。
2.3.2 多层索引
多层索引:建立多层索引(原理类似多级页表)。使第一层索引块执行第二层索引块。还可以根据文件大小的要求建立第三层、第四层....
如上图,假设磁盘块大小为1KB,一个索引表项占4B,则一个磁盘块只能存放256个索引项。若某文件采用两层索引,则该文件最大长度可以到256 * 256 * 1KB = 65535KB = 64MB。
可以根据逻辑块号算出应该查找索表中的哪个表项。如访问1026号逻辑块。则1026 / 256 = 4,1026 % 256 = 2,。因此可以先将一级索引表调入内存,查询4号表项,将其对应的二级索引表调入内存,再查询二级索引表的2号表项即可得到1026号逻辑块存放的磁盘号了。访问目标数据块需要3次磁盘I/O。
对于K层索引结构,且顶级索引表未调入内存,则访问一个数据块需要K+1次读磁盘操作。
2.3.2 混合索引
混合索引:多种索引分配方式的结合。对于多层索引,如果文件占用几个磁盘块,每次访问都要多次访问磁盘,这显然不合理,并且一般计算机中小文件更多,所以就有了混合索引。如在一个文件的顶级索引表中,即包含直接地址索引(直接指向数据块),又包含以及间接索引(指向单层索引表),还包含两级间接索引(指向两层索引表)。
如下图,顶级索引表中有8个直接地址,一个一级间接索引和一个二级间接索引。
对于上图,如果顶级索引表还没有读入内存
访问0~7号逻辑块:两次磁盘。
访问8~263号逻辑块:三次磁盘。
访问264~65799逻辑块:四次读操作。
对于小文件,这种混合索引只需较少的读磁盘次数就可以访问目标数据块。