目录
一、相关概念
二、文件的分配
三、空闲空间列表
四、多磁盘管理-RAID
五、磁盘调度
文件系统是一种用于持久性存储的系统抽象。硬盘属于持久性存储介质的一种。管理文件系统例如硬盘,需要管理文件块,哪一块属于哪一个文件;需要管理空闲空间和分配策略;为文件提供相应的保护,文件数据的存储需要可靠性持久性。文件的属性包含名称、文件类型(后缀)、位置、大小、读写权,创建者、创建时间,最近修改时间等 ; 文件头 保存了文件的控制信息。
文件描述符是操作系统为每个进程维护维护的一个打开文件表的索引。需要元数据来对文件进行有效的管理,元数据包括文件指针来记录最后一次读写位置,文件打开计数(文件是共享资源,允许多个进程打开同一个文件),文件磁盘位置(缓存数据的访问信息),访问权限等。在操作系统更上层的应用程序不需要关心文件在磁盘中的哪一个位置,只管对缓存区Buffer的读写就行。具体的逻辑内存和外存之间的映射关系由操作系统完成。内存的读写单位是页或者字节,而外存磁盘的读写是扇区。
当用户需要读取文件数据时,操作系统会获取用户需要访问的字节空间,进一步地操作系统会根据用户需要访问字节所在的扇区给取出来。
别名,及一个文件由多个名字。软连接生成出的文件,其内容是另一个文件的路径名(指针),通过访问这路径名可以间接的访问对应的文件,又称快捷方式。硬链接生成出的文件其文件项指向同一个文件的内容。对于硬链接,有种特殊的数据结构记录了文件被引用的计数。删除硬链接对应的文件,只是把计数减1,直到减为0文件才会彻底删除。如果删除软连接对应的文件,文件没了,链接也就悬空了。有点像C++里的智能指针和弱指针。别名的应用潜在的风险就是循环引用,可能在遍历路径时造成异常,所以需要考虑检索文件算法的健壮性。
文件系统分为磁盘文件系统,数据库文件系统(例如WinFs),日志文件系统(例如 Journaling file system,用于可恢复文件数据),网络/分布式文件系统(例如NFS、GFS等,利用网络访问其他系统的文件),特殊/虚拟文件系统
虚拟文件系统是对所有文件系统的抽象,管理所有文件和文件系统关联的数据结构,给上层提供统一的接口,实现对各种文件系统高效的读/写/查/打开/关闭等功能。
对于基本的文件系统数据结构包含:卷控制块(超级块)用来记录文件系统的特征信息,例如块大小,块数量,空余块,指针等;文件控制块用来记录文件的特征信息,例如拥有者,文件大小,数据库位置等; 目录节点,每个目录项一个,包含了目录项的数据结构和指向的文件控制块、父节点项目列表等。
文件的分配分成3种,连续分配方式、链式分配方式、索引分配方式。对于不同大小文件应考虑空间高效和时间高效采用适合数据块分配方式。通常的表现指标是访问时间和空间利用率。
连续分配策略就是找到一块满足文件大小的数据块进行分配。和页内存的连续分配策略类似。如果频繁进行文件的修改/删除可能会有无法利用的空闲块。当然这种组织方式是简单的,通常方法就最佳分配,最先适配等。
链式分配策略,像链表一样的数据结构。优点就是很少的碎片,但是串行访问可能会比较花时间。访问第三个数据块,先要访问第二个数据块,访问第二个数据库,首先应访问第一个数据库才行。还有一个缺点就是,链表的指针(链接)信息,可能会因为突然断点导致文件数据来不及写入到硬盘中导致中间修改数据块的链接信息丢失,断了“链”就会造成之后的文件数据无法关联起来。
多级索引分配策略,像树一样的数据结构,每个非叶子节点都是索引,通过索引块可以找到数据库的位置。这种方式可以高效地利用碎片,增删也方便。缺点就是存储小文件也需要为索引块分配空间,不能直接访问。
文件系统需要把空闲空间组织起来。可以用‘0’ 和 ‘1’ 表示数据块是否为空闲。所以可以用位图来管理文件系统的所有数据块列表的空闲情况。访问文件系统时,数据块空闲列表需要装入到内存中,因此还需要考虑可能因为断电造成内存和硬盘数据信息不一致情况的问题。
早期磁盘容易坏,数据容易丢失。为了保持高健壮性,通常用多个便宜的硬盘并行写数据,这样一个硬盘损坏也不至于数据丢失,同时也可以提高磁盘的访问效率。
RAID-0:把数据均匀地放在独立的硬盘里,对硬盘并行的写操作和读操作。对于操作系统来说,访问数据,可以并行地将不同硬盘的数据写入内存中。
RAID-1:如果其中有一个硬盘损坏,那么其他硬盘可以替代损坏的硬盘的工作,提高可靠性。多硬盘起到了镜像作用。
RAID-4:多硬盘中,用一个硬盘用来完成数据纠错功能,称为Parity Disk。此方法考虑到了RAID-0 和RAID-1的高效和高可靠的特点。缺点是Parity Disk 的读写非常频繁。
RAID-5:多硬盘中,选其中用几个或多个硬盘用来完成数据纠错功能。让多个硬盘分摊原先Parity Disk的读写负担。
磁头通过移动来找到扇区具体位置,磁盘通过旋转来寻道找到数据的位置。一个磁盘有多个盘片,每个盘片有一到两个的磁头来读取数据。“旋转”和“移动”都是机械操作,与电子读取的效率相比慢了好几个数量级。
那么有什么调度策略来减少读取磁盘的开销呢?当有一系列寻道请求时,如果采用先来先服务策略,访问数据如果在不同扇区,而扇区在磁盘的物理位置距离过长,那么磁头读取数据时可能会来回“跳动”。造成很大的开销。
最短寻道时间,在系列寻道请求中,找到扇区位置与当前磁头所在扇区的位置的距离最短的请求,先执行。这个可能会造成离磁头的远的寻道请求长时间无法执行,造成饥饿现象。
Scan,又称电梯算法,磁头先往磁盘内环移动接收相应的寻道请求,再往磁盘外环接收相应的寻道请求,像电梯一样。那么所有请求都可以公平地得到访问。
C-Scan,单方向寻道法,磁头从磁盘内环当作起始位置。往磁盘外环移动接收相应的寻道请求,到了外环后迅速回到起始位置。
C-Look, 单方向寻道法,磁头从磁盘内环当作起始位置。往磁盘外环移动接收相应的寻道请求,到了最外环的寻道请求后迅速回到起始位置。
N-step-Scan.将寻道请求队列分成N个子队列,每处理子队列请求都采用Scan算法。
F-Scan。是N-step-Scan的特例,只分成两个子队列,每处理子队列请求都采用Scan算法。
以上是基本的寻道策略,然而现实情况可能根据磁盘的特点指定出特有的策略,有些硬盘的寻道甚至都不需要程序来完成,硬件帮你做了。