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::{ 1206d5e247SLoGin libs::{ 1306d5e247SLoGin casting::DowncastArc, 1406d5e247SLoGin rwlock::RwLock, 1506d5e247SLoGin spinlock::{SpinLock, SpinLockGuard}, 1606d5e247SLoGin }, 176b4e7a29SLoGin time::TimeSpec, 186b4e7a29SLoGin }; 196b4e7a29SLoGin 206b4e7a29SLoGin use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}; 216b4e7a29SLoGin 226b4e7a29SLoGin use super::vfs::{ 236b4e7a29SLoGin core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, 2440609970SGnoCiYeH FileType, FsInfo, IndexNode, InodeId, Metadata, 256b4e7a29SLoGin }; 266b4e7a29SLoGin 276b4e7a29SLoGin pub mod callback; 286b4e7a29SLoGin 296b4e7a29SLoGin #[derive(Debug)] 306b4e7a29SLoGin pub struct KernFS { 316b4e7a29SLoGin root_inode: Arc<KernFSInode>, 326b4e7a29SLoGin } 336b4e7a29SLoGin 346b4e7a29SLoGin impl FileSystem for KernFS { 356b4e7a29SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 366b4e7a29SLoGin self 376b4e7a29SLoGin } 386b4e7a29SLoGin 396b4e7a29SLoGin fn info(&self) -> FsInfo { 406b4e7a29SLoGin return FsInfo { 416b4e7a29SLoGin blk_dev_id: 0, 426b4e7a29SLoGin max_name_len: KernFS::MAX_NAMELEN, 436b4e7a29SLoGin }; 446b4e7a29SLoGin } 456b4e7a29SLoGin 466b4e7a29SLoGin fn root_inode(&self) -> Arc<dyn IndexNode> { 476b4e7a29SLoGin return self.root_inode.clone(); 486b4e7a29SLoGin } 496b4e7a29SLoGin } 506b4e7a29SLoGin 516b4e7a29SLoGin impl KernFS { 526b4e7a29SLoGin pub const MAX_NAMELEN: usize = 4096; 536b4e7a29SLoGin 546b4e7a29SLoGin #[allow(dead_code)] 556b4e7a29SLoGin pub fn new() -> Arc<Self> { 566b4e7a29SLoGin let root_inode = Self::create_root_inode(); 576b4e7a29SLoGin let fs = Arc::new(Self { 586b4e7a29SLoGin root_inode: root_inode.clone(), 596b4e7a29SLoGin }); 606b4e7a29SLoGin 616b4e7a29SLoGin { 626b4e7a29SLoGin let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode; 636b4e7a29SLoGin unsafe { 646b4e7a29SLoGin (*ptr).self_ref = Arc::downgrade(&root_inode); 656b4e7a29SLoGin } 666b4e7a29SLoGin } 67a03c4f9dSLoGin root_inode.inner.write().parent = Arc::downgrade(&root_inode); 686b4e7a29SLoGin *root_inode.fs.write() = Arc::downgrade(&fs); 696b4e7a29SLoGin return fs; 706b4e7a29SLoGin } 716b4e7a29SLoGin 726b4e7a29SLoGin fn create_root_inode() -> Arc<KernFSInode> { 736b4e7a29SLoGin let metadata = Metadata { 746b4e7a29SLoGin size: 0, 756b4e7a29SLoGin mode: ModeType::from_bits_truncate(0o755), 766b4e7a29SLoGin uid: 0, 776b4e7a29SLoGin gid: 0, 786b4e7a29SLoGin blk_size: 0, 796b4e7a29SLoGin blocks: 0, 806b4e7a29SLoGin atime: TimeSpec::new(0, 0), 816b4e7a29SLoGin mtime: TimeSpec::new(0, 0), 826b4e7a29SLoGin ctime: TimeSpec::new(0, 0), 836b4e7a29SLoGin dev_id: 0, 846b4e7a29SLoGin inode_id: generate_inode_id(), 856b4e7a29SLoGin file_type: FileType::Dir, 866b4e7a29SLoGin nlinks: 1, 876b4e7a29SLoGin raw_dev: 0, 886b4e7a29SLoGin }; 896b4e7a29SLoGin let root_inode = Arc::new(KernFSInode { 9006d5e247SLoGin name: String::from(""), 91a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 926b4e7a29SLoGin parent: Weak::new(), 936b4e7a29SLoGin metadata, 94a03c4f9dSLoGin symlink_target: None, 95a03c4f9dSLoGin symlink_target_absolute_path: None, 966b4e7a29SLoGin }), 976b4e7a29SLoGin self_ref: Weak::new(), 986b4e7a29SLoGin fs: RwLock::new(Weak::new()), 996b4e7a29SLoGin private_data: SpinLock::new(None), 1006b4e7a29SLoGin callback: None, 1016b4e7a29SLoGin children: SpinLock::new(HashMap::new()), 1026b4e7a29SLoGin inode_type: KernInodeType::Dir, 1036b4e7a29SLoGin }); 1046b4e7a29SLoGin 1056b4e7a29SLoGin return root_inode; 1066b4e7a29SLoGin } 1076b4e7a29SLoGin } 1086b4e7a29SLoGin 1096b4e7a29SLoGin #[derive(Debug)] 1106b4e7a29SLoGin pub struct KernFSInode { 111a03c4f9dSLoGin inner: RwLock<InnerKernFSInode>, 1126b4e7a29SLoGin /// 指向当前Inode所属的文件系统的弱引用 1136b4e7a29SLoGin fs: RwLock<Weak<KernFS>>, 1146b4e7a29SLoGin /// 指向自身的弱引用 1156b4e7a29SLoGin self_ref: Weak<KernFSInode>, 1166b4e7a29SLoGin /// 私有数据 1176b4e7a29SLoGin private_data: SpinLock<Option<KernInodePrivateData>>, 1186b4e7a29SLoGin /// 回调函数 1196b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 1206b4e7a29SLoGin /// 子Inode 1216b4e7a29SLoGin children: SpinLock<HashMap<String, Arc<KernFSInode>>>, 1226b4e7a29SLoGin /// Inode类型 1236b4e7a29SLoGin inode_type: KernInodeType, 12406d5e247SLoGin /// Inode名称 12506d5e247SLoGin name: String, 1266b4e7a29SLoGin } 1276b4e7a29SLoGin 1286b4e7a29SLoGin #[derive(Debug)] 1296b4e7a29SLoGin pub struct InnerKernFSInode { 1306b4e7a29SLoGin parent: Weak<KernFSInode>, 1316b4e7a29SLoGin 1326b4e7a29SLoGin /// 当前inode的元数据 1336b4e7a29SLoGin metadata: Metadata, 134a03c4f9dSLoGin /// 符号链接指向的inode(仅当inode_type为SymLink时有效) 135a03c4f9dSLoGin symlink_target: Option<Weak<KernFSInode>>, 136a03c4f9dSLoGin symlink_target_absolute_path: Option<String>, 1376b4e7a29SLoGin } 1386b4e7a29SLoGin 1396b4e7a29SLoGin impl IndexNode for KernFSInode { 1406b4e7a29SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 1416b4e7a29SLoGin self 1426b4e7a29SLoGin } 1436b4e7a29SLoGin 1446b4e7a29SLoGin fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { 1456b4e7a29SLoGin if let Some(callback) = self.callback { 1466b4e7a29SLoGin let callback_data = 1476b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 1486b4e7a29SLoGin return callback.open(callback_data); 1496b4e7a29SLoGin } 1506b4e7a29SLoGin 1516b4e7a29SLoGin return Ok(()); 1526b4e7a29SLoGin } 1536b4e7a29SLoGin 1546b4e7a29SLoGin fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 1556b4e7a29SLoGin return Ok(()); 1566b4e7a29SLoGin } 1576b4e7a29SLoGin 1586b4e7a29SLoGin fn metadata(&self) -> Result<Metadata, SystemError> { 159a03c4f9dSLoGin return Ok(self.inner.read().metadata.clone()); 1606b4e7a29SLoGin } 1616b4e7a29SLoGin 1626b4e7a29SLoGin fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> { 1636b4e7a29SLoGin // 若文件系统没有实现此方法,则返回“不支持” 1646b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1656b4e7a29SLoGin } 1666b4e7a29SLoGin 1676b4e7a29SLoGin fn resize(&self, _len: usize) -> Result<(), SystemError> { 1686b4e7a29SLoGin return Ok(()); 1696b4e7a29SLoGin } 1706b4e7a29SLoGin 1716b4e7a29SLoGin fn create_with_data( 1726b4e7a29SLoGin &self, 1736b4e7a29SLoGin _name: &str, 1746b4e7a29SLoGin _file_type: FileType, 1756b4e7a29SLoGin _mode: ModeType, 1766b4e7a29SLoGin _data: usize, 1776b4e7a29SLoGin ) -> Result<Arc<dyn IndexNode>, SystemError> { 1786b4e7a29SLoGin // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。 1796b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1806b4e7a29SLoGin } 1816b4e7a29SLoGin 1826b4e7a29SLoGin fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 1836b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 1846b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1856b4e7a29SLoGin } 1866b4e7a29SLoGin 1876b4e7a29SLoGin fn unlink(&self, _name: &str) -> Result<(), SystemError> { 1886b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 1896b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1906b4e7a29SLoGin } 1916b4e7a29SLoGin 1926b4e7a29SLoGin fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 1936b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 1946b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 1956b4e7a29SLoGin } 1966b4e7a29SLoGin 1976b4e7a29SLoGin fn move_( 1986b4e7a29SLoGin &self, 1996b4e7a29SLoGin _old_name: &str, 2006b4e7a29SLoGin _target: &Arc<dyn IndexNode>, 2016b4e7a29SLoGin _new_name: &str, 2026b4e7a29SLoGin ) -> Result<(), SystemError> { 2036b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2046b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2056b4e7a29SLoGin } 2066b4e7a29SLoGin 2076b4e7a29SLoGin fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 2086b4e7a29SLoGin if unlikely(name.len() > KernFS::MAX_NAMELEN) { 2096b4e7a29SLoGin return Err(SystemError::ENAMETOOLONG); 2106b4e7a29SLoGin } 2116b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 2126b4e7a29SLoGin return Err(SystemError::ENOTDIR); 2136b4e7a29SLoGin } 21406d5e247SLoGin match name { 21506d5e247SLoGin "" | "." => { 21606d5e247SLoGin return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 21706d5e247SLoGin } 21806d5e247SLoGin 21906d5e247SLoGin ".." => { 22006d5e247SLoGin return Ok(self 22106d5e247SLoGin .inner 222a03c4f9dSLoGin .read() 22306d5e247SLoGin .parent 22406d5e247SLoGin .upgrade() 22506d5e247SLoGin .ok_or(SystemError::ENOENT)?); 22606d5e247SLoGin } 22706d5e247SLoGin name => { 22806d5e247SLoGin // 在子目录项中查找 22906d5e247SLoGin return Ok(self 2306b4e7a29SLoGin .children 2316b4e7a29SLoGin .lock() 2326b4e7a29SLoGin .get(name) 23306d5e247SLoGin .ok_or(SystemError::ENOENT)? 23406d5e247SLoGin .clone()); 23506d5e247SLoGin } 23606d5e247SLoGin } 2376b4e7a29SLoGin } 2386b4e7a29SLoGin 2396b4e7a29SLoGin fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 2406b4e7a29SLoGin if self.inode_type != KernInodeType::Dir { 2416b4e7a29SLoGin return Err(SystemError::ENOTDIR); 2426b4e7a29SLoGin } 2436b4e7a29SLoGin 2446b4e7a29SLoGin let children = self.children.lock(); 2456b4e7a29SLoGin let r = children 2466b4e7a29SLoGin .iter() 2476b4e7a29SLoGin .find(|(_, v)| v.metadata().unwrap().inode_id == ino) 2486b4e7a29SLoGin .map(|(k, _)| k.clone()); 2496b4e7a29SLoGin 2506b4e7a29SLoGin return r.ok_or(SystemError::ENOENT); 2516b4e7a29SLoGin } 2526b4e7a29SLoGin 2536b4e7a29SLoGin fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> { 2546b4e7a29SLoGin // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 2556b4e7a29SLoGin let name = self.get_entry_name(ino)?; 2566b4e7a29SLoGin let entry = self.find(&name)?; 2576b4e7a29SLoGin return Ok((name, entry.metadata()?)); 2586b4e7a29SLoGin } 2596b4e7a29SLoGin 2606b4e7a29SLoGin fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 2616b4e7a29SLoGin // 若文件系统没有实现此方法,则返回“不支持” 2626b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2636b4e7a29SLoGin } 2646b4e7a29SLoGin 2656b4e7a29SLoGin fn truncate(&self, _len: usize) -> Result<(), SystemError> { 2666b4e7a29SLoGin // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 2676b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 2686b4e7a29SLoGin } 2696b4e7a29SLoGin 2706b4e7a29SLoGin fn sync(&self) -> Result<(), SystemError> { 2716b4e7a29SLoGin return Ok(()); 2726b4e7a29SLoGin } 2736b4e7a29SLoGin 2746b4e7a29SLoGin fn fs(&self) -> Arc<dyn FileSystem> { 2756b4e7a29SLoGin return self.fs.read().upgrade().unwrap(); 2766b4e7a29SLoGin } 2776b4e7a29SLoGin 2786b4e7a29SLoGin fn list(&self) -> Result<Vec<String>, SystemError> { 27906d5e247SLoGin let info = self.metadata()?; 28006d5e247SLoGin if info.file_type != FileType::Dir { 28106d5e247SLoGin return Err(SystemError::ENOTDIR); 2826b4e7a29SLoGin } 28306d5e247SLoGin 28406d5e247SLoGin let mut keys: Vec<String> = Vec::new(); 28506d5e247SLoGin keys.push(String::from(".")); 28606d5e247SLoGin keys.push(String::from("..")); 28706d5e247SLoGin self.children 28806d5e247SLoGin .lock() 28906d5e247SLoGin .keys() 29006d5e247SLoGin .into_iter() 29106d5e247SLoGin .for_each(|x| keys.push(x.clone())); 29206d5e247SLoGin 29306d5e247SLoGin return Ok(keys); 2946b4e7a29SLoGin } 2956b4e7a29SLoGin 2966b4e7a29SLoGin fn read_at( 2976b4e7a29SLoGin &self, 2986b4e7a29SLoGin offset: usize, 2996b4e7a29SLoGin len: usize, 3006b4e7a29SLoGin buf: &mut [u8], 3016b4e7a29SLoGin _data: &mut FilePrivateData, 3026b4e7a29SLoGin ) -> Result<usize, SystemError> { 303a03c4f9dSLoGin if self.inode_type == KernInodeType::SymLink { 304a03c4f9dSLoGin let inner = self.inner.read(); 305a03c4f9dSLoGin if offset >= inner.symlink_target_absolute_path.as_ref().unwrap().len() { 306a03c4f9dSLoGin return Ok(0); 307a03c4f9dSLoGin } 308a03c4f9dSLoGin let len = min(len, buf.len()); 309a03c4f9dSLoGin let len = min( 310a03c4f9dSLoGin len, 311a03c4f9dSLoGin inner.symlink_target_absolute_path.as_ref().unwrap().len() - offset, 312a03c4f9dSLoGin ); 313a03c4f9dSLoGin buf[0..len].copy_from_slice( 314a03c4f9dSLoGin &inner 315a03c4f9dSLoGin .symlink_target_absolute_path 316a03c4f9dSLoGin .as_ref() 317a03c4f9dSLoGin .unwrap() 318a03c4f9dSLoGin .as_bytes()[offset..offset + len], 319a03c4f9dSLoGin ); 320a03c4f9dSLoGin return Ok(len); 321a03c4f9dSLoGin } 3226b4e7a29SLoGin if self.inode_type != KernInodeType::File { 3236b4e7a29SLoGin return Err(SystemError::EISDIR); 3246b4e7a29SLoGin } 3256b4e7a29SLoGin 3266b4e7a29SLoGin if self.callback.is_none() { 32706d5e247SLoGin kwarn!("kernfs: callback is none"); 3286b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 3296b4e7a29SLoGin } 3306b4e7a29SLoGin 3316b4e7a29SLoGin let callback_data = 3326b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 3336b4e7a29SLoGin return self 3346b4e7a29SLoGin .callback 3356b4e7a29SLoGin .as_ref() 3366b4e7a29SLoGin .unwrap() 3376b4e7a29SLoGin .read(callback_data, &mut buf[..len], offset); 3386b4e7a29SLoGin } 3396b4e7a29SLoGin 3406b4e7a29SLoGin fn write_at( 3416b4e7a29SLoGin &self, 3426b4e7a29SLoGin offset: usize, 3436b4e7a29SLoGin len: usize, 3446b4e7a29SLoGin buf: &[u8], 3456b4e7a29SLoGin _data: &mut FilePrivateData, 3466b4e7a29SLoGin ) -> Result<usize, SystemError> { 3476b4e7a29SLoGin if self.inode_type != KernInodeType::File { 3486b4e7a29SLoGin return Err(SystemError::EISDIR); 3496b4e7a29SLoGin } 3506b4e7a29SLoGin 3516b4e7a29SLoGin if self.callback.is_none() { 3526b4e7a29SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 3536b4e7a29SLoGin } 3546b4e7a29SLoGin 3556b4e7a29SLoGin let callback_data = 3566b4e7a29SLoGin KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 3576b4e7a29SLoGin return self 3586b4e7a29SLoGin .callback 3596b4e7a29SLoGin .as_ref() 3606b4e7a29SLoGin .unwrap() 3616b4e7a29SLoGin .write(callback_data, &buf[..len], offset); 3626b4e7a29SLoGin } 3636b4e7a29SLoGin } 3646b4e7a29SLoGin 3656b4e7a29SLoGin impl KernFSInode { 366a03c4f9dSLoGin pub fn new( 367a03c4f9dSLoGin parent: Option<Arc<KernFSInode>>, 368a03c4f9dSLoGin name: String, 369a03c4f9dSLoGin mut metadata: Metadata, 370a03c4f9dSLoGin inode_type: KernInodeType, 371a03c4f9dSLoGin private_data: Option<KernInodePrivateData>, 372a03c4f9dSLoGin callback: Option<&'static dyn KernFSCallback>, 373a03c4f9dSLoGin ) -> Arc<KernFSInode> { 374a03c4f9dSLoGin metadata.file_type = inode_type.into(); 375a03c4f9dSLoGin let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 376a03c4f9dSLoGin 377a03c4f9dSLoGin let inode = Arc::new(KernFSInode { 378a03c4f9dSLoGin name, 379a03c4f9dSLoGin inner: RwLock::new(InnerKernFSInode { 380a03c4f9dSLoGin parent: parent.clone(), 381a03c4f9dSLoGin metadata, 382a03c4f9dSLoGin symlink_target: None, 383a03c4f9dSLoGin symlink_target_absolute_path: None, 384a03c4f9dSLoGin }), 385a03c4f9dSLoGin self_ref: Weak::new(), 386a03c4f9dSLoGin fs: RwLock::new(Weak::new()), 387a03c4f9dSLoGin private_data: SpinLock::new(private_data), 388a03c4f9dSLoGin callback, 389a03c4f9dSLoGin children: SpinLock::new(HashMap::new()), 390a03c4f9dSLoGin inode_type, 391a03c4f9dSLoGin }); 392a03c4f9dSLoGin 393a03c4f9dSLoGin { 394a03c4f9dSLoGin let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 395a03c4f9dSLoGin unsafe { 396a03c4f9dSLoGin (*ptr).self_ref = Arc::downgrade(&inode); 397a03c4f9dSLoGin } 398a03c4f9dSLoGin } 399a03c4f9dSLoGin if parent.strong_count() > 0 { 400a03c4f9dSLoGin let kernfs = parent 401a03c4f9dSLoGin .upgrade() 402a03c4f9dSLoGin .unwrap() 403a03c4f9dSLoGin .fs() 404a03c4f9dSLoGin .downcast_arc::<KernFS>() 405a03c4f9dSLoGin .expect("KernFSInode::new: parent is not a KernFS instance"); 406a03c4f9dSLoGin *inode.fs.write() = Arc::downgrade(&kernfs); 407a03c4f9dSLoGin } 408a03c4f9dSLoGin return inode; 409a03c4f9dSLoGin } 410a03c4f9dSLoGin 4116b4e7a29SLoGin /// 在当前inode下增加子目录 4126b4e7a29SLoGin /// 4136b4e7a29SLoGin /// ## 参数 4146b4e7a29SLoGin /// 4156b4e7a29SLoGin /// - `name`:子目录名称 4166b4e7a29SLoGin /// - `mode`:子目录权限 4176b4e7a29SLoGin /// - `private_data`:子目录私有数据 4186b4e7a29SLoGin /// - `callback`:子目录回调函数 4196b4e7a29SLoGin /// 4206b4e7a29SLoGin /// ## 返回值 4216b4e7a29SLoGin /// 4226b4e7a29SLoGin /// - 成功:子目录inode 4236b4e7a29SLoGin /// - 失败:错误码 4246b4e7a29SLoGin #[allow(dead_code)] 4256b4e7a29SLoGin #[inline] 4266b4e7a29SLoGin pub fn add_dir( 4276b4e7a29SLoGin &self, 4286b4e7a29SLoGin name: String, 4296b4e7a29SLoGin mode: ModeType, 4306b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4316b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4326b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4336b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4346b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4356b4e7a29SLoGin } 4366b4e7a29SLoGin 4377eda31b2SLoGin return self.inner_create(name, KernInodeType::Dir, mode, 0, private_data, callback); 4386b4e7a29SLoGin } 4396b4e7a29SLoGin 4406b4e7a29SLoGin /// 在当前inode下增加文件 4416b4e7a29SLoGin /// 4426b4e7a29SLoGin /// ## 参数 4436b4e7a29SLoGin /// 4446b4e7a29SLoGin /// - `name`:文件名称 4456b4e7a29SLoGin /// - `mode`:文件权限 4467eda31b2SLoGin /// - `size`:文件大小(如果不指定,则默认为4096) 4476b4e7a29SLoGin /// - `private_data`:文件私有数据 4486b4e7a29SLoGin /// - `callback`:文件回调函数 4496b4e7a29SLoGin /// 4507eda31b2SLoGin /// 4516b4e7a29SLoGin /// ## 返回值 4526b4e7a29SLoGin /// 4536b4e7a29SLoGin /// - 成功:文件inode 4546b4e7a29SLoGin /// - 失败:错误码 4556b4e7a29SLoGin #[allow(dead_code)] 4566b4e7a29SLoGin #[inline] 4576b4e7a29SLoGin pub fn add_file( 4586b4e7a29SLoGin &self, 4596b4e7a29SLoGin name: String, 4606b4e7a29SLoGin mode: ModeType, 4617eda31b2SLoGin size: Option<usize>, 4626b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4636b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4646b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 4656b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 4666b4e7a29SLoGin return Err(SystemError::ENOTDIR); 4676b4e7a29SLoGin } 4686b4e7a29SLoGin 4697eda31b2SLoGin let size = size.unwrap_or(4096); 4707eda31b2SLoGin return self.inner_create( 4717eda31b2SLoGin name, 4727eda31b2SLoGin KernInodeType::File, 4737eda31b2SLoGin mode, 4747eda31b2SLoGin size, 4757eda31b2SLoGin private_data, 4767eda31b2SLoGin callback, 4777eda31b2SLoGin ); 4786b4e7a29SLoGin } 4796b4e7a29SLoGin 4806b4e7a29SLoGin fn inner_create( 4816b4e7a29SLoGin &self, 4826b4e7a29SLoGin name: String, 4836b4e7a29SLoGin file_type: KernInodeType, 4846b4e7a29SLoGin mode: ModeType, 4857eda31b2SLoGin mut size: usize, 4866b4e7a29SLoGin private_data: Option<KernInodePrivateData>, 4876b4e7a29SLoGin callback: Option<&'static dyn KernFSCallback>, 4886b4e7a29SLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 489a03c4f9dSLoGin match file_type { 490a03c4f9dSLoGin KernInodeType::Dir | KernInodeType::SymLink => { 491a03c4f9dSLoGin size = 0; 492a03c4f9dSLoGin } 4937eda31b2SLoGin _ => {} 494a03c4f9dSLoGin } 49506d5e247SLoGin 4966b4e7a29SLoGin let metadata = Metadata { 4977eda31b2SLoGin size: size as i64, 4986b4e7a29SLoGin mode, 4996b4e7a29SLoGin uid: 0, 5006b4e7a29SLoGin gid: 0, 5016b4e7a29SLoGin blk_size: 0, 5026b4e7a29SLoGin blocks: 0, 5036b4e7a29SLoGin atime: TimeSpec::new(0, 0), 5046b4e7a29SLoGin mtime: TimeSpec::new(0, 0), 5056b4e7a29SLoGin ctime: TimeSpec::new(0, 0), 5066b4e7a29SLoGin dev_id: 0, 5076b4e7a29SLoGin inode_id: generate_inode_id(), 5086b4e7a29SLoGin file_type: file_type.into(), 5096b4e7a29SLoGin nlinks: 1, 5106b4e7a29SLoGin raw_dev: 0, 5116b4e7a29SLoGin }; 5126b4e7a29SLoGin 5136b4e7a29SLoGin let new_inode: Arc<KernFSInode> = Self::new( 51406d5e247SLoGin Some(self.self_ref.upgrade().unwrap()), 51506d5e247SLoGin name.clone(), 5166b4e7a29SLoGin metadata, 51706d5e247SLoGin file_type, 5186b4e7a29SLoGin private_data, 5196b4e7a29SLoGin callback, 5206b4e7a29SLoGin ); 5216b4e7a29SLoGin 5226b4e7a29SLoGin self.children.lock().insert(name, new_inode.clone()); 5236b4e7a29SLoGin 5246b4e7a29SLoGin return Ok(new_inode); 5256b4e7a29SLoGin } 5266b4e7a29SLoGin 5276b4e7a29SLoGin /// 在当前inode下删除子目录或者文件 5286b4e7a29SLoGin /// 5296b4e7a29SLoGin /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 5306b4e7a29SLoGin /// 5316b4e7a29SLoGin /// ## 参数 5326b4e7a29SLoGin /// 5336b4e7a29SLoGin /// - `name`:子目录或者文件名称 5346b4e7a29SLoGin /// 5356b4e7a29SLoGin /// ## 返回值 5366b4e7a29SLoGin /// 5376b4e7a29SLoGin /// - 成功:() 5386b4e7a29SLoGin /// - 失败:错误码 5396b4e7a29SLoGin #[allow(dead_code)] 5406b4e7a29SLoGin pub fn remove(&self, name: &str) -> Result<(), SystemError> { 5416b4e7a29SLoGin if unlikely(self.inode_type != KernInodeType::Dir) { 5426b4e7a29SLoGin return Err(SystemError::ENOTDIR); 5436b4e7a29SLoGin } 5446b4e7a29SLoGin 5456b4e7a29SLoGin let mut children = self.children.lock(); 5466b4e7a29SLoGin let inode = children.get(name).ok_or(SystemError::ENOENT)?; 5476b4e7a29SLoGin if inode.children.lock().is_empty() { 5486b4e7a29SLoGin children.remove(name); 5496b4e7a29SLoGin return Ok(()); 5506b4e7a29SLoGin } else { 5516b4e7a29SLoGin return Err(SystemError::ENOTEMPTY); 5526b4e7a29SLoGin } 5536b4e7a29SLoGin } 5546b4e7a29SLoGin 555a03c4f9dSLoGin /// add_link - create a symlink in kernfs 556a03c4f9dSLoGin /// 557a03c4f9dSLoGin /// ## 参数 558a03c4f9dSLoGin /// 559a03c4f9dSLoGin /// - `parent`: directory to create the symlink in 560a03c4f9dSLoGin /// - `name`: name of the symlink 561a03c4f9dSLoGin /// - `target`: target node for the symlink to point to 562a03c4f9dSLoGin /// 563a03c4f9dSLoGin /// Returns the created node on success 564a03c4f9dSLoGin /// 565*e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25 566a03c4f9dSLoGin pub fn add_link( 567a03c4f9dSLoGin &self, 56806d5e247SLoGin name: String, 569a03c4f9dSLoGin target: &Arc<KernFSInode>, 570a03c4f9dSLoGin target_absolute_path: String, 571a03c4f9dSLoGin ) -> Result<Arc<KernFSInode>, SystemError> { 572a03c4f9dSLoGin // kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}"); 573a03c4f9dSLoGin let inode = self.inner_create( 57406d5e247SLoGin name, 575a03c4f9dSLoGin KernInodeType::SymLink, 576a03c4f9dSLoGin ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777), 5777eda31b2SLoGin 0, 578a03c4f9dSLoGin None, 579a03c4f9dSLoGin None, 580a03c4f9dSLoGin )?; 5816b4e7a29SLoGin 582a03c4f9dSLoGin inode.inner.write().symlink_target = Some(Arc::downgrade(target)); 583a03c4f9dSLoGin inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path); 584a03c4f9dSLoGin return Ok(inode); 5856b4e7a29SLoGin } 58606d5e247SLoGin 58706d5e247SLoGin pub fn name(&self) -> &str { 58806d5e247SLoGin return &self.name; 58906d5e247SLoGin } 59006d5e247SLoGin 59106d5e247SLoGin pub fn parent(&self) -> Option<Arc<KernFSInode>> { 592a03c4f9dSLoGin return self.inner.read().parent.upgrade(); 59306d5e247SLoGin } 59406d5e247SLoGin 59506d5e247SLoGin pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 59606d5e247SLoGin return self.private_data.lock(); 59706d5e247SLoGin } 59806d5e247SLoGin 599a03c4f9dSLoGin #[allow(dead_code)] 600a03c4f9dSLoGin pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> { 601a03c4f9dSLoGin return self.inner.read().symlink_target.as_ref()?.upgrade(); 602a03c4f9dSLoGin } 603a03c4f9dSLoGin 60406d5e247SLoGin /// remove a kernfs_node recursively 60506d5e247SLoGin pub fn remove_recursive(&self) { 60606d5e247SLoGin let mut children = self.children.lock().drain().collect::<Vec<_>>(); 60706d5e247SLoGin while let Some((_, child)) = children.pop() { 60806d5e247SLoGin children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 60906d5e247SLoGin } 61006d5e247SLoGin } 61106d5e247SLoGin 61206d5e247SLoGin /// 删除当前的inode(包括其自身、子目录和子文件) 61306d5e247SLoGin #[allow(dead_code)] 61406d5e247SLoGin pub fn remove_inode_include_self(&self) { 61506d5e247SLoGin let parent = self.parent(); 61606d5e247SLoGin if let Some(parent) = parent { 61706d5e247SLoGin parent.children.lock().remove(self.name()); 61806d5e247SLoGin } 61906d5e247SLoGin self.remove_recursive(); 62006d5e247SLoGin } 6216b4e7a29SLoGin } 6226b4e7a29SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)] 62306d5e247SLoGin pub enum KernInodeType { 6246b4e7a29SLoGin Dir, 6256b4e7a29SLoGin File, 626a03c4f9dSLoGin SymLink, 6276b4e7a29SLoGin } 6286b4e7a29SLoGin 6296b4e7a29SLoGin impl Into<FileType> for KernInodeType { 6306b4e7a29SLoGin fn into(self) -> FileType { 6316b4e7a29SLoGin match self { 6326b4e7a29SLoGin KernInodeType::Dir => FileType::Dir, 6336b4e7a29SLoGin KernInodeType::File => FileType::File, 634a03c4f9dSLoGin KernInodeType::SymLink => FileType::SymLink, 6356b4e7a29SLoGin } 6366b4e7a29SLoGin } 6376b4e7a29SLoGin } 638