MinFS 是为 Zircon 构建的类似于 unix 的简单文件系统。
它目前支持的文件大小上限为 4 GB。
使用 MinFS
主机设备(仅限 QEMU)
创建存储 MinFS 的磁盘映像
# (Linux) $ truncate --size=16G blk.bin # (Mac) $ mkfile -n 16g blk.bin
使用“--”在您的平台上执行运行 zircon 脚本才能传递 参数直接传递给 QEMU,然后使用“-hda”指向该文件。如果您 要连接其他设备,则可为它们提供“-hdb”、“-hdc” 依此类推。
fx set bringup.x64 fx build fx qemu -- -hda blk.bin
目标设备(QEMU 和 Real Hardware)
注意不要格式化错误的设备。如有疑问,请仅运行
运行此命令
lsblk
命令可用于查看有关设备的更多信息
。
在 Zircon 中,
lsblk
可用于列出当前所在的块设备 系统。在下面的示例系统中,/dev/class/block/000
是一个原始值, 块存储设备> lsblk ID DEV DRV SIZE TYPE LABEL 000 block block 16G
我们先向这个块存储设备添加 GPT。
> gpt init /dev/class/block/000 ... > lsblk ID DEV DRV SIZE TYPE LABEL 002 block block 16G
现在,我们在此设备上已经有了 GPT,我们看看能用它做些什么。 (注意:对 GPS 进行操作后,设备编号可能会发生变化。使用
lsblk
来跟踪如何引用块存储设备)。> gpt dump /dev/class/block/002 blocksize=512 blocks=33554432 Partition table is valid GPT contains usable blocks from 34 to 33554398 (inclusive) Total: 0 partitions
gpt dump
告诉我们一些重要信息:它告诉我们 (1) 区块有多大; (2) 哪些代码块可供我们实际使用。 让我们用 MinFS 文件系统填满磁盘的一部分。> gpt add 34 20000000 minfs /dev/class/block/002
在 Zircon 中,将分区格式设置为 MinFS。使用
lsblk
时,您应该会看到 块存储设备(即整个磁盘)和稍微小一点的设备(包含整个磁盘), 是分区在上面的输出中,分区为设备 003, 路径为/dev/class/block/003
> mkfs <PARTITION_PATH> minfs
如果您希望设备在重新启动时自动装载,请使用 GPT 工具设置其类型。正如我们前面所说,您必须
lsblk
再次使用 找到该磁盘的条目。我们想要修改 。这里我们使用关键字“fuchsia-data”用于设置类型 GUID 如果您想使用任意 GUID,则可以在 “紫红色数据”。> gpt edit 0 type fuchsia-data <DEVICE_PATH>
以后每次启动时,该分区都将自动装载到
/data
。如果您不希望自动装载该分区,则可以 分区的可见性(即 GUID),并直接手动装载分区即可。
> mount <PARTITION_PATH> /data
任何写入
/data
(此 GUID 的装载点)的文件都将保留 如需测试这一点,请尝试在新的 MinFS 卷上创建一个文件, 但发现它仍然存在> touch /data/foobar > dm reboot > ls /data
确定在每个子目录中装载了哪个块存储设备/文件系统 请使用以下命令:
> df <PATH>
Minfs 操作
以下部分介绍了为完成简单的结束,需要执行哪些 IO 用户操作,如 read()/write()。
假设
- 不会缓存或批量执行的操作(读取或写入)。上述各项操作 就像使用 Sync 和 Directio Set 一样调用。
- 如需重命名,请执行以下操作:目标文件不存在。在以下情况下,重命名可能会删除文件: 重命名操作的目标为有效文件。这种假设 让数学变得简单易行。
- “撰写”操作将单个数据块写入 vnode 的未访问部分。
- “覆盖”操作会将单个数据块写入数据块中的一部分 之前从之前的“Write”中分配的块,操作。
列的键。
- OPERATION:文件系统的客户端请求的操作。
- 阻止类型:每个文件系统操作都会导致访问一种或多种类型
一组数据。
- 数据:包含用户数据和目录条目。
- 间接:文件块映射树中的间接块
- Dindirect:文件块映射树中的两个间接块。
- Inode 表:包含一个或多个 inode 的 Inode 表块。
- Inode 位图:包含一系列位,每个位表示空闲/已使用状态 多个 inode 的列表。
- 数据位图:包含位数组,其中每个位都表示空闲/已使用状态 一组数据块
- 超级块:包含描述文件系统布局和状态的数据。
- IO TYPE:IO 访问的类型、读/写类型。
- JOURNALED:IO 是否会记入日志。读数不会记入日志,但有一些读数 写入日志的数据。
- 条件访问:取决于 OPERATION 的输入参数和
某些块是有条件地访问。
- 否:始终会执行 IO。
- 是:文件系统状态和输入参数决定了此 IO 是否 。
- READ COUNT:读取的文件系统块数。
- WRITE COUNT (IGNORING JOURNAL):写入的文件系统块数。写作 日记或日记开销不会计入此数字。
- WRITE COUNT (WITH JOURNAL):写入日志的文件系统块数 然后再到达最终位置这不包括块日志 以保持日志状态。
一个<operation>与“创建总计”一样,“总计”提供屏蔽的总数
读写。对于涉及日记的操作,该日记另外还写了两篇
日志块、日记条目标头和提交块。下方所示的数字
超级块、Inode 表、Inode 位图、数据位图和 Journal 的一部分 在启动(装载/fsck)文件系统时缓存在内存中。读取 IO 是 从未针对这些屏蔽类型签发的警告。
运营 | 屏蔽类型 | 广告订单类型 | 新闻稿 | 有条件地访问 | 已读数 | 写入计数(忽略新闻报道) | 写入次数(含新闻稿) | 评论 |
---|---|---|---|---|---|---|---|---|
查找/打开 | 数据 | 已读 | 否 | 否 | >=1 | 0 | 0 | 如果目录很大,则会读取多个块。 |
间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | 可以通过直接屏蔽设置查询。所以“间接”为可选项。 | |
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | 可以通过直接屏蔽设置查询。因此 dindirect 是可选的。 | |
查询/打开总计 | >=1 | 0 | 0 | |||||
创建 | 数据 | 已读 | 否 | 否 | >=1 | 0 | 0 | 创建涉及首先查找名称冲突。 |
间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
数据 | 写入 | 是 | 否 | 0 | >=1 | >=2 | ||
间接 | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
DIndirect | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
Inode 表 | 写入 | 是 | 否 | 0 | 1 | 2 | 新文件的 Inode。 | |
Inode 位图 | 写入 | 是 | 否 | 0 | 1 | 2 | 将 inode 标记为已分配。 | |
数据位图 | 写入 | 是 | 否 | 0 | >=0 | >=0 | 目录可能会增大,以包含新的目录条目。 | |
超级区块 | 写入 | 是 | 否 | 0 | 1 | 2 | 除此之外,分配的 inode 编号也会发生变化。 | |
创建总计 | >=1 | >=4 | >=10 | 包含 2 个用于日记条目的块。 | ||||
重命名 | 数据 | 已读 | 否 | 否 | >=1 | 0 | 0 | 重命名操作需要在源目录中查找。 |
间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
数据 | 写入 | 是 | 否 | 0 | >=1 | >=2 | 源目录条目。 | |
间接 | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
DIndirect | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
Inode 表 | 写入 | 是 | 否 | 0 | 1 | 2 | 更新源目录 inode。 | |
数据 | 已读 | 否 | 否 | >=0 | 0 | 0 | 重命名操作需要在源目录中查找。 | |
间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
数据 | 写入 | 是 | 是 | 0 | >=0 | >=0 | 正在写入目标目录条目。 | |
间接 | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
DIndirect | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
Inode 表 | 写入 | 是 | 是 | 0 | 1 | 2 | 更新目标目录 inode。 | |
Inode 表 | 写入 | 是 | 否 | 0 | 1 | 2 | 已重命名文件的 mtime。 | |
数据位图 | 写入 | 是 | 否 | 0 | >=0 | >=0 | 如果我们分配了数据,则为间接或间接的块。 | |
超级区块 | 写入 | 是 | 否 | 0 | 1 | 2 | ||
重命名总计 | >=1 | >=5 | >=12 | 包含 2 个用于日记条目的块。 | ||||
已读 | 数据 | 已读 | 否 | 否 | >=1 | 0 | 0 | |
间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
读取总计 | >=1 | 0 | 0 | |||||
写入 | 间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | 即使写入未被覆盖,我们也可能与现有数据共享 (D) 间接块。指向读取修改写入。 |
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
数据 | 写入 | 否 | 否 | 0 | 1 | 1 | ||
间接 | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
DIndirect | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
Inode 表 | 写入 | 是 | 否 | 0 | 1 | 2 | Inode 的 mtime 更新。 | |
数据位图 | 写入 | 是 | 否 | 0 | 1 | 2 | 针对已分配的块。 | |
超级区块 | 写入 | 是 | 否 | 0 | 1 | 2 | 分配的块数的变化。 | |
写入总计 | >=0 | >=4 | >=9 | 包含 2 个用于日记条目的块。 | ||||
覆盖 | 数据 | 已读 | 否 | 是 | >=0 | 0 | 0 | 读取修改写入。 |
间接 | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
DIndirect | 已读 | 否 | 是 | >=0 | 0 | 0 | ||
数据 | 写入 | 否 | 否 | 0 | 1 | 1 | ||
间接 | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
DIndirect | 写入 | 是 | 是 | 0 | >=0 | >=0 | ||
Inode 表 | 写入 | 是 | 否 | 0 | 1 | 2 | ||
数据位图 | 写入 | 是 | 否 | 0 | 1 | 2 | 写入新分配。 | |
数据位图 | 写入 | 是 | 否 | 0 | >=0 | >=0 | 释放旧块。此块位可能属于分配的块位图。 | |
超级区块 | 写入 | 是 | 否 | 0 | 1 | 2 | ||
覆盖总计 | >=0 | >=4 | >=9 | 包含 2 个用于日记条目的块。 |