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