Skip to content

Commit 768f389

Browse files
committed
docs: 更新文件系统文档,添加 AxFS 组件设计和读写流程
1 parent 282729a commit 768f389

8 files changed

Lines changed: 825 additions & 40 deletions

File tree

docs/design/filesystem/crates.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
---
2+
sidebar_position: 2
3+
---
4+
5+
# 组件设计
6+
7+
## 组件概述
8+
AxFS(ArceOS File System)是 AxVisor 虚拟化平台的核心文件系统组件,负责为操作系统内核和应用提供统一的文件系统访问接口。它作为虚拟化环境中的存储抽象层,支持多种文件系统类型(Ext4、FAT32、RAMFS等),并为用户空间提供类POSIX的文件操作API。
9+
10+
主要职责为:
11+
12+
1. **统一文件系统抽象**:为不同类型的底层文件系统提供统一的VFS(虚拟文件系统)接口
13+
2. **多文件系统支持**:支持Ext4、FAT32、内存文件系统等多种文件系统并行运行
14+
3. **挂载点管理**:管理多文件系统的挂载和卸载,提供统一的命名空间
15+
4. **路径解析**:提供路径解析、规范化和跨挂载点查找功能
16+
5. **权限控制**:基于能力的访问控制机制,确保文件操作的安全性
17+
6. **设备抽象**:为块设备提供统一接口,支持从GPT分区表动态发现和挂载分区
18+
19+
20+
## 核心概念
21+
22+
### VFS 抽象
23+
24+
AXFS 基于外部 crate `axfs_vfs` 提供的 VFS 抽象:
25+
26+
```rust
27+
// 文件系统操作接口
28+
pub trait VfsOps {
29+
fn root_dir(&self) -> VfsNodeRef;
30+
fn mount(&self, mount_point: &str, parent: VfsNodeRef) -> VfsResult<()>;
31+
fn umount(&self) -> VfsResult<()>;
32+
}
33+
34+
// 文件/目录节点操作接口
35+
pub trait VfsNodeOps {
36+
fn get_attr(&self) -> VfsResult<VfsNodeAttr>;
37+
fn lookup(self: Arc<Self>, path: &str) -> VfsResult<VfsNodeRef>;
38+
fn create(&self, path: &str, ty: VfsNodeType) -> VfsResult;
39+
fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult<usize>;
40+
fn write_at(&self, offset: u64, buf: &[u8]) -> VfsResult<usize>;
41+
// ...
42+
}
43+
```
44+
45+
**设计要点**
46+
- 所有文件系统必须实现 `VfsOps` trait
47+
- 所有文件/目录节点必须实现 `VfsNodeOps` trait
48+
- 返回类型为 `Arc<dyn VfsNodeOps>`,支持动态分发
49+
50+
### 挂载点管理
51+
52+
根文件系统通过 `RootDirectory` 统一管理多个挂载点:
53+
54+
```rust
55+
pub struct RootDirectory {
56+
main_fs: Arc<dyn VfsOps>, // 主文件系统
57+
mounts: Vec<MountPoint>, // 挂载点列表
58+
}
59+
60+
struct MountPoint {
61+
path: String, // 挂载点路径
62+
fs: Arc<dyn VfsOps>, // 挂载的文件系统
63+
}
64+
```
65+
66+
**设计要点**
67+
- 主文件系统 (`main_fs`) 通常是第一个挂载的分区或 ramfs
68+
- 路径解析时优先匹配最长前缀的挂载点
69+
- 当前目录跟踪 (`CURRENT_DIR_PATH``CURRENT_DIR`)
70+
71+
### 设备抽象
72+
73+
块设备通过 `Disk``Partition` 两层抽象:
74+
75+
```rust
76+
// 完整磁盘设备
77+
pub struct Disk {
78+
block_id: u64, // 当前块号
79+
offset: usize, // 块内偏移
80+
dev: Arc<Mutex<AxBlockDevice>>, // 底层块设备
81+
}
82+
83+
// 分区设备(磁盘切片)
84+
pub struct Partition {
85+
inner: Arc<Disk>, // 关联的磁盘
86+
start_lba: u64, // 起始 LBA
87+
end_lba: u64, // 结束 LBA
88+
}
89+
90+
impl Partition {
91+
pub fn new(disk: Arc<Disk>, start_lba: u64, size_bytes: u64) -> Self { ... }
92+
pub fn read_one(&mut self, buf: &mut [u8]) -> DevResult<usize> { ... }
93+
pub fn write_one(&mut self, buf: &[u8]) -> DevResult<usize> { ... }
94+
}
95+
```
96+
97+
**设计要点**
98+
- `Partition` 复用 `Disk` 实现,通过 LBA 偏移转发
99+
- 统一 `read_one` / `write_one` 接口
100+
- 512 字节块大小对齐
101+
102+
### 分区扫描与检测
103+
104+
通过 GPT 分区表解析和文件系统魔数识别:
105+
106+
```rust
107+
pub fn scan_gpt_partitions(disk: &mut Disk) -> AxResult<Vec<PartitionInfo>> {
108+
// 1. 尝试解析 GPT
109+
match parse_gpt_partitions(disk) {
110+
Ok(partitions) if !partitions.is_empty() => return Ok(partitions),
111+
Ok(_) => { /* 尝试 MBR */ }
112+
Err(_) => { /* 尝试 MBR */ }
113+
}
114+
// 2. 解析 MBR
115+
parse_mbr_partitions(disk)
116+
}
117+
118+
pub enum FilesystemType {
119+
Fat, // FAT32/FAT16
120+
Ext4, // ext4/ext3/ext2
121+
Unknown,
122+
}
123+
```
124+
125+
**检测策略**
126+
1. 读取分区前几个扇区
127+
2. 识别 FAT32 (0xEB, 0xAA, 0x55) 和 ext4 (0x53, 0xEF) 魔数
128+
3. 填充 `PartitionInfo.filesystem_type`
129+
130+
### OpenOptions 配置
131+
132+
文件打开选项通过 `OpenOptions` 结构体配置:
133+
134+
```rust
135+
pub struct OpenOptions {
136+
read: bool, // 可读
137+
write: bool, // 可写
138+
append: bool, // 追加模式
139+
truncate: bool, // 截断(清空)文件
140+
create: bool, // 文件不存在则创建
141+
create_new: bool, // 强制创建新文件(已存在则失败)
142+
_custom_flags: i32, // 系统特定标志
143+
_mode: u32, // 文件权限模式
144+
}
145+
```
146+
147+
**权限模型**
148+
- 基于 `cap_access` crate 的能力令牌
149+
- 打开时捕获令牌、后续操作验证权限
150+
151+
152+
## API 设计
153+
154+
### 高级 API (api/)
155+
156+
提供 `std::fs` 风格的接口:
157+
158+
```rust
159+
// 文件操作
160+
pub fn read(path: &str) -> io::Result<Vec<u8>>
161+
pub fn read_to_string(path: &str) -> io::Result<String>
162+
pub fn write(path: &str, contents: C) -> io::Result<()>
163+
pub fn metadata(path: &str) -> io::Result<Metadata>
164+
165+
// 目录操作
166+
pub fn read_dir(path: &str) -> io::Result<ReadDir>
167+
pub fn create_dir(path: &str) -> io::Result<()>
168+
pub fn remove_dir(path: &str) -> io::Result<()>
169+
pub fn remove_file(path: &str) -> io::Result<()>
170+
171+
// 路径操作
172+
pub fn canonicalize(path: &str) -> io::Result<String>
173+
pub fn current_dir() -> io::Result<String>
174+
pub fn set_current_dir(path: &str) -> io::Result<()>
175+
```
176+
177+
### 低级 API (fops.rs)
178+
179+
提供带权限的文件操作:
180+
181+
```rust
182+
pub struct File {
183+
node: WithCap<VfsNodeRef>, // 带权限令牌的节点
184+
is_append: bool,
185+
offset: u64,
186+
}
187+
188+
impl File {
189+
pub fn open(path: &str) -> io::Result<Self>;
190+
pub fn create(path: &str) -> io::Result<Self>;
191+
pub fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
192+
pub fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
193+
pub fn seek(&mut self, pos: SeekFrom) -> io::Result<u64>;
194+
}
195+
196+
pub struct Directory {
197+
node: WithCap<VfsNodeRef>,
198+
entry_idx: usize,
199+
}
200+
201+
impl Directory {
202+
pub fn open(path: &str) -> io::Result<Self>;
203+
pub fn read_entry(&mut self) -> io::Result<Option<DirEntry>>;
204+
}
205+
```
206+
207+
208+
## 组件依赖
209+
![DEPENDENCY](./images_fs/dependency.png)
210+
211+
axfs 尽量保证对其他组件较少的依赖程度,仅依赖于 axdriver、axio、axfs_vfs 等核心组件,且其他组件的依赖关系尽量简单,以降低组件之间的耦合度,提高系统的可维护性和可扩展性。大部分依赖库为自主开发,部分依赖库为第三方开源通用库。
212+
213+
### 自主依赖库
214+
- axdriver:提供统一的设备驱动抽象层,为块设备提供标准化的接口,是文件系统与硬件设备之间的桥梁
215+
216+
- axdriver_block:提供块设备驱动接口,支持块设备的读写操作
217+
218+
- axio:输入输出抽象层,提供统一的I/O操作接口,支持内存分配
219+
220+
- axfs_vfs:虚拟文件系统层,提供统一的文件系统抽象接口,支持多种文件系统的挂载和操作
221+
222+
- fatfs:FAT文件系统具体实现,提供对FAT32文件系统的支持
223+
224+
- rsext4:ext4文件系统的具体实现,提供对ext4文件系统的读写等功能的支持
225+
226+
- axfs_ramfs:内存文件系统,提供基于内存的文件系统实现,用于临时文件存储
227+
228+
- axerrno:提供统一的错误处理机制,定义文件系统操作中的错误类型和处理方式
229+
230+
## 第三方通用库
231+
232+
- cap_access:提供能力访问控制,管理文件系统访问权限
233+
234+
- lazyinit:提供延迟初始化机制,优化系统启动性能,按需初始化
235+
236+
- spin:提供自旋锁实现,在多核环境下保护共享数据
237+
238+
- log:提供日志记录功能,记录文件系统操作和调试信息

docs/design/filesystem/framework.md

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
sidebar_position: 1
33
---
44

5-
# 框架流程
6-
## 文件系统框架
5+
# 文件系统框架
76

8-
Axvisor 文件系统是一个为现代操作系统设计的模块化、分层文件系统架构。它采用虚拟文件系统(VFS)抽象层设计,支持多种文件系统类型,包括 FAT32、EXT4、内存文件系统(RAMFS)、设备文件系统(DEVFS)等,具有高度的可扩展性和灵活性。
7+
Axvisor 文件系统是一个为现代操作系统设计的模块化、分层文件系统架构。它采用虚拟文件系统(VFS)抽象层设计,支持多种文件系统类型,包括 FAT32、EXT4、内存文件系统(RAMFS)等,具有高度的可扩展性和灵活性。
98

10-
### 设计理念
9+
## 设计理念
1110

1211
Axvisor 文件系统的设计遵循以下核心原则:
1312

@@ -17,39 +16,38 @@ Axvisor 文件系统的设计遵循以下核心原则:
1716
- **高性能**:优化的数据结构和算法,支持并发访问
1817
- **可扩展性**:易于添加新的文件系统类型支持
1918

20-
### 架构层次
19+
## 架构层次
2120

2221
Axvisor 文件系统采用清晰的分层架构,从上到下分为以下几个层次:
2322

2423
![FILESYSTEM](./images_fs/framework.png)
2524

26-
#### 1. API 层 (API Layer)
25+
### API 层 (API Layer)
2726
API 层为用户提供了一组高级文件操作接口,包括文件读写、目录操作、文件属性管理等。这一层屏蔽了底层文件系统的差异,提供了一致的编程接口。
2827

29-
#### 2. 虚拟文件系统层 (VFS Layer)
28+
### 虚拟文件系统层 (VFS Layer)
3029
VFS 是文件系统的核心抽象层,负责:
3130
- 路径解析和名称管理
3231
- 文件系统挂载和卸载管理
3332
- 文件描述符管理
3433
- 统一的文件操作接口转换
3534
- 缓存管理和优化
3635

37-
#### 3. 具体文件系统层 (Filesystem Implementations)
36+
### 具体文件系统层 (Filesystem Implementations)
3837
这一层包含各种具体文件系统的实现,每个文件系统都实现了标准的 VFS 接口:
3938
- **FAT32**:支持 FAT12/FAT16/FAT32 文件系统
4039
- **EXT4**:支持 Linux 标准的 EXT4 文件系统
4140
- **RAMFS**:内存文件系统,用于临时文件存储
42-
- **DEVFS**:设备文件系统,管理设备节点
4341
- **PROCFS**:进程文件系统,提供进程信息访问
4442

45-
#### 4. 存储设备层 (Storage Layer)
43+
### 存储设备层 (Storage Layer)
4644
存储设备层负责与具体的存储设备进行交互,包括:
4745
- 设备初始化和驱动加载
4846
- 分区扫描和管理
4947
- I/O 操作和调度
5048

5149

52-
### 实现代码结构
50+
## 实现代码结构
5351
```
5452
axfs/
5553
├── src/
@@ -80,16 +78,3 @@ axfs/
8078
- **dev.rs**:设备抽象层,提供统一的设备访问接口
8179
- **fs/**:包含各种具体文件系统的实现
8280
- **partition.rs**:处理磁盘分区识别和管理
83-
84-
85-
## 系统启动流程
86-
87-
文件系统的初始化是系统启动的关键步骤,它确保了操作系统能够正确访问存储设备并提供文件服务。整个启动流程经过精心设计,既保证了系统的可靠性,又提供了灵活的配置选项。
88-
89-
### 详细启动流程
90-
1. 设备初始化:初始化块设备驱动
91-
2. 分区扫描:扫描并识别分区
92-
3. 文件系统检测:检测各分区的文件系统类型
93-
4. 根文件系统选择:根据启动参数或默认策略选择根文件系统
94-
5. 文件系统挂载:挂载根文件系统和其他分区
95-
6. 子文件系统挂载:挂载/dev, /proc, /sys等子文件系统
96.9 KB
Loading
-12.9 KB
Loading

docs/design/filesystem/partion.md

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 4
2+
sidebar_position: 5
33
---
44

55
# 分区管理
@@ -26,26 +26,15 @@ GPT解析过程如下:
2626
4. 读取分区项数组
2727
5. 提取分区信息
2828

29-
#### MBR(主引导记录)
30-
31-
MBR是传统的分区表格式,虽然功能有限,但仍广泛使用:
32-
33-
- 支持4个主分区
34-
- 使用分区类型标识(1字节)
35-
- 支持扩展分区
36-
37-
当GPT解析失败时,系统会尝试解析MBR分区表,确保向后兼容。
38-
3929
### 分区扫描流程
4030

4131
分区扫描是系统启动时的关键步骤,流程如下:
4232

4333
1. **初始化块设备**:创建`Disk`对象,获取设备信息
4434
2. **尝试GPT解析**:读取GPT头,验证签名
4535
3. **解析分区项**:读取分区项数组,提取分区信息
46-
4. **MBR回退**:如果GPT解析失败,尝试MBR
47-
5. **全盘处理**:如果都没有分区表,将整个磁盘作为单个分区
48-
6. **文件系统检测**:对每个分区进行文件系统类型检测
36+
4. **全盘处理**:如果没有分区表,将整个磁盘作为单个分区
37+
5. **文件系统检测**:对每个分区进行文件系统类型检测
4938

5039
### 分区信息结构
5140

0 commit comments

Comments
 (0)