1f678331aShanjiezhou use crate::{ 2f678331aShanjiezhou arch::{sched::sched, CurrentIrqArch}, 3f678331aShanjiezhou exception::InterruptArch, 4f678331aShanjiezhou filesystem::vfs::{ 5*22c9db31Shanjiezhou core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, 6*22c9db31Shanjiezhou Metadata, PollStatus, 7f678331aShanjiezhou }, 8f678331aShanjiezhou include::bindings::bindings::PROC_INTERRUPTIBLE, 9f678331aShanjiezhou libs::{spinlock::SpinLock, wait_queue::WaitQueue}, 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, 35*22c9db31Shanjiezhou flags: FileMode, 36f678331aShanjiezhou } 37f678331aShanjiezhou 38f678331aShanjiezhou impl LockedPipeInode { 39*22c9db31Shanjiezhou 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(), 52*22c9db31Shanjiezhou 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 }, 65*22c9db31Shanjiezhou 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 { 92f678331aShanjiezhou inode.write_wait_queue.wakeup(PROC_INTERRUPTIBLE.into()); 93*22c9db31Shanjiezhou // 如果为非阻塞管道,直接返回错误 94*22c9db31Shanjiezhou if inode.flags.contains(FileMode::O_NONBLOCK) { 95*22c9db31Shanjiezhou drop(inode); 96*22c9db31Shanjiezhou return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 97*22c9db31Shanjiezhou } 98*22c9db31Shanjiezhou // 否则在读等待队列中睡眠,并释放锁 99f678331aShanjiezhou unsafe { 100f678331aShanjiezhou let irq_guard = CurrentIrqArch::save_and_disable_irq(); 101f678331aShanjiezhou inode.read_wait_queue.sleep_without_schedule(); 102f678331aShanjiezhou drop(inode); 103f678331aShanjiezhou 104f678331aShanjiezhou drop(irq_guard); 105f678331aShanjiezhou } 106f678331aShanjiezhou sched(); 107f678331aShanjiezhou inode = self.0.lock(); 108f678331aShanjiezhou } 109f678331aShanjiezhou 110f678331aShanjiezhou let mut num = inode.valid_cnt as usize; 111f678331aShanjiezhou //决定要输出的字节 112f678331aShanjiezhou let start = inode.read_pos as usize; 113f678331aShanjiezhou //如果读端希望读取的字节数大于有效字节数,则输出有效字节 114f678331aShanjiezhou let mut end = (inode.valid_cnt as usize + inode.read_pos as usize) % PIPE_BUFF_SIZE; 115f678331aShanjiezhou //如果读端希望读取的字节数少于有效字节数,则输出希望读取的字节 116f678331aShanjiezhou if len < inode.valid_cnt as usize { 117f678331aShanjiezhou end = (len + inode.read_pos as usize) % PIPE_BUFF_SIZE; 118f678331aShanjiezhou num = len; 119f678331aShanjiezhou } 120f678331aShanjiezhou 121f678331aShanjiezhou // 从管道拷贝数据到用户的缓冲区 122f678331aShanjiezhou 123f678331aShanjiezhou if end < start { 124f678331aShanjiezhou buf[0..(PIPE_BUFF_SIZE - start)].copy_from_slice(&inode.data[start..PIPE_BUFF_SIZE]); 125f678331aShanjiezhou buf[(PIPE_BUFF_SIZE - start)..num].copy_from_slice(&inode.data[0..end]); 126f678331aShanjiezhou } else { 127f678331aShanjiezhou buf[0..num].copy_from_slice(&inode.data[start..end]); 128f678331aShanjiezhou } 129f678331aShanjiezhou 130f678331aShanjiezhou //更新读位置以及valid_cnt 131f678331aShanjiezhou inode.read_pos = (inode.read_pos + num as i32) % PIPE_BUFF_SIZE as i32; 132f678331aShanjiezhou inode.valid_cnt -= num as i32; 133f678331aShanjiezhou 134f678331aShanjiezhou //读完后解锁并唤醒等待在写等待队列中的进程 135f678331aShanjiezhou inode.write_wait_queue.wakeup(PROC_INTERRUPTIBLE.into()); 136f678331aShanjiezhou //返回读取的字节数 137f678331aShanjiezhou return Ok(num); 138f678331aShanjiezhou } 139f678331aShanjiezhou 140f678331aShanjiezhou fn open( 141f678331aShanjiezhou &self, 142f678331aShanjiezhou _data: &mut FilePrivateData, 143f678331aShanjiezhou _mode: &crate::filesystem::vfs::file::FileMode, 144f678331aShanjiezhou ) -> Result<(), SystemError> { 145f678331aShanjiezhou return Ok(()); 146f678331aShanjiezhou } 147f678331aShanjiezhou 148f678331aShanjiezhou fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> { 149f678331aShanjiezhou let inode = self.0.lock(); 150f678331aShanjiezhou let mut metadata = inode.metadata.clone(); 151f678331aShanjiezhou metadata.size = inode.data.len() as i64; 152f678331aShanjiezhou 153f678331aShanjiezhou return Ok(metadata); 154f678331aShanjiezhou } 155f678331aShanjiezhou 156f678331aShanjiezhou fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 157f678331aShanjiezhou return Ok(()); 158f678331aShanjiezhou } 159f678331aShanjiezhou 160f678331aShanjiezhou fn write_at( 161f678331aShanjiezhou &self, 162f678331aShanjiezhou _offset: usize, 163f678331aShanjiezhou len: usize, 164f678331aShanjiezhou buf: &[u8], 165f678331aShanjiezhou _data: &mut FilePrivateData, 166f678331aShanjiezhou ) -> Result<usize, crate::syscall::SystemError> { 167f678331aShanjiezhou if buf.len() < len || len > PIPE_BUFF_SIZE { 168f678331aShanjiezhou return Err(SystemError::EINVAL); 169f678331aShanjiezhou } 170f678331aShanjiezhou // 加锁 171f678331aShanjiezhou 172f678331aShanjiezhou let mut inode = self.0.lock(); 173f678331aShanjiezhou 174f678331aShanjiezhou // 如果管道空间不够 175f678331aShanjiezhou 176f678331aShanjiezhou while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE { 177f678331aShanjiezhou // 唤醒读端 178f678331aShanjiezhou inode.read_wait_queue.wakeup(PROC_INTERRUPTIBLE.into()); 179*22c9db31Shanjiezhou // 如果为非阻塞管道,直接返回错误 180*22c9db31Shanjiezhou if inode.flags.contains(FileMode::O_NONBLOCK) { 181*22c9db31Shanjiezhou drop(inode); 182*22c9db31Shanjiezhou return Err(SystemError::ENOMEM); 183*22c9db31Shanjiezhou } 184f678331aShanjiezhou // 解锁并睡眠 185f678331aShanjiezhou unsafe { 186f678331aShanjiezhou let irq_guard = CurrentIrqArch::save_and_disable_irq(); 187f678331aShanjiezhou inode.write_wait_queue.sleep_without_schedule(); 188f678331aShanjiezhou drop(inode); 189f678331aShanjiezhou drop(irq_guard); 190f678331aShanjiezhou } 191f678331aShanjiezhou sched(); 192f678331aShanjiezhou inode = self.0.lock(); 193f678331aShanjiezhou } 194f678331aShanjiezhou 195f678331aShanjiezhou // 决定要输入的字节 196f678331aShanjiezhou let start = inode.write_pos as usize; 197f678331aShanjiezhou let end = (inode.write_pos as usize + len) % PIPE_BUFF_SIZE; 198f678331aShanjiezhou // 从用户的缓冲区拷贝数据到管道 199f678331aShanjiezhou 200f678331aShanjiezhou if end < start { 201f678331aShanjiezhou inode.data[start..PIPE_BUFF_SIZE].copy_from_slice(&buf[0..(PIPE_BUFF_SIZE - start)]); 202f678331aShanjiezhou inode.data[0..end].copy_from_slice(&buf[(PIPE_BUFF_SIZE - start)..len]); 203f678331aShanjiezhou } else { 204f678331aShanjiezhou inode.data[start..end].copy_from_slice(&buf[0..len]); 205f678331aShanjiezhou } 206f678331aShanjiezhou // 更新写位置以及valid_cnt 207f678331aShanjiezhou inode.write_pos = (inode.write_pos + len as i32) % PIPE_BUFF_SIZE as i32; 208f678331aShanjiezhou inode.valid_cnt += len as i32; 209f678331aShanjiezhou 210f678331aShanjiezhou // 读完后解锁并唤醒等待在读等待队列中的进程 211f678331aShanjiezhou inode.read_wait_queue.wakeup(PROC_INTERRUPTIBLE.into()); 212f678331aShanjiezhou // 返回写入的字节数 213f678331aShanjiezhou return Ok(len); 214f678331aShanjiezhou } 215f678331aShanjiezhou 216f678331aShanjiezhou fn poll(&self) -> Result<PollStatus, crate::syscall::SystemError> { 217f678331aShanjiezhou return Ok(PollStatus::READ | PollStatus::WRITE); 218f678331aShanjiezhou } 219f678331aShanjiezhou 220f678331aShanjiezhou fn as_any_ref(&self) -> &dyn core::any::Any { 221f678331aShanjiezhou self 222f678331aShanjiezhou } 223f678331aShanjiezhou 224f678331aShanjiezhou fn get_entry_name_and_metadata( 225f678331aShanjiezhou &self, 226f678331aShanjiezhou ino: crate::filesystem::vfs::InodeId, 227f678331aShanjiezhou ) -> Result<(alloc::string::String, crate::filesystem::vfs::Metadata), SystemError> { 228f678331aShanjiezhou // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 229f678331aShanjiezhou let name = self.get_entry_name(ino)?; 230f678331aShanjiezhou let entry = self.find(&name)?; 231f678331aShanjiezhou return Ok((name, entry.metadata()?)); 232f678331aShanjiezhou } 233f678331aShanjiezhou 234f678331aShanjiezhou fn fs(&self) -> Arc<(dyn FileSystem)> { 235f678331aShanjiezhou todo!() 236f678331aShanjiezhou } 237f678331aShanjiezhou 238f678331aShanjiezhou fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 239f678331aShanjiezhou return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 240f678331aShanjiezhou } 241f678331aShanjiezhou } 242