Lec 14: File system
- Ref: https://github.com/huihongxiao/MIT6.S081/tree/master/lec14-file-systems-frans
- Preparation: xv6 book Chapter 8 except for the logging sections
概述
文件系统的突出特性
- 对用户友好的文件名, 即层级的路径名
- 文件命名有利于用户间和进程间的文件共享
- 文件系统提供了持久化.
文件系统的机制有趣之处
- 文件系统对硬件的抽象
- 崩溃安全(Crash Safety). 计算机崩溃后重启文件系统的数据仍然存在.
- 文件系统在磁盘上的排布. 即文件系统的结构和内容在磁盘上对应的数据结构.
- 性能. 文件系统的缓冲区缓存(buffer cache)或块缓存(block cache). 并发操作.
文件系统相关的系统调用
系统调用 API
- 创建文件:
fd=open("x/y", _);
- 写文件:
write(fd, "adc", 3);
- 创建链接:
link("x/y", "x/z");
- 删除特定文件名:
unlink("x/y");
特点
- 接口中的路径名是可识别的(human readable), 是由用户选择的字符串
write()
系统调用写入的文件位置隐式包含在文件系统中- 文件系统内部, 文件描述符与某个文件对象关联, 而该文件对象不依赖于文件名. 即使文件名改变, 通过文件描述符仍能指向或引用相同的文件大小.
- 仍存在其他方式能组织存储系统. 如数据库系统.
文件系统的结构
inode
- 代表一个文件对象, 不依赖于文件名
- 通过自身编号进行区分
- 需要通过 link count 和 openfd count 来记录文件的引用计数和打开文件的文件描述符计数, 只有两个计数均为 0 时可删除文件.
文件描述符
- 维护了对于文件的偏移(offset)
- 主要用于与用户进程进行交互
文件系统的分层结构
分层自底向上:
- 磁盘. 实际保存数据的存储设备, 用于提供持久化存储.
- 缓冲区缓存(buffer cache/block cache): 避免频繁读写.
- 记录层(logging). 用于保证持久性.
- inode cache. 主要为了向单个 inode 提供同步操作, inode 小于一个磁盘块(disk block), 通常多个 inode 打包存储在一个 disk block 中.
- inode. 实现了
read
,write
系统调用. - 文件名和文件描述符.
- 注: 以上是一个宽泛的文件系统分层结构, 不同文件系统会存在差异, 且分层可能没有那么严格的界限.
存储设备
- 术语:
- 扇区(sector): 磁盘驱动可读写的最小单元, 通常 512B. 有时也被称为 block.
- 块(block): 操作系统或文件系统视角的数据, 有文件系统定义. 通常 1 个 block 对应多个扇区.
- 通过以 block 编号为参数的 read/write 接口进行磁盘的读写.
- 磁盘驱动使用标准协议屏蔽硬件(SSD/HDD)的差异.
block cache
- 文件系统角度可将磁盘视为一个 block 数组.
- XV6 的磁盘布局结构:
- block0 要么不使用, 要么用作启动扇区(boot sector)启动操作系统
- block1 被称为 super block. 描述了文件系统, 构造了大部分文件系统的信息.
- log 存储在 block2 到 block32.
- inode 存储在 block32 到 block45.
- bitmap block. 构建文件系统的默认方法. 只占 1 个 block, 记录了数据 block 是否空闲.
- 之后全是数据 block. 存储文件的内容和目录的内容.
- 注: bitmap block, inode blocks 和 log blocks 被统称为 metadata block. 不存储实际数据.
- inode(64B) 和 block(1024B) 对应关系:
b l o c k = 32 + i n o d e # × 64 1024 block =32+\frac{inode\#\ \times 64}{1024} block=32+1024inode# ×64
inode
-
XV6 inode 组成:
- type: 表明是空闲, 文件还是目录
- nlink: link 计数器.
- size: 文件数据的字节数
- 直接块编号(direct block number): 共 12 个编号, 对应着构成文件的前 12 个block 的编号. 根据文件大小有些编号不会被使用
- 间接块编号(indirect block number): 对应磁盘上 1 个 block, 包含 256 个块编号, 每个编号 4B. 每个块编号再指向文件的 1 个 block.
-
XV6 文件最大为:
( ∣ d i r e c t b l o c k n u m b e r ∣ + ∣ i n d i r e c t b l o c k n u m b e r ∣ ) × b l o c k s i z e = ( 12 + 256 ) × 1024 B = 268 K B (|direct\ block\ number|+|indirect\ block\ number|)\times block\ size=(12+256)\times 1024B=268KB (∣direct block number∣+∣indirect block number∣)×block size=(12+256)×1024B=268KB
目录
-
特性: 层次化的命名空间(hierarchical namespace).
-
大部分 Unix 文件系统的目录本质上是 1 个文件加上一些文件系统能够理解的结构.
-
XV6 目录: 包含多个目录项(directory entry), 每个 entry 前 2B 包含目录中文件或者子目录的 inode 编号. 接下来 14B 包含文件或子目录名.
-
XV6 的文件查找采用的是线性扫描.
block cache 代码特点
- 在内存中, 每个 block 只能有一份缓存
- 每个 block 持有的是 sleep lock, 用于 I/O 操作 该锁的特点是获取锁时若未获取到进程会进入休眠状态, 这意味着该锁可以长期持有.
- 采用 LRU 作为 block cache 的替换策略
- 两层锁: 第一层用来保护 buffer cache 的内部数据; 第二层用来包含单个 block 的缓存.