1a03c4f9dSLoGin use core::{cmp::min, fmt::Debug, intrinsics::unlikely}; 26b4e7a29SLoGin 36b4e7a29SLoGin use alloc::{ 46b4e7a29SLoGin string::String, 56b4e7a29SLoGin sync::{Arc, Weak}, 66b4e7a29SLoGin vec::Vec, 76b4e7a29SLoGin }; 86b4e7a29SLoGin use hashbrown::HashMap; 991e9d4abSLoGin use system_error::SystemError; 106b4e7a29SLoGin 116b4e7a29SLoGin use crate::{ 1202343d0bSLoGin driver::base::device::device_number::DeviceNumber, 1306d5e247SLoGin libs::{ 1406d5e247SLoGin casting::DowncastArc, 1506d5e247SLoGin rwlock::RwLock, 1606d5e247SLoGin spinlock::{SpinLock, SpinLockGuard}, 1706d5e247SLoGin }, 186fc066acSJomo time::PosixTimeSpec, 196b4e7a29SLoGin }; 206b4e7a29SLoGin 216b4e7a29SLoGin use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}; 226b4e7a29SLoGin 236b4e7a29SLoGin use super::vfs::{ 246b4e7a29SLoGin core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, 25597ecc08STTaq FileType, FsInfo, IndexNode, InodeId, Magic, Metadata, SuperBlock, 266b4e7a29SLoGin }; 276b4e7a29SLoGin 286b4e7a29SLoGin pub mod callback; 296b4e7a29SLoGin 306b4e7a29SLoGin #[derive(Debug)] 316b4e7a29SLoGin pub struct KernFS { 326b4e7a29SLoGin root_inode: Arc<KernFSInode>, 336b4e7a29SLoGin } 346b4e7a29SLoGin 356b4e7a29SLoGin impl FileSystem for KernFS { 366b4e7a29SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 376b4e7a29SLoGin self 386b4e7a29SLoGin } 396b4e7a29SLoGin 406b4e7a29SLoGin fn info(&self) -> FsInfo { 416b4e7a29SLoGin return FsInfo { 426b4e7a29SLoGin blk_dev_id: 0, 436b4e7a29SLoGin max_name_len: KernFS::MAX_NAMELEN, 446b4e7a29SLoGin }; 456b4e7a29SLoGin } 466b4e7a29SLoGin 476b4e7a29SLoGin fn root_inode(&self) -> Arc<dyn IndexNode> { 486b4e7a29SLoGin return self.root_inode.clone(); 496b4e7a29SLoGin } 501d37ca6dSDonkey Kane 511d37ca6dSDonkey Kane fn name(&self) -> &str { 521d37ca6dSDonkey Kane "kernfs" 531d37ca6dSDonkey Kane } 54597ecc08STTaq 55597ecc08STTaq fn super_block(&self) -> SuperBlock { 56597ecc08STTaq SuperBlock::new( 57597ecc08STTaq Magic::KER_MAGIC, 58597ecc08STTaq KernFS::KERNFS_BLOCK_SIZE, 59597ecc08STTaq KernFS::MAX_NAMELEN as u64, 60597ecc08STTaq ) 61597ecc08STTaq } 626b4e7a29SLoGin } 636b4e7a29SLoGin 646b4e7a29SLoGin impl KernFS { 656b4e7a29SLoGin pub const MAX_NAMELEN: usize = 4096; 66597ecc08STTaq pub const KERNFS_BLOCK_SIZE: u64 = 512; 676b4e7a29SLoGin #[allow(dead_code)] 686b4e7a29SLoGin pub fn new() -> Arc<Self> { 696b4e7a29SLoGin let root_inode = Self::create_root_inode(); 706b4e7a29SLoGin let fs = Arc::new(Self { 716b4e7a29SLoGin root_inode: root_inode.clone(), 726b4e7a29SLoGin }); 736b4e7a29SLoGin 746b4e7a29SLoGin { 756b4e7a29SLoGin let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode; 766b4e7a29SLoGin unsafe { 776b4e7a29SLoGin (*ptr).self_ref = Arc::downgrade(&root_inode); 786b4e7a29SLoGin } 796b4e7a29SLoGin } 80a03c4f9dSLoGin root_inode.inner.write().parent = Arc::downgrade(&root_inode); 816b4e7a29SLoGin *root_inode.fs.write() = Arc::downgrade(&fs); 826b4e7a29SLoGin return fs; 836b4e7a29SLoGin } 846b4e7a29SLoGin 856b4e7a29SLoGin fn create_root_inode() -> Arc<KernFSInode> { 866b4e7a29SLoGin let metadata = Metadata { 876b4e7a29SLoGin size: 0, 886b4e7a29SLoGin mode: ModeType::from_bits_truncate(0o755), 896b4e7a29SLoGin uid: 0, 906b4e7a29SLoGin gid: 0, 916b4e7a29SLoGin blk_size: 0, 926b4e7a29SLoGin blocks: 0, 936fc066acSJomo atime: PosixTimeSpec::new(0, 0), 946fc066acSJomo mtime: PosixTimeSpec::new(0, 0), 956fc066acSJomo ctime: PosixTimeSpec::new(0, 0), 966b4e7a29SLoGin dev_id: 0, 976b4e7a29SLoGin inode_id: generate_inode_id(), 986b4e7a29SLoGin file_type: FileType::Dir, 996b4e7a29SLoGin nlinks: 1, 10002343d0bSLoGin raw_dev: DeviceNumber::default(), 1016b4e7a29SLoGin }; 1026b4e7a29SLoGin let root_inode = Arc::new(KernFSInode { 10306d5e247SLoGin name: String::from(""), 104a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 1056b4e7a29SLoGin parent: Weak::new(), 1066b4e7a29SLoGin metadata, 107a03c4f9dSLoGin symlink_target: None, 108a03c4f9dSLoGin symlink_target_absolute_path: None, 1096b4e7a29SLoGin }), 1106b4e7a29SLoGin self_ref: Weak::new(), 1116b4e7a29SLoGin fs: RwLock::new(Weak::new()), 1126b4e7a29SLoGin private_data: SpinLock::new(None), 1136b4e7a29SLoGin callback: None, 1146b4e7a29SLoGin children: SpinLock::new(HashMap::new()), 1156b4e7a29SLoGin inode_type: KernInodeType::Dir, 1166b4e7a29SLoGin }); 1176b4e7a29SLoGin 1186b4e7a29SLoGin return root_inode; 1196b4e7a29SLoGin } 1206b4e7a29SLoGin } 1216b4e7a29SLoGin 1226b4e7a29SLoGin #[derive(Debug)] 1236b4e7a29SLoGin pub struct KernFSInode { 124a03c4f9dSLoGin inner: RwLock<InnerKernFSInode>, 1256b4e7a29SLoGin /// 指向当前Inode所属的文件系统的弱引用 1266b4e7a29SLoGin fs: RwLock<Weak<KernFS>>, 1276b4e7a29SLoGin /// 指向自身的弱引用 1286b4e7a29SLoGin self_ref: Weak<KernFSInode>, 1296b4e7a29SLoGin /// 私有数据 1306b4e7a29SLoGin private_data: SpinLock<Option<KernInodePrivateData>>, 1316b4e7a29SLoGin /// 回调函数 1326b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 1336b4e7a29SLoGin /// 子Inode 1346b4e7a29SLoGin children: SpinLock<HashMap<String, Arc<KernFSInode>>>, 1356b4e7a29SLoGin /// Inode类型 1366b4e7a29SLoGin inode_type: KernInodeType, 13706d5e247SLoGin /// Inode名称 13806d5e247SLoGin name: String, 1396b4e7a29SLoGin } 1406b4e7a29SLoGin 1416b4e7a29SLoGin #[derive(Debug)] 1426b4e7a29SLoGin pub struct InnerKernFSInode { 1436b4e7a29SLoGin parent: Weak<KernFSInode>, 1446b4e7a29SLoGin 1456b4e7a29SLoGin /// 当前inode的元数据 1466b4e7a29SLoGin metadata: Metadata, 147a03c4f9dSLoGin /// 符号链接指向的inode(仅当inode_type为SymLink时有效) 148a03c4f9dSLoGin symlink_target: Option<Weak<KernFSInode>>, 149a03c4f9dSLoGin symlink_target_absolute_path: Option<String>, 1506b4e7a29SLoGin } 1516b4e7a29SLoGin 1526b4e7a29SLoGin impl IndexNode for KernFSInode { 1536b4e7a29SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 1546b4e7a29SLoGin self 1556b4e7a29SLoGin } 1566b4e7a29SLoGin 157dfe53cf0SGnoCiYeH fn open( 158dfe53cf0SGnoCiYeH &self, 159dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 160dfe53cf0SGnoCiYeH _mode: &FileMode, 161dfe53cf0SGnoCiYeH ) -> Result<(), SystemError> { 1626b4e7a29SLoGin if let Some(callback) = self.callback { 1636b4e7a29SLoGin let callback_data = 1646b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 1656b4e7a29SLoGin return callback.open(callback_data); 1666b4e7a29SLoGin } 1676b4e7a29SLoGin 1686b4e7a29SLoGin return Ok(()); 1696b4e7a29SLoGin } 1706b4e7a29SLoGin 171dfe53cf0SGnoCiYeH fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 1726b4e7a29SLoGin return Ok(()); 1736b4e7a29SLoGin } 1746b4e7a29SLoGin 1756b4e7a29SLoGin fn metadata(&self) -> Result<Metadata, SystemError> { 176a03c4f9dSLoGin return Ok(self.inner.read().metadata.clone()); 1776b4e7a29SLoGin } 1786b4e7a29SLoGin 1796b4e7a29SLoGin fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> { 1806b4e7a29SLoGin // 若文件系统没有实现此方法,则返回“不支持” 181*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 1826b4e7a29SLoGin } 1836b4e7a29SLoGin 1846b4e7a29SLoGin fn resize(&self, _len: usize) -> Result<(), SystemError> { 1856b4e7a29SLoGin return Ok(()); 1866b4e7a29SLoGin } 1876b4e7a29SLoGin 1886b4e7a29SLoGin fn create_with_data( 1896b4e7a29SLoGin &self, 1906b4e7a29SLoGin _name: &str, 1916b4e7a29SLoGin _file_type: FileType, 1926b4e7a29SLoGin _mode: ModeType, 1936b4e7a29SLoGin _data: usize, 1946b4e7a29SLoGin ) -> Result<Arc<dyn IndexNode>, SystemError> { 1956b4e7a29SLoGin // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。 196*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 1976b4e7a29SLoGin } 1986b4e7a29SLoGin 1996b4e7a29SLoGin fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 2006b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 201*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 2026b4e7a29SLoGin } 2036b4e7a29SLoGin 2046b4e7a29SLoGin fn unlink(&self, _name: &str) -> Result<(), SystemError> { 2056b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 206*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 2076b4e7a29SLoGin } 2086b4e7a29SLoGin 2096b4e7a29SLoGin fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 2106b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 211*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 2126b4e7a29SLoGin } 2136b4e7a29SLoGin 2149e481b3bSTTaq fn move_to( 2156b4e7a29SLoGin &self, 2166b4e7a29SLoGin _old_name: &str, 2176b4e7a29SLoGin _target: &Arc<dyn IndexNode>, 2186b4e7a29SLoGin _new_name: &str, 2196b4e7a29SLoGin ) -> Result<(), SystemError> { 2206b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 221*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 2226b4e7a29SLoGin } 2236b4e7a29SLoGin 2246b4e7a29SLoGin fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 2256b4e7a29SLoGin if unlikely(name.len() > KernFS::MAX_NAMELEN) { 2266b4e7a29SLoGin return Err(SystemError::ENAMETOOLONG); 2276b4e7a29SLoGin } 2286b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 2296b4e7a29SLoGin return Err(SystemError::ENOTDIR); 2306b4e7a29SLoGin } 23106d5e247SLoGin match name { 23206d5e247SLoGin "" | "." => { 23306d5e247SLoGin return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 23406d5e247SLoGin } 23506d5e247SLoGin 23606d5e247SLoGin ".." => { 23706d5e247SLoGin return Ok(self 23806d5e247SLoGin .inner 239a03c4f9dSLoGin .read() 24006d5e247SLoGin .parent 24106d5e247SLoGin .upgrade() 24206d5e247SLoGin .ok_or(SystemError::ENOENT)?); 24306d5e247SLoGin } 24406d5e247SLoGin name => { 24506d5e247SLoGin // 在子目录项中查找 24606d5e247SLoGin return Ok(self 2476b4e7a29SLoGin .children 2486b4e7a29SLoGin .lock() 2496b4e7a29SLoGin .get(name) 25006d5e247SLoGin .ok_or(SystemError::ENOENT)? 25106d5e247SLoGin .clone()); 25206d5e247SLoGin } 25306d5e247SLoGin } 2546b4e7a29SLoGin } 2556b4e7a29SLoGin 2566b4e7a29SLoGin fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 2576b4e7a29SLoGin if self.inode_type != KernInodeType::Dir { 2586b4e7a29SLoGin return Err(SystemError::ENOTDIR); 2596b4e7a29SLoGin } 2606b4e7a29SLoGin 2616b4e7a29SLoGin let children = self.children.lock(); 2626b4e7a29SLoGin let r = children 2636b4e7a29SLoGin .iter() 2646b4e7a29SLoGin .find(|(_, v)| v.metadata().unwrap().inode_id == ino) 2656b4e7a29SLoGin .map(|(k, _)| k.clone()); 2666b4e7a29SLoGin 2676b4e7a29SLoGin return r.ok_or(SystemError::ENOENT); 2686b4e7a29SLoGin } 2696b4e7a29SLoGin 2706b4e7a29SLoGin fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> { 2716b4e7a29SLoGin // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 2726b4e7a29SLoGin let name = self.get_entry_name(ino)?; 2736b4e7a29SLoGin let entry = self.find(&name)?; 2746b4e7a29SLoGin return Ok((name, entry.metadata()?)); 2756b4e7a29SLoGin } 2766b4e7a29SLoGin 27752da9a59SGnoCiYeH fn ioctl( 27852da9a59SGnoCiYeH &self, 27952da9a59SGnoCiYeH _cmd: u32, 28052da9a59SGnoCiYeH _data: usize, 28152da9a59SGnoCiYeH _private_data: &FilePrivateData, 28252da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 2836b4e7a29SLoGin // 若文件系统没有实现此方法,则返回“不支持” 284*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 2856b4e7a29SLoGin } 2866b4e7a29SLoGin 2876b4e7a29SLoGin fn truncate(&self, _len: usize) -> Result<(), SystemError> { 2886b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 289*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 2906b4e7a29SLoGin } 2916b4e7a29SLoGin 2926b4e7a29SLoGin fn sync(&self) -> Result<(), SystemError> { 2936b4e7a29SLoGin return Ok(()); 2946b4e7a29SLoGin } 2956b4e7a29SLoGin 2966b4e7a29SLoGin fn fs(&self) -> Arc<dyn FileSystem> { 2976b4e7a29SLoGin return self.fs.read().upgrade().unwrap(); 2986b4e7a29SLoGin } 2996b4e7a29SLoGin 3006b4e7a29SLoGin fn list(&self) -> Result<Vec<String>, SystemError> { 30106d5e247SLoGin let info = self.metadata()?; 30206d5e247SLoGin if info.file_type != FileType::Dir { 30306d5e247SLoGin return Err(SystemError::ENOTDIR); 3046b4e7a29SLoGin } 30506d5e247SLoGin 30606d5e247SLoGin let mut keys: Vec<String> = Vec::new(); 30706d5e247SLoGin keys.push(String::from(".")); 30806d5e247SLoGin keys.push(String::from("..")); 30906d5e247SLoGin self.children 31006d5e247SLoGin .lock() 31106d5e247SLoGin .keys() 31206d5e247SLoGin .for_each(|x| keys.push(x.clone())); 31306d5e247SLoGin 31406d5e247SLoGin return Ok(keys); 3156b4e7a29SLoGin } 3166b4e7a29SLoGin 3176b4e7a29SLoGin fn read_at( 3186b4e7a29SLoGin &self, 3196b4e7a29SLoGin offset: usize, 3206b4e7a29SLoGin len: usize, 3216b4e7a29SLoGin buf: &mut [u8], 322dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 3236b4e7a29SLoGin ) -> Result<usize, SystemError> { 324a03c4f9dSLoGin if self.inode_type == KernInodeType::SymLink { 325a03c4f9dSLoGin let inner = self.inner.read(); 326a03c4f9dSLoGin if offset >= inner.symlink_target_absolute_path.as_ref().unwrap().len() { 327a03c4f9dSLoGin return Ok(0); 328a03c4f9dSLoGin } 329a03c4f9dSLoGin let len = min(len, buf.len()); 330a03c4f9dSLoGin let len = min( 331a03c4f9dSLoGin len, 332a03c4f9dSLoGin inner.symlink_target_absolute_path.as_ref().unwrap().len() - offset, 333a03c4f9dSLoGin ); 334a03c4f9dSLoGin buf[0..len].copy_from_slice( 335a03c4f9dSLoGin &inner 336a03c4f9dSLoGin .symlink_target_absolute_path 337a03c4f9dSLoGin .as_ref() 338a03c4f9dSLoGin .unwrap() 339a03c4f9dSLoGin .as_bytes()[offset..offset + len], 340a03c4f9dSLoGin ); 341a03c4f9dSLoGin return Ok(len); 342a03c4f9dSLoGin } 3436b4e7a29SLoGin if self.inode_type != KernInodeType::File { 3446b4e7a29SLoGin return Err(SystemError::EISDIR); 3456b4e7a29SLoGin } 3466b4e7a29SLoGin 3476b4e7a29SLoGin if self.callback.is_none() { 34806d5e247SLoGin kwarn!("kernfs: callback is none"); 349*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 3506b4e7a29SLoGin } 3516b4e7a29SLoGin 3526b4e7a29SLoGin let callback_data = 3536b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 3546b4e7a29SLoGin return self 3556b4e7a29SLoGin .callback 3566b4e7a29SLoGin .as_ref() 3576b4e7a29SLoGin .unwrap() 3586b4e7a29SLoGin .read(callback_data, &mut buf[..len], offset); 3596b4e7a29SLoGin } 3606b4e7a29SLoGin 3616b4e7a29SLoGin fn write_at( 3626b4e7a29SLoGin &self, 3636b4e7a29SLoGin offset: usize, 3646b4e7a29SLoGin len: usize, 3656b4e7a29SLoGin buf: &[u8], 366dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 3676b4e7a29SLoGin ) -> Result<usize, SystemError> { 3686b4e7a29SLoGin if self.inode_type != KernInodeType::File { 3696b4e7a29SLoGin return Err(SystemError::EISDIR); 3706b4e7a29SLoGin } 3716b4e7a29SLoGin 3726b4e7a29SLoGin if self.callback.is_none() { 373*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 3746b4e7a29SLoGin } 3756b4e7a29SLoGin 3766b4e7a29SLoGin let callback_data = 3776b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 3786b4e7a29SLoGin return self 3796b4e7a29SLoGin .callback 3806b4e7a29SLoGin .as_ref() 3816b4e7a29SLoGin .unwrap() 3826b4e7a29SLoGin .write(callback_data, &buf[..len], offset); 3836b4e7a29SLoGin } 3846b4e7a29SLoGin } 3856b4e7a29SLoGin 3866b4e7a29SLoGin impl KernFSInode { 387a03c4f9dSLoGin pub fn new( 388a03c4f9dSLoGin parent: Option<Arc<KernFSInode>>, 389a03c4f9dSLoGin name: String, 390a03c4f9dSLoGin mut metadata: Metadata, 391a03c4f9dSLoGin inode_type: KernInodeType, 392a03c4f9dSLoGin private_data: Option<KernInodePrivateData>, 393a03c4f9dSLoGin callback: Option<&'static dyn KernFSCallback>, 394a03c4f9dSLoGin ) -> Arc<KernFSInode> { 395a03c4f9dSLoGin metadata.file_type = inode_type.into(); 396a03c4f9dSLoGin let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 397a03c4f9dSLoGin 398a03c4f9dSLoGin let inode = Arc::new(KernFSInode { 399a03c4f9dSLoGin name, 400a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 401a03c4f9dSLoGin parent: parent.clone(), 402a03c4f9dSLoGin metadata, 403a03c4f9dSLoGin symlink_target: None, 404a03c4f9dSLoGin symlink_target_absolute_path: None, 405a03c4f9dSLoGin }), 406a03c4f9dSLoGin self_ref: Weak::new(), 407a03c4f9dSLoGin fs: RwLock::new(Weak::new()), 408a03c4f9dSLoGin private_data: SpinLock::new(private_data), 409a03c4f9dSLoGin callback, 410a03c4f9dSLoGin children: SpinLock::new(HashMap::new()), 411a03c4f9dSLoGin inode_type, 412a03c4f9dSLoGin }); 413a03c4f9dSLoGin 414a03c4f9dSLoGin { 415a03c4f9dSLoGin let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 416a03c4f9dSLoGin unsafe { 417a03c4f9dSLoGin (*ptr).self_ref = Arc::downgrade(&inode); 418a03c4f9dSLoGin } 419a03c4f9dSLoGin } 420a03c4f9dSLoGin if parent.strong_count() > 0 { 421a03c4f9dSLoGin let kernfs = parent 422a03c4f9dSLoGin .upgrade() 423a03c4f9dSLoGin .unwrap() 424a03c4f9dSLoGin .fs() 425a03c4f9dSLoGin .downcast_arc::<KernFS>() 426a03c4f9dSLoGin .expect("KernFSInode::new: parent is not a KernFS instance"); 427a03c4f9dSLoGin *inode.fs.write() = Arc::downgrade(&kernfs); 428a03c4f9dSLoGin } 429a03c4f9dSLoGin return inode; 430a03c4f9dSLoGin } 431a03c4f9dSLoGin 4326b4e7a29SLoGin /// 在当前inode下增加子目录 4336b4e7a29SLoGin /// 4346b4e7a29SLoGin /// ## 参数 4356b4e7a29SLoGin /// 4366b4e7a29SLoGin /// - `name`:子目录名称 4376b4e7a29SLoGin /// - `mode`:子目录权限 4386b4e7a29SLoGin /// - `private_data`:子目录私有数据 4396b4e7a29SLoGin /// - `callback`:子目录回调函数 4406b4e7a29SLoGin /// 4416b4e7a29SLoGin /// ## 返回值 4426b4e7a29SLoGin /// 4436b4e7a29SLoGin /// - 成功:子目录inode 4446b4e7a29SLoGin /// - 失败:错误码 4456b4e7a29SLoGin #[allow(dead_code)] 4466b4e7a29SLoGin #[inline] 4476b4e7a29SLoGin pub fn add_dir( 4486b4e7a29SLoGin &self, 4496b4e7a29SLoGin name: String, 4506b4e7a29SLoGin mode: ModeType, 4516b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4526b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4536b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4546b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4556b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4566b4e7a29SLoGin } 4576b4e7a29SLoGin 4587eda31b2SLoGin return self.inner_create(name, KernInodeType::Dir, mode, 0, private_data, callback); 4596b4e7a29SLoGin } 4606b4e7a29SLoGin 4616b4e7a29SLoGin /// 在当前inode下增加文件 4626b4e7a29SLoGin /// 4636b4e7a29SLoGin /// ## 参数 4646b4e7a29SLoGin /// 4656b4e7a29SLoGin /// - `name`:文件名称 4666b4e7a29SLoGin /// - `mode`:文件权限 4677eda31b2SLoGin /// - `size`:文件大小(如果不指定,则默认为4096) 4686b4e7a29SLoGin /// - `private_data`:文件私有数据 4696b4e7a29SLoGin /// - `callback`:文件回调函数 4706b4e7a29SLoGin /// 4717eda31b2SLoGin /// 4726b4e7a29SLoGin /// ## 返回值 4736b4e7a29SLoGin /// 4746b4e7a29SLoGin /// - 成功:文件inode 4756b4e7a29SLoGin /// - 失败:错误码 4766b4e7a29SLoGin #[allow(dead_code)] 4776b4e7a29SLoGin #[inline] 4786b4e7a29SLoGin pub fn add_file( 4796b4e7a29SLoGin &self, 4806b4e7a29SLoGin name: String, 4816b4e7a29SLoGin mode: ModeType, 4827eda31b2SLoGin size: Option<usize>, 4836b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4846b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4856b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4866b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4876b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4886b4e7a29SLoGin } 4896b4e7a29SLoGin 4907eda31b2SLoGin let size = size.unwrap_or(4096); 4917eda31b2SLoGin return self.inner_create( 4927eda31b2SLoGin name, 4937eda31b2SLoGin KernInodeType::File, 4947eda31b2SLoGin mode, 4957eda31b2SLoGin size, 4967eda31b2SLoGin private_data, 4977eda31b2SLoGin callback, 4987eda31b2SLoGin ); 4996b4e7a29SLoGin } 5006b4e7a29SLoGin 5016b4e7a29SLoGin fn inner_create( 5026b4e7a29SLoGin &self, 5036b4e7a29SLoGin name: String, 5046b4e7a29SLoGin file_type: KernInodeType, 5056b4e7a29SLoGin mode: ModeType, 5067eda31b2SLoGin mut size: usize, 5076b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 5086b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 5096b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 510a03c4f9dSLoGin match file_type { 511a03c4f9dSLoGin KernInodeType::Dir | KernInodeType::SymLink => { 512a03c4f9dSLoGin size = 0; 513a03c4f9dSLoGin } 5147eda31b2SLoGin _ => {} 515a03c4f9dSLoGin } 51606d5e247SLoGin 5176b4e7a29SLoGin let metadata = Metadata { 5187eda31b2SLoGin size: size as i64, 5196b4e7a29SLoGin mode, 5206b4e7a29SLoGin uid: 0, 5216b4e7a29SLoGin gid: 0, 5226b4e7a29SLoGin blk_size: 0, 5236b4e7a29SLoGin blocks: 0, 5246fc066acSJomo atime: PosixTimeSpec::new(0, 0), 5256fc066acSJomo mtime: PosixTimeSpec::new(0, 0), 5266fc066acSJomo ctime: PosixTimeSpec::new(0, 0), 5276b4e7a29SLoGin dev_id: 0, 5286b4e7a29SLoGin inode_id: generate_inode_id(), 5296b4e7a29SLoGin file_type: file_type.into(), 5306b4e7a29SLoGin nlinks: 1, 53102343d0bSLoGin raw_dev: DeviceNumber::default(), 5326b4e7a29SLoGin }; 5336b4e7a29SLoGin 5346b4e7a29SLoGin let new_inode: Arc<KernFSInode> = Self::new( 53506d5e247SLoGin Some(self.self_ref.upgrade().unwrap()), 53606d5e247SLoGin name.clone(), 5376b4e7a29SLoGin metadata, 53806d5e247SLoGin file_type, 5396b4e7a29SLoGin private_data, 5406b4e7a29SLoGin callback, 5416b4e7a29SLoGin ); 5426b4e7a29SLoGin 5436b4e7a29SLoGin self.children.lock().insert(name, new_inode.clone()); 5446b4e7a29SLoGin 5456b4e7a29SLoGin return Ok(new_inode); 5466b4e7a29SLoGin } 5476b4e7a29SLoGin 5486b4e7a29SLoGin /// 在当前inode下删除子目录或者文件 5496b4e7a29SLoGin /// 5506b4e7a29SLoGin /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 5516b4e7a29SLoGin /// 5526b4e7a29SLoGin /// ## 参数 5536b4e7a29SLoGin /// 5546b4e7a29SLoGin /// - `name`:子目录或者文件名称 5556b4e7a29SLoGin /// 5566b4e7a29SLoGin /// ## 返回值 5576b4e7a29SLoGin /// 5586b4e7a29SLoGin /// - 成功:() 5596b4e7a29SLoGin /// - 失败:错误码 5606b4e7a29SLoGin #[allow(dead_code)] 5616b4e7a29SLoGin pub fn remove(&self, name: &str) -> Result<(), SystemError> { 5626b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 5636b4e7a29SLoGin return Err(SystemError::ENOTDIR); 5646b4e7a29SLoGin } 5656b4e7a29SLoGin 5666b4e7a29SLoGin let mut children = self.children.lock(); 5676b4e7a29SLoGin let inode = children.get(name).ok_or(SystemError::ENOENT)?; 5686b4e7a29SLoGin if inode.children.lock().is_empty() { 5696b4e7a29SLoGin children.remove(name); 5706b4e7a29SLoGin return Ok(()); 5716b4e7a29SLoGin } else { 5726b4e7a29SLoGin return Err(SystemError::ENOTEMPTY); 5736b4e7a29SLoGin } 5746b4e7a29SLoGin } 5756b4e7a29SLoGin 576a03c4f9dSLoGin /// add_link - create a symlink in kernfs 577a03c4f9dSLoGin /// 578a03c4f9dSLoGin /// ## 参数 579a03c4f9dSLoGin /// 580a03c4f9dSLoGin /// - `parent`: directory to create the symlink in 581a03c4f9dSLoGin /// - `name`: name of the symlink 582a03c4f9dSLoGin /// - `target`: target node for the symlink to point to 583a03c4f9dSLoGin /// 584a03c4f9dSLoGin /// Returns the created node on success 585a03c4f9dSLoGin /// 586e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25 587a03c4f9dSLoGin pub fn add_link( 588a03c4f9dSLoGin &self, 58906d5e247SLoGin name: String, 590a03c4f9dSLoGin target: &Arc<KernFSInode>, 591a03c4f9dSLoGin target_absolute_path: String, 592a03c4f9dSLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 593a03c4f9dSLoGin // kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}"); 594a03c4f9dSLoGin let inode = self.inner_create( 59506d5e247SLoGin name, 596a03c4f9dSLoGin KernInodeType::SymLink, 597a03c4f9dSLoGin ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777), 5987eda31b2SLoGin 0, 599a03c4f9dSLoGin None, 600a03c4f9dSLoGin None, 601a03c4f9dSLoGin )?; 6026b4e7a29SLoGin 603a03c4f9dSLoGin inode.inner.write().symlink_target = Some(Arc::downgrade(target)); 604a03c4f9dSLoGin inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path); 605a03c4f9dSLoGin return Ok(inode); 6066b4e7a29SLoGin } 60706d5e247SLoGin 60806d5e247SLoGin pub fn name(&self) -> &str { 60906d5e247SLoGin return &self.name; 61006d5e247SLoGin } 61106d5e247SLoGin 61206d5e247SLoGin pub fn parent(&self) -> Option<Arc<KernFSInode>> { 613a03c4f9dSLoGin return self.inner.read().parent.upgrade(); 61406d5e247SLoGin } 61506d5e247SLoGin 61606d5e247SLoGin pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 61706d5e247SLoGin return self.private_data.lock(); 61806d5e247SLoGin } 61906d5e247SLoGin 620a03c4f9dSLoGin #[allow(dead_code)] 621a03c4f9dSLoGin pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> { 622a03c4f9dSLoGin return self.inner.read().symlink_target.as_ref()?.upgrade(); 623a03c4f9dSLoGin } 624a03c4f9dSLoGin 62506d5e247SLoGin /// remove a kernfs_node recursively 62606d5e247SLoGin pub fn remove_recursive(&self) { 62706d5e247SLoGin let mut children = self.children.lock().drain().collect::<Vec<_>>(); 62806d5e247SLoGin while let Some((_, child)) = children.pop() { 62906d5e247SLoGin children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 63006d5e247SLoGin } 63106d5e247SLoGin } 63206d5e247SLoGin 63306d5e247SLoGin /// 删除当前的inode(包括其自身、子目录和子文件) 63406d5e247SLoGin #[allow(dead_code)] 63506d5e247SLoGin pub fn remove_inode_include_self(&self) { 63606d5e247SLoGin let parent = self.parent(); 63706d5e247SLoGin if let Some(parent) = parent { 63806d5e247SLoGin parent.children.lock().remove(self.name()); 63906d5e247SLoGin } 64006d5e247SLoGin self.remove_recursive(); 64106d5e247SLoGin } 6426b4e7a29SLoGin } 6436b4e7a29SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)] 64406d5e247SLoGin pub enum KernInodeType { 6456b4e7a29SLoGin Dir, 6466b4e7a29SLoGin File, 647a03c4f9dSLoGin SymLink, 6486b4e7a29SLoGin } 6496b4e7a29SLoGin 650b5b571e0SLoGin impl From<KernInodeType> for FileType { 651b5b571e0SLoGin fn from(val: KernInodeType) -> Self { 652b5b571e0SLoGin match val { 6536b4e7a29SLoGin KernInodeType::Dir => FileType::Dir, 6546b4e7a29SLoGin KernInodeType::File => FileType::File, 655a03c4f9dSLoGin KernInodeType::SymLink => FileType::SymLink, 6566b4e7a29SLoGin } 6576b4e7a29SLoGin } 6586b4e7a29SLoGin } 659