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, 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, 936b4e7a29SLoGin atime: TimeSpec::new(0, 0), 946b4e7a29SLoGin mtime: TimeSpec::new(0, 0), 956b4e7a29SLoGin ctime: TimeSpec::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 157*dfe53cf0SGnoCiYeH fn open( 158*dfe53cf0SGnoCiYeH &self, 159*dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 160*dfe53cf0SGnoCiYeH _mode: &FileMode, 161*dfe53cf0SGnoCiYeH ) -> 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 171*dfe53cf0SGnoCiYeH 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 // 若文件系统没有实现此方法,则返回“不支持” 1816b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 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的其它方法来创建文件,而不能从用户态直接调用此方法。 1966b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1976b4e7a29SLoGin } 1986b4e7a29SLoGin 1996b4e7a29SLoGin fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 2006b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2016b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2026b4e7a29SLoGin } 2036b4e7a29SLoGin 2046b4e7a29SLoGin fn unlink(&self, _name: &str) -> Result<(), SystemError> { 2056b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2066b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2076b4e7a29SLoGin } 2086b4e7a29SLoGin 2096b4e7a29SLoGin fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 2106b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2116b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 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的其它方法来操作文件,而不能从用户态直接调用此方法。 2216b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 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 // 若文件系统没有实现此方法,则返回“不支持” 2846b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2856b4e7a29SLoGin } 2866b4e7a29SLoGin 2876b4e7a29SLoGin fn truncate(&self, _len: usize) -> Result<(), SystemError> { 2886b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2896b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 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], 322*dfe53cf0SGnoCiYeH _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"); 3496b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 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], 366*dfe53cf0SGnoCiYeH _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() { 3736b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 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 } 3849e481b3bSTTaq 3859e481b3bSTTaq fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> { 3869e481b3bSTTaq // 待实现 3879e481b3bSTTaq Err(SystemError::ENOSYS) 3889e481b3bSTTaq } 3896b4e7a29SLoGin } 3906b4e7a29SLoGin 3916b4e7a29SLoGin impl KernFSInode { 392a03c4f9dSLoGin pub fn new( 393a03c4f9dSLoGin parent: Option<Arc<KernFSInode>>, 394a03c4f9dSLoGin name: String, 395a03c4f9dSLoGin mut metadata: Metadata, 396a03c4f9dSLoGin inode_type: KernInodeType, 397a03c4f9dSLoGin private_data: Option<KernInodePrivateData>, 398a03c4f9dSLoGin callback: Option<&'static dyn KernFSCallback>, 399a03c4f9dSLoGin ) -> Arc<KernFSInode> { 400a03c4f9dSLoGin metadata.file_type = inode_type.into(); 401a03c4f9dSLoGin let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 402a03c4f9dSLoGin 403a03c4f9dSLoGin let inode = Arc::new(KernFSInode { 404a03c4f9dSLoGin name, 405a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 406a03c4f9dSLoGin parent: parent.clone(), 407a03c4f9dSLoGin metadata, 408a03c4f9dSLoGin symlink_target: None, 409a03c4f9dSLoGin symlink_target_absolute_path: None, 410a03c4f9dSLoGin }), 411a03c4f9dSLoGin self_ref: Weak::new(), 412a03c4f9dSLoGin fs: RwLock::new(Weak::new()), 413a03c4f9dSLoGin private_data: SpinLock::new(private_data), 414a03c4f9dSLoGin callback, 415a03c4f9dSLoGin children: SpinLock::new(HashMap::new()), 416a03c4f9dSLoGin inode_type, 417a03c4f9dSLoGin }); 418a03c4f9dSLoGin 419a03c4f9dSLoGin { 420a03c4f9dSLoGin let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 421a03c4f9dSLoGin unsafe { 422a03c4f9dSLoGin (*ptr).self_ref = Arc::downgrade(&inode); 423a03c4f9dSLoGin } 424a03c4f9dSLoGin } 425a03c4f9dSLoGin if parent.strong_count() > 0 { 426a03c4f9dSLoGin let kernfs = parent 427a03c4f9dSLoGin .upgrade() 428a03c4f9dSLoGin .unwrap() 429a03c4f9dSLoGin .fs() 430a03c4f9dSLoGin .downcast_arc::<KernFS>() 431a03c4f9dSLoGin .expect("KernFSInode::new: parent is not a KernFS instance"); 432a03c4f9dSLoGin *inode.fs.write() = Arc::downgrade(&kernfs); 433a03c4f9dSLoGin } 434a03c4f9dSLoGin return inode; 435a03c4f9dSLoGin } 436a03c4f9dSLoGin 4376b4e7a29SLoGin /// 在当前inode下增加子目录 4386b4e7a29SLoGin /// 4396b4e7a29SLoGin /// ## 参数 4406b4e7a29SLoGin /// 4416b4e7a29SLoGin /// - `name`:子目录名称 4426b4e7a29SLoGin /// - `mode`:子目录权限 4436b4e7a29SLoGin /// - `private_data`:子目录私有数据 4446b4e7a29SLoGin /// - `callback`:子目录回调函数 4456b4e7a29SLoGin /// 4466b4e7a29SLoGin /// ## 返回值 4476b4e7a29SLoGin /// 4486b4e7a29SLoGin /// - 成功:子目录inode 4496b4e7a29SLoGin /// - 失败:错误码 4506b4e7a29SLoGin #[allow(dead_code)] 4516b4e7a29SLoGin #[inline] 4526b4e7a29SLoGin pub fn add_dir( 4536b4e7a29SLoGin &self, 4546b4e7a29SLoGin name: String, 4556b4e7a29SLoGin mode: ModeType, 4566b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4576b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4586b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4596b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4606b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4616b4e7a29SLoGin } 4626b4e7a29SLoGin 4637eda31b2SLoGin return self.inner_create(name, KernInodeType::Dir, mode, 0, private_data, callback); 4646b4e7a29SLoGin } 4656b4e7a29SLoGin 4666b4e7a29SLoGin /// 在当前inode下增加文件 4676b4e7a29SLoGin /// 4686b4e7a29SLoGin /// ## 参数 4696b4e7a29SLoGin /// 4706b4e7a29SLoGin /// - `name`:文件名称 4716b4e7a29SLoGin /// - `mode`:文件权限 4727eda31b2SLoGin /// - `size`:文件大小(如果不指定,则默认为4096) 4736b4e7a29SLoGin /// - `private_data`:文件私有数据 4746b4e7a29SLoGin /// - `callback`:文件回调函数 4756b4e7a29SLoGin /// 4767eda31b2SLoGin /// 4776b4e7a29SLoGin /// ## 返回值 4786b4e7a29SLoGin /// 4796b4e7a29SLoGin /// - 成功:文件inode 4806b4e7a29SLoGin /// - 失败:错误码 4816b4e7a29SLoGin #[allow(dead_code)] 4826b4e7a29SLoGin #[inline] 4836b4e7a29SLoGin pub fn add_file( 4846b4e7a29SLoGin &self, 4856b4e7a29SLoGin name: String, 4866b4e7a29SLoGin mode: ModeType, 4877eda31b2SLoGin size: Option<usize>, 4886b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4896b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4906b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4916b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4926b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4936b4e7a29SLoGin } 4946b4e7a29SLoGin 4957eda31b2SLoGin let size = size.unwrap_or(4096); 4967eda31b2SLoGin return self.inner_create( 4977eda31b2SLoGin name, 4987eda31b2SLoGin KernInodeType::File, 4997eda31b2SLoGin mode, 5007eda31b2SLoGin size, 5017eda31b2SLoGin private_data, 5027eda31b2SLoGin callback, 5037eda31b2SLoGin ); 5046b4e7a29SLoGin } 5056b4e7a29SLoGin 5066b4e7a29SLoGin fn inner_create( 5076b4e7a29SLoGin &self, 5086b4e7a29SLoGin name: String, 5096b4e7a29SLoGin file_type: KernInodeType, 5106b4e7a29SLoGin mode: ModeType, 5117eda31b2SLoGin mut size: usize, 5126b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 5136b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 5146b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 515a03c4f9dSLoGin match file_type { 516a03c4f9dSLoGin KernInodeType::Dir | KernInodeType::SymLink => { 517a03c4f9dSLoGin size = 0; 518a03c4f9dSLoGin } 5197eda31b2SLoGin _ => {} 520a03c4f9dSLoGin } 52106d5e247SLoGin 5226b4e7a29SLoGin let metadata = Metadata { 5237eda31b2SLoGin size: size as i64, 5246b4e7a29SLoGin mode, 5256b4e7a29SLoGin uid: 0, 5266b4e7a29SLoGin gid: 0, 5276b4e7a29SLoGin blk_size: 0, 5286b4e7a29SLoGin blocks: 0, 5296b4e7a29SLoGin atime: TimeSpec::new(0, 0), 5306b4e7a29SLoGin mtime: TimeSpec::new(0, 0), 5316b4e7a29SLoGin ctime: TimeSpec::new(0, 0), 5326b4e7a29SLoGin dev_id: 0, 5336b4e7a29SLoGin inode_id: generate_inode_id(), 5346b4e7a29SLoGin file_type: file_type.into(), 5356b4e7a29SLoGin nlinks: 1, 53602343d0bSLoGin raw_dev: DeviceNumber::default(), 5376b4e7a29SLoGin }; 5386b4e7a29SLoGin 5396b4e7a29SLoGin let new_inode: Arc<KernFSInode> = Self::new( 54006d5e247SLoGin Some(self.self_ref.upgrade().unwrap()), 54106d5e247SLoGin name.clone(), 5426b4e7a29SLoGin metadata, 54306d5e247SLoGin file_type, 5446b4e7a29SLoGin private_data, 5456b4e7a29SLoGin callback, 5466b4e7a29SLoGin ); 5476b4e7a29SLoGin 5486b4e7a29SLoGin self.children.lock().insert(name, new_inode.clone()); 5496b4e7a29SLoGin 5506b4e7a29SLoGin return Ok(new_inode); 5516b4e7a29SLoGin } 5526b4e7a29SLoGin 5536b4e7a29SLoGin /// 在当前inode下删除子目录或者文件 5546b4e7a29SLoGin /// 5556b4e7a29SLoGin /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 5566b4e7a29SLoGin /// 5576b4e7a29SLoGin /// ## 参数 5586b4e7a29SLoGin /// 5596b4e7a29SLoGin /// - `name`:子目录或者文件名称 5606b4e7a29SLoGin /// 5616b4e7a29SLoGin /// ## 返回值 5626b4e7a29SLoGin /// 5636b4e7a29SLoGin /// - 成功:() 5646b4e7a29SLoGin /// - 失败:错误码 5656b4e7a29SLoGin #[allow(dead_code)] 5666b4e7a29SLoGin pub fn remove(&self, name: &str) -> Result<(), SystemError> { 5676b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 5686b4e7a29SLoGin return Err(SystemError::ENOTDIR); 5696b4e7a29SLoGin } 5706b4e7a29SLoGin 5716b4e7a29SLoGin let mut children = self.children.lock(); 5726b4e7a29SLoGin let inode = children.get(name).ok_or(SystemError::ENOENT)?; 5736b4e7a29SLoGin if inode.children.lock().is_empty() { 5746b4e7a29SLoGin children.remove(name); 5756b4e7a29SLoGin return Ok(()); 5766b4e7a29SLoGin } else { 5776b4e7a29SLoGin return Err(SystemError::ENOTEMPTY); 5786b4e7a29SLoGin } 5796b4e7a29SLoGin } 5806b4e7a29SLoGin 581a03c4f9dSLoGin /// add_link - create a symlink in kernfs 582a03c4f9dSLoGin /// 583a03c4f9dSLoGin /// ## 参数 584a03c4f9dSLoGin /// 585a03c4f9dSLoGin /// - `parent`: directory to create the symlink in 586a03c4f9dSLoGin /// - `name`: name of the symlink 587a03c4f9dSLoGin /// - `target`: target node for the symlink to point to 588a03c4f9dSLoGin /// 589a03c4f9dSLoGin /// Returns the created node on success 590a03c4f9dSLoGin /// 591e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25 592a03c4f9dSLoGin pub fn add_link( 593a03c4f9dSLoGin &self, 59406d5e247SLoGin name: String, 595a03c4f9dSLoGin target: &Arc<KernFSInode>, 596a03c4f9dSLoGin target_absolute_path: String, 597a03c4f9dSLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 598a03c4f9dSLoGin // kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}"); 599a03c4f9dSLoGin let inode = self.inner_create( 60006d5e247SLoGin name, 601a03c4f9dSLoGin KernInodeType::SymLink, 602a03c4f9dSLoGin ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777), 6037eda31b2SLoGin 0, 604a03c4f9dSLoGin None, 605a03c4f9dSLoGin None, 606a03c4f9dSLoGin )?; 6076b4e7a29SLoGin 608a03c4f9dSLoGin inode.inner.write().symlink_target = Some(Arc::downgrade(target)); 609a03c4f9dSLoGin inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path); 610a03c4f9dSLoGin return Ok(inode); 6116b4e7a29SLoGin } 61206d5e247SLoGin 61306d5e247SLoGin pub fn name(&self) -> &str { 61406d5e247SLoGin return &self.name; 61506d5e247SLoGin } 61606d5e247SLoGin 61706d5e247SLoGin pub fn parent(&self) -> Option<Arc<KernFSInode>> { 618a03c4f9dSLoGin return self.inner.read().parent.upgrade(); 61906d5e247SLoGin } 62006d5e247SLoGin 62106d5e247SLoGin pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 62206d5e247SLoGin return self.private_data.lock(); 62306d5e247SLoGin } 62406d5e247SLoGin 625a03c4f9dSLoGin #[allow(dead_code)] 626a03c4f9dSLoGin pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> { 627a03c4f9dSLoGin return self.inner.read().symlink_target.as_ref()?.upgrade(); 628a03c4f9dSLoGin } 629a03c4f9dSLoGin 63006d5e247SLoGin /// remove a kernfs_node recursively 63106d5e247SLoGin pub fn remove_recursive(&self) { 63206d5e247SLoGin let mut children = self.children.lock().drain().collect::<Vec<_>>(); 63306d5e247SLoGin while let Some((_, child)) = children.pop() { 63406d5e247SLoGin children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 63506d5e247SLoGin } 63606d5e247SLoGin } 63706d5e247SLoGin 63806d5e247SLoGin /// 删除当前的inode(包括其自身、子目录和子文件) 63906d5e247SLoGin #[allow(dead_code)] 64006d5e247SLoGin pub fn remove_inode_include_self(&self) { 64106d5e247SLoGin let parent = self.parent(); 64206d5e247SLoGin if let Some(parent) = parent { 64306d5e247SLoGin parent.children.lock().remove(self.name()); 64406d5e247SLoGin } 64506d5e247SLoGin self.remove_recursive(); 64606d5e247SLoGin } 6476b4e7a29SLoGin } 6486b4e7a29SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)] 64906d5e247SLoGin pub enum KernInodeType { 6506b4e7a29SLoGin Dir, 6516b4e7a29SLoGin File, 652a03c4f9dSLoGin SymLink, 6536b4e7a29SLoGin } 6546b4e7a29SLoGin 655b5b571e0SLoGin impl From<KernInodeType> for FileType { 656b5b571e0SLoGin fn from(val: KernInodeType) -> Self { 657b5b571e0SLoGin match val { 6586b4e7a29SLoGin KernInodeType::Dir => FileType::Dir, 6596b4e7a29SLoGin KernInodeType::File => FileType::File, 660a03c4f9dSLoGin KernInodeType::SymLink => FileType::SymLink, 6616b4e7a29SLoGin } 6626b4e7a29SLoGin } 6636b4e7a29SLoGin } 664