前面我们挖了一个大坑,计划写一些列的文章,介绍如何从零开发一个文件系统。但是前一段时间一直在忙着写一本关于存储方面的书,原定的关于从零开发文件系统的相关文章就一直没有更新。最近这本书已经交稿,可以稍微有点空闲的时间,打算把原来挖的坑给天上。
写作这一系列文章的源起是我的拙著《文件系统技术内幕》介绍了文件系统的原理和流程,并结合了一些的开源实现。很多读者朋友反馈开源项目过于庞大,代码阅读比较费劲。因此,这里想搞一个五脏俱全的小文件系统,一方面能够解释清楚文件系统的原理,另外一方面能够带领大家从零实现一个文件系统,增加大家的动手能力。
本系列文章基于如下约定:
核心理念:每章实现一个可编译、可挂载、可测试的文件系统实例,功能逐章递增。
技术栈:C++17 / Linux / libfuse3 / CMake /Ubuntu 20.04
代码演进路线:HelloFS → MemFS(v1
v5) → DiskFS(v1v7) → ProdFS
如果有精力和机缘的话,我也希望本系列文章能够成为一本书,可以是电子书或者纸质书。所以,后续的内容以书籍的形式组织,大家姑且认为是一本书吧。最近几天,我认真思考了一下内容的框架,希望通过本书的介绍,大家能够对文件系统的核心内容有有一个相对全面的理解。全书内容遵循由易到难,由简单到复杂的顺序组织。整体而言,本书分为如下几部分,不仅仅包含单机文件系统,还包括分布式文件系统的内容。
第一部分:基础篇 —— FUSE3 与内存文件系统(第1~6章)
第二部分:持久化篇 —— 从内存到磁盘(第7~10章)
第三部分:可靠性篇 —— 日志、缓存与一致性(第11~13章)
第四部分:进阶篇 —— 高级特性与生产实践(第14~15章)
第五部分:分布式篇 —— 从单机到集群(第16~20章)
接下来我们介绍一下规划的内容,让大家能够对这一系列文章有个整体的认知。整本书的开发基于FUSE3开发,而不是基于Linux内核。原因很简单,Linux内核文件系统会极大的提高学习门槛,而基于FUSE3的文件系统可以在用户态开发,大家学起来会非常方便。
第一部分:基础入门篇 —— 从 HelloFS 到内存文件系统
本部分实现一个基于内存的文件系统,所谓基于内存是数据存储在内存当中而不是持久化到硬盘中。希望通过本部分的介绍能够让大家理解文件系统的核心概念,如文件系统的层次结构、文件的数据组织、属性和扩展属性及目录数据等。
第 1 章:文件系统原理与 FUSE3 环境搭建
本章先梳理文件系统在操作系统中的核心定位,详解 VFS 虚拟文件系统的桥梁作用,区分内核与用户态文件系统的差异,并拆解从open()系统调用到磁盘 I/O 的完整执行路径,夯实底层原理基础;再深入剖析 FUSE 架构,讲解内核模块与用户态库的协作机制、/dev/fuse设备通信协议及 FUSE3 与 FUSE2 的核心差异,完成 libfuse3 开发环境搭建、CMake 项目配置与基础编译挂载流程,最终实现极简 HelloFS 只读文件系统,验证 FUSE 基础开发流程,达成ls、cat基础命令可正常运行的目标。
第 2 章:基于内存的只读文件系统
本章围绕 inode 与目录项核心概念,设计内存文件系统的核心数据结构,通过哈希表与映射表实现 inode 统一管理与目录子项关联,构建多级目录与多文件的内存文件树;重点实现getattr()、readdir()、read()等核心 FUSE 回调函数,完成规范化路径解析逻辑,解决路径分割、特殊字符处理等问题,最终开发出 MemReadFS,支持完整的目录浏览、文件读取与stat信息查询,实现从单文件到结构化文件树的升级。
第 3 章:支持写入的内存文件系统
本章在只读内存文件系统基础上,新增 inode 分配回收、引用计数管理机制,完善文件生命周期管控;实现文件创建、写入、截断、删除、重命名等核心写入操作,适配O_CREAT、O_APPEND等文件打开标志位,同时针对 FUSE3 多线程模型引入共享锁与单文件读写锁,保障基础并发安全,最终产出 MemFS v1,支持touch、echo、rm、mv等常规文件操作,具备完整的文件读写修改能力。
第 4 章:完整的目录操作
本章聚焦目录操作完善,实现目录创建、删除核心功能,处理目录中.与..特殊项的关联维护,解决跨目录重命名时父目录引用更新问题,规范目录项管理与目录大小语义;同时实现statfs()文件系统统计接口,合理上报内存文件系统的空间与 inode 信息,最终推出 MemFS v2,支持mkdir -p、rmdir、tree、df等目录相关命令,具备完整的目录层级管理能力。
第 5 章:文件属性与权限模型
本章深入讲解 POSIX 文件权限模型,涵盖 rwx 基础权限、特殊权限位与 umask 机制,基于 FUSE3 的fuse_context获取调用者身份信息,实现chmod()、chown()、access()等权限相关回调函数;同时完善文件时间戳管理与utimens()接口,规范权限检查逻辑,处理 root 用户特殊权限,最终打造 MemFS v3,实现完整的多用户访问控制与文件属性修改,符合 POSIX 权限语义规范。
第 6 章:链接与特殊文件
本章区分硬链接与符号链接的核心差异,实现硬链接link()、符号链接symlink()及readlink()核心接口,维护 inode 链接计数与链接文件路径解析规则,补充特殊文件类型的基础概念与实现逻辑;通过 pjdfstest 测试套件验证文件系统的 POSIX 合规性,修复语义兼容问题,最终完成 MemFS v4,支持软硬链接操作,链接数统计准确,通过核心 POSIX 测试用例,功能完整性进一步提升。
第二部分:持久化篇 —— 从内存到磁盘
上一部分实现的内存文件系统不能称为一个真正的文件系统,因为系统掉电将导致所有数据的丢失。上一部分的内容主要是简化文件系统的开发,让大家更加容易入门文件的开发工作。本部分将实现数据持久化的功能,将文件系统从内存写入磁盘。首先设计块设备抽象层,以普通文件模拟块设备,参考 ext2 简化设计磁盘布局,开发格式化工具完成磁盘映像初始化,为持久化提供存储基础;随后逐步实现持久化读写能力,先完成只读挂载与磁盘数据读取逻辑,推出可读取磁盘预置文件的 SimpleFS v1,再完善磁盘写入、数据刷盘与空闲资源管理,打造支持文件创建、写入、删除且数据可持久化的 SimpleFS v2;最终优化目录操作与重命名功能,实现持久化软硬链接,推出 SimpleFS v3,完成常规单机文件系统核心操作的持久化覆盖,成功打通从内存存储到磁盘持久化的完整链路。
第 7 章:块设备抽象与磁盘布局设计
本章分析内存文件系统掉电丢失的核心痛点,引入磁盘块 I/O 核心概念,设计块设备抽象层,通过普通文件模拟块设备,实现块级读写与 4KB 对齐操作;参考 ext2 简化设计磁盘布局,划分超级块、inode 位图、数据位图、inode 表与数据块区域,定义磁盘 inode 固定结构,开发mkfs.simplefs格式化工具,完成磁盘映像初始化与根目录预分配,产出可复用的块设备模块与格式化工具,为持久化奠定存储基础。
第 8 章:持久化文件系统的挂载与读取
本章实现持久化文件系统的只读核心逻辑,完成超级块加载与校验、磁盘 inode 读取与缓存、目录项磁盘解析与线性查找,通过 inode 块指针实现文件跨块数据读取;构建完整的只读挂载流程,打通getattr()、readdir()、read()的磁盘数据协作链路,最终推出 SimpleFS v1,可挂载磁盘映像并读取预置文件,数据从磁盘加载而非内存,实现基础持久化只读能力。
第 9 章:持久化文件系统的写入
本章围绕磁盘数据持久化写入,实现 inode 与数据块位图的分配释放管理,封装空闲资源申请与回收接口;梳理文件创建、写入、删除的完整磁盘操作流程,处理文件空洞、按需块分配与脏数据刷盘逻辑,实现fsync()数据同步接口,确保元数据与用户数据落盘;最终打造 SimpleFS v2,支持文件创建、写入、删除操作,重新挂载后数据不丢失,具备基础持久化写入能力。
第 10 章:持久化目录与重命名
本章完善持久化文件系统的目录与重命名功能,实现目录创建、空目录删除逻辑,处理目录块增长与空间回收,解决跨目录重命名的原子性操作难题;同时实现持久化软硬链接功能,同步更新磁盘 inode 链接计数与目录项,最终推出 SimpleFS v3,支持完整目录树操作与文件重命名,所有目录、链接操作均可持久化存储,功能覆盖常规单机文件系统核心操作。
第三部分:可靠性篇 —— 日志、缓存与一致性
上一张虽然实现了一个可持久化的简单文件系统,但是还有很多问题,比如可靠性与性能问题,解决持久化过程中的数据一致性、I/O 延迟与大容量存储问题。首先针对崩溃导致的数据不一致问题,引入 WAL 预写日志机制,设计日志系统与崩溃恢复流程,推出可实现完整故障恢复的 SimpleFS v4,提升系统可靠性;随后为解决磁盘 I/O 延迟痛点,设计 LRU 策略的缓冲区缓存与 inode 缓存,优化同步接口并通过性能测试验证效果,产出兼顾可靠性与效率的 SimpleFS v5;最后突破小文件限制,设计多级索引结构支持 GB 级大文件存储,优化空间分配策略减少磁盘碎片,打造支持大文件、稀疏文件操作的 SimpleFS v6,实现可靠性、性能与存储容量的三重提升。
第 11 章:崩溃一致性与日志系统
本章剖析文件系统崩溃导致的数据不一致问题,对比 fsck 事后修复与 WAL 预写日志的优劣,讲解 WAL 事务与日志核心原理;设计磁盘日志区域与日志记录格式,实现日志事务的开启、写入、提交与回滚,将元数据修改纳入日志管控,完成崩溃恢复流程,挂载时自动回放有效事务、丢弃无效操作;最终产出 SimpleFS v4,可在任意写入节点模拟断电后完整恢复,杜绝数据不一致与空间泄漏问题,提升文件系统可靠性。
第 12 章:缓存层与性能优化
本章针对磁盘 I/O 延迟高的痛点,设计 LRU 淘汰策略的缓冲区缓存与 inode 缓存,跟踪脏块与脏 inode 状态,实现缓存与日志的协同工作,规范写入与刷盘顺序;优化sync()、fsync()接口,通过缓存减少重复磁盘 I/O,使用 fio 工具完成性能对比测试,验证缓存提升效果;最终推出 SimpleFS v5,实现延迟写入与批量刷盘,读写性能大幅提升,兼顾可靠性与运行效率。
第 13 章:大文件支持与空间管理
本章突破小文件限制,设计多级索引结构,通过直接块、一级间接块、二级间接块支持 GB 级大文件存储,讲解稀疏文件表示与lseek空洞定位逻辑;优化空间分配策略,采用连续分配与预分配减少磁盘碎片,对比 extent 机制与块指针的优劣;最终打造 SimpleFS v6,支持大文件存储、高效空间分配与稀疏文件操作,解决大容量文件存储与空间利用率问题。
第四部分:进阶篇 —— 高级特性与生产实践
本部分立足生产级需求,完善文件系统高级功能并完成生产环境优化。首先实现扩展属性(xattr)、POSIX ACL 权限管控、内存映射(mmap)、文件锁等高级特性,推出符合企业级需求的 SimpleFS v7;随后针对生产环境进行深度优化,细化 FUSE3 多线程模型、优化锁粒度提升并发性能,搭建完整测试框架(基准测试、压力测试、内存泄漏检测),解决性能瓶颈,最终产出 ProdFS 生产级文件系统。本部分不仅实现了文件系统从基础功能到高级特性的升级,更完成了从开发原型到生产可用产品的转变,同时回顾了从 HelloFS 到 ProdFS 的完整演进历程,为后续进阶方向提供了清晰指引。
第 14 章:扩展属性与高级功能
本章实现文件系统高级特性,完成扩展属性 xattr 的增删改查与 POSIX ACL 权限管控,将 ACL 作为特殊扩展属性存储,适配setfattr、getfacl等工具;支持内存映射 mmap、零拷贝 splice 优化与直接 I/O 操作,实现 POSIX 文件锁与字节范围锁,最终推出 SimpleFS v7,覆盖扩展属性、ACL、mmap、文件锁等高级功能,符合企业级文件系统功能需求。
第 15 章:多线程、性能调优与生产级实践
本章针对生产环境优化,细化 FUSE3 多线程模型,优化锁粒度提升并发性能,启用回写缓存、零拷贝等 FUSE3 高级特性;搭建完整测试框架,通过基准测试、压力测试、内存泄漏检测保障文件系统可靠性,完成性能瓶颈分析与调优;最终产出 ProdFS 生产级文件系统,回顾从 HelloFS 到 ProdFS 的完整演进,梳理模块依赖关系,指明分布式、写时复制等后续进阶方向。
第五部分:分布式篇 —— 从单机到集群
AI的出现使得分布式文件系统再次称为热点,本部分将实现分布式文件系统最核心的功能。首先搭建基于 TCP 的 RPC 通信框架,开发网络块设备服务端与客户端,实现远程磁盘映像挂载,完成从单机到网络的初步过渡;随后采用元数据与数据分离架构,搭建元数据服务器、数据服务器与 FUSE 客户端三组件系统,产出具备基础分布式架构的 DistFS v1;接着引入数据分片、一致性哈希与多副本机制,解决分布式存储的可靠性与扩展性问题,推出支持动态扩缩容的 DistFS v2;再通过客户端缓存与租约机制,降低网络延迟并保障多客户端数据一致性,优化并发性能,产出 DistFS v3;最终基于 Raft 协议实现元数据服务器高可用,完善运维监控与性能优化,打造生产级分布式文件系统 DistFS v4,完整覆盖从单机到集群的开发历程,形成可落地的分布式文件系统实战方案。
第 16 章:网络文件系统基础与 RPC 框架
本章突破单机限制,讲解分布式文件系统的核心价值与业界主流方案,设计基于 TCP 的 RPC 通信框架,实现请求响应序列化与长连接通信;开发网络块设备服务端与客户端,复用本地块设备接口,将磁盘 I/O 转化为网络 RPC 调用,通过 FUSE 实现透明远程挂载;最终产出网络块设备服务端与远程文件系统客户端,支持跨机器挂载远程磁盘映像,完成从单机到网络的初步过渡。
第 17 章:分布式元数据管理
本章采用元数据与数据分离架构,搭建元数据服务器、数据服务器与 FUSE 客户端三组件系统,元数据服务器负责命名空间、inode 与块映射管理,数据服务器负责块存储与心跳上报;客户端通过 RPC 分别对接两类服务器,完成文件打开、读写的远程调用流程,实现基础故障检测与重试;最终产出 DistFS v1,实现三组件协同工作,具备分布式文件系统基础架构。
第 18 章:数据分片与副本机制
本章优化分布式存储可靠性与扩展性,采用固定分片与一致性哈希实现数据块路由,通过虚拟节点解决数据倾斜问题;设计 3 副本流水线写入与机架感知副本放置策略,保障写后读一致性,实现副本丢失检测、补全与集群再平衡;最终推出 DistFS v2,支持多副本存储与一致性哈希路由,任一数据服务器下线后数据仍可正常访问,支持动态扩缩容。
第 19 章:分布式缓存一致性与租约机制
本章针对分布式网络延迟痛点,引入客户端缓存与租约机制,区分读租约与写租约,通过回调失效与序列号机制保障缓存一致性,实现分布式文件锁与死锁检测;优化缓存读写策略,提升多客户端并发读写性能,完成缓存命中率与延迟测试;最终产出 DistFS v3,通过客户端缓存与租约机制大幅降低读延迟,保障多客户端访问的数据一致性。
第 20 章:生产级分布式文件系统实战
本章打造生产级分布式文件系统,基于 Raft 协议实现元数据服务器主备高可用,引入块校验和与后台扫描保障数据完整性;搭建集群运维监控体系,优化小文件合并、大文件并行读写等性能特性,完成容量规划与故障切换设计;最终产出 DistFS v4,回顾从单机到分布式的完整开发历程,梳理系统架构与模块边界,指明纠删码、对象存储、容器化部署等后续优化方向,形成完整的分布式文件系统实战方案。
最后,通过上述内容的实践,大家能够对文件系统的理论有更加深入的认识。通过代码实践,大家可以提升自己的动手能力。通过本书,大家不仅可以知其然,知其所以然,还能真正实现一个完整的系统。