# 第 43 章实验:日志结构文件系统(LFS) 本目录有两个小实验: | 文件 | 做什么 | | --- | --- | | `seqbuf.c` | 在真实磁盘上测“写缓冲”的效果:随机 4KB 写、顺序但逐块落盘、攒成段再顺序写(段大小 16KB~8MB),每次落盘都调用 `fdatasync()` | | `lfs_mini.py` | 一个迷你 LFS 模拟器(思路仿 ostep-homework 的 `lfs.py`):CR、imap 片段、inode、目录块、段摘要块 SS,支持创建/写/删除/硬链接,以及按书中伪代码判断存活并清理段 | ## 怎么跑 ```bash cd labs/43-lfs make # 编译 seqbuf ./seqbuf # 约 5~10 秒,会在当前目录建一个 64MB 的临时文件,结束后删掉 python3 lfs_mini.py -L "c,/foo:w,/foo,0,1" -c python3 lfs_mini.py -L "c,/foo:w,/foo,0,1:w,/foo,1,1:w,/foo,2,1:w,/foo,3,1" -c python3 lfs_mini.py -L "c,/foo:w,/foo,0,4" -c python3 lfs_mini.py --demo-clean make run # 一次跑完上面三类 ``` `lfs_mini.py` 的命令格式(与 `lfs.py` 的 `-L` 相同): `c,/路径` 创建文件,`d,/路径` 创建目录,`w,/路径,起始块,块数` 写文件,`r,/路径` 删除,`l,/已有,/新名` 建硬链接。 `-c` 在每个块前标出 `live`(从 CR 出发可达)。 ## 该观察到什么 ### seqbuf - 每次 `fdatasync()` 都有一笔近似固定的开销(本机约 1ms,相当于原书里的 Tposition)。 只写 4KB 就落盘,带宽只有几 MB/s——**不管是随机写还是顺序写**。这正是原书 43.2 节说的: “仅仅按顺序写还不够,必须一次写很多”。 - 段越大,固定开销被摊得越薄,带宽一路上涨,最后接近设备的峰值(本机几百 MB/s)后趋于平缓。 用原书式 (43.6) 可以反推:若 Tposition≈1ms、Rpeak≈500MB/s,想拿到 90% 峰值需要 D = 0.9/0.1 × 500MB/s × 0.001s ≈ 4.5MB,和实测“4MB 段附近开始饱和”吻合。 - 在 WSL2 的虚拟磁盘(底层通常是 SSD)上,随机与顺序的 4KB 写差别不大;在机械硬盘上随机写会慢一个数量级。 但“攒大块再写”在两种设备上都有效——这也是原书总结里说 LFS 风格在 SSD 上同样有意义的原因。 ### lfs_mini.py - `c,/foo:w,/foo,0,1`:创建文件写出 I[1]、新目录块、新根目录 inode、imap 片段;写一个块写出 **数据块 D → inode I → imap 片段**, 然后 CR(地址 0)指向最新的 imap 片段。 - 四次单块写 vs 一次写四块:最终存活块数一样多(9 个),但前者多写了 6 个块的垃圾(旧 inode、旧 imap 片段)—— 这就是为什么真实 LFS 要在内存里缓冲更新。 - `--demo-clean`:第一轮直接回收“全死”的段;第二轮清理利用率最低的两个段,逐块打印 `(N, T) = SS[A]` 判断存活, 搬走活块后还要重写相关 inode 和 imap 片段,于是**其他段里的旧 inode 也变成了垃圾**(S5 从 5/7 降到 2/7)。 清理前后文件内容(每块的版本号)完全相同。 ## 示例输出(你的机器上数字会不同) ``` mode write total syncs time(s) MB/s ms/sync 1 rand-inplace 4 KB 2000 KB 500 0.485 4.03 0.969 2 seq-sync-each 4 KB 2000 KB 500 0.420 4.65 0.840 3 seg-buffered 16 KB 65536 KB 4096 4.945 12.94 1.207 3 seg-buffered 64 KB 65536 KB 1024 1.121 57.12 1.094 3 seg-buffered 256 KB 65536 KB 256 0.436 146.72 1.704 3 seg-buffered 1024 KB 65536 KB 64 0.301 212.95 4.696 3 seg-buffered 4096 KB 65536 KB 16 0.138 463.15 8.637 3 seg-buffered 8192 KB 65536 KB 8 0.145 442.38 18.084 ```