第八十九章:btrfs 之术
斩灵期涉及内核源码:
一
林小源在森林的另一端发现了一棵与众不同的树。
这棵树的树干是半透明的,内部的结构清晰可见——不是 ext4 那种 Block Group 的方阵,而是一棵倒挂的 B-tree。树根在上,树冠在下,每一层枝干都分出无数细小的分支。
"你是什么?"林小源问。
"btrfs,"树发出一个年轻而自信的声音,"新一代文件系统。你还在用原地修改的老办法?我用的是 COW——Copy-on-Write。"
"写时复制?"
"对,"btrfs 树说,"每次修改数据,我不覆盖原来的位置。我分配一个新块,把修改写到新块里,然后更新指针。原来的数据块保留不动。"
林小源绕着树走了一圈,观察树干内部的 B-tree 结构。每个节点都是一块数据,节点之间通过指针连接。当一个节点被修改时,新节点出现在旁边,旧节点依然保留。
"那旧节点什么时候删除?"
"快照不用了的时候,"btrfs 树说,"这就是我的杀手锏——快照。因为 COW 的特性,创建快照只需要复制 B-tree 的根节点,共享所有子节点。几乎不占额外空间。"
林小源伸手触摸树干。树皮温热,表面有一层细密的纹路——每个纹路都是一个校验和。
"校验和?"
"每个数据块都有,"btrfs 树说,"CRC32C。读取的时候验证——如果校验和不匹配,说明数据损坏了。ext4 不做这个检查,磁盘上的数据坏了它不知道。我知道。"
二
林小源在 btrfs 树下坐了下来。
他闭上眼睛,将神识沉入 B-tree 的深处。树的每一层都有不同的数据——最顶层是元数据,中间层是 extent 信息,最底层是实际的数据块。整个结构像一座倒挂的金字塔。
"你的数据都用 B-tree 组织?"他问。
"所有东西,"btrfs 树说,"文件数据、inode 信息、目录内容、校验和——全部用 B-tree。一个统一的结构,管理所有数据。"
"ext4 用的是独立的结构——inode table、block bitmap、extent tree 各管各的。"
"所以 ext4 的管理是分散的,"btrfs 树说,"我的是统一的。添加新功能不需要改磁盘布局——在 B-tree 里加一种新的 item 就行。"
林小源睁开眼睛,发现树干上有一处凹陷。凹陷里嵌着一个小小的晶体,晶体表面刻着"zlib""lzo""zstd"的字样。
"压缩?"
"透明压缩,"btrfs 树说,"写入的时候自动压缩,读取的时候自动解压。应用完全感知不到。可以节省 30% 到 50% 的磁盘空间。"
"性能呢?"
"看算法,"btrfs 树说,"zstd 压缩率高,CPU 开销适中。lzo 速度快,压缩率低。zlib 压缩率最高,但 CPU 开销大。你可以选。"
三
林小源在 btrfs 树的树冠处发现了一个裂缝。
裂缝里透出暗红色的光,像是内部有什么东西在燃烧。他凑近看——裂缝深处有一块区域的 B-tree 节点排列杂乱,指针交错,像是被什么东西搅乱了。
"这是什么?"
btrfs 树的声音变得有些尴尬:"RAID 5/6 的元数据。这块……还不太稳定。"
"你不完美?"
"我在发展中,"btrfs 树说,声音坦诚,"COW、快照、校验和、压缩、子卷——这些都成熟了。但 RAID 5/6 的元数据平衡还有 bug。用的人不多,测试还不够充分。"
林小源退后一步,看着 btrfs 树。它比 ext4 年轻,也比 ext4 大胆——COW 的设计带来了快照、校验和、压缩等高级特性,但也带来了碎片化、写放大等新问题。
"你和 ext4 谁更好?"
"看场景,"btrfs 树说,"需要快照和校验和,选我。需要稳定和成熟,选 ext4。没有绝对的好坏——只有合不合适。"
林小源点了点头。他站起身,拍了拍 btrfs 树的树干。树干微微震颤,像是在笑。
"新需要时间来成熟,"他说。
"但未来是我的,"btrfs 树说。
归根结底,新树的根就是 COW——写时复制撑起了一切,快照、校验和、压缩,全都从这一个机制长出来。
/*
* btrfs 的核心特性:
*
* 1. Copy-on-Write (COW)
* 修改数据时写到新位置
* 不覆盖原有数据
* 快照的基础
*
* 2. B-tree 存储
* 所有数据和元数据都用 B-tree 组织
* 包括文件数据、inode、目录
*
* 3. 校验和
* 每个数据块都有校验和
* 检测数据损坏
*
* 4. 压缩
* 支持透明压缩
* zlib, lzo, zstd
*
* 5. 子卷
* 文件系统可以有多个子卷
* 每个子卷可以独立挂载
*
* 6. 快照
* 基于 COW 的快照
* 几乎不占用额外空间
*/
printf("=== btrfs — COW 文件系统 ===\n\n");
printf("btrfs vs ext4:\n");
printf(" ext4:\n");
printf(" 原地修改\n");
printf(" 日志保证一致性\n");
printf(" 成熟稳定\n\n");
printf(" btrfs:\n");
printf(" COW(写时复制)\n");
printf(" 校验和保证数据完整性\n");
printf(" 支持快照、压缩、子卷\n\n");
printf("--- COW 工作原理 ---\n");
printf("修改前:\n");
printf(" 原始数据块 A\n\n");
printf("修改时:\n");
printf(" 分配新块 B\n");
printf(" 把修改写到 B\n");
printf(" 更新指针指向 B\n\n");
printf("修改后:\n");
printf(" 原始块 A 保留(快照使用)\n");
printf(" 新数据在块 B\n\n");
printf("--- B-tree 组织 ---\n");
printf("btrfs 的 B-tree:\n");
printf(" root\n");
printf(" ├── inode items\n");
printf(" ├── file data extents\n");
printf(" ├── directory items\n");
printf(" └── checksums\n\n");
printf("--- 校验和 ---\n");
printf("每个数据块有校验和:\n");
printf(" 数据块 + CRC32C 校验和\n");
printf(" 读取时验证\n");
printf(" 检测静默数据损坏\n\n");
printf("--- 压缩 ---\n");
printf("透明压缩:\n");
printf(" 压缩算法: zlib, lzo, zstd\n");
printf(" 自动压缩/解压\n");
printf(" 节省磁盘空间\n");#include <stdio.h>
/*
* btrfs 的核心特性:
*
* 1. Copy-on-Write (COW)
* 修改数据时写到新位置
* 不覆盖原有数据
* 快照的基础
*
* 2. B-tree 存储
* 所有数据和元数据都用 B-tree 组织
* 包括文件数据、inode、目录
*
* 3. 校验和
* 每个数据块都有校验和
* 检测数据损坏
*
* 4. 压缩
* 支持透明压缩
* zlib, lzo, zstd
*
* 5. 子卷
* 文件系统可以有多个子卷
* 每个子卷可以独立挂载
*
* 6. 快照
* 基于 COW 的快照
* 几乎不占用额外空间
*/
int main() {
printf("=== btrfs — COW 文件系统 ===\n\n");
printf("btrfs vs ext4:\n");
printf(" ext4:\n");
printf(" 原地修改\n");
printf(" 日志保证一致性\n");
printf(" 成熟稳定\n\n");
printf(" btrfs:\n");
printf(" COW(写时复制)\n");
printf(" 校验和保证数据完整性\n");
printf(" 支持快照、压缩、子卷\n\n");
printf("--- COW 工作原理 ---\n");
printf("修改前:\n");
printf(" 原始数据块 A\n\n");
printf("修改时:\n");
printf(" 分配新块 B\n");
printf(" 把修改写到 B\n");
printf(" 更新指针指向 B\n\n");
printf("修改后:\n");
printf(" 原始块 A 保留(快照使用)\n");
printf(" 新数据在块 B\n\n");
printf("--- B-tree 组织 ---\n");
printf("btrfs 的 B-tree:\n");
printf(" root\n");
printf(" ├── inode items\n");
printf(" ├── file data extents\n");
printf(" ├── directory items\n");
printf(" └── checksums\n\n");
printf("--- 校验和 ---\n");
printf("每个数据块有校验和:\n");
printf(" 数据块 + CRC32C 校验和\n");
printf(" 读取时验证\n");
printf(" 检测静默数据损坏\n\n");
printf("--- 压缩 ---\n");
printf("透明压缩:\n");
printf(" 压缩算法: zlib, lzo, zstd\n");
printf(" 自动压缩/解压\n");
printf(" 节省磁盘空间\n");
return 0;
}道藏笔记
内核启示
btrfs 是基于 COW(写时复制)的新一代文件系统。它的核心思路是:修改数据时不覆盖原来的位置,而是写到新块里,然后更新指针。旧数据保留着——这就是快照的基础。
它所有数据都用 B-tree 组织,文件数据、inode 信息、目录内容、校验和全在一个统一的结构里。添加新功能不需要改磁盘布局,往 B-tree 里加一种新的 item 就行。每个数据块都有 CRC32C 校验和,读取时验证——数据坏了它能发现,ext4 做不到这一点。
透明压缩也是 btrfs 的亮点,写入时自动压缩,读取时自动解压,应用完全感知不到,能省 30% 到 50% 的磁盘空间。
跟 ext4 比,btrfs 功能更丰富但还没那么成熟。需要快照和校验和选它,需要稳定和成熟选 ext4。没有绝对的好坏,只有合不合适。
btrfs 之试
本章讲写时复制、校验和、B-tree 等能力时,核心文件系统是哪一个?