本文首发于稀土掘金。该平台的作者 逐光而行 也是本人。
文件系统目录实现
在何处存放文件属性
- 直接存放在目录项中
(u1s1,我感觉Windows也是这样的)
- 对于采用i节点的系统,把文件属性放在i节点中。
如何支持可变长的文件名
- 给予文件名一个长度限制
(像关系型数据库的表一样,设定最大长度255,不过就是有点浪费空间)
- 在内存中,划定某一块存放文件a的信息,下一块存b,依次类推。
(让我联想到了写c代码的时候的变量放置位置还有那个对应的内存占用表,最好把相同类型的放一处,把空间占满,比如先全设int,再全放double。。咳咳。。只可意会,没法言传)
- 文件项存放指向文件名的指针和文件属性,专门有个堆存放文件名信息。
- 加快查找速度可以考虑哈希表
适用于经常有很多数量文件的系统,否则管理的开销也很大。
- 使用cache
适合查询目标密集的情况
共享文件
linked机制表明文件系统本质是个有向无环图(注意:不是树)
linked的两种实现方式
- 磁盘块列入与该文件相关的小型数据结构(如i节点),目录将指向该数据结构(类似于指针记录的用法)
存在的问题是如果文件所有者将文件删除,该节点被重新分配,链接文件指向的是无效的节点。
- 不用指针,用符号链接,即产生链接后在原文件目录下产生一个新文件,里面存放所链接的文件的路径。
会产生额外开销,且查找目录时被链接的文件将多次被定位到。
日志结构文件系统(Log-structured file system)
- 市场需求:未来多数磁盘访问是零碎的写操作。
- 工作原理:通过索引维护分散在整个日志中的i节点。所有写操作最初都被缓冲在内存中,并周期性地把所有已缓冲的写作为独立端,在日志末尾处写入磁盘。
- 如何解决磁盘空间不够大,日志可能占满磁盘的问题?
有清理线程,周期性扫描日志以进行磁盘压缩。
日志文件系统
- 思想:保存一个用于记录系统下一步要做什么的日志,如果系统崩溃了,重启后还可以通过查看日志继续未完成的任务。
- 为了让文件系统工作,被写入日志的操作必须是幂等的。可以引入 事务 来减少失误。
虚拟文件系统(VFS)
绝大多数UNIX OS都使用虚拟文件系统的概念,尝试将多种文件系统统一成有序结构。
大多数VFS应用的本质上都是面向对象的,抽象出所有文件系统都共有的部分。
磁盘空间管理
把文件系统分割成固定大小的块来存储,各块之间不一定相邻。
如何记录跟踪空闲块?
- 用空闲磁盘块存放空闲表
- 位图。n个块的磁盘只需要n位的位图。
如何避免过多磁盘I/O?
拆分满了的指针块。
如果内核是分页的,把位图放在虚拟内存内,在需要时将位图的页面调入。
文件系统的一致性
- 块一致性
- 文件一致性
UNIX的fsck,Windows的scandisk都可用于检查一致性。
提升文件系统性能
- cache
- 块提前读
- 减少磁盘臂运动
磁盘碎片整理
Windows的defrag可以移动文件,从而把大部分空闲空间放在一个或多个大的连续区域内。
Linux选择磁盘块的方式使得它很少需要手动的磁盘碎片清理。
!!注意:不要在固态硬盘上进行这一操作!!
参考书籍
《现代操作系统》 Andrew S.Tanenbaum,Herbert Bos著,陈向群,马洪兵等译