mod.rs 7.5 KB

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