1f678331aShanjiezhou use crate::{ 2f678331aShanjiezhou arch::{sched::sched, CurrentIrqArch}, 3f678331aShanjiezhou exception::InterruptArch, 4f678331aShanjiezhou filesystem::vfs::{ 56b4e7a29SLoGin core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, 66b4e7a29SLoGin FileType, IndexNode, Metadata, PollStatus, 7f678331aShanjiezhou }, 8f678331aShanjiezhou libs::{spinlock::SpinLock, wait_queue::WaitQueue}, 91496ba7bSLoGin process::ProcessState, 10f678331aShanjiezhou syscall::SystemError, 11f678331aShanjiezhou time::TimeSpec, 12f678331aShanjiezhou }; 13f678331aShanjiezhou 14f678331aShanjiezhou use alloc::sync::{Arc, Weak}; 15f678331aShanjiezhou 16f678331aShanjiezhou /// 我们设定pipe_buff的总大小为1024字节 17f678331aShanjiezhou const PIPE_BUFF_SIZE: usize = 1024; 18f678331aShanjiezhou 19*876cb89eSGnoCiYeH #[derive(Debug, Clone)] 20*876cb89eSGnoCiYeH pub struct PipeFsPrivateData { 21*876cb89eSGnoCiYeH mode: FileMode, 22*876cb89eSGnoCiYeH } 23*876cb89eSGnoCiYeH 24*876cb89eSGnoCiYeH impl PipeFsPrivateData { 25*876cb89eSGnoCiYeH pub fn new(mode: FileMode) -> Self { 26*876cb89eSGnoCiYeH return PipeFsPrivateData { mode: mode }; 27*876cb89eSGnoCiYeH } 28*876cb89eSGnoCiYeH } 29*876cb89eSGnoCiYeH 30f678331aShanjiezhou /// @brief 管道文件i节点(锁) 31f678331aShanjiezhou #[derive(Debug)] 32f678331aShanjiezhou pub struct LockedPipeInode(SpinLock<InnerPipeInode>); 33f678331aShanjiezhou 34f678331aShanjiezhou /// @brief 管道文件i节点(无锁) 35f678331aShanjiezhou #[derive(Debug)] 36f678331aShanjiezhou pub struct InnerPipeInode { 37f678331aShanjiezhou self_ref: Weak<LockedPipeInode>, 38f678331aShanjiezhou valid_cnt: i32, 39f678331aShanjiezhou read_pos: i32, 40f678331aShanjiezhou write_pos: i32, 41f678331aShanjiezhou read_wait_queue: WaitQueue, 42f678331aShanjiezhou write_wait_queue: WaitQueue, 43f678331aShanjiezhou data: [u8; PIPE_BUFF_SIZE], 44f678331aShanjiezhou /// INode 元数据 45f678331aShanjiezhou metadata: Metadata, 46*876cb89eSGnoCiYeH reader: u32, 47*876cb89eSGnoCiYeH writer: u32, 48f678331aShanjiezhou } 49f678331aShanjiezhou 50f678331aShanjiezhou impl LockedPipeInode { 51*876cb89eSGnoCiYeH pub fn new() -> Arc<Self> { 52f678331aShanjiezhou let inner = InnerPipeInode { 53f678331aShanjiezhou self_ref: Weak::default(), 54f678331aShanjiezhou valid_cnt: 0, 55f678331aShanjiezhou read_pos: 0, 56f678331aShanjiezhou write_pos: 0, 57f678331aShanjiezhou read_wait_queue: WaitQueue::INIT, 58f678331aShanjiezhou write_wait_queue: WaitQueue::INIT, 59f678331aShanjiezhou data: [0; PIPE_BUFF_SIZE], 60f678331aShanjiezhou 61f678331aShanjiezhou metadata: Metadata { 62f678331aShanjiezhou dev_id: 0, 63f678331aShanjiezhou inode_id: generate_inode_id(), 6422c9db31Shanjiezhou size: PIPE_BUFF_SIZE as i64, 65f678331aShanjiezhou blk_size: 0, 66f678331aShanjiezhou blocks: 0, 67f678331aShanjiezhou atime: TimeSpec::default(), 68f678331aShanjiezhou mtime: TimeSpec::default(), 69f678331aShanjiezhou ctime: TimeSpec::default(), 70f678331aShanjiezhou file_type: FileType::Pipe, 716b4e7a29SLoGin mode: ModeType::from_bits_truncate(0o666), 72f678331aShanjiezhou nlinks: 1, 73f678331aShanjiezhou uid: 0, 74f678331aShanjiezhou gid: 0, 75f678331aShanjiezhou raw_dev: 0, 76f678331aShanjiezhou }, 77*876cb89eSGnoCiYeH reader: 0, 78*876cb89eSGnoCiYeH writer: 0, 79f678331aShanjiezhou }; 80f678331aShanjiezhou let result = Arc::new(Self(SpinLock::new(inner))); 81f678331aShanjiezhou let mut guard = result.0.lock(); 82f678331aShanjiezhou guard.self_ref = Arc::downgrade(&result); 83f678331aShanjiezhou // 释放锁 84f678331aShanjiezhou drop(guard); //这一步其实不需要,只要离开作用域,guard生命周期结束,自会解锁 85f678331aShanjiezhou return result; 86f678331aShanjiezhou } 87f678331aShanjiezhou } 88f678331aShanjiezhou 89f678331aShanjiezhou impl IndexNode for LockedPipeInode { 90f678331aShanjiezhou fn read_at( 91f678331aShanjiezhou &self, 92f678331aShanjiezhou _offset: usize, 93f678331aShanjiezhou len: usize, 94f678331aShanjiezhou buf: &mut [u8], 95*876cb89eSGnoCiYeH data: &mut FilePrivateData, 96f678331aShanjiezhou ) -> Result<usize, crate::syscall::SystemError> { 97*876cb89eSGnoCiYeH // 获取mode 98*876cb89eSGnoCiYeH let mode: FileMode; 99*876cb89eSGnoCiYeH if let FilePrivateData::Pipefs(pdata) = data { 100*876cb89eSGnoCiYeH mode = pdata.mode; 101*876cb89eSGnoCiYeH } else { 102*876cb89eSGnoCiYeH return Err(SystemError::EBADF); 103*876cb89eSGnoCiYeH } 104*876cb89eSGnoCiYeH 105f678331aShanjiezhou if buf.len() < len { 106f678331aShanjiezhou return Err(SystemError::EINVAL); 107f678331aShanjiezhou } 108f678331aShanjiezhou // 加锁 109f678331aShanjiezhou let mut inode = self.0.lock(); 110f678331aShanjiezhou 111f678331aShanjiezhou // 如果管道里面没有数据,则唤醒写端, 112f678331aShanjiezhou while inode.valid_cnt == 0 { 113*876cb89eSGnoCiYeH // 如果当前管道写者数为0,则返回EOF 114*876cb89eSGnoCiYeH if inode.writer == 0 { 115*876cb89eSGnoCiYeH return Ok(0); 116*876cb89eSGnoCiYeH } 117*876cb89eSGnoCiYeH 1181496ba7bSLoGin inode 1191496ba7bSLoGin .write_wait_queue 1201496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 1211496ba7bSLoGin 12222c9db31Shanjiezhou // 如果为非阻塞管道,直接返回错误 123*876cb89eSGnoCiYeH if mode.contains(FileMode::O_NONBLOCK) { 12422c9db31Shanjiezhou drop(inode); 12522c9db31Shanjiezhou return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 12622c9db31Shanjiezhou } 1271496ba7bSLoGin 12822c9db31Shanjiezhou // 否则在读等待队列中睡眠,并释放锁 129f678331aShanjiezhou unsafe { 130f678331aShanjiezhou let irq_guard = CurrentIrqArch::save_and_disable_irq(); 131f678331aShanjiezhou inode.read_wait_queue.sleep_without_schedule(); 132f678331aShanjiezhou drop(inode); 133f678331aShanjiezhou 134f678331aShanjiezhou drop(irq_guard); 135f678331aShanjiezhou } 136f678331aShanjiezhou sched(); 137f678331aShanjiezhou inode = self.0.lock(); 138f678331aShanjiezhou } 139f678331aShanjiezhou 140f678331aShanjiezhou let mut num = inode.valid_cnt as usize; 141f678331aShanjiezhou //决定要输出的字节 142f678331aShanjiezhou let start = inode.read_pos as usize; 143f678331aShanjiezhou //如果读端希望读取的字节数大于有效字节数,则输出有效字节 144f678331aShanjiezhou let mut end = (inode.valid_cnt as usize + inode.read_pos as usize) % PIPE_BUFF_SIZE; 145f678331aShanjiezhou //如果读端希望读取的字节数少于有效字节数,则输出希望读取的字节 146f678331aShanjiezhou if len < inode.valid_cnt as usize { 147f678331aShanjiezhou end = (len + inode.read_pos as usize) % PIPE_BUFF_SIZE; 148f678331aShanjiezhou num = len; 149f678331aShanjiezhou } 150f678331aShanjiezhou 151f678331aShanjiezhou // 从管道拷贝数据到用户的缓冲区 152f678331aShanjiezhou 153f678331aShanjiezhou if end < start { 154f678331aShanjiezhou buf[0..(PIPE_BUFF_SIZE - start)].copy_from_slice(&inode.data[start..PIPE_BUFF_SIZE]); 155f678331aShanjiezhou buf[(PIPE_BUFF_SIZE - start)..num].copy_from_slice(&inode.data[0..end]); 156f678331aShanjiezhou } else { 157f678331aShanjiezhou buf[0..num].copy_from_slice(&inode.data[start..end]); 158f678331aShanjiezhou } 159f678331aShanjiezhou 160f678331aShanjiezhou //更新读位置以及valid_cnt 161f678331aShanjiezhou inode.read_pos = (inode.read_pos + num as i32) % PIPE_BUFF_SIZE as i32; 162f678331aShanjiezhou inode.valid_cnt -= num as i32; 163f678331aShanjiezhou 164f678331aShanjiezhou //读完后解锁并唤醒等待在写等待队列中的进程 1651496ba7bSLoGin inode 1661496ba7bSLoGin .write_wait_queue 1671496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 168f678331aShanjiezhou //返回读取的字节数 169f678331aShanjiezhou return Ok(num); 170f678331aShanjiezhou } 171f678331aShanjiezhou 172f678331aShanjiezhou fn open( 173f678331aShanjiezhou &self, 174*876cb89eSGnoCiYeH data: &mut FilePrivateData, 175*876cb89eSGnoCiYeH mode: &crate::filesystem::vfs::file::FileMode, 176f678331aShanjiezhou ) -> Result<(), SystemError> { 177*876cb89eSGnoCiYeH let mut guard = self.0.lock(); 178*876cb89eSGnoCiYeH // 不能以读写方式打开管道 179*876cb89eSGnoCiYeH if mode.contains(FileMode::O_RDWR) { 180*876cb89eSGnoCiYeH return Err(SystemError::EACCES); 181*876cb89eSGnoCiYeH } 182*876cb89eSGnoCiYeH if mode.contains(FileMode::O_RDONLY) { 183*876cb89eSGnoCiYeH guard.reader += 1; 184*876cb89eSGnoCiYeH } 185*876cb89eSGnoCiYeH if mode.contains(FileMode::O_WRONLY) { 186*876cb89eSGnoCiYeH guard.writer += 1; 187*876cb89eSGnoCiYeH } 188*876cb89eSGnoCiYeH 189*876cb89eSGnoCiYeH // 设置mode 190*876cb89eSGnoCiYeH *data = FilePrivateData::Pipefs(PipeFsPrivateData { mode: *mode }); 191*876cb89eSGnoCiYeH 192f678331aShanjiezhou return Ok(()); 193f678331aShanjiezhou } 194f678331aShanjiezhou 195f678331aShanjiezhou fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> { 196f678331aShanjiezhou let inode = self.0.lock(); 197f678331aShanjiezhou let mut metadata = inode.metadata.clone(); 198f678331aShanjiezhou metadata.size = inode.data.len() as i64; 199f678331aShanjiezhou 200f678331aShanjiezhou return Ok(metadata); 201f678331aShanjiezhou } 202f678331aShanjiezhou 203*876cb89eSGnoCiYeH fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> { 204*876cb89eSGnoCiYeH let mode: FileMode; 205*876cb89eSGnoCiYeH if let FilePrivateData::Pipefs(pipe_data) = data { 206*876cb89eSGnoCiYeH mode = pipe_data.mode; 207*876cb89eSGnoCiYeH } else { 208*876cb89eSGnoCiYeH return Err(SystemError::EBADF); 209*876cb89eSGnoCiYeH } 210*876cb89eSGnoCiYeH let mut guard = self.0.lock(); 211*876cb89eSGnoCiYeH 212*876cb89eSGnoCiYeH // 写端关闭 213*876cb89eSGnoCiYeH if mode.contains(FileMode::O_WRONLY) { 214*876cb89eSGnoCiYeH assert!(guard.writer > 0); 215*876cb89eSGnoCiYeH guard.writer -= 1; 216*876cb89eSGnoCiYeH // 如果已经没有写端了,则唤醒读端 217*876cb89eSGnoCiYeH if guard.writer == 0 { 218*876cb89eSGnoCiYeH guard 219*876cb89eSGnoCiYeH .read_wait_queue 220*876cb89eSGnoCiYeH .wakeup_all(Some(ProcessState::Blocked(true))); 221*876cb89eSGnoCiYeH } 222*876cb89eSGnoCiYeH } 223*876cb89eSGnoCiYeH 224*876cb89eSGnoCiYeH // 读端关闭 225*876cb89eSGnoCiYeH if mode.contains(FileMode::O_RDONLY) { 226*876cb89eSGnoCiYeH assert!(guard.reader > 0); 227*876cb89eSGnoCiYeH guard.reader -= 1; 228*876cb89eSGnoCiYeH // 如果已经没有写端了,则唤醒读端 229*876cb89eSGnoCiYeH if guard.reader == 0 { 230*876cb89eSGnoCiYeH guard 231*876cb89eSGnoCiYeH .write_wait_queue 232*876cb89eSGnoCiYeH .wakeup_all(Some(ProcessState::Blocked(true))); 233*876cb89eSGnoCiYeH } 234*876cb89eSGnoCiYeH } 235*876cb89eSGnoCiYeH 236f678331aShanjiezhou return Ok(()); 237f678331aShanjiezhou } 238f678331aShanjiezhou 239f678331aShanjiezhou fn write_at( 240f678331aShanjiezhou &self, 241f678331aShanjiezhou _offset: usize, 242f678331aShanjiezhou len: usize, 243f678331aShanjiezhou buf: &[u8], 244*876cb89eSGnoCiYeH data: &mut FilePrivateData, 245f678331aShanjiezhou ) -> Result<usize, crate::syscall::SystemError> { 246*876cb89eSGnoCiYeH // 获取mode 247*876cb89eSGnoCiYeH let mode: FileMode; 248*876cb89eSGnoCiYeH if let FilePrivateData::Pipefs(pdata) = data { 249*876cb89eSGnoCiYeH mode = pdata.mode; 250*876cb89eSGnoCiYeH } else { 251*876cb89eSGnoCiYeH return Err(SystemError::EBADF); 252*876cb89eSGnoCiYeH } 253*876cb89eSGnoCiYeH 254f678331aShanjiezhou if buf.len() < len || len > PIPE_BUFF_SIZE { 255f678331aShanjiezhou return Err(SystemError::EINVAL); 256f678331aShanjiezhou } 257f678331aShanjiezhou // 加锁 258f678331aShanjiezhou 259f678331aShanjiezhou let mut inode = self.0.lock(); 260f678331aShanjiezhou 261*876cb89eSGnoCiYeH // TODO: 如果已经没有读端存在了,则向写端进程发送SIGPIPE信号 262*876cb89eSGnoCiYeH if inode.reader == 0 {} 263*876cb89eSGnoCiYeH 264f678331aShanjiezhou // 如果管道空间不够 265f678331aShanjiezhou 266f678331aShanjiezhou while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE { 267f678331aShanjiezhou // 唤醒读端 2681496ba7bSLoGin inode 2691496ba7bSLoGin .read_wait_queue 2701496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 2711496ba7bSLoGin 27222c9db31Shanjiezhou // 如果为非阻塞管道,直接返回错误 273*876cb89eSGnoCiYeH if mode.contains(FileMode::O_NONBLOCK) { 27422c9db31Shanjiezhou drop(inode); 27522c9db31Shanjiezhou return Err(SystemError::ENOMEM); 27622c9db31Shanjiezhou } 2771496ba7bSLoGin 278f678331aShanjiezhou // 解锁并睡眠 279f678331aShanjiezhou unsafe { 280f678331aShanjiezhou let irq_guard = CurrentIrqArch::save_and_disable_irq(); 281f678331aShanjiezhou inode.write_wait_queue.sleep_without_schedule(); 282f678331aShanjiezhou drop(inode); 283f678331aShanjiezhou drop(irq_guard); 284f678331aShanjiezhou } 285f678331aShanjiezhou sched(); 286f678331aShanjiezhou inode = self.0.lock(); 287f678331aShanjiezhou } 288f678331aShanjiezhou 289f678331aShanjiezhou // 决定要输入的字节 290f678331aShanjiezhou let start = inode.write_pos as usize; 291f678331aShanjiezhou let end = (inode.write_pos as usize + len) % PIPE_BUFF_SIZE; 292f678331aShanjiezhou // 从用户的缓冲区拷贝数据到管道 293f678331aShanjiezhou 294f678331aShanjiezhou if end < start { 295f678331aShanjiezhou inode.data[start..PIPE_BUFF_SIZE].copy_from_slice(&buf[0..(PIPE_BUFF_SIZE - start)]); 296f678331aShanjiezhou inode.data[0..end].copy_from_slice(&buf[(PIPE_BUFF_SIZE - start)..len]); 297f678331aShanjiezhou } else { 298f678331aShanjiezhou inode.data[start..end].copy_from_slice(&buf[0..len]); 299f678331aShanjiezhou } 300f678331aShanjiezhou // 更新写位置以及valid_cnt 301f678331aShanjiezhou inode.write_pos = (inode.write_pos + len as i32) % PIPE_BUFF_SIZE as i32; 302f678331aShanjiezhou inode.valid_cnt += len as i32; 303f678331aShanjiezhou 304f678331aShanjiezhou // 读完后解锁并唤醒等待在读等待队列中的进程 3051496ba7bSLoGin inode 3061496ba7bSLoGin .read_wait_queue 3071496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 308f678331aShanjiezhou // 返回写入的字节数 309f678331aShanjiezhou return Ok(len); 310f678331aShanjiezhou } 311f678331aShanjiezhou 312f678331aShanjiezhou fn poll(&self) -> Result<PollStatus, crate::syscall::SystemError> { 313f678331aShanjiezhou return Ok(PollStatus::READ | PollStatus::WRITE); 314f678331aShanjiezhou } 315f678331aShanjiezhou 316f678331aShanjiezhou fn as_any_ref(&self) -> &dyn core::any::Any { 317f678331aShanjiezhou self 318f678331aShanjiezhou } 319f678331aShanjiezhou 320f678331aShanjiezhou fn get_entry_name_and_metadata( 321f678331aShanjiezhou &self, 322f678331aShanjiezhou ino: crate::filesystem::vfs::InodeId, 323f678331aShanjiezhou ) -> Result<(alloc::string::String, crate::filesystem::vfs::Metadata), SystemError> { 324f678331aShanjiezhou // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 325f678331aShanjiezhou let name = self.get_entry_name(ino)?; 326f678331aShanjiezhou let entry = self.find(&name)?; 327f678331aShanjiezhou return Ok((name, entry.metadata()?)); 328f678331aShanjiezhou } 329f678331aShanjiezhou 330f678331aShanjiezhou fn fs(&self) -> Arc<(dyn FileSystem)> { 331f678331aShanjiezhou todo!() 332f678331aShanjiezhou } 333f678331aShanjiezhou 334f678331aShanjiezhou fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 335f678331aShanjiezhou return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 336f678331aShanjiezhou } 337f678331aShanjiezhou } 338