1 use core::sync::atomic::{AtomicU32, Ordering}; 2 3 use alloc::{ 4 collections::BTreeMap, 5 string::{String, ToString}, 6 sync::{Arc, Weak}, 7 vec::Vec, 8 }; 9 use ida::IdAllocator; 10 use system_error::SystemError; 11 use unified_init::macros::unified_init; 12 13 use crate::{ 14 driver::{ 15 base::device::{ 16 device_number::{DeviceNumber, Major}, 17 IdTable, 18 }, 19 tty::{ 20 pty::unix98pty::NR_UNIX98_PTY_MAX, 21 tty_device::{PtyType, TtyDevice, TtyType}, 22 }, 23 }, 24 filesystem::vfs::{syscall::ModeType, FileType, ROOT_INODE}, 25 init::initcall::INITCALL_FS, 26 libs::spinlock::{SpinLock, SpinLockGuard}, 27 time::TimeSpec, 28 }; 29 30 use super::vfs::{ 31 core::generate_inode_id, FilePrivateData, FileSystem, FsInfo, IndexNode, Metadata, 32 }; 33 34 const DEV_PTYFS_MAX_NAMELEN: usize = 16; 35 36 #[allow(dead_code)] 37 const PTY_NR_LIMIT: usize = 4096; 38 39 #[derive(Debug)] 40 pub struct DevPtsFs { 41 /// 根节点 42 root_inode: Arc<LockedDevPtsFSInode>, 43 pts_ida: IdAllocator, 44 pts_count: AtomicU32, 45 } 46 47 impl DevPtsFs { 48 pub fn new() -> Arc<Self> { 49 let root_inode = Arc::new(LockedDevPtsFSInode::new()); 50 let ret = Arc::new(Self { 51 root_inode, 52 pts_ida: IdAllocator::new(1, NR_UNIX98_PTY_MAX as usize), 53 pts_count: AtomicU32::new(0), 54 }); 55 56 ret.root_inode.set_fs(Arc::downgrade(&ret)); 57 58 ret 59 } 60 61 pub fn alloc_index(&self) -> Result<usize, SystemError> { 62 self.pts_ida.alloc().ok_or(SystemError::ENOSPC) 63 } 64 } 65 66 impl FileSystem for DevPtsFs { 67 fn root_inode(&self) -> Arc<dyn IndexNode> { 68 self.root_inode.clone() 69 } 70 71 fn info(&self) -> super::vfs::FsInfo { 72 return FsInfo { 73 blk_dev_id: 0, 74 max_name_len: DEV_PTYFS_MAX_NAMELEN, 75 }; 76 } 77 78 fn as_any_ref(&self) -> &dyn core::any::Any { 79 self 80 } 81 82 fn name(&self) -> &str { 83 "devpts" 84 } 85 86 fn super_block(&self) -> super::vfs::SuperBlock { 87 todo!() 88 } 89 } 90 91 #[derive(Debug)] 92 pub struct LockedDevPtsFSInode { 93 inner: SpinLock<PtsDevInode>, 94 } 95 96 impl LockedDevPtsFSInode { 97 pub fn new() -> Self { 98 Self { 99 inner: SpinLock::new(PtsDevInode { 100 fs: Weak::new(), 101 children: Some(BTreeMap::new()), 102 metadata: Metadata { 103 dev_id: 0, 104 inode_id: generate_inode_id(), 105 size: 0, 106 blk_size: 0, 107 blocks: 0, 108 atime: TimeSpec::default(), 109 mtime: TimeSpec::default(), 110 ctime: TimeSpec::default(), 111 file_type: FileType::Dir, 112 mode: ModeType::from_bits_truncate(0x777), 113 nlinks: 1, 114 uid: 0, 115 gid: 0, 116 raw_dev: DeviceNumber::default(), 117 }, 118 }), 119 } 120 } 121 122 pub fn set_fs(&self, fs: Weak<DevPtsFs>) { 123 self.inner.lock().fs = fs; 124 } 125 } 126 127 #[derive(Debug)] 128 pub struct PtsDevInode { 129 fs: Weak<DevPtsFs>, 130 children: Option<BTreeMap<String, Arc<TtyDevice>>>, 131 metadata: Metadata, 132 } 133 134 impl PtsDevInode { 135 pub fn children_unchecked(&self) -> &BTreeMap<String, Arc<TtyDevice>> { 136 self.children.as_ref().unwrap() 137 } 138 139 pub fn children_unchecked_mut(&mut self) -> &mut BTreeMap<String, Arc<TtyDevice>> { 140 self.children.as_mut().unwrap() 141 } 142 } 143 144 impl IndexNode for LockedDevPtsFSInode { 145 fn open( 146 &self, 147 _data: SpinLockGuard<FilePrivateData>, 148 _mode: &super::vfs::file::FileMode, 149 ) -> Result<(), SystemError> { 150 Ok(()) 151 } 152 153 fn metadata(&self) -> Result<super::vfs::Metadata, SystemError> { 154 let inode = self.inner.lock(); 155 let metadata = inode.metadata.clone(); 156 157 return Ok(metadata); 158 } 159 160 fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 161 // TODO: 回收 162 Ok(()) 163 } 164 165 fn read_at( 166 &self, 167 _offset: usize, 168 _len: usize, 169 _buf: &mut [u8], 170 _data: SpinLockGuard<FilePrivateData>, 171 ) -> Result<usize, system_error::SystemError> { 172 todo!() 173 } 174 175 fn write_at( 176 &self, 177 _offset: usize, 178 _len: usize, 179 _buf: &[u8], 180 _data: SpinLockGuard<FilePrivateData>, 181 ) -> Result<usize, system_error::SystemError> { 182 todo!() 183 } 184 185 fn fs(&self) -> alloc::sync::Arc<dyn super::vfs::FileSystem> { 186 self.inner.lock().fs.upgrade().unwrap() 187 } 188 189 fn as_any_ref(&self) -> &dyn core::any::Any { 190 todo!() 191 } 192 193 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> { 194 let info = self.metadata()?; 195 if info.file_type != FileType::Dir { 196 return Err(SystemError::ENOTDIR); 197 } 198 199 let mut keys: Vec<String> = Vec::new(); 200 keys.push(String::from(".")); 201 keys.push(String::from("..")); 202 keys.append( 203 &mut self 204 .inner 205 .lock() 206 .children_unchecked() 207 .keys() 208 .cloned() 209 .collect(), 210 ); 211 212 return Ok(keys); 213 } 214 215 fn create_with_data( 216 &self, 217 name: &str, 218 file_type: FileType, 219 _mode: super::vfs::syscall::ModeType, 220 _data: usize, 221 ) -> Result<Arc<dyn IndexNode>, SystemError> { 222 if file_type != FileType::CharDevice { 223 return Err(SystemError::ENOSYS); 224 } 225 226 let mut guard = self.inner.lock(); 227 228 if guard.children_unchecked_mut().contains_key(name) { 229 return Err(SystemError::EEXIST); 230 } 231 232 let fs = guard.fs.upgrade().unwrap(); 233 234 let result = TtyDevice::new( 235 name.to_string(), 236 IdTable::new(name.to_string(), None), 237 TtyType::Pty(PtyType::Pts), 238 ); 239 240 let mut metadata = result.metadata()?; 241 242 metadata.mode.insert(ModeType::S_IFCHR); 243 metadata.raw_dev = 244 DeviceNumber::new(Major::UNIX98_PTY_SLAVE_MAJOR, name.parse::<u32>().unwrap()); 245 246 result.set_metadata(&metadata)?; 247 248 guard 249 .children_unchecked_mut() 250 .insert(name.to_string(), result.clone()); 251 252 fs.pts_count.fetch_add(1, Ordering::SeqCst); 253 254 Ok(result) 255 } 256 257 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 258 let guard = self.inner.lock(); 259 260 if let Some(dev) = guard.children_unchecked().get(name) { 261 Ok(dev.clone() as Arc<dyn IndexNode>) 262 } else { 263 Err(SystemError::ENOENT) 264 } 265 } 266 267 fn unlink(&self, name: &str) -> Result<(), SystemError> { 268 let mut guard = self.inner.lock(); 269 guard.children_unchecked_mut().remove(name); 270 Ok(()) 271 } 272 } 273 274 #[unified_init(INITCALL_FS)] 275 #[inline(never)] 276 pub fn devpts_init() -> Result<(), SystemError> { 277 let dev_inode = ROOT_INODE().find("dev")?; 278 279 let pts_inode = dev_inode.create("pts", FileType::Dir, ModeType::from_bits_truncate(0o755))?; 280 281 // 创建 devptsfs 实例 282 let ptsfs: Arc<DevPtsFs> = DevPtsFs::new(); 283 284 // let mountfs = dev_inode.mount(ptsfs).expect("Failed to mount DevPtsFS"); 285 286 pts_inode.mount(ptsfs).expect("Failed to mount DevPtsFS"); 287 kinfo!("DevPtsFs mounted."); 288 289 Ok(()) 290 } 291