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