1 use core::{fmt::Debug, intrinsics::unlikely}; 2 3 use alloc::{ 4 string::String, 5 sync::{Arc, Weak}, 6 vec::Vec, 7 }; 8 use hashbrown::HashMap; 9 10 use crate::{ 11 libs::{rwlock::RwLock, spinlock::SpinLock}, 12 syscall::SystemError, 13 time::TimeSpec, 14 }; 15 16 use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}; 17 18 use super::vfs::{ 19 core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, 20 FileType, FsInfo, IndexNode, InodeId, Metadata, PollStatus, 21 }; 22 23 pub mod callback; 24 25 #[derive(Debug)] 26 pub struct KernFS { 27 root_inode: Arc<KernFSInode>, 28 } 29 30 impl FileSystem for KernFS { 31 fn as_any_ref(&self) -> &dyn core::any::Any { 32 self 33 } 34 35 fn info(&self) -> FsInfo { 36 return FsInfo { 37 blk_dev_id: 0, 38 max_name_len: KernFS::MAX_NAMELEN, 39 }; 40 } 41 42 fn root_inode(&self) -> Arc<dyn IndexNode> { 43 return self.root_inode.clone(); 44 } 45 } 46 47 impl KernFS { 48 pub const MAX_NAMELEN: usize = 4096; 49 50 #[allow(dead_code)] 51 pub fn new() -> Arc<Self> { 52 let root_inode = Self::create_root_inode(); 53 let fs = Arc::new(Self { 54 root_inode: root_inode.clone(), 55 }); 56 57 { 58 let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode; 59 unsafe { 60 (*ptr).self_ref = Arc::downgrade(&root_inode); 61 } 62 } 63 root_inode.inner.lock().parent = Arc::downgrade(&root_inode); 64 *root_inode.fs.write() = Arc::downgrade(&fs); 65 return fs; 66 } 67 68 fn create_root_inode() -> Arc<KernFSInode> { 69 let metadata = Metadata { 70 size: 0, 71 mode: ModeType::from_bits_truncate(0o755), 72 uid: 0, 73 gid: 0, 74 blk_size: 0, 75 blocks: 0, 76 atime: TimeSpec::new(0, 0), 77 mtime: TimeSpec::new(0, 0), 78 ctime: TimeSpec::new(0, 0), 79 dev_id: 0, 80 inode_id: generate_inode_id(), 81 file_type: FileType::Dir, 82 nlinks: 1, 83 raw_dev: 0, 84 }; 85 let root_inode = Arc::new(KernFSInode { 86 inner: SpinLock::new(InnerKernFSInode { 87 parent: Weak::new(), 88 metadata, 89 }), 90 self_ref: Weak::new(), 91 fs: RwLock::new(Weak::new()), 92 private_data: SpinLock::new(None), 93 callback: None, 94 children: SpinLock::new(HashMap::new()), 95 inode_type: KernInodeType::Dir, 96 }); 97 98 return root_inode; 99 } 100 } 101 102 #[derive(Debug)] 103 pub struct KernFSInode { 104 inner: SpinLock<InnerKernFSInode>, 105 /// 指向当前Inode所属的文件系统的弱引用 106 fs: RwLock<Weak<KernFS>>, 107 /// 指向自身的弱引用 108 self_ref: Weak<KernFSInode>, 109 /// 私有数据 110 private_data: SpinLock<Option<KernInodePrivateData>>, 111 /// 回调函数 112 callback: Option<&'static dyn KernFSCallback>, 113 /// 子Inode 114 children: SpinLock<HashMap<String, Arc<KernFSInode>>>, 115 /// Inode类型 116 inode_type: KernInodeType, 117 } 118 119 #[derive(Debug)] 120 pub struct InnerKernFSInode { 121 parent: Weak<KernFSInode>, 122 123 /// 当前inode的元数据 124 metadata: Metadata, 125 } 126 127 impl IndexNode for KernFSInode { 128 fn as_any_ref(&self) -> &dyn core::any::Any { 129 self 130 } 131 132 fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { 133 if let Some(callback) = self.callback { 134 let callback_data = 135 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 136 return callback.open(callback_data); 137 } 138 139 return Ok(()); 140 } 141 142 fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 143 return Ok(()); 144 } 145 146 fn metadata(&self) -> Result<Metadata, SystemError> { 147 return Ok(self.inner.lock().metadata.clone()); 148 } 149 150 fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> { 151 // 若文件系统没有实现此方法,则返回“不支持” 152 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 153 } 154 155 fn resize(&self, _len: usize) -> Result<(), SystemError> { 156 return Ok(()); 157 } 158 159 fn create_with_data( 160 &self, 161 _name: &str, 162 _file_type: FileType, 163 _mode: ModeType, 164 _data: usize, 165 ) -> Result<Arc<dyn IndexNode>, SystemError> { 166 // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。 167 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 168 } 169 170 fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 171 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 172 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 173 } 174 175 fn unlink(&self, _name: &str) -> Result<(), SystemError> { 176 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 177 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 178 } 179 180 fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 181 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 182 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 183 } 184 185 fn move_( 186 &self, 187 _old_name: &str, 188 _target: &Arc<dyn IndexNode>, 189 _new_name: &str, 190 ) -> Result<(), SystemError> { 191 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 192 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 193 } 194 195 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 196 if unlikely(name.len() > KernFS::MAX_NAMELEN) { 197 return Err(SystemError::ENAMETOOLONG); 198 } 199 if unlikely(self.inode_type != KernInodeType::Dir) { 200 return Err(SystemError::ENOTDIR); 201 } 202 let x: Arc<KernFSInode> = self 203 .children 204 .lock() 205 .get(name) 206 .cloned() 207 .ok_or(SystemError::ENOENT)?; 208 return Ok(x); 209 } 210 211 fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 212 if self.inode_type != KernInodeType::Dir { 213 return Err(SystemError::ENOTDIR); 214 } 215 216 let children = self.children.lock(); 217 let r = children 218 .iter() 219 .find(|(_, v)| v.metadata().unwrap().inode_id == ino) 220 .map(|(k, _)| k.clone()); 221 222 return r.ok_or(SystemError::ENOENT); 223 } 224 225 fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> { 226 // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 227 let name = self.get_entry_name(ino)?; 228 let entry = self.find(&name)?; 229 return Ok((name, entry.metadata()?)); 230 } 231 232 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 233 // 若文件系统没有实现此方法,则返回“不支持” 234 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 235 } 236 237 fn truncate(&self, _len: usize) -> Result<(), SystemError> { 238 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 239 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 240 } 241 242 fn sync(&self) -> Result<(), SystemError> { 243 return Ok(()); 244 } 245 246 fn fs(&self) -> Arc<dyn FileSystem> { 247 return self.fs.read().upgrade().unwrap(); 248 } 249 250 fn list(&self) -> Result<Vec<String>, SystemError> { 251 let mut list = Vec::new(); 252 for (name, _) in self.children.lock().iter() { 253 list.push(name.clone()); 254 } 255 return Ok(list); 256 } 257 258 fn poll(&self) -> Result<PollStatus, SystemError> { 259 // todo: 根据inode的具体attribute,返回PollStatus 260 return Ok(PollStatus::READ | PollStatus::WRITE); 261 } 262 263 fn read_at( 264 &self, 265 offset: usize, 266 len: usize, 267 buf: &mut [u8], 268 _data: &mut FilePrivateData, 269 ) -> Result<usize, SystemError> { 270 if self.inode_type != KernInodeType::File { 271 return Err(SystemError::EISDIR); 272 } 273 274 if self.callback.is_none() { 275 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 276 } 277 278 let callback_data = 279 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 280 return self 281 .callback 282 .as_ref() 283 .unwrap() 284 .read(callback_data, &mut buf[..len], offset); 285 } 286 287 fn write_at( 288 &self, 289 offset: usize, 290 len: usize, 291 buf: &[u8], 292 _data: &mut FilePrivateData, 293 ) -> Result<usize, SystemError> { 294 if self.inode_type != KernInodeType::File { 295 return Err(SystemError::EISDIR); 296 } 297 298 if self.callback.is_none() { 299 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 300 } 301 302 let callback_data = 303 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 304 return self 305 .callback 306 .as_ref() 307 .unwrap() 308 .write(callback_data, &buf[..len], offset); 309 } 310 } 311 312 impl KernFSInode { 313 /// 在当前inode下增加子目录 314 /// 315 /// ## 参数 316 /// 317 /// - `name`:子目录名称 318 /// - `mode`:子目录权限 319 /// - `private_data`:子目录私有数据 320 /// - `callback`:子目录回调函数 321 /// 322 /// ## 返回值 323 /// 324 /// - 成功:子目录inode 325 /// - 失败:错误码 326 #[allow(dead_code)] 327 #[inline] 328 pub fn add_dir( 329 &self, 330 name: String, 331 mode: ModeType, 332 private_data: Option<KernInodePrivateData>, 333 callback: Option<&'static dyn KernFSCallback>, 334 ) -> Result<Arc<KernFSInode>, SystemError> { 335 if unlikely(self.inode_type != KernInodeType::Dir) { 336 return Err(SystemError::ENOTDIR); 337 } 338 339 return self.inner_create(name, KernInodeType::Dir, mode, private_data, callback); 340 } 341 342 /// 在当前inode下增加文件 343 /// 344 /// ## 参数 345 /// 346 /// - `name`:文件名称 347 /// - `mode`:文件权限 348 /// - `private_data`:文件私有数据 349 /// - `callback`:文件回调函数 350 /// 351 /// ## 返回值 352 /// 353 /// - 成功:文件inode 354 /// - 失败:错误码 355 #[allow(dead_code)] 356 #[inline] 357 pub fn add_file( 358 &self, 359 name: String, 360 mode: ModeType, 361 private_data: Option<KernInodePrivateData>, 362 callback: Option<&'static dyn KernFSCallback>, 363 ) -> Result<Arc<KernFSInode>, SystemError> { 364 if unlikely(self.inode_type != KernInodeType::Dir) { 365 return Err(SystemError::ENOTDIR); 366 } 367 368 return self.inner_create(name, KernInodeType::File, mode, private_data, callback); 369 } 370 371 fn inner_create( 372 &self, 373 name: String, 374 file_type: KernInodeType, 375 mode: ModeType, 376 private_data: Option<KernInodePrivateData>, 377 callback: Option<&'static dyn KernFSCallback>, 378 ) -> Result<Arc<KernFSInode>, SystemError> { 379 let metadata = Metadata { 380 size: 0, 381 mode, 382 uid: 0, 383 gid: 0, 384 blk_size: 0, 385 blocks: 0, 386 atime: TimeSpec::new(0, 0), 387 mtime: TimeSpec::new(0, 0), 388 ctime: TimeSpec::new(0, 0), 389 dev_id: 0, 390 inode_id: generate_inode_id(), 391 file_type: file_type.into(), 392 nlinks: 1, 393 raw_dev: 0, 394 }; 395 396 let new_inode: Arc<KernFSInode> = Self::new( 397 self.self_ref.upgrade().unwrap(), 398 metadata, 399 KernInodeType::Dir, 400 private_data, 401 callback, 402 ); 403 404 self.children.lock().insert(name, new_inode.clone()); 405 406 return Ok(new_inode); 407 } 408 409 /// 在当前inode下删除子目录或者文件 410 /// 411 /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 412 /// 413 /// ## 参数 414 /// 415 /// - `name`:子目录或者文件名称 416 /// 417 /// ## 返回值 418 /// 419 /// - 成功:() 420 /// - 失败:错误码 421 #[allow(dead_code)] 422 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 423 if unlikely(self.inode_type != KernInodeType::Dir) { 424 return Err(SystemError::ENOTDIR); 425 } 426 427 let mut children = self.children.lock(); 428 let inode = children.get(name).ok_or(SystemError::ENOENT)?; 429 if inode.children.lock().is_empty() { 430 children.remove(name); 431 return Ok(()); 432 } else { 433 return Err(SystemError::ENOTEMPTY); 434 } 435 } 436 437 pub(self) fn new( 438 parent: Arc<KernFSInode>, 439 metadata: Metadata, 440 inode_type: KernInodeType, 441 private_data: Option<KernInodePrivateData>, 442 callback: Option<&'static dyn KernFSCallback>, 443 ) -> Arc<KernFSInode> { 444 let inode = Arc::new(KernFSInode { 445 inner: SpinLock::new(InnerKernFSInode { 446 parent: Arc::downgrade(&parent), 447 metadata, 448 }), 449 self_ref: Weak::new(), 450 fs: RwLock::new(Weak::new()), 451 private_data: SpinLock::new(private_data), 452 callback, 453 children: SpinLock::new(HashMap::new()), 454 inode_type, 455 }); 456 457 { 458 let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 459 unsafe { 460 (*ptr).self_ref = Arc::downgrade(&inode); 461 } 462 } 463 *inode.fs.write() = Arc::downgrade( 464 parent 465 .fs() 466 .as_any_ref() 467 .downcast_ref() 468 .expect("KernFSInode::new: parent is not a KernFS instance"), 469 ); 470 return inode; 471 } 472 } 473 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 474 pub(self) enum KernInodeType { 475 Dir, 476 File, 477 } 478 479 impl Into<FileType> for KernInodeType { 480 fn into(self) -> FileType { 481 match self { 482 KernInodeType::Dir => FileType::Dir, 483 KernInodeType::File => FileType::File, 484 } 485 } 486 } 487