6 个版本 (破坏性更新)
0.11.0 | 2024年7月30日 |
---|---|
0.10.0 | 2024年7月3日 |
0.9.0 | 2024年5月22日 |
0.8.0 | 2024年5月1日 |
0.6.0 | 2024年3月29日 |
535 在 文件系统 中
每月下载 266 次
在 8 个包中使用 (通过 maelstrom-worker)
675KB
17K SLoC
Maelstrom FUSE
此库包含一个用于 Maelstrom 项目的 FUSE 文件系统实现,名为 LayerFS。
有关更多信息,请参阅 GitHub 上的 Maelstrom 项目。
lib.rs
:
此包包含一个名为 LayerFS 的 Linux FUSE 文件系统实现。
简介
该文件系统基于“层”构建,可以相互堆叠。每一层代表一个完整的文件系统,当堆叠在一起时,文件系统会被合并。当文件系统合并时,位于“顶部”的文件系统会被优先考虑。这实现了类似于 overlay-fs 的效果。
磁盘布局
层存储在磁盘上作为一个文件的目录。每个目录包含以下文件
super.bin
包含有关层的所有信息,包括其堆叠在上面的任何层file_table.bin
包含层中所有文件的列表attributes_table.bin
包含层中所有文件的特征<<offset>>.dir_data.bin
包含在文件表中找到的<offset>
目录的内容
请注意,上述所有项目符号都没有提到包含文件数据。大多数文件数据实际上是从层外部的文件中读取的。这就是在LayerFs::from_path
中使用的cache_dir
所用于的。然而,如果一个文件包含少量数据,它实际上可以以“内联数据”的形式存储在属性中,以避免从另一个文件读取的开销。
堆叠
当一个层堆叠在其他层之上时,该层的目录条目可能指向较低层的目录或文件。这是因为FileId
包含一个LayerId
。这允许我们创建上述类似于overlay-fs的功能。
当一个上层包含在较低层也存在的文件时,较低层的文件会被上层文件遮挡。当一个上层包含在较低层也存在的目录时,目录内容会被合并。
+------------------------+ +-----------+
| / layer_id 2 | built from | / |
| `-- a.txt => (2, 10) | <========== | `-- a.txt |
| `-- b.txt => (2, 3) | +-----------+
| `-- c.txt => (1, 3) |
| `-- d/ => (0, 3) |
+------------------------+ +-----------+
| / layer_id 1 | built from | / |
| `-- a.txt => (1, 10) | <========== | `-- a.txt |
| `-- c.txt => (1, 3) | | `-- c.txt |
| `-- d/ => (0, 3) | +-----------+
+------------------------+
| / layer_id 0 |
| `-- d/ => (0, 3) |
| `-- e.txt => (0, 4)|
+------------------------+
图1. 三层堆叠
在图1中,我们展示了每个目录条目FileId
,以说明堆叠功能如何工作。以下是各层的描述
- 层0有一个目录
/d
和一个文件/d/e.txt
。由于这是一个底层,所有目录条目都有LayerId
0 - 层1有两个文件
/a.txt
和/c.txt
。它还有一个来自层0的/d
目录条目。由于这个层没有自己的/d
条目,所以它是合并进来的。 - 层2有文件
/a.txt
、/b.txt
、/c.txt
和目录/d
。它继承了/b.txt
、/c.txt
和/d
的条目。这是因为它们所有的FileId
都指向层1或0。/a.txt
有LayerId
2,这意味着这个文件正在遮盖来自层1的/a.txt
。这意味着层1中的/a.txt
现在无法访问。
构建层
从概念上讲,有两种不同类型的层:“底层”和“上层”。上层是堆叠在其他层之上的层。底层是那些没有被堆叠在其他任何层之上的层,因此是自给自足的。上层需要它们所堆叠的层存在才能使用。上层是通过在某个层之上堆叠一个底层来创建的。
+----------------+
| 2 upper layer | <-------+
+----------------+ |
+----------------+ | UpperLayerBuilder::fill_from_bottom_layer
| 1 upper layer | |
+----------------+ |
+----------------+ +---------------+
| 0 bottom layer | | bottom layer |
+----------------+ +---------------+
图2. 正在创建一个新的id为2的上层,堆叠在其他两个层之上。
在创建底层时,必须使用BottomLayerBuilder
。它可以使用清单或tar文件作为输入来创建底层。
在创建上层时,必须使用UpperLayerBuilder
。要在上层中堆叠的层的路径作为输入提供给UpperLayerBuilder::new
。作为创建上层输入的底层层传递给UpperLayerBuilder::fill_from_bottom_layer
。
创建上层时,它们堆叠在上面的层不会被修改。这意味着层可以在多个堆叠中重复使用。这也是层编号从下往上进行的原因。
文件系统服务
通过FUSE提供文件系统服务。首先,应将想要服务的层堆叠的顶层的路径传递给LayerFs::from_path
。然后调用LayerFs::mount
或LayerFs::run_fuse
。
依赖项
~18–31MB
~465K SLoC