1f678331aShanjiezhou use crate::{ 2f678331aShanjiezhou arch::{sched::sched, CurrentIrqArch}, 3f678331aShanjiezhou exception::InterruptArch, 4f678331aShanjiezhou filesystem::vfs::{ 522c9db31Shanjiezhou core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, 622c9db31Shanjiezhou Metadata, PollStatus, 7f678331aShanjiezhou }, 8f678331aShanjiezhou libs::{spinlock::SpinLock, wait_queue::WaitQueue}, 9*1496ba7bSLoGin 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 19f678331aShanjiezhou /// @brief 管道文件i节点(锁) 20f678331aShanjiezhou #[derive(Debug)] 21f678331aShanjiezhou pub struct LockedPipeInode(SpinLock<InnerPipeInode>); 22f678331aShanjiezhou 23f678331aShanjiezhou /// @brief 管道文件i节点(无锁) 24f678331aShanjiezhou #[derive(Debug)] 25f678331aShanjiezhou pub struct InnerPipeInode { 26f678331aShanjiezhou self_ref: Weak<LockedPipeInode>, 27f678331aShanjiezhou valid_cnt: i32, 28f678331aShanjiezhou read_pos: i32, 29f678331aShanjiezhou write_pos: i32, 30f678331aShanjiezhou read_wait_queue: WaitQueue, 31f678331aShanjiezhou write_wait_queue: WaitQueue, 32f678331aShanjiezhou data: [u8; PIPE_BUFF_SIZE], 33f678331aShanjiezhou /// INode 元数据 34f678331aShanjiezhou metadata: Metadata, 3522c9db31Shanjiezhou flags: FileMode, 36f678331aShanjiezhou } 37f678331aShanjiezhou 38f678331aShanjiezhou impl LockedPipeInode { 3922c9db31Shanjiezhou pub fn new(flags: FileMode) -> Arc<Self> { 40f678331aShanjiezhou let inner = InnerPipeInode { 41f678331aShanjiezhou self_ref: Weak::default(), 42f678331aShanjiezhou valid_cnt: 0, 43f678331aShanjiezhou read_pos: 0, 44f678331aShanjiezhou write_pos: 0, 45f678331aShanjiezhou read_wait_queue: WaitQueue::INIT, 46f678331aShanjiezhou write_wait_queue: WaitQueue::INIT, 47f678331aShanjiezhou data: [0; PIPE_BUFF_SIZE], 48f678331aShanjiezhou 49f678331aShanjiezhou metadata: Metadata { 50f678331aShanjiezhou dev_id: 0, 51f678331aShanjiezhou inode_id: generate_inode_id(), 5222c9db31Shanjiezhou size: PIPE_BUFF_SIZE as i64, 53f678331aShanjiezhou blk_size: 0, 54f678331aShanjiezhou blocks: 0, 55f678331aShanjiezhou atime: TimeSpec::default(), 56f678331aShanjiezhou mtime: TimeSpec::default(), 57f678331aShanjiezhou ctime: TimeSpec::default(), 58f678331aShanjiezhou file_type: FileType::Pipe, 59f678331aShanjiezhou mode: 0o666, 60f678331aShanjiezhou nlinks: 1, 61f678331aShanjiezhou uid: 0, 62f678331aShanjiezhou gid: 0, 63f678331aShanjiezhou raw_dev: 0, 64f678331aShanjiezhou }, 6522c9db31Shanjiezhou flags, 66f678331aShanjiezhou }; 67f678331aShanjiezhou let result = Arc::new(Self(SpinLock::new(inner))); 68f678331aShanjiezhou let mut guard = result.0.lock(); 69f678331aShanjiezhou guard.self_ref = Arc::downgrade(&result); 70f678331aShanjiezhou // 释放锁 71f678331aShanjiezhou drop(guard); //这一步其实不需要,只要离开作用域,guard生命周期结束,自会解锁 72f678331aShanjiezhou return result; 73f678331aShanjiezhou } 74f678331aShanjiezhou } 75f678331aShanjiezhou 76f678331aShanjiezhou impl IndexNode for LockedPipeInode { 77f678331aShanjiezhou fn read_at( 78f678331aShanjiezhou &self, 79f678331aShanjiezhou _offset: usize, 80f678331aShanjiezhou len: usize, 81f678331aShanjiezhou buf: &mut [u8], 82f678331aShanjiezhou _data: &mut FilePrivateData, 83f678331aShanjiezhou ) -> Result<usize, crate::syscall::SystemError> { 84f678331aShanjiezhou if buf.len() < len { 85f678331aShanjiezhou return Err(SystemError::EINVAL); 86f678331aShanjiezhou } 87f678331aShanjiezhou // 加锁 88f678331aShanjiezhou let mut inode = self.0.lock(); 89f678331aShanjiezhou 90f678331aShanjiezhou // 如果管道里面没有数据,则唤醒写端, 91f678331aShanjiezhou while inode.valid_cnt == 0 { 92*1496ba7bSLoGin inode 93*1496ba7bSLoGin .write_wait_queue 94*1496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 95*1496ba7bSLoGin 9622c9db31Shanjiezhou // 如果为非阻塞管道,直接返回错误 9722c9db31Shanjiezhou if inode.flags.contains(FileMode::O_NONBLOCK) { 9822c9db31Shanjiezhou drop(inode); 9922c9db31Shanjiezhou return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 10022c9db31Shanjiezhou } 101*1496ba7bSLoGin 10222c9db31Shanjiezhou // 否则在读等待队列中睡眠,并释放锁 103f678331aShanjiezhou unsafe { 104f678331aShanjiezhou let irq_guard = CurrentIrqArch::save_and_disable_irq(); 105f678331aShanjiezhou inode.read_wait_queue.sleep_without_schedule(); 106f678331aShanjiezhou drop(inode); 107f678331aShanjiezhou 108f678331aShanjiezhou drop(irq_guard); 109f678331aShanjiezhou } 110f678331aShanjiezhou sched(); 111f678331aShanjiezhou inode = self.0.lock(); 112f678331aShanjiezhou } 113f678331aShanjiezhou 114f678331aShanjiezhou let mut num = inode.valid_cnt as usize; 115f678331aShanjiezhou //决定要输出的字节 116f678331aShanjiezhou let start = inode.read_pos as usize; 117f678331aShanjiezhou //如果读端希望读取的字节数大于有效字节数,则输出有效字节 118f678331aShanjiezhou let mut end = (inode.valid_cnt as usize + inode.read_pos as usize) % PIPE_BUFF_SIZE; 119f678331aShanjiezhou //如果读端希望读取的字节数少于有效字节数,则输出希望读取的字节 120f678331aShanjiezhou if len < inode.valid_cnt as usize { 121f678331aShanjiezhou end = (len + inode.read_pos as usize) % PIPE_BUFF_SIZE; 122f678331aShanjiezhou num = len; 123f678331aShanjiezhou } 124f678331aShanjiezhou 125f678331aShanjiezhou // 从管道拷贝数据到用户的缓冲区 126f678331aShanjiezhou 127f678331aShanjiezhou if end < start { 128f678331aShanjiezhou buf[0..(PIPE_BUFF_SIZE - start)].copy_from_slice(&inode.data[start..PIPE_BUFF_SIZE]); 129f678331aShanjiezhou buf[(PIPE_BUFF_SIZE - start)..num].copy_from_slice(&inode.data[0..end]); 130f678331aShanjiezhou } else { 131f678331aShanjiezhou buf[0..num].copy_from_slice(&inode.data[start..end]); 132f678331aShanjiezhou } 133f678331aShanjiezhou 134f678331aShanjiezhou //更新读位置以及valid_cnt 135f678331aShanjiezhou inode.read_pos = (inode.read_pos + num as i32) % PIPE_BUFF_SIZE as i32; 136f678331aShanjiezhou inode.valid_cnt -= num as i32; 137f678331aShanjiezhou 138f678331aShanjiezhou //读完后解锁并唤醒等待在写等待队列中的进程 139*1496ba7bSLoGin inode 140*1496ba7bSLoGin .write_wait_queue 141*1496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 142f678331aShanjiezhou //返回读取的字节数 143f678331aShanjiezhou return Ok(num); 144f678331aShanjiezhou } 145f678331aShanjiezhou 146f678331aShanjiezhou fn open( 147f678331aShanjiezhou &self, 148f678331aShanjiezhou _data: &mut FilePrivateData, 149f678331aShanjiezhou _mode: &crate::filesystem::vfs::file::FileMode, 150f678331aShanjiezhou ) -> Result<(), SystemError> { 151f678331aShanjiezhou return Ok(()); 152f678331aShanjiezhou } 153f678331aShanjiezhou 154f678331aShanjiezhou fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> { 155f678331aShanjiezhou let inode = self.0.lock(); 156f678331aShanjiezhou let mut metadata = inode.metadata.clone(); 157f678331aShanjiezhou metadata.size = inode.data.len() as i64; 158f678331aShanjiezhou 159f678331aShanjiezhou return Ok(metadata); 160f678331aShanjiezhou } 161f678331aShanjiezhou 162f678331aShanjiezhou fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 163f678331aShanjiezhou return Ok(()); 164f678331aShanjiezhou } 165f678331aShanjiezhou 166f678331aShanjiezhou fn write_at( 167f678331aShanjiezhou &self, 168f678331aShanjiezhou _offset: usize, 169f678331aShanjiezhou len: usize, 170f678331aShanjiezhou buf: &[u8], 171f678331aShanjiezhou _data: &mut FilePrivateData, 172f678331aShanjiezhou ) -> Result<usize, crate::syscall::SystemError> { 173f678331aShanjiezhou if buf.len() < len || len > PIPE_BUFF_SIZE { 174f678331aShanjiezhou return Err(SystemError::EINVAL); 175f678331aShanjiezhou } 176f678331aShanjiezhou // 加锁 177f678331aShanjiezhou 178f678331aShanjiezhou let mut inode = self.0.lock(); 179f678331aShanjiezhou 180f678331aShanjiezhou // 如果管道空间不够 181f678331aShanjiezhou 182f678331aShanjiezhou while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE { 183f678331aShanjiezhou // 唤醒读端 184*1496ba7bSLoGin inode 185*1496ba7bSLoGin .read_wait_queue 186*1496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 187*1496ba7bSLoGin 18822c9db31Shanjiezhou // 如果为非阻塞管道,直接返回错误 18922c9db31Shanjiezhou if inode.flags.contains(FileMode::O_NONBLOCK) { 19022c9db31Shanjiezhou drop(inode); 19122c9db31Shanjiezhou return Err(SystemError::ENOMEM); 19222c9db31Shanjiezhou } 193*1496ba7bSLoGin 194f678331aShanjiezhou // 解锁并睡眠 195f678331aShanjiezhou unsafe { 196f678331aShanjiezhou let irq_guard = CurrentIrqArch::save_and_disable_irq(); 197f678331aShanjiezhou inode.write_wait_queue.sleep_without_schedule(); 198f678331aShanjiezhou drop(inode); 199f678331aShanjiezhou drop(irq_guard); 200f678331aShanjiezhou } 201f678331aShanjiezhou sched(); 202f678331aShanjiezhou inode = self.0.lock(); 203f678331aShanjiezhou } 204f678331aShanjiezhou 205f678331aShanjiezhou // 决定要输入的字节 206f678331aShanjiezhou let start = inode.write_pos as usize; 207f678331aShanjiezhou let end = (inode.write_pos as usize + len) % PIPE_BUFF_SIZE; 208f678331aShanjiezhou // 从用户的缓冲区拷贝数据到管道 209f678331aShanjiezhou 210f678331aShanjiezhou if end < start { 211f678331aShanjiezhou inode.data[start..PIPE_BUFF_SIZE].copy_from_slice(&buf[0..(PIPE_BUFF_SIZE - start)]); 212f678331aShanjiezhou inode.data[0..end].copy_from_slice(&buf[(PIPE_BUFF_SIZE - start)..len]); 213f678331aShanjiezhou } else { 214f678331aShanjiezhou inode.data[start..end].copy_from_slice(&buf[0..len]); 215f678331aShanjiezhou } 216f678331aShanjiezhou // 更新写位置以及valid_cnt 217f678331aShanjiezhou inode.write_pos = (inode.write_pos + len as i32) % PIPE_BUFF_SIZE as i32; 218f678331aShanjiezhou inode.valid_cnt += len as i32; 219f678331aShanjiezhou 220f678331aShanjiezhou // 读完后解锁并唤醒等待在读等待队列中的进程 221*1496ba7bSLoGin inode 222*1496ba7bSLoGin .read_wait_queue 223*1496ba7bSLoGin .wakeup(Some(ProcessState::Blocked(true))); 224f678331aShanjiezhou // 返回写入的字节数 225f678331aShanjiezhou return Ok(len); 226f678331aShanjiezhou } 227f678331aShanjiezhou 228f678331aShanjiezhou fn poll(&self) -> Result<PollStatus, crate::syscall::SystemError> { 229f678331aShanjiezhou return Ok(PollStatus::READ | PollStatus::WRITE); 230f678331aShanjiezhou } 231f678331aShanjiezhou 232f678331aShanjiezhou fn as_any_ref(&self) -> &dyn core::any::Any { 233f678331aShanjiezhou self 234f678331aShanjiezhou } 235f678331aShanjiezhou 236f678331aShanjiezhou fn get_entry_name_and_metadata( 237f678331aShanjiezhou &self, 238f678331aShanjiezhou ino: crate::filesystem::vfs::InodeId, 239f678331aShanjiezhou ) -> Result<(alloc::string::String, crate::filesystem::vfs::Metadata), SystemError> { 240f678331aShanjiezhou // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 241f678331aShanjiezhou let name = self.get_entry_name(ino)?; 242f678331aShanjiezhou let entry = self.find(&name)?; 243f678331aShanjiezhou return Ok((name, entry.metadata()?)); 244f678331aShanjiezhou } 245f678331aShanjiezhou 246f678331aShanjiezhou fn fs(&self) -> Arc<(dyn FileSystem)> { 247f678331aShanjiezhou todo!() 248f678331aShanjiezhou } 249f678331aShanjiezhou 250f678331aShanjiezhou fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 251f678331aShanjiezhou return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 252f678331aShanjiezhou } 253f678331aShanjiezhou } 254