1 use super::vfs::{ 2 core::generate_inode_id, file::FileMode, FileSystem, FileType, FsInfo, IndexNode, Metadata, 3 PollStatus, 4 }; 5 use crate::{ 6 libs::spinlock::{SpinLock, SpinLockGuard}, 7 syscall::SystemError, 8 time::TimeSpec, 9 }; 10 use alloc::{ 11 boxed::Box, 12 collections::BTreeMap, 13 string::{String, ToString}, 14 sync::{Arc, Weak}, 15 vec::Vec, 16 }; 17 use core::ptr::null_mut; 18 19 pub mod bus; 20 pub mod class; 21 pub mod devices; 22 pub mod fs; 23 24 const SYSFS_MAX_NAMELEN: usize = 64; 25 26 static mut __SYS_DEVICES_INODE: *mut Arc<dyn IndexNode> = null_mut(); 27 static mut __SYS_BUS_INODE: *mut Arc<dyn IndexNode> = null_mut(); 28 static mut __SYS_CLASS_INODE: *mut Arc<dyn IndexNode> = null_mut(); 29 static mut __SYS_FS_INODE: *mut Arc<dyn IndexNode> = null_mut(); 30 31 /// @brief 获取全局的sys/devices节点 32 #[inline(always)] 33 #[allow(non_snake_case)] 34 pub fn SYS_DEVICES_INODE() -> Arc<dyn IndexNode> { 35 unsafe { 36 return __SYS_DEVICES_INODE.as_ref().unwrap().clone(); 37 } 38 } 39 40 /// @brief 获取全局的sys/bus节点 41 #[inline(always)] 42 #[allow(non_snake_case)] 43 pub fn SYS_BUS_INODE() -> Arc<dyn IndexNode> { 44 unsafe { 45 return __SYS_BUS_INODE.as_ref().unwrap().clone(); 46 } 47 } 48 49 /// @brief 获取全局的sys/class节点 50 #[inline(always)] 51 #[allow(non_snake_case)] 52 pub fn SYS_CLASS_INODE() -> Arc<dyn IndexNode> { 53 unsafe { 54 return __SYS_CLASS_INODE.as_ref().unwrap().clone(); 55 } 56 } 57 58 /// @brief 获取全局的sys/fs节点 59 #[inline(always)] 60 #[allow(non_snake_case)] 61 pub fn SYS_FS_INODE() -> Arc<dyn IndexNode> { 62 unsafe { 63 return __SYS_FS_INODE.as_ref().unwrap().clone(); 64 } 65 } 66 67 /// @brief dev文件系统 68 #[derive(Debug)] 69 pub struct SysFS { 70 // 文件系统根节点 71 root_inode: Arc<LockedSysFSInode>, 72 } 73 74 impl FileSystem for SysFS { 75 fn as_any_ref(&self) -> &dyn core::any::Any { 76 self 77 } 78 79 fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> { 80 return self.root_inode.clone(); 81 } 82 83 fn info(&self) -> super::vfs::FsInfo { 84 return FsInfo { 85 blk_dev_id: 0, 86 max_name_len: SYSFS_MAX_NAMELEN, 87 }; 88 } 89 } 90 91 impl SysFS { 92 pub fn new() -> Arc<Self> { 93 // 初始化root inode 94 let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new( 95 // /sys 的权限设置为 读+执行,root 可以读写 96 // root 的 parent 是空指针 97 SysFSInode::new(FileType::Dir, 0o755 as u32, 0), 98 ))); 99 100 let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root }); 101 102 // 对root inode加锁,并继续完成初始化工作 103 let mut root_guard: SpinLockGuard<SysFSInode> = sysfs.root_inode.0.lock(); 104 root_guard.parent = Arc::downgrade(&sysfs.root_inode); 105 root_guard.self_ref = Arc::downgrade(&sysfs.root_inode); 106 root_guard.fs = Arc::downgrade(&sysfs); 107 // 释放锁 108 drop(root_guard); 109 110 // 创建文件夹 111 let root: &Arc<LockedSysFSInode> = &sysfs.root_inode; 112 match root.add_dir("devices") { 113 Ok(devices) => unsafe { 114 __SYS_DEVICES_INODE = Box::leak(Box::new(devices)); 115 }, 116 Err(_) => panic!("SysFS: Failed to create /sys/devices"), 117 } 118 119 match root.add_dir("bus") { 120 Ok(bus) => unsafe { 121 __SYS_BUS_INODE = Box::leak(Box::new(bus)); 122 }, 123 Err(_) => panic!("SysFS: Failed to create /sys/bus"), 124 } 125 126 match root.add_dir("class") { 127 Ok(class) => unsafe { 128 __SYS_CLASS_INODE = Box::leak(Box::new(class)); 129 }, 130 Err(_) => panic!("SysFS: Failed to create /sys/class"), 131 } 132 133 match root.add_dir("fs") { 134 Ok(fs) => unsafe { 135 __SYS_FS_INODE = Box::leak(Box::new(fs)); 136 }, 137 Err(_) => panic!("SysFS: Failed to create /sys/fs"), 138 } 139 // 初始化platform总线 140 crate::driver::base::platform::platform_bus_init().expect("platform bus init failed"); 141 // 初始化串口 142 crate::driver::uart::uart::uart_init().expect("initilize uart error"); 143 return sysfs; 144 } 145 } 146 147 /// @brief sys文件i节点(锁) 148 #[derive(Debug)] 149 pub struct LockedSysFSInode(SpinLock<SysFSInode>); 150 151 impl IndexNode for LockedSysFSInode { 152 fn as_any_ref(&self) -> &dyn core::any::Any { 153 self 154 } 155 156 fn open( 157 &self, 158 _data: &mut super::vfs::FilePrivateData, 159 _mode: &FileMode, 160 ) -> Result<(), SystemError> { 161 return Ok(()); 162 } 163 164 fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> { 165 return Ok(()); 166 } 167 168 fn read_at( 169 &self, 170 _offset: usize, 171 _len: usize, 172 _buf: &mut [u8], 173 _data: &mut super::vfs::FilePrivateData, 174 ) -> Result<usize, SystemError> { 175 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 176 } 177 178 fn write_at( 179 &self, 180 _offset: usize, 181 _len: usize, 182 _buf: &[u8], 183 _data: &mut super::vfs::FilePrivateData, 184 ) -> Result<usize, SystemError> { 185 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 186 } 187 188 fn poll(&self) -> Result<super::vfs::PollStatus, SystemError> { 189 // 加锁 190 let inode: SpinLockGuard<SysFSInode> = self.0.lock(); 191 192 // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 193 if inode.metadata.file_type == FileType::Dir { 194 return Err(SystemError::EISDIR); 195 } 196 197 return Ok(PollStatus::READ | PollStatus::WRITE); 198 } 199 200 fn metadata(&self) -> Result<Metadata, SystemError> { 201 return Ok(self.0.lock().metadata.clone()); 202 } 203 204 fn fs(&self) -> Arc<dyn FileSystem> { 205 return self.0.lock().fs.upgrade().unwrap(); 206 } 207 208 fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> { 209 let inode: SpinLockGuard<SysFSInode> = self.0.lock(); 210 if inode.metadata.file_type != FileType::Dir { 211 return Err(SystemError::ENOTDIR); 212 } 213 214 match ino { 215 0 => { 216 return Ok(String::from(".")); 217 } 218 1 => { 219 return Ok(String::from("..")); 220 } 221 ino => { 222 // 暴力遍历所有的children,判断inode id是否相同 223 // TODO: 优化这里,这个地方性能很差! 224 let mut key: Vec<String> = inode 225 .children 226 .keys() 227 .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino) 228 .cloned() 229 .collect(); 230 231 match key.len() { 232 0=>{return Err(SystemError::ENOENT);} 233 1=>{return Ok(key.remove(0));} 234 _ => panic!("Sysfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino) 235 } 236 } 237 } 238 } 239 240 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 241 let inode = self.0.lock(); 242 243 if inode.metadata.file_type != FileType::Dir { 244 return Err(SystemError::ENOTDIR); 245 } 246 247 match name { 248 "" | "." => { 249 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 250 } 251 ".." => { 252 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?); 253 } 254 name => { 255 // 在子目录项中查找 256 // match inode.children.get(name) { 257 // Some(_) => {} 258 // None => kdebug!("Sysfs find {} error", name), 259 // } 260 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone()); 261 } 262 } 263 } 264 265 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 266 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 267 } 268 269 fn list(&self) -> Result<Vec<String>, SystemError> { 270 let info = self.metadata()?; 271 if info.file_type != FileType::Dir { 272 return Err(SystemError::ENOTDIR); 273 } 274 275 let mut keys: Vec<String> = Vec::new(); 276 keys.push(String::from(".")); 277 keys.push(String::from("..")); 278 keys.append(&mut self.0.lock().children.keys().cloned().collect()); 279 280 return Ok(keys); 281 } 282 } 283 284 impl LockedSysFSInode { 285 fn do_create_with_data( 286 &self, 287 mut guard: SpinLockGuard<SysFSInode>, 288 _name: &str, 289 _file_type: FileType, 290 _mode: u32, 291 _data: usize, 292 ) -> Result<Arc<dyn IndexNode>, SystemError> { 293 if guard.metadata.file_type != FileType::Dir { 294 return Err(SystemError::ENOTDIR); 295 } 296 297 // 如果有重名的,则返回 298 if guard.children.contains_key(_name) { 299 return Err(SystemError::EEXIST); 300 } 301 302 // 创建inode 303 let result: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(SysFSInode { 304 parent: guard.self_ref.clone(), 305 self_ref: Weak::default(), 306 children: BTreeMap::new(), 307 metadata: Metadata { 308 dev_id: 0, 309 inode_id: generate_inode_id(), 310 size: 0, 311 blk_size: 0, 312 blocks: 0, 313 atime: TimeSpec::default(), 314 mtime: TimeSpec::default(), 315 ctime: TimeSpec::default(), 316 file_type: _file_type, 317 mode: _mode, 318 nlinks: 1, 319 uid: 0, 320 gid: 0, 321 raw_dev: _data, 322 }, 323 fs: guard.fs.clone(), 324 }))); 325 326 // 初始化inode的自引用的weak指针 327 result.0.lock().self_ref = Arc::downgrade(&result); 328 329 // 将子inode插入父inode的B树中 330 guard.children.insert(String::from(_name), result.clone()); 331 return Ok(result); 332 } 333 334 /// @brief 在当前目录下,创建一个目录 335 /// @param name: 目录名 336 /// @return 成功返回目录inode, 失败返回Err(错误码) 337 #[inline] 338 #[allow(dead_code)] 339 pub fn add_dir(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 340 let guard: SpinLockGuard<SysFSInode> = self.0.lock(); 341 342 if guard.children.contains_key(name) { 343 return Err(SystemError::EEXIST); 344 } 345 346 match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) { 347 Ok(inode) => return Ok(inode), 348 Err(err) => { 349 return Err(err); 350 } 351 }; 352 } 353 354 /// @brief 在当前目录下,创建一个二进制文件 355 /// @param name: 文件名 356 /// @return 成功返回Ok(()), 失败返回Err(错误码) 357 #[inline] 358 #[allow(dead_code)] 359 pub fn add_file(&self, name: &str, file: Arc<dyn IndexNode>) -> Result<(), SystemError> { 360 let mut this = self.0.lock(); 361 362 if this.children.contains_key(name) { 363 return Err(SystemError::EEXIST); 364 } 365 366 this.children.insert(name.to_string(), file); 367 return Ok(()); 368 } 369 370 /// @brief 为该inode创建硬链接 371 /// @param None 372 /// @return 当前inode强引用 373 #[inline] 374 #[allow(dead_code)] 375 pub fn link(&self) -> Arc<dyn IndexNode> { 376 return self 377 .0 378 .lock() 379 .self_ref 380 .clone() 381 .upgrade() 382 .ok_or(SystemError::E2BIG) 383 .unwrap(); 384 } 385 386 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 387 let x = self 388 .0 389 .lock() 390 .children 391 .remove(name) 392 .ok_or(SystemError::ENOENT)?; 393 394 drop(x); 395 return Ok(()); 396 } 397 } 398 399 /// @brief sys文件i节点(无锁) 400 #[derive(Debug)] 401 pub struct SysFSInode { 402 /// 指向父Inode的弱引用 403 parent: Weak<LockedSysFSInode>, 404 /// 指向自身的弱引用 405 self_ref: Weak<LockedSysFSInode>, 406 /// 子Inode的B树 407 children: BTreeMap<String, Arc<dyn IndexNode>>, 408 /// 指向inode所在的文件系统对象的指针 409 fs: Weak<SysFS>, 410 /// INode 元数据 411 metadata: Metadata, 412 } 413 414 impl SysFSInode { 415 pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self { 416 return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_); 417 } 418 419 pub fn new_with_parent( 420 parent: Weak<LockedSysFSInode>, 421 dev_type_: FileType, 422 mode_: u32, 423 data_: usize, 424 ) -> Self { 425 return SysFSInode { 426 parent: parent, 427 self_ref: Weak::default(), 428 children: BTreeMap::new(), 429 metadata: Metadata { 430 dev_id: 1, 431 inode_id: generate_inode_id(), 432 size: 0, 433 blk_size: 0, 434 blocks: 0, 435 atime: TimeSpec::default(), 436 mtime: TimeSpec::default(), 437 ctime: TimeSpec::default(), 438 file_type: dev_type_, // 文件夹 439 mode: mode_, 440 nlinks: 1, 441 uid: 0, 442 gid: 0, 443 raw_dev: data_, 444 }, 445 fs: Weak::default(), 446 }; 447 } 448 } 449