os/fs/ext4/mod.rs
1//! Ext4 - Linux Ext4 文件系统支持
2//!
3//! 该模块提供了与 **Linux Ext4 文件系统兼容** 的读写支持,基于 `ext4_rs` crate 实现。
4//!
5//! # 组件
6//!
7//! - [`Ext4FileSystem`] - 文件系统结构,实现 `FileSystem` trait
8//! - [`Ext4Inode`] - Inode 包装,将 `ext4_rs` 操作映射到 VFS
9//! - [`BlockDeviceAdapter`] - 块设备适配器,桥接 VirtIO 和 ext4_rs
10//!
11//! # 设计概览
12//!
13//! ## 适配层架构
14//!
15//! ```text
16//! VFS (Inode trait)
17//! ↓
18//! Ext4Inode (包装层)
19//! ↓
20//! ext4_rs::Ext4 (第三方库)
21//! ↓
22//! BlockDeviceAdapter
23//! ↓
24//! BlockDriver (VirtIO Block)
25//! ```
26//!
27//! ## 支持的操作
28//!
29//! - **文件操作**:read、write、truncate、sync
30//! - **目录操作**:lookup、create、mkdir、readdir、rmdir
31//! - **链接操作**:symlink、link、unlink、readlink
32//! - **元数据**:chmod、chown、set_times
33//! - **重命名**:rename(支持跨目录移动)
34//!
35//! # 使用示例
36//!
37//! ```rust
38//! use crate::fs::init_ext4_from_block_device;
39//!
40//! // 从第一个块设备挂载 ext4 为根文件系统
41//! init_ext4_from_block_device()?;
42//!
43//! // 读写文件
44//! let content = vfs_load_file("/bin/hello")?;
45//! ```
46//!
47//! # 配置要求
48//!
49//! - **块大小**:必须为 4096 字节(与 `mkfs.ext4 -b 4096` 匹配)
50//! - **块设备**:需要支持 VirtIO Block 或兼容驱动
51//!
52//! # 限制
53//!
54//! - `mknod` 未实现(设备文件创建)
55//! - 非日志模式,崩溃可能导致不一致
56pub mod adpaters;
57pub mod inode;
58
59pub use adpaters::BlockDeviceAdapter;
60pub use inode::Ext4Inode;
61
62use crate::device::block::BlockDriver;
63use crate::pr_info;
64use crate::sync::Mutex;
65use crate::vfs::{FileSystem, FsError, Inode, StatFs};
66use alloc::sync::Arc;
67
68/// Ext4 文件系统
69pub struct Ext4FileSystem {
70 /// 底层块设备驱动
71 device: Arc<dyn BlockDriver>,
72
73 /// 块大小
74 block_size: usize,
75
76 /// 总块数
77 total_blocks: usize,
78
79 /// 设备 ID
80 device_id: usize,
81
82 /// ext4_rs 文件系统对象
83 ext4: Arc<Mutex<ext4_rs::Ext4>>,
84
85 /// 根 inode
86 root: Arc<dyn Inode>,
87}
88
89impl Ext4FileSystem {
90 /// 打开 Ext4 文件系统
91 ///
92 /// # 参数
93 /// - `device`: 块设备驱动
94 /// - `block_size`: 块大小
95 /// - `total_blocks`: 总块数
96 /// - `device_id`: 设备 ID
97 ///
98 /// # 返回
99 /// Ext4 文件系统实例
100 pub fn open(
101 device: Arc<dyn BlockDriver>,
102 block_size: usize,
103 total_blocks: usize,
104 device_id: usize,
105 ) -> Result<Arc<Self>, FsError> {
106 pr_info!("[Ext4] Opening Ext4 filesystem on block device");
107 pr_info!(
108 "[Ext4] Device block size: {}, total blocks: {}",
109 block_size,
110 total_blocks
111 );
112
113 // 创建适配器
114 let adapter = Arc::new(BlockDeviceAdapter::new(device.clone(), block_size));
115
116 // 使用 ext4_rs 打开文件系统
117 // 注意:ext4_rs::Ext4::open 直接返回 Ext4,不返回 Result
118 pr_info!("[Ext4] Calling ext4_rs::Ext4::open...");
119 let ext4 = ext4_rs::Ext4::open(adapter);
120 pr_info!("[Ext4] ext4_rs returned successfully");
121
122 let ext4 = Arc::new(Mutex::new(ext4));
123
124 // 创建根 inode (inode 号 2 是 Ext4 的根目录)
125 let root = Arc::new(Ext4Inode::new(ext4.clone(), 2));
126
127 let fs = Arc::new(Ext4FileSystem {
128 device,
129 block_size,
130 total_blocks,
131 device_id,
132 ext4,
133 root,
134 });
135
136 pr_info!("[Ext4] Filesystem opened successfully");
137 Ok(fs)
138 }
139}
140
141impl FileSystem for Ext4FileSystem {
142 fn fs_type(&self) -> &'static str {
143 "ext4"
144 }
145
146 fn root_inode(&self) -> Arc<dyn Inode> {
147 self.root.clone()
148 }
149
150 fn sync(&self) -> Result<(), FsError> {
151 // 调用底层块设备的 flush 方法,将缓存刷新到磁盘
152 if self.device.flush() {
153 Ok(())
154 } else {
155 Err(FsError::IoError)
156 }
157 }
158
159 fn statfs(&self) -> Result<StatFs, FsError> {
160 let ext4 = self.ext4.lock();
161 let sb = &ext4.super_block;
162
163 Ok(StatFs {
164 block_size: self.block_size,
165 total_blocks: self.total_blocks,
166 free_blocks: sb.free_blocks_count() as usize,
167 available_blocks: sb.free_blocks_count() as usize,
168 total_inodes: sb.inodes_count as usize,
169 free_inodes: sb.free_inodes_count() as usize,
170 fsid: self.device_id as u64,
171 max_filename_len: 255, // EXT4_NAME_LEN
172 })
173 }
174}