Directory
目录定义
目录是一种特殊的有结构文件。目录中的每条记录对应一个文件或子目录,这条记录称为目录项。
一个 FCB 就是一个文件目录项,FCB 的有序集合就是文件目录。
!457
目录结构
单级目录
整个系统只有一张目录表。它实现简单,但所有文件共享同一命名空间,不允许重名,不适合多用户系统。
两级目录
两级目录分为:
- MFD:主文件目录,记录用户名及其用户文件目录位置。
- UFD:用户文件目录,由该用户文件的 FCB 组成。
两级目录允许不同用户使用相同文件名,也可以在用户目录层面做访问限制。但用户仍不能灵活分类自己的文件。
树形目录
树形目录也称多级目录。目录之间形成层次关系,既便于分类,也允许不同目录中出现同名文件。
文件路径名是从某个起点出发,依次写出沿途各级目录名和目标文件名所形成的名称序列。操作系统按照这个序列逐级查找目录项,最终定位文件。
绝对路径以根目录为起点,路径的开头是 /。无论进程当前位于哪个目录,同一绝对路径都指向同一位置。例如:
1 | /照片/2015-08/自拍.jpg |
相对路径以进程的当前工作目录为起点。例如当前目录是 /照片 时,可以写:
1 | 2015-08/自拍.jpg |
其中 . 表示当前目录,.. 表示上一级目录。设置当前目录后,访问附近文件不必每次都从根目录开始查找,可以减少路径长度和目录读取次数。
无环图目录
树形目录不便共享文件。无环图目录允许多个目录项指向同一个文件或目录节点,用有向无环图表达共享关系。
共享节点通常设置共享计数器。删除某个目录项时,只减少共享计数;只有计数变为 0,才真正删除共享节点。
目录操作
目录系统至少要支持:
| 操作 | 含义 |
|---|---|
| 搜索 | 根据文件名找到对应目录项 |
| 创建文件 | 在目录中增加目录项 |
| 删除文件 | 从目录中删除目录项,并配合回收文件空间 |
| 显示目录 | 显示目录中所有文件及其属性 |
| 修改目录 | 文件重命名、属性变化时修改目录项 |
文件链接
硬链接
基于 inode 的共享方式也称硬链接。目录项保存文件名和 inode 号,因此硬链接 f1、f2 是两个文件名不同、inode 号相同的目录项。磁盘 inode 中的链接计数 count 表示有多少目录项指向它。
路径查找完成后,内核会按“文件系统 + inode 号”查找 inode 缓存。两个进程分别打开 f1、f2 时,通常会引用同一个内存 inode,因而看到同一份文件属性和数据;但两次 open 通常建立两个独立的打开文件描述,当前读写偏移互不影响。只有通过 dup 复制文件描述符,或通过 fork 继承同一打开文件描述时,才会共享读写偏移。
删除某个硬链接时:
- 删除该用户目录中的目录项。
- inode 的
count减 1。 count=0后,文件不再有路径名;若仍有进程打开它,数据会保留到最后一个打开引用关闭。只有链接计数和打开引用都归零,文件数据和 inode 才会被回收。
硬链接不会因为某个目录项删除而立即造成数据丢失,但通常要求共享者位于同一文件系统内。
不能给目录文件创建硬链接。若目录可以任意硬链接,目录树可能出现环,路径遍历、递归删除、备份和引用计数回收都会变得复杂,甚至可能无限循环。
目录中的 . 和 .. 是由文件系统维护的特殊目录项,不是普通用户创建的目录硬链接。
软链接
软链接也称符号链接。它本身是一个特殊文件,文件内容记录目标文件路径。
访问软链接时,操作系统先发现它是 Link 类型文件,再根据其中保存的路径继续查目录,最终找到目标文件。
软链接类似快捷方式。若目标文件被删除,软链接本身仍存在,但再通过该路径就找不到目标文件。
即使目标文件被删除,由于软链接这个文件本身仍存在,所以 count 为 1 。