关注了就能看到更多这么棒的文章哦~
Toward fast, containerized, user-space filesystems
By Jonathan Corbet
November 6, 2025
Gemini flash translation
https://lwn.net/Articles/1044432/
文件系统是复杂且对性能敏感的“野兽”。它们也可能带来安全问题。基于微内核(microkernel)的系统长期以来一直将文件系统放在独立的进程中,从而期望遏制可能在其中发现的任何漏洞。Linux 可以通过 用户空间文件系统 (FUSE) 子系统做到这一点,但使用 FUSE 会带来显著的性能损失。Darrick Wong 正在努力消除这种性能损失,他发布了 一个庞大的补丁集,展示了非特权进程如何在用户空间安全地实现 ext4 文件系统,并获得良好的性能。这项工作有潜力彻底改变 Linux 系统上文件系统的管理方式。
文件系统实现面临的最大挑战之一是需要解析和维护一个复杂的数据结构,而这个数据结构可能完全受攻击者控制。几乎任何 Linux 文件系统实现都可能被恶意构造的文件系统镜像所损害。虽然大多数文件系统通常对损坏的镜像具有鲁棒性,但恶意的损坏(malicious corruption)则是另一回事,大多数文件系统开发者在防范这种情况上投入的精力有限。因此,挂载文件系统——在某些保护措施(例如防止过度挂载系统目录或添加 setuid 二进制文件)到位时,这本应是已经确保安全的操作——仍然仅限于特权用户。
然而,如果文件系统元数据(metadata)的管理被移动到用户空间,那么恶意镜像可能造成的破坏潜力将大大降低。FUSE 正好允许这样做,但所有文件系统 I/O 都需要通过连接传递给用户空间的 FUSE 服务器,这种开销使得 FUSE 文件系统速度缓慢。Wong 试图解决这个问题的方法乍一看有些令人望而生畏;它由五个独立的补丁主题组成,其中大部分又包含多个子部分。总共有 182 个补丁。虽然复杂度很高,但核心思想相对简单。
Iomap
文件系统会移动大量数据。FUSE 文件系统的大部分额外开销来自于在请求文件系统操作时,需要在内核和 FUSE 服务器之间传递数据。如果一个进程向 FUSE 文件系统上的文件写入一些数据,内核必须将这些数据传递给用户空间的 FUSE 服务器来执行写入;然后,该服务器几乎肯定会将数据 再次 传递给内核,以便最终将其存入持久存储。一个显而易见的改进方法是设法将数据移动限制在内核内部,而只让 FUSE 服务器告诉内核数据块应该从哪里读取或写入。这将允许 FUSE 服务器处理元数据管理,同时消除 I/O 路径中的额外开销。
归根结底,文件系统的大部分工作在于维护文件内部逻辑偏移量(logical offsets)与持久存储上的物理位置之间的映射。一旦完成这项工作,文件 I/O 就归结为利用这些映射在数据块之间来回移动数据——这是一项独立于任何给定文件系统的任务。(当然,每位阅读此文的文件系统开发者现在都会对这种极端简化感到愤怒;对此也无能为力。)内核提供了各种机制来管理这种映射,包括 缓冲区头(buffer heads),这在 Linux 内核的首次公开发布中就已存在。
然而,在更近期的版本中,这项映射任务得到了内核中 iomap 层的支持。它最初由 Christoph Hellwig(基于 XFS 文件系统的旧代码)于 2016 年为 4.8 版本 引入,此后其他文件系统也一直在慢慢使用它。iomap 层抽象出了许多细节,简化了文件系统方面的问题。其核心是文件系统必须提供的 两个回调函数:

不深入细节,iomap_begin() 请求文件系统为给定 inode 在从 pos 开始的 length 字节范围内指定磁盘上的映射。当内核完成映射后,它将通过调用 iomap_end() 通知文件系统。在此期间,内核很可能会使用该映射在内存和文件系统的存储设备之间移动数据。
Wong 系列的 子部分 4 为 FUSE API 添加了两个新操作:FUSE_IOMAP_BEGIN 和 FUSE_IOMAP_END。这些操作对应于上述的两个回调函数,允许用户空间文件系统在内核中构建一个 I/O 映射,然后内核可以使用该映射直接执行许多 I/O 操作,而无需进一步涉及用户空间服务器。虽然长期目标是实现非特权文件系统挂载,但 FUSE 中使用 iomap 的能力目前仅限于拥有 CAP_SYS_RAWIO 能力的进程。
提供基本的 iomap 访问可以通过避免在内核和用户空间之间移动文件数据来加速 FUSE 服务器,但要达到高水平性能还需要做更多工作。其中一步是 这个系列:它允许内核缓存由 FUSE 服务器创建的 iomap 映射。这减少了往返服务器的次数,同时也是在 I/O 可能导致映射改变的情况下正确管理映射所必需的。另一个性能改进来自 这个系列,它将时间戳和访问控制列表(access-control lists)的大部分管理工作转移到内核中。
最后,这个短系列 允许特权挂载助手(mount helper)设置一个特殊位,使 FUSE 服务器进程能够使用 iomap 功能,无论它是否拥有 CAP_SYS_RAWIO。这使得服务器进程可以在非特权模式下运行,从而开启了在无法损害系统的非特权进程中实现文件系统的可能性。
用户空间
然而,这仅仅是问题在内核侧的解决方案。该系列还有另外五个子部分,用于向 libfuse 用户空间库添加相应的支持。此外,还有六个子部分向 fuse2fs 添加了对新 FUSE 功能的支持,fuse2fs 是在用户空间实现 ext4 文件系统(以及 ext3 和 ext2)的服务器程序。正如 Wong 在 子部分 1 中指出的,结果令人鼓舞:
这个新数据路径的性能相当惊人:在热系统上,通过页缓存(pagecache)的流式读写速度从 60-90MB/s 提升到 2-2.5GB/s。直接 I/O(Direct IO)的读写从相同的基准提升到 2.5-8GB/s。FIEMAP 和 SEEK_DATA/SEEK_HOLE 现在也工作了。内核 ext4 驱动器对于页缓存 I/O 可以达到大约 1.6GB/s,对于直接 I/O 可以达到大约 2.6-8.5GB/s,这意味着 fuse2fs 对于流式文件 I/O 来说,速度几乎与内核一样快。
他也承认,目前随机缓冲 I/O 的结果并不理想。
该补丁系列包含了大量支持运行非特权 FUSE 文件系统服务器的工作,进一步遏制了因受损(或恶意)FUSE 服务器而可能造成的任何影响。整个系列以 一个包含 33 个补丁的子部分 结束,该部分增加了对 FUSE 下 ext4 的测试支持。
前景
这是一项带来明显益处的大量工作,但对于文件系统开发者来说,吸收这些内容也是一项巨大的挑战。即便如此,Wong 在封面信中表示,他希望能在 6.19 内核发布时合并这些补丁。这看起来相当雄心勃勃。Hellwig 要求 将该系列拆分,并使其更易于审查;目前尚不清楚 Wong 是否打算这样做。他还没有开始编写 iomap 更改的文档,尽管这项工作肯定在他的待办事项列表首位。当然,所有这些工作在合并之前都需要经过审查,并可能进行修订。
因此,总而言之,如果这些更改在 6.19 版本中实际落地,那将有些令人惊讶。但是,鉴于这项工作带来的明显价值,Wong 很可能在不远的将来成功地将其上游化。如果他的成果在更广泛的使用中得到验证,发行商和系统集成商可能会开始销售带有 FUSE 实现文件系统的系统,这将是 Linux 系统自诞生以来工作方式的一个重大改变。Linux 可能永远不会成为微内核,但它很快就会看起来比现在更像微内核系统。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

1829

被折叠的 条评论
为什么被折叠?



