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 }, 186b4e7a29SLoGin time::TimeSpec, 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, 2540609970SGnoCiYeH FileType, FsInfo, IndexNode, InodeId, Metadata, 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 } 506b4e7a29SLoGin } 516b4e7a29SLoGin 526b4e7a29SLoGin impl KernFS { 536b4e7a29SLoGin pub const MAX_NAMELEN: usize = 4096; 546b4e7a29SLoGin 556b4e7a29SLoGin #[allow(dead_code)] 566b4e7a29SLoGin pub fn new() -> Arc<Self> { 576b4e7a29SLoGin let root_inode = Self::create_root_inode(); 586b4e7a29SLoGin let fs = Arc::new(Self { 596b4e7a29SLoGin root_inode: root_inode.clone(), 606b4e7a29SLoGin }); 616b4e7a29SLoGin 626b4e7a29SLoGin { 636b4e7a29SLoGin let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode; 646b4e7a29SLoGin unsafe { 656b4e7a29SLoGin (*ptr).self_ref = Arc::downgrade(&root_inode); 666b4e7a29SLoGin } 676b4e7a29SLoGin } 68a03c4f9dSLoGin root_inode.inner.write().parent = Arc::downgrade(&root_inode); 696b4e7a29SLoGin *root_inode.fs.write() = Arc::downgrade(&fs); 706b4e7a29SLoGin return fs; 716b4e7a29SLoGin } 726b4e7a29SLoGin 736b4e7a29SLoGin fn create_root_inode() -> Arc<KernFSInode> { 746b4e7a29SLoGin let metadata = Metadata { 756b4e7a29SLoGin size: 0, 766b4e7a29SLoGin mode: ModeType::from_bits_truncate(0o755), 776b4e7a29SLoGin uid: 0, 786b4e7a29SLoGin gid: 0, 796b4e7a29SLoGin blk_size: 0, 806b4e7a29SLoGin blocks: 0, 816b4e7a29SLoGin atime: TimeSpec::new(0, 0), 826b4e7a29SLoGin mtime: TimeSpec::new(0, 0), 836b4e7a29SLoGin ctime: TimeSpec::new(0, 0), 846b4e7a29SLoGin dev_id: 0, 856b4e7a29SLoGin inode_id: generate_inode_id(), 866b4e7a29SLoGin file_type: FileType::Dir, 876b4e7a29SLoGin nlinks: 1, 8802343d0bSLoGin raw_dev: DeviceNumber::default(), 896b4e7a29SLoGin }; 906b4e7a29SLoGin let root_inode = Arc::new(KernFSInode { 9106d5e247SLoGin name: String::from(""), 92a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 936b4e7a29SLoGin parent: Weak::new(), 946b4e7a29SLoGin metadata, 95a03c4f9dSLoGin symlink_target: None, 96a03c4f9dSLoGin symlink_target_absolute_path: None, 976b4e7a29SLoGin }), 986b4e7a29SLoGin self_ref: Weak::new(), 996b4e7a29SLoGin fs: RwLock::new(Weak::new()), 1006b4e7a29SLoGin private_data: SpinLock::new(None), 1016b4e7a29SLoGin callback: None, 1026b4e7a29SLoGin children: SpinLock::new(HashMap::new()), 1036b4e7a29SLoGin inode_type: KernInodeType::Dir, 1046b4e7a29SLoGin }); 1056b4e7a29SLoGin 1066b4e7a29SLoGin return root_inode; 1076b4e7a29SLoGin } 1086b4e7a29SLoGin } 1096b4e7a29SLoGin 1106b4e7a29SLoGin #[derive(Debug)] 1116b4e7a29SLoGin pub struct KernFSInode { 112a03c4f9dSLoGin inner: RwLock<InnerKernFSInode>, 1136b4e7a29SLoGin /// 指向当前Inode所属的文件系统的弱引用 1146b4e7a29SLoGin fs: RwLock<Weak<KernFS>>, 1156b4e7a29SLoGin /// 指向自身的弱引用 1166b4e7a29SLoGin self_ref: Weak<KernFSInode>, 1176b4e7a29SLoGin /// 私有数据 1186b4e7a29SLoGin private_data: SpinLock<Option<KernInodePrivateData>>, 1196b4e7a29SLoGin /// 回调函数 1206b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 1216b4e7a29SLoGin /// 子Inode 1226b4e7a29SLoGin children: SpinLock<HashMap<String, Arc<KernFSInode>>>, 1236b4e7a29SLoGin /// Inode类型 1246b4e7a29SLoGin inode_type: KernInodeType, 12506d5e247SLoGin /// Inode名称 12606d5e247SLoGin name: String, 1276b4e7a29SLoGin } 1286b4e7a29SLoGin 1296b4e7a29SLoGin #[derive(Debug)] 1306b4e7a29SLoGin pub struct InnerKernFSInode { 1316b4e7a29SLoGin parent: Weak<KernFSInode>, 1326b4e7a29SLoGin 1336b4e7a29SLoGin /// 当前inode的元数据 1346b4e7a29SLoGin metadata: Metadata, 135a03c4f9dSLoGin /// 符号链接指向的inode(仅当inode_type为SymLink时有效) 136a03c4f9dSLoGin symlink_target: Option<Weak<KernFSInode>>, 137a03c4f9dSLoGin symlink_target_absolute_path: Option<String>, 1386b4e7a29SLoGin } 1396b4e7a29SLoGin 1406b4e7a29SLoGin impl IndexNode for KernFSInode { 1416b4e7a29SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 1426b4e7a29SLoGin self 1436b4e7a29SLoGin } 1446b4e7a29SLoGin 1456b4e7a29SLoGin fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { 1466b4e7a29SLoGin if let Some(callback) = self.callback { 1476b4e7a29SLoGin let callback_data = 1486b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 1496b4e7a29SLoGin return callback.open(callback_data); 1506b4e7a29SLoGin } 1516b4e7a29SLoGin 1526b4e7a29SLoGin return Ok(()); 1536b4e7a29SLoGin } 1546b4e7a29SLoGin 1556b4e7a29SLoGin fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 1566b4e7a29SLoGin return Ok(()); 1576b4e7a29SLoGin } 1586b4e7a29SLoGin 1596b4e7a29SLoGin fn metadata(&self) -> Result<Metadata, SystemError> { 160a03c4f9dSLoGin return Ok(self.inner.read().metadata.clone()); 1616b4e7a29SLoGin } 1626b4e7a29SLoGin 1636b4e7a29SLoGin fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> { 1646b4e7a29SLoGin // 若文件系统没有实现此方法,则返回“不支持” 1656b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1666b4e7a29SLoGin } 1676b4e7a29SLoGin 1686b4e7a29SLoGin fn resize(&self, _len: usize) -> Result<(), SystemError> { 1696b4e7a29SLoGin return Ok(()); 1706b4e7a29SLoGin } 1716b4e7a29SLoGin 1726b4e7a29SLoGin fn create_with_data( 1736b4e7a29SLoGin &self, 1746b4e7a29SLoGin _name: &str, 1756b4e7a29SLoGin _file_type: FileType, 1766b4e7a29SLoGin _mode: ModeType, 1776b4e7a29SLoGin _data: usize, 1786b4e7a29SLoGin ) -> Result<Arc<dyn IndexNode>, SystemError> { 1796b4e7a29SLoGin // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。 1806b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1816b4e7a29SLoGin } 1826b4e7a29SLoGin 1836b4e7a29SLoGin fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 1846b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 1856b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1866b4e7a29SLoGin } 1876b4e7a29SLoGin 1886b4e7a29SLoGin fn unlink(&self, _name: &str) -> Result<(), SystemError> { 1896b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 1906b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1916b4e7a29SLoGin } 1926b4e7a29SLoGin 1936b4e7a29SLoGin fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 1946b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 1956b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1966b4e7a29SLoGin } 1976b4e7a29SLoGin 198*9e481b3bSTTaq fn move_to( 1996b4e7a29SLoGin &self, 2006b4e7a29SLoGin _old_name: &str, 2016b4e7a29SLoGin _target: &Arc<dyn IndexNode>, 2026b4e7a29SLoGin _new_name: &str, 2036b4e7a29SLoGin ) -> Result<(), SystemError> { 2046b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2056b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2066b4e7a29SLoGin } 2076b4e7a29SLoGin 2086b4e7a29SLoGin fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 2096b4e7a29SLoGin if unlikely(name.len() > KernFS::MAX_NAMELEN) { 2106b4e7a29SLoGin return Err(SystemError::ENAMETOOLONG); 2116b4e7a29SLoGin } 2126b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 2136b4e7a29SLoGin return Err(SystemError::ENOTDIR); 2146b4e7a29SLoGin } 21506d5e247SLoGin match name { 21606d5e247SLoGin "" | "." => { 21706d5e247SLoGin return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 21806d5e247SLoGin } 21906d5e247SLoGin 22006d5e247SLoGin ".." => { 22106d5e247SLoGin return Ok(self 22206d5e247SLoGin .inner 223a03c4f9dSLoGin .read() 22406d5e247SLoGin .parent 22506d5e247SLoGin .upgrade() 22606d5e247SLoGin .ok_or(SystemError::ENOENT)?); 22706d5e247SLoGin } 22806d5e247SLoGin name => { 22906d5e247SLoGin // 在子目录项中查找 23006d5e247SLoGin return Ok(self 2316b4e7a29SLoGin .children 2326b4e7a29SLoGin .lock() 2336b4e7a29SLoGin .get(name) 23406d5e247SLoGin .ok_or(SystemError::ENOENT)? 23506d5e247SLoGin .clone()); 23606d5e247SLoGin } 23706d5e247SLoGin } 2386b4e7a29SLoGin } 2396b4e7a29SLoGin 2406b4e7a29SLoGin fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 2416b4e7a29SLoGin if self.inode_type != KernInodeType::Dir { 2426b4e7a29SLoGin return Err(SystemError::ENOTDIR); 2436b4e7a29SLoGin } 2446b4e7a29SLoGin 2456b4e7a29SLoGin let children = self.children.lock(); 2466b4e7a29SLoGin let r = children 2476b4e7a29SLoGin .iter() 2486b4e7a29SLoGin .find(|(_, v)| v.metadata().unwrap().inode_id == ino) 2496b4e7a29SLoGin .map(|(k, _)| k.clone()); 2506b4e7a29SLoGin 2516b4e7a29SLoGin return r.ok_or(SystemError::ENOENT); 2526b4e7a29SLoGin } 2536b4e7a29SLoGin 2546b4e7a29SLoGin fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> { 2556b4e7a29SLoGin // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 2566b4e7a29SLoGin let name = self.get_entry_name(ino)?; 2576b4e7a29SLoGin let entry = self.find(&name)?; 2586b4e7a29SLoGin return Ok((name, entry.metadata()?)); 2596b4e7a29SLoGin } 2606b4e7a29SLoGin 26152da9a59SGnoCiYeH fn ioctl( 26252da9a59SGnoCiYeH &self, 26352da9a59SGnoCiYeH _cmd: u32, 26452da9a59SGnoCiYeH _data: usize, 26552da9a59SGnoCiYeH _private_data: &FilePrivateData, 26652da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 2676b4e7a29SLoGin // 若文件系统没有实现此方法,则返回“不支持” 2686b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2696b4e7a29SLoGin } 2706b4e7a29SLoGin 2716b4e7a29SLoGin fn truncate(&self, _len: usize) -> Result<(), SystemError> { 2726b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2736b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2746b4e7a29SLoGin } 2756b4e7a29SLoGin 2766b4e7a29SLoGin fn sync(&self) -> Result<(), SystemError> { 2776b4e7a29SLoGin return Ok(()); 2786b4e7a29SLoGin } 2796b4e7a29SLoGin 2806b4e7a29SLoGin fn fs(&self) -> Arc<dyn FileSystem> { 2816b4e7a29SLoGin return self.fs.read().upgrade().unwrap(); 2826b4e7a29SLoGin } 2836b4e7a29SLoGin 2846b4e7a29SLoGin fn list(&self) -> Result<Vec<String>, SystemError> { 28506d5e247SLoGin let info = self.metadata()?; 28606d5e247SLoGin if info.file_type != FileType::Dir { 28706d5e247SLoGin return Err(SystemError::ENOTDIR); 2886b4e7a29SLoGin } 28906d5e247SLoGin 29006d5e247SLoGin let mut keys: Vec<String> = Vec::new(); 29106d5e247SLoGin keys.push(String::from(".")); 29206d5e247SLoGin keys.push(String::from("..")); 29306d5e247SLoGin self.children 29406d5e247SLoGin .lock() 29506d5e247SLoGin .keys() 29606d5e247SLoGin .into_iter() 29706d5e247SLoGin .for_each(|x| keys.push(x.clone())); 29806d5e247SLoGin 29906d5e247SLoGin return Ok(keys); 3006b4e7a29SLoGin } 3016b4e7a29SLoGin 3026b4e7a29SLoGin fn read_at( 3036b4e7a29SLoGin &self, 3046b4e7a29SLoGin offset: usize, 3056b4e7a29SLoGin len: usize, 3066b4e7a29SLoGin buf: &mut [u8], 3076b4e7a29SLoGin _data: &mut FilePrivateData, 3086b4e7a29SLoGin ) -> Result<usize, SystemError> { 309a03c4f9dSLoGin if self.inode_type == KernInodeType::SymLink { 310a03c4f9dSLoGin let inner = self.inner.read(); 311a03c4f9dSLoGin if offset >= inner.symlink_target_absolute_path.as_ref().unwrap().len() { 312a03c4f9dSLoGin return Ok(0); 313a03c4f9dSLoGin } 314a03c4f9dSLoGin let len = min(len, buf.len()); 315a03c4f9dSLoGin let len = min( 316a03c4f9dSLoGin len, 317a03c4f9dSLoGin inner.symlink_target_absolute_path.as_ref().unwrap().len() - offset, 318a03c4f9dSLoGin ); 319a03c4f9dSLoGin buf[0..len].copy_from_slice( 320a03c4f9dSLoGin &inner 321a03c4f9dSLoGin .symlink_target_absolute_path 322a03c4f9dSLoGin .as_ref() 323a03c4f9dSLoGin .unwrap() 324a03c4f9dSLoGin .as_bytes()[offset..offset + len], 325a03c4f9dSLoGin ); 326a03c4f9dSLoGin return Ok(len); 327a03c4f9dSLoGin } 3286b4e7a29SLoGin if self.inode_type != KernInodeType::File { 3296b4e7a29SLoGin return Err(SystemError::EISDIR); 3306b4e7a29SLoGin } 3316b4e7a29SLoGin 3326b4e7a29SLoGin if self.callback.is_none() { 33306d5e247SLoGin kwarn!("kernfs: callback is none"); 3346b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 3356b4e7a29SLoGin } 3366b4e7a29SLoGin 3376b4e7a29SLoGin let callback_data = 3386b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 3396b4e7a29SLoGin return self 3406b4e7a29SLoGin .callback 3416b4e7a29SLoGin .as_ref() 3426b4e7a29SLoGin .unwrap() 3436b4e7a29SLoGin .read(callback_data, &mut buf[..len], offset); 3446b4e7a29SLoGin } 3456b4e7a29SLoGin 3466b4e7a29SLoGin fn write_at( 3476b4e7a29SLoGin &self, 3486b4e7a29SLoGin offset: usize, 3496b4e7a29SLoGin len: usize, 3506b4e7a29SLoGin buf: &[u8], 3516b4e7a29SLoGin _data: &mut FilePrivateData, 3526b4e7a29SLoGin ) -> Result<usize, SystemError> { 3536b4e7a29SLoGin if self.inode_type != KernInodeType::File { 3546b4e7a29SLoGin return Err(SystemError::EISDIR); 3556b4e7a29SLoGin } 3566b4e7a29SLoGin 3576b4e7a29SLoGin if self.callback.is_none() { 3586b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 3596b4e7a29SLoGin } 3606b4e7a29SLoGin 3616b4e7a29SLoGin let callback_data = 3626b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 3636b4e7a29SLoGin return self 3646b4e7a29SLoGin .callback 3656b4e7a29SLoGin .as_ref() 3666b4e7a29SLoGin .unwrap() 3676b4e7a29SLoGin .write(callback_data, &buf[..len], offset); 3686b4e7a29SLoGin } 369*9e481b3bSTTaq 370*9e481b3bSTTaq fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> { 371*9e481b3bSTTaq // 待实现 372*9e481b3bSTTaq Err(SystemError::ENOSYS) 373*9e481b3bSTTaq } 3746b4e7a29SLoGin } 3756b4e7a29SLoGin 3766b4e7a29SLoGin impl KernFSInode { 377a03c4f9dSLoGin pub fn new( 378a03c4f9dSLoGin parent: Option<Arc<KernFSInode>>, 379a03c4f9dSLoGin name: String, 380a03c4f9dSLoGin mut metadata: Metadata, 381a03c4f9dSLoGin inode_type: KernInodeType, 382a03c4f9dSLoGin private_data: Option<KernInodePrivateData>, 383a03c4f9dSLoGin callback: Option<&'static dyn KernFSCallback>, 384a03c4f9dSLoGin ) -> Arc<KernFSInode> { 385a03c4f9dSLoGin metadata.file_type = inode_type.into(); 386a03c4f9dSLoGin let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 387a03c4f9dSLoGin 388a03c4f9dSLoGin let inode = Arc::new(KernFSInode { 389a03c4f9dSLoGin name, 390a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 391a03c4f9dSLoGin parent: parent.clone(), 392a03c4f9dSLoGin metadata, 393a03c4f9dSLoGin symlink_target: None, 394a03c4f9dSLoGin symlink_target_absolute_path: None, 395a03c4f9dSLoGin }), 396a03c4f9dSLoGin self_ref: Weak::new(), 397a03c4f9dSLoGin fs: RwLock::new(Weak::new()), 398a03c4f9dSLoGin private_data: SpinLock::new(private_data), 399a03c4f9dSLoGin callback, 400a03c4f9dSLoGin children: SpinLock::new(HashMap::new()), 401a03c4f9dSLoGin inode_type, 402a03c4f9dSLoGin }); 403a03c4f9dSLoGin 404a03c4f9dSLoGin { 405a03c4f9dSLoGin let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 406a03c4f9dSLoGin unsafe { 407a03c4f9dSLoGin (*ptr).self_ref = Arc::downgrade(&inode); 408a03c4f9dSLoGin } 409a03c4f9dSLoGin } 410a03c4f9dSLoGin if parent.strong_count() > 0 { 411a03c4f9dSLoGin let kernfs = parent 412a03c4f9dSLoGin .upgrade() 413a03c4f9dSLoGin .unwrap() 414a03c4f9dSLoGin .fs() 415a03c4f9dSLoGin .downcast_arc::<KernFS>() 416a03c4f9dSLoGin .expect("KernFSInode::new: parent is not a KernFS instance"); 417a03c4f9dSLoGin *inode.fs.write() = Arc::downgrade(&kernfs); 418a03c4f9dSLoGin } 419a03c4f9dSLoGin return inode; 420a03c4f9dSLoGin } 421a03c4f9dSLoGin 4226b4e7a29SLoGin /// 在当前inode下增加子目录 4236b4e7a29SLoGin /// 4246b4e7a29SLoGin /// ## 参数 4256b4e7a29SLoGin /// 4266b4e7a29SLoGin /// - `name`:子目录名称 4276b4e7a29SLoGin /// - `mode`:子目录权限 4286b4e7a29SLoGin /// - `private_data`:子目录私有数据 4296b4e7a29SLoGin /// - `callback`:子目录回调函数 4306b4e7a29SLoGin /// 4316b4e7a29SLoGin /// ## 返回值 4326b4e7a29SLoGin /// 4336b4e7a29SLoGin /// - 成功:子目录inode 4346b4e7a29SLoGin /// - 失败:错误码 4356b4e7a29SLoGin #[allow(dead_code)] 4366b4e7a29SLoGin #[inline] 4376b4e7a29SLoGin pub fn add_dir( 4386b4e7a29SLoGin &self, 4396b4e7a29SLoGin name: String, 4406b4e7a29SLoGin mode: ModeType, 4416b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4426b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4436b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4446b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4456b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4466b4e7a29SLoGin } 4476b4e7a29SLoGin 4487eda31b2SLoGin return self.inner_create(name, KernInodeType::Dir, mode, 0, private_data, callback); 4496b4e7a29SLoGin } 4506b4e7a29SLoGin 4516b4e7a29SLoGin /// 在当前inode下增加文件 4526b4e7a29SLoGin /// 4536b4e7a29SLoGin /// ## 参数 4546b4e7a29SLoGin /// 4556b4e7a29SLoGin /// - `name`:文件名称 4566b4e7a29SLoGin /// - `mode`:文件权限 4577eda31b2SLoGin /// - `size`:文件大小(如果不指定,则默认为4096) 4586b4e7a29SLoGin /// - `private_data`:文件私有数据 4596b4e7a29SLoGin /// - `callback`:文件回调函数 4606b4e7a29SLoGin /// 4617eda31b2SLoGin /// 4626b4e7a29SLoGin /// ## 返回值 4636b4e7a29SLoGin /// 4646b4e7a29SLoGin /// - 成功:文件inode 4656b4e7a29SLoGin /// - 失败:错误码 4666b4e7a29SLoGin #[allow(dead_code)] 4676b4e7a29SLoGin #[inline] 4686b4e7a29SLoGin pub fn add_file( 4696b4e7a29SLoGin &self, 4706b4e7a29SLoGin name: String, 4716b4e7a29SLoGin mode: ModeType, 4727eda31b2SLoGin size: Option<usize>, 4736b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4746b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4756b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4766b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4776b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4786b4e7a29SLoGin } 4796b4e7a29SLoGin 4807eda31b2SLoGin let size = size.unwrap_or(4096); 4817eda31b2SLoGin return self.inner_create( 4827eda31b2SLoGin name, 4837eda31b2SLoGin KernInodeType::File, 4847eda31b2SLoGin mode, 4857eda31b2SLoGin size, 4867eda31b2SLoGin private_data, 4877eda31b2SLoGin callback, 4887eda31b2SLoGin ); 4896b4e7a29SLoGin } 4906b4e7a29SLoGin 4916b4e7a29SLoGin fn inner_create( 4926b4e7a29SLoGin &self, 4936b4e7a29SLoGin name: String, 4946b4e7a29SLoGin file_type: KernInodeType, 4956b4e7a29SLoGin mode: ModeType, 4967eda31b2SLoGin mut size: usize, 4976b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4986b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4996b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 500a03c4f9dSLoGin match file_type { 501a03c4f9dSLoGin KernInodeType::Dir | KernInodeType::SymLink => { 502a03c4f9dSLoGin size = 0; 503a03c4f9dSLoGin } 5047eda31b2SLoGin _ => {} 505a03c4f9dSLoGin } 50606d5e247SLoGin 5076b4e7a29SLoGin let metadata = Metadata { 5087eda31b2SLoGin size: size as i64, 5096b4e7a29SLoGin mode, 5106b4e7a29SLoGin uid: 0, 5116b4e7a29SLoGin gid: 0, 5126b4e7a29SLoGin blk_size: 0, 5136b4e7a29SLoGin blocks: 0, 5146b4e7a29SLoGin atime: TimeSpec::new(0, 0), 5156b4e7a29SLoGin mtime: TimeSpec::new(0, 0), 5166b4e7a29SLoGin ctime: TimeSpec::new(0, 0), 5176b4e7a29SLoGin dev_id: 0, 5186b4e7a29SLoGin inode_id: generate_inode_id(), 5196b4e7a29SLoGin file_type: file_type.into(), 5206b4e7a29SLoGin nlinks: 1, 52102343d0bSLoGin raw_dev: DeviceNumber::default(), 5226b4e7a29SLoGin }; 5236b4e7a29SLoGin 5246b4e7a29SLoGin let new_inode: Arc<KernFSInode> = Self::new( 52506d5e247SLoGin Some(self.self_ref.upgrade().unwrap()), 52606d5e247SLoGin name.clone(), 5276b4e7a29SLoGin metadata, 52806d5e247SLoGin file_type, 5296b4e7a29SLoGin private_data, 5306b4e7a29SLoGin callback, 5316b4e7a29SLoGin ); 5326b4e7a29SLoGin 5336b4e7a29SLoGin self.children.lock().insert(name, new_inode.clone()); 5346b4e7a29SLoGin 5356b4e7a29SLoGin return Ok(new_inode); 5366b4e7a29SLoGin } 5376b4e7a29SLoGin 5386b4e7a29SLoGin /// 在当前inode下删除子目录或者文件 5396b4e7a29SLoGin /// 5406b4e7a29SLoGin /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 5416b4e7a29SLoGin /// 5426b4e7a29SLoGin /// ## 参数 5436b4e7a29SLoGin /// 5446b4e7a29SLoGin /// - `name`:子目录或者文件名称 5456b4e7a29SLoGin /// 5466b4e7a29SLoGin /// ## 返回值 5476b4e7a29SLoGin /// 5486b4e7a29SLoGin /// - 成功:() 5496b4e7a29SLoGin /// - 失败:错误码 5506b4e7a29SLoGin #[allow(dead_code)] 5516b4e7a29SLoGin pub fn remove(&self, name: &str) -> Result<(), SystemError> { 5526b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 5536b4e7a29SLoGin return Err(SystemError::ENOTDIR); 5546b4e7a29SLoGin } 5556b4e7a29SLoGin 5566b4e7a29SLoGin let mut children = self.children.lock(); 5576b4e7a29SLoGin let inode = children.get(name).ok_or(SystemError::ENOENT)?; 5586b4e7a29SLoGin if inode.children.lock().is_empty() { 5596b4e7a29SLoGin children.remove(name); 5606b4e7a29SLoGin return Ok(()); 5616b4e7a29SLoGin } else { 5626b4e7a29SLoGin return Err(SystemError::ENOTEMPTY); 5636b4e7a29SLoGin } 5646b4e7a29SLoGin } 5656b4e7a29SLoGin 566a03c4f9dSLoGin /// add_link - create a symlink in kernfs 567a03c4f9dSLoGin /// 568a03c4f9dSLoGin /// ## 参数 569a03c4f9dSLoGin /// 570a03c4f9dSLoGin /// - `parent`: directory to create the symlink in 571a03c4f9dSLoGin /// - `name`: name of the symlink 572a03c4f9dSLoGin /// - `target`: target node for the symlink to point to 573a03c4f9dSLoGin /// 574a03c4f9dSLoGin /// Returns the created node on success 575a03c4f9dSLoGin /// 576e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25 577a03c4f9dSLoGin pub fn add_link( 578a03c4f9dSLoGin &self, 57906d5e247SLoGin name: String, 580a03c4f9dSLoGin target: &Arc<KernFSInode>, 581a03c4f9dSLoGin target_absolute_path: String, 582a03c4f9dSLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 583a03c4f9dSLoGin // kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}"); 584a03c4f9dSLoGin let inode = self.inner_create( 58506d5e247SLoGin name, 586a03c4f9dSLoGin KernInodeType::SymLink, 587a03c4f9dSLoGin ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777), 5887eda31b2SLoGin 0, 589a03c4f9dSLoGin None, 590a03c4f9dSLoGin None, 591a03c4f9dSLoGin )?; 5926b4e7a29SLoGin 593a03c4f9dSLoGin inode.inner.write().symlink_target = Some(Arc::downgrade(target)); 594a03c4f9dSLoGin inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path); 595a03c4f9dSLoGin return Ok(inode); 5966b4e7a29SLoGin } 59706d5e247SLoGin 59806d5e247SLoGin pub fn name(&self) -> &str { 59906d5e247SLoGin return &self.name; 60006d5e247SLoGin } 60106d5e247SLoGin 60206d5e247SLoGin pub fn parent(&self) -> Option<Arc<KernFSInode>> { 603a03c4f9dSLoGin return self.inner.read().parent.upgrade(); 60406d5e247SLoGin } 60506d5e247SLoGin 60606d5e247SLoGin pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 60706d5e247SLoGin return self.private_data.lock(); 60806d5e247SLoGin } 60906d5e247SLoGin 610a03c4f9dSLoGin #[allow(dead_code)] 611a03c4f9dSLoGin pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> { 612a03c4f9dSLoGin return self.inner.read().symlink_target.as_ref()?.upgrade(); 613a03c4f9dSLoGin } 614a03c4f9dSLoGin 61506d5e247SLoGin /// remove a kernfs_node recursively 61606d5e247SLoGin pub fn remove_recursive(&self) { 61706d5e247SLoGin let mut children = self.children.lock().drain().collect::<Vec<_>>(); 61806d5e247SLoGin while let Some((_, child)) = children.pop() { 61906d5e247SLoGin children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 62006d5e247SLoGin } 62106d5e247SLoGin } 62206d5e247SLoGin 62306d5e247SLoGin /// 删除当前的inode(包括其自身、子目录和子文件) 62406d5e247SLoGin #[allow(dead_code)] 62506d5e247SLoGin pub fn remove_inode_include_self(&self) { 62606d5e247SLoGin let parent = self.parent(); 62706d5e247SLoGin if let Some(parent) = parent { 62806d5e247SLoGin parent.children.lock().remove(self.name()); 62906d5e247SLoGin } 63006d5e247SLoGin self.remove_recursive(); 63106d5e247SLoGin } 6326b4e7a29SLoGin } 6336b4e7a29SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)] 63406d5e247SLoGin pub enum KernInodeType { 6356b4e7a29SLoGin Dir, 6366b4e7a29SLoGin File, 637a03c4f9dSLoGin SymLink, 6386b4e7a29SLoGin } 6396b4e7a29SLoGin 6406b4e7a29SLoGin impl Into<FileType> for KernInodeType { 6416b4e7a29SLoGin fn into(self) -> FileType { 6426b4e7a29SLoGin match self { 6436b4e7a29SLoGin KernInodeType::Dir => FileType::Dir, 6446b4e7a29SLoGin KernInodeType::File => FileType::File, 645a03c4f9dSLoGin KernInodeType::SymLink => FileType::SymLink, 6466b4e7a29SLoGin } 6476b4e7a29SLoGin } 6486b4e7a29SLoGin } 649