1dfe53cf0SGnoCiYeH use core::sync::atomic::{AtomicUsize, Ordering}; 2dfe53cf0SGnoCiYeH 340609970SGnoCiYeH use alloc::{ 440609970SGnoCiYeH string::String, 540609970SGnoCiYeH sync::{Arc, Weak}, 640609970SGnoCiYeH vec::Vec, 740609970SGnoCiYeH }; 82eab6dd7S曾俊 use log::error; 991e9d4abSLoGin use system_error::SystemError; 10004e86ffSlogin 11*4afc5b7bSlinfeng use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; 12*4afc5b7bSlinfeng use crate::filesystem::eventfd::EventFdInode; 13004e86ffSlogin use crate::{ 14b087521eSChiichen driver::{ 15b087521eSChiichen base::{block::SeekFrom, device::DevicePrivateData}, 1652da9a59SGnoCiYeH tty::tty_device::TtyFilePrivateData, 17b087521eSChiichen }, 18b087521eSChiichen filesystem::procfs::ProcfsFilePrivateData, 195e948c56SGnoCiYeH ipc::pipe::{LockedPipeInode, PipeFsPrivateData}, 20dfe53cf0SGnoCiYeH libs::{rwlock::RwLock, spinlock::SpinLock}, 2140609970SGnoCiYeH net::{ 2240609970SGnoCiYeH event_poll::{EPollItem, EPollPrivateData, EventPoll}, 2340609970SGnoCiYeH socket::SocketInode, 2440609970SGnoCiYeH }, 250648a547SJomo process::{cred::Cred, ProcessManager}, 26004e86ffSlogin }; 27004e86ffSlogin 28004e86ffSlogin /// 文件私有信息的枚举类型 29004e86ffSlogin #[derive(Debug, Clone)] 30bf4a4899SLoGin #[allow(dead_code)] 31004e86ffSlogin pub enum FilePrivateData { 32876cb89eSGnoCiYeH /// 管道文件私有信息 33876cb89eSGnoCiYeH Pipefs(PipeFsPrivateData), 340d48c3c9Slogin /// procfs文件私有信息 35004e86ffSlogin Procfs(ProcfsFilePrivateData), 36b087521eSChiichen /// 设备文件的私有信息 37b087521eSChiichen DevFS(DevicePrivateData), 38b087521eSChiichen /// tty设备文件的私有信息 390d48c3c9Slogin Tty(TtyFilePrivateData), 4040609970SGnoCiYeH /// epoll私有信息 4140609970SGnoCiYeH EPoll(EPollPrivateData), 420d48c3c9Slogin /// 不需要文件私有信息 43004e86ffSlogin Unused, 44004e86ffSlogin } 45004e86ffSlogin 46004e86ffSlogin impl Default for FilePrivateData { 47004e86ffSlogin fn default() -> Self { 48004e86ffSlogin return Self::Unused; 49004e86ffSlogin } 50004e86ffSlogin } 51004e86ffSlogin 525e948c56SGnoCiYeH impl FilePrivateData { 535e948c56SGnoCiYeH pub fn update_mode(&mut self, mode: FileMode) { 545e948c56SGnoCiYeH if let FilePrivateData::Pipefs(pdata) = self { 555e948c56SGnoCiYeH pdata.set_mode(mode); 565e948c56SGnoCiYeH } 575e948c56SGnoCiYeH } 585e948c56SGnoCiYeH } 595e948c56SGnoCiYeH 60004e86ffSlogin bitflags! { 61004e86ffSlogin /// @brief 文件打开模式 62004e86ffSlogin /// 其中,低2bit组合而成的数字的值,用于表示访问权限。其他的bit,才支持通过按位或的方式来表示参数 63004e86ffSlogin /// 64004e86ffSlogin /// 与Linux 5.19.10的uapi/asm-generic/fcntl.h相同 65e7071df6SLoGin /// https://code.dragonos.org.cn/xref/linux-5.19.10/tools/include/uapi/asm-generic/fcntl.h#19 66b5b571e0SLoGin #[allow(clippy::bad_bit_mask)] 67004e86ffSlogin pub struct FileMode: u32{ 68004e86ffSlogin /* File access modes for `open' and `fcntl'. */ 69004e86ffSlogin /// Open Read-only 7084407d36Slogin const O_RDONLY = 0o0; 71004e86ffSlogin /// Open Write-only 7284407d36Slogin const O_WRONLY = 0o1; 73004e86ffSlogin /// Open read/write 7484407d36Slogin const O_RDWR = 0o2; 75004e86ffSlogin /// Mask for file access modes 7684407d36Slogin const O_ACCMODE = 0o00000003; 77004e86ffSlogin 78004e86ffSlogin /* Bits OR'd into the second argument to open. */ 79004e86ffSlogin /// Create file if it does not exist 8084407d36Slogin const O_CREAT = 0o00000100; 81004e86ffSlogin /// Fail if file already exists 8284407d36Slogin const O_EXCL = 0o00000200; 83004e86ffSlogin /// Do not assign controlling terminal 8484407d36Slogin const O_NOCTTY = 0o00000400; 85004e86ffSlogin /// 文件存在且是普通文件,并以O_RDWR或O_WRONLY打开,则它会被清空 8684407d36Slogin const O_TRUNC = 0o00001000; 87004e86ffSlogin /// 文件指针会被移动到文件末尾 8884407d36Slogin const O_APPEND = 0o00002000; 89004e86ffSlogin /// 非阻塞式IO模式 9084407d36Slogin const O_NONBLOCK = 0o00004000; 9120e3152eSlogin /// 每次write都等待物理I/O完成,但是如果写操作不影响读取刚写入的数据,则不等待文件属性更新 9284407d36Slogin const O_DSYNC = 0o00010000; 93004e86ffSlogin /// fcntl, for BSD compatibility 9484407d36Slogin const FASYNC = 0o00020000; 95004e86ffSlogin /* direct disk access hint */ 9684407d36Slogin const O_DIRECT = 0o00040000; 9784407d36Slogin const O_LARGEFILE = 0o00100000; 98004e86ffSlogin /// 打开的必须是一个目录 9984407d36Slogin const O_DIRECTORY = 0o00200000; 100004e86ffSlogin /// Do not follow symbolic links 10184407d36Slogin const O_NOFOLLOW = 0o00400000; 10284407d36Slogin const O_NOATIME = 0o01000000; 103004e86ffSlogin /// set close_on_exec 10484407d36Slogin const O_CLOEXEC = 0o02000000; 10520e3152eSlogin /// 每次write都等到物理I/O完成,包括write引起的文件属性的更新 10620e3152eSlogin const O_SYNC = 0o04000000; 1070fb515b0SLoGin 1080fb515b0SLoGin const O_PATH = 0o10000000; 1090fb515b0SLoGin 1100fb515b0SLoGin const O_PATH_FLAGS = Self::O_DIRECTORY.bits|Self::O_NOFOLLOW.bits|Self::O_CLOEXEC.bits|Self::O_PATH.bits; 111004e86ffSlogin } 112004e86ffSlogin } 113004e86ffSlogin 11420e3152eSlogin impl FileMode { 11520e3152eSlogin /// @brief 获取文件的访问模式的值 11620e3152eSlogin #[inline] 11720e3152eSlogin pub fn accmode(&self) -> u32 { 11820e3152eSlogin return self.bits() & FileMode::O_ACCMODE.bits(); 11920e3152eSlogin } 12020e3152eSlogin } 121004e86ffSlogin /// @brief 抽象文件结构体 12264aea4b3SGou Ngai #[derive(Debug)] 123004e86ffSlogin pub struct File { 124004e86ffSlogin inode: Arc<dyn IndexNode>, 125004e86ffSlogin /// 对于文件,表示字节偏移量;对于文件夹,表示当前操作的子目录项偏移量 126dfe53cf0SGnoCiYeH offset: AtomicUsize, 127004e86ffSlogin /// 文件的打开模式 128dfe53cf0SGnoCiYeH mode: RwLock<FileMode>, 129004e86ffSlogin /// 文件类型 130004e86ffSlogin file_type: FileType, 131004e86ffSlogin /// readdir时候用的,暂存的本次循环中,所有子目录项的名字的数组 132dfe53cf0SGnoCiYeH readdir_subdirs_name: SpinLock<Vec<String>>, 133dfe53cf0SGnoCiYeH pub private_data: SpinLock<FilePrivateData>, 1340648a547SJomo /// 文件的凭证 1350648a547SJomo cred: Cred, 136004e86ffSlogin } 137004e86ffSlogin 138004e86ffSlogin impl File { 139004e86ffSlogin /// @brief 创建一个新的文件对象 140004e86ffSlogin /// 141004e86ffSlogin /// @param inode 文件对象对应的inode 142004e86ffSlogin /// @param mode 文件的打开模式 143676b8ef6SMork pub fn new(inode: Arc<dyn IndexNode>, mode: FileMode) -> Result<Self, SystemError> { 1442dbef785SGnoCiYeH let mut inode = inode; 1452dbef785SGnoCiYeH let file_type = inode.metadata()?.file_type; 146b5b571e0SLoGin if file_type == FileType::Pipe { 1472dbef785SGnoCiYeH if let Some(SpecialNodeData::Pipe(pipe_inode)) = inode.special_node() { 1482dbef785SGnoCiYeH inode = pipe_inode; 1492dbef785SGnoCiYeH } 1502dbef785SGnoCiYeH } 1512dbef785SGnoCiYeH 152dfe53cf0SGnoCiYeH let f = File { 153004e86ffSlogin inode, 154dfe53cf0SGnoCiYeH offset: AtomicUsize::new(0), 155dfe53cf0SGnoCiYeH mode: RwLock::new(mode), 156004e86ffSlogin file_type, 157dfe53cf0SGnoCiYeH readdir_subdirs_name: SpinLock::new(Vec::default()), 158dfe53cf0SGnoCiYeH private_data: SpinLock::new(FilePrivateData::default()), 1590648a547SJomo cred: ProcessManager::current_pcb().cred(), 160004e86ffSlogin }; 161dfe53cf0SGnoCiYeH f.inode.open(f.private_data.lock(), &mode)?; 16240314b30SXiaoye Zheng 163004e86ffSlogin return Ok(f); 164004e86ffSlogin } 165004e86ffSlogin 166004e86ffSlogin /// @brief 从文件中读取指定的字节数到buffer中 167004e86ffSlogin /// 168004e86ffSlogin /// @param len 要读取的字节数 169004e86ffSlogin /// @param buf 目标buffer 170004e86ffSlogin /// 171004e86ffSlogin /// @return Ok(usize) 成功读取的字节数 172676b8ef6SMork /// @return Err(SystemError) 错误码 173dfe53cf0SGnoCiYeH pub fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> { 174dfe53cf0SGnoCiYeH self.do_read( 175dfe53cf0SGnoCiYeH self.offset.load(core::sync::atomic::Ordering::SeqCst), 176dfe53cf0SGnoCiYeH len, 177dfe53cf0SGnoCiYeH buf, 178dfe53cf0SGnoCiYeH true, 179dfe53cf0SGnoCiYeH ) 180004e86ffSlogin } 181004e86ffSlogin 182004e86ffSlogin /// @brief 从buffer向文件写入指定的字节数的数据 183004e86ffSlogin /// 184004e86ffSlogin /// @param len 要写入的字节数 185004e86ffSlogin /// @param buf 源数据buffer 186004e86ffSlogin /// 187004e86ffSlogin /// @return Ok(usize) 成功写入的字节数 188676b8ef6SMork /// @return Err(SystemError) 错误码 189dfe53cf0SGnoCiYeH pub fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError> { 190dfe53cf0SGnoCiYeH self.do_write( 191dfe53cf0SGnoCiYeH self.offset.load(core::sync::atomic::Ordering::SeqCst), 192dfe53cf0SGnoCiYeH len, 193dfe53cf0SGnoCiYeH buf, 194dfe53cf0SGnoCiYeH true, 195dfe53cf0SGnoCiYeH ) 19627b967a3S裕依 } 19727b967a3S裕依 19827b967a3S裕依 /// ## 从文件中指定的偏移处读取指定的字节数到buf中 19927b967a3S裕依 /// 20027b967a3S裕依 /// ### 参数 20127b967a3S裕依 /// - `offset`: 文件偏移量 20227b967a3S裕依 /// - `len`: 要读取的字节数 20327b967a3S裕依 /// - `buf`: 读出缓冲区 20427b967a3S裕依 /// 20527b967a3S裕依 /// ### 返回值 20627b967a3S裕依 /// - `Ok(usize)`: 成功读取的字节数 207dfe53cf0SGnoCiYeH pub fn pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> { 20827b967a3S裕依 self.do_read(offset, len, buf, false) 20927b967a3S裕依 } 21027b967a3S裕依 21127b967a3S裕依 /// ## 从buf向文件中指定的偏移处写入指定的字节数的数据 21227b967a3S裕依 /// 21327b967a3S裕依 /// ### 参数 21427b967a3S裕依 /// - `offset`: 文件偏移量 21527b967a3S裕依 /// - `len`: 要写入的字节数 21627b967a3S裕依 /// - `buf`: 写入缓冲区 21727b967a3S裕依 /// 21827b967a3S裕依 /// ### 返回值 21927b967a3S裕依 /// - `Ok(usize)`: 成功写入的字节数 220dfe53cf0SGnoCiYeH pub fn pwrite(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> { 22127b967a3S裕依 self.do_write(offset, len, buf, false) 22227b967a3S裕依 } 22327b967a3S裕依 22427b967a3S裕依 fn do_read( 225dfe53cf0SGnoCiYeH &self, 22627b967a3S裕依 offset: usize, 22727b967a3S裕依 len: usize, 22827b967a3S裕依 buf: &mut [u8], 22927b967a3S裕依 update_offset: bool, 23027b967a3S裕依 ) -> Result<usize, SystemError> { 23127b967a3S裕依 // 先检查本文件在权限等规则下,是否可读取。 23227b967a3S裕依 self.readable()?; 23327b967a3S裕依 if buf.len() < len { 23427b967a3S裕依 return Err(SystemError::ENOBUFS); 23527b967a3S裕依 } 23627b967a3S裕依 23727b967a3S裕依 let len = self 23827b967a3S裕依 .inode 239dfe53cf0SGnoCiYeH .read_at(offset, len, buf, self.private_data.lock())?; 24027b967a3S裕依 24127b967a3S裕依 if update_offset { 242dfe53cf0SGnoCiYeH self.offset 243dfe53cf0SGnoCiYeH .fetch_add(len, core::sync::atomic::Ordering::SeqCst); 24427b967a3S裕依 } 24527b967a3S裕依 24627b967a3S裕依 Ok(len) 24727b967a3S裕依 } 24827b967a3S裕依 24927b967a3S裕依 fn do_write( 250dfe53cf0SGnoCiYeH &self, 25127b967a3S裕依 offset: usize, 25227b967a3S裕依 len: usize, 25327b967a3S裕依 buf: &[u8], 25427b967a3S裕依 update_offset: bool, 25527b967a3S裕依 ) -> Result<usize, SystemError> { 256004e86ffSlogin // 先检查本文件在权限等规则下,是否可写入。 257004e86ffSlogin self.writeable()?; 258004e86ffSlogin if buf.len() < len { 259676b8ef6SMork return Err(SystemError::ENOBUFS); 260004e86ffSlogin } 2616d81180bSLoGin 2626d81180bSLoGin // 如果文件指针已经超过了文件大小,则需要扩展文件大小 26327b967a3S裕依 if offset > self.inode.metadata()?.size as usize { 26427b967a3S裕依 self.inode.resize(offset)?; 2656d81180bSLoGin } 266004e86ffSlogin let len = self 267004e86ffSlogin .inode 268dfe53cf0SGnoCiYeH .write_at(offset, len, buf, self.private_data.lock())?; 26927b967a3S裕依 27027b967a3S裕依 if update_offset { 271dfe53cf0SGnoCiYeH self.offset 272dfe53cf0SGnoCiYeH .fetch_add(len, core::sync::atomic::Ordering::SeqCst); 27327b967a3S裕依 } 27427b967a3S裕依 27527b967a3S裕依 Ok(len) 276004e86ffSlogin } 277004e86ffSlogin 278004e86ffSlogin /// @brief 获取文件的元数据 279676b8ef6SMork pub fn metadata(&self) -> Result<Metadata, SystemError> { 280004e86ffSlogin return self.inode.metadata(); 281004e86ffSlogin } 282004e86ffSlogin 283004e86ffSlogin /// @brief 根据inode号获取子目录项的名字 284bf4a4899SLoGin #[allow(dead_code)] 2856b4e7a29SLoGin pub fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 286004e86ffSlogin return self.inode.get_entry_name(ino); 287004e86ffSlogin } 288004e86ffSlogin 289004e86ffSlogin /// @brief 调整文件操作指针的位置 290004e86ffSlogin /// 291004e86ffSlogin /// @param origin 调整的起始位置 292dfe53cf0SGnoCiYeH pub fn lseek(&self, origin: SeekFrom) -> Result<usize, SystemError> { 29340fe15e0SLoGin let file_type = self.inode.metadata()?.file_type; 294bfafc102Slogin match file_type { 295bfafc102Slogin FileType::Pipe | FileType::CharDevice => { 296676b8ef6SMork return Err(SystemError::ESPIPE); 297004e86ffSlogin } 298bfafc102Slogin _ => {} 299bfafc102Slogin } 300bfafc102Slogin 301b5b571e0SLoGin let pos: i64 = match origin { 302b5b571e0SLoGin SeekFrom::SeekSet(offset) => offset, 303dfe53cf0SGnoCiYeH SeekFrom::SeekCurrent(offset) => self.offset.load(Ordering::SeqCst) as i64 + offset, 304004e86ffSlogin SeekFrom::SeekEnd(offset) => { 305004e86ffSlogin let metadata = self.metadata()?; 306b5b571e0SLoGin metadata.size + offset 307004e86ffSlogin } 308004e86ffSlogin SeekFrom::Invalid => { 309676b8ef6SMork return Err(SystemError::EINVAL); 310004e86ffSlogin } 311b5b571e0SLoGin }; 3126d81180bSLoGin // 根据linux man page, lseek允许超出文件末尾,并且不改变文件大小 3136d81180bSLoGin // 当pos超出文件末尾时,read返回0。直到开始写入数据时,才会改变文件大小 3146d81180bSLoGin if pos < 0 { 315676b8ef6SMork return Err(SystemError::EOVERFLOW); 316004e86ffSlogin } 317dfe53cf0SGnoCiYeH self.offset.store(pos as usize, Ordering::SeqCst); 318dfe53cf0SGnoCiYeH return Ok(pos as usize); 319004e86ffSlogin } 320004e86ffSlogin 321004e86ffSlogin /// @brief 判断当前文件是否可读 322004e86ffSlogin #[inline] 323676b8ef6SMork pub fn readable(&self) -> Result<(), SystemError> { 324004e86ffSlogin // 暂时认为只要不是write only, 就可读 325dfe53cf0SGnoCiYeH if *self.mode.read() == FileMode::O_WRONLY { 326676b8ef6SMork return Err(SystemError::EPERM); 327004e86ffSlogin } 328004e86ffSlogin 329004e86ffSlogin return Ok(()); 330004e86ffSlogin } 331004e86ffSlogin 332004e86ffSlogin /// @brief 判断当前文件是否可写 333004e86ffSlogin #[inline] 334676b8ef6SMork pub fn writeable(&self) -> Result<(), SystemError> { 335004e86ffSlogin // 暂时认为只要不是read only, 就可写 336dfe53cf0SGnoCiYeH if *self.mode.read() == FileMode::O_RDONLY { 337676b8ef6SMork return Err(SystemError::EPERM); 338004e86ffSlogin } 339004e86ffSlogin 340004e86ffSlogin return Ok(()); 341004e86ffSlogin } 342004e86ffSlogin 343004e86ffSlogin /// @biref 充填dirent结构体 344004e86ffSlogin /// @return 返回dirent结构体的大小 345dfe53cf0SGnoCiYeH pub fn readdir(&self, dirent: &mut Dirent) -> Result<u64, SystemError> { 346004e86ffSlogin let inode: &Arc<dyn IndexNode> = &self.inode; 347dfe53cf0SGnoCiYeH let mut readdir_subdirs_name = self.readdir_subdirs_name.lock(); 348dfe53cf0SGnoCiYeH let offset = self.offset.load(Ordering::SeqCst); 349004e86ffSlogin // 如果偏移量为0 350dfe53cf0SGnoCiYeH if offset == 0 { 3511effcfe5SGnoCiYeH // 通过list更新readdir_subdirs_name 352dfe53cf0SGnoCiYeH *readdir_subdirs_name = inode.list()?; 353dfe53cf0SGnoCiYeH readdir_subdirs_name.sort(); 354004e86ffSlogin } 3552eab6dd7S曾俊 // debug!("sub_entries={sub_entries:?}"); 3561effcfe5SGnoCiYeH 3571effcfe5SGnoCiYeH // 已经读到末尾 358dfe53cf0SGnoCiYeH if offset == readdir_subdirs_name.len() { 359dfe53cf0SGnoCiYeH self.offset.store(0, Ordering::SeqCst); 360004e86ffSlogin return Ok(0); 361004e86ffSlogin } 362dfe53cf0SGnoCiYeH let name = &readdir_subdirs_name[offset]; 363b5b571e0SLoGin let sub_inode: Arc<dyn IndexNode> = match inode.find(name) { 364004e86ffSlogin Ok(i) => i, 365004e86ffSlogin Err(e) => { 3662eab6dd7S曾俊 error!( 36706d5e247SLoGin "Readdir error: Failed to find sub inode:{name:?}, file={self:?}, error={e:?}" 36806d5e247SLoGin ); 369004e86ffSlogin return Err(e); 370004e86ffSlogin } 371004e86ffSlogin }; 372004e86ffSlogin 373004e86ffSlogin let name_bytes: &[u8] = name.as_bytes(); 374004e86ffSlogin 375004e86ffSlogin // 根据posix的规定,dirent中的d_name是一个不定长的数组,因此需要unsafe来拷贝数据 376004e86ffSlogin unsafe { 377004e86ffSlogin let ptr = &mut dirent.d_name as *mut u8; 3781effcfe5SGnoCiYeH 379004e86ffSlogin let buf: &mut [u8] = 3801effcfe5SGnoCiYeH ::core::slice::from_raw_parts_mut::<'static, u8>(ptr, name_bytes.len() + 1); 3811effcfe5SGnoCiYeH buf[0..name_bytes.len()].copy_from_slice(name_bytes); 3821effcfe5SGnoCiYeH buf[name_bytes.len()] = 0; 383004e86ffSlogin } 384004e86ffSlogin 385dfe53cf0SGnoCiYeH self.offset.fetch_add(1, Ordering::SeqCst); 3861effcfe5SGnoCiYeH dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64; 3871effcfe5SGnoCiYeH dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8; 3881effcfe5SGnoCiYeH 389004e86ffSlogin // 计算dirent结构体的大小 390bb0e4d41SGnoCiYeH let size = (name_bytes.len() + ::core::mem::size_of::<Dirent>() 391bb0e4d41SGnoCiYeH - ::core::mem::size_of_val(&dirent.d_name)) as u64; 392bb0e4d41SGnoCiYeH 393bb0e4d41SGnoCiYeH dirent.d_reclen = size as u16; 394bb0e4d41SGnoCiYeH dirent.d_off += dirent.d_reclen as i64; 395bb0e4d41SGnoCiYeH 396bb0e4d41SGnoCiYeH return Ok(size); 397004e86ffSlogin } 39864aea4b3SGou Ngai 399004e86ffSlogin pub fn inode(&self) -> Arc<dyn IndexNode> { 400004e86ffSlogin return self.inode.clone(); 401004e86ffSlogin } 40264aea4b3SGou Ngai 40364aea4b3SGou Ngai /// @brief 尝试克隆一个文件 40464aea4b3SGou Ngai /// 4051496ba7bSLoGin /// @return Option<File> 克隆后的文件结构体。如果克隆失败,返回None 4061496ba7bSLoGin pub fn try_clone(&self) -> Option<File> { 407dfe53cf0SGnoCiYeH let res = Self { 40864aea4b3SGou Ngai inode: self.inode.clone(), 409dfe53cf0SGnoCiYeH offset: AtomicUsize::new(self.offset.load(Ordering::SeqCst)), 410dfe53cf0SGnoCiYeH mode: RwLock::new(self.mode()), 411b5b571e0SLoGin file_type: self.file_type, 412dfe53cf0SGnoCiYeH readdir_subdirs_name: SpinLock::new(self.readdir_subdirs_name.lock().clone()), 413dfe53cf0SGnoCiYeH private_data: SpinLock::new(self.private_data.lock().clone()), 4140648a547SJomo cred: self.cred.clone(), 4151496ba7bSLoGin }; 41664aea4b3SGou Ngai // 调用inode的open方法,让inode知道有新的文件打开了这个inode 417dfe53cf0SGnoCiYeH if self 418dfe53cf0SGnoCiYeH .inode 419dfe53cf0SGnoCiYeH .open(res.private_data.lock(), &res.mode()) 420dfe53cf0SGnoCiYeH .is_err() 421dfe53cf0SGnoCiYeH { 42264aea4b3SGou Ngai return None; 42364aea4b3SGou Ngai } 42464aea4b3SGou Ngai 42564aea4b3SGou Ngai return Some(res); 42664aea4b3SGou Ngai } 427cde5492fSlogin 428cde5492fSlogin /// @brief 获取文件的类型 429cde5492fSlogin #[inline] 430cde5492fSlogin pub fn file_type(&self) -> FileType { 431cde5492fSlogin return self.file_type; 432cde5492fSlogin } 4336d81180bSLoGin 4346d81180bSLoGin /// @brief 获取文件的打开模式 4356d81180bSLoGin #[inline] 4366d81180bSLoGin pub fn mode(&self) -> FileMode { 437dfe53cf0SGnoCiYeH return *self.mode.read(); 4386d81180bSLoGin } 4396d81180bSLoGin 4406d81180bSLoGin /// 获取文件是否在execve时关闭 4416d81180bSLoGin #[inline] 4426d81180bSLoGin pub fn close_on_exec(&self) -> bool { 443dfe53cf0SGnoCiYeH return self.mode().contains(FileMode::O_CLOEXEC); 4446d81180bSLoGin } 4456d81180bSLoGin 4466d81180bSLoGin /// 设置文件是否在execve时关闭 4476d81180bSLoGin #[inline] 448dfe53cf0SGnoCiYeH pub fn set_close_on_exec(&self, close_on_exec: bool) { 449dfe53cf0SGnoCiYeH let mut mode_guard = self.mode.write(); 4506d81180bSLoGin if close_on_exec { 451dfe53cf0SGnoCiYeH mode_guard.insert(FileMode::O_CLOEXEC); 4526d81180bSLoGin } else { 453dfe53cf0SGnoCiYeH mode_guard.remove(FileMode::O_CLOEXEC); 4546d81180bSLoGin } 4556d81180bSLoGin } 4566d81180bSLoGin 457dfe53cf0SGnoCiYeH pub fn set_mode(&self, mode: FileMode) -> Result<(), SystemError> { 4586d81180bSLoGin // todo: 是否需要调用inode的open方法,以更新private data(假如它与mode有关的话)? 4596d81180bSLoGin // 也许需要加个更好的设计,让inode知晓文件的打开模式发生了变化,让它自己决定是否需要更新private data 4606d81180bSLoGin 4616d81180bSLoGin // 直接修改文件的打开模式 462dfe53cf0SGnoCiYeH *self.mode.write() = mode; 463dfe53cf0SGnoCiYeH self.private_data.lock().update_mode(mode); 4646d81180bSLoGin return Ok(()); 4656d81180bSLoGin } 4666d81180bSLoGin 4676d81180bSLoGin /// @brief 重新设置文件的大小 4686d81180bSLoGin /// 4696d81180bSLoGin /// 如果文件大小增加,则文件内容不变,但是文件的空洞部分会被填充为0 4706d81180bSLoGin /// 如果文件大小减小,则文件内容会被截断 4716d81180bSLoGin /// 4726d81180bSLoGin /// @return 成功:Ok() 4736d81180bSLoGin /// 失败:Err(错误码) 4741496ba7bSLoGin pub fn ftruncate(&self, len: usize) -> Result<(), SystemError> { 4756d81180bSLoGin // 如果文件不可写,返回错误 4766d81180bSLoGin self.writeable()?; 4776d81180bSLoGin 4786d81180bSLoGin // 调用inode的truncate方法 4796d81180bSLoGin self.inode.resize(len)?; 4806d81180bSLoGin return Ok(()); 4816d81180bSLoGin } 48240609970SGnoCiYeH 48340609970SGnoCiYeH /// ## 向该文件添加一个EPollItem对象 48440609970SGnoCiYeH /// 48540609970SGnoCiYeH /// 在文件状态发生变化时,需要向epoll通知 486dfe53cf0SGnoCiYeH pub fn add_epoll(&self, epitem: Arc<EPollItem>) -> Result<(), SystemError> { 48740609970SGnoCiYeH match self.file_type { 48840609970SGnoCiYeH FileType::Socket => { 48940609970SGnoCiYeH let inode = self.inode.downcast_ref::<SocketInode>().unwrap(); 49040609970SGnoCiYeH let mut socket = inode.inner(); 49140609970SGnoCiYeH 49240609970SGnoCiYeH return socket.add_epoll(epitem); 49340609970SGnoCiYeH } 4945e948c56SGnoCiYeH FileType::Pipe => { 4955e948c56SGnoCiYeH let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap(); 4965e948c56SGnoCiYeH return inode.inner().lock().add_epoll(epitem); 4975e948c56SGnoCiYeH } 49852bcb59eSGnoCiYeH _ => { 499415e14e9Slaokengwt let r = self.inode.kernel_ioctl(epitem, &self.private_data.lock()); 50052bcb59eSGnoCiYeH if r.is_err() { 50152bcb59eSGnoCiYeH return Err(SystemError::ENOSYS); 50252bcb59eSGnoCiYeH } 50352bcb59eSGnoCiYeH 50452bcb59eSGnoCiYeH Ok(()) 50552bcb59eSGnoCiYeH } 50640609970SGnoCiYeH } 50740609970SGnoCiYeH } 50840609970SGnoCiYeH 50940609970SGnoCiYeH /// ## 删除一个绑定的epoll 510dfe53cf0SGnoCiYeH pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> { 51140609970SGnoCiYeH match self.file_type { 51240609970SGnoCiYeH FileType::Socket => { 51340609970SGnoCiYeH let inode = self.inode.downcast_ref::<SocketInode>().unwrap(); 51440609970SGnoCiYeH let mut socket = inode.inner(); 51540609970SGnoCiYeH 516*4afc5b7bSlinfeng socket.remove_epoll(epoll) 51740609970SGnoCiYeH } 518*4afc5b7bSlinfeng FileType::Pipe => { 519*4afc5b7bSlinfeng let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap(); 520*4afc5b7bSlinfeng inode.inner().lock().remove_epoll(epoll) 521*4afc5b7bSlinfeng } 522*4afc5b7bSlinfeng _ => { 523*4afc5b7bSlinfeng let inode = self 524*4afc5b7bSlinfeng .inode 525*4afc5b7bSlinfeng .downcast_ref::<EventFdInode>() 526*4afc5b7bSlinfeng .ok_or(SystemError::ENOSYS)?; 527*4afc5b7bSlinfeng inode.remove_epoll(epoll) 528*4afc5b7bSlinfeng } 52940609970SGnoCiYeH } 53040609970SGnoCiYeH } 53140609970SGnoCiYeH 53240609970SGnoCiYeH pub fn poll(&self) -> Result<usize, SystemError> { 533dfe53cf0SGnoCiYeH self.inode.poll(&self.private_data.lock()) 53440609970SGnoCiYeH } 535004e86ffSlogin } 536004e86ffSlogin 537004e86ffSlogin impl Drop for File { 538004e86ffSlogin fn drop(&mut self) { 539dfe53cf0SGnoCiYeH let r: Result<(), SystemError> = self.inode.close(self.private_data.lock()); 540004e86ffSlogin // 打印错误信息 541004e86ffSlogin if r.is_err() { 5422eab6dd7S曾俊 error!( 5431496ba7bSLoGin "pid: {:?} failed to close file: {:?}, errno={:?}", 5441496ba7bSLoGin ProcessManager::current_pcb().pid(), 545004e86ffSlogin self, 5468d72b68dSJomo r.as_ref().unwrap_err() 547004e86ffSlogin ); 548004e86ffSlogin } 549004e86ffSlogin } 550004e86ffSlogin } 551004e86ffSlogin 552004e86ffSlogin /// @brief pcb里面的文件描述符数组 55364aea4b3SGou Ngai #[derive(Debug)] 554004e86ffSlogin pub struct FileDescriptorVec { 555004e86ffSlogin /// 当前进程打开的文件描述符 556dfe53cf0SGnoCiYeH fds: Vec<Option<Arc<File>>>, 557004e86ffSlogin } 558004e86ffSlogin 559004e86ffSlogin impl FileDescriptorVec { 5600d9b7d92SLoGin pub const PROCESS_MAX_FD: usize = 1024; 561004e86ffSlogin 5624fda81ceSLoGin #[inline(never)] 5631496ba7bSLoGin pub fn new() -> FileDescriptorVec { 5644fda81ceSLoGin let mut data = Vec::with_capacity(FileDescriptorVec::PROCESS_MAX_FD); 5654fda81ceSLoGin data.resize(FileDescriptorVec::PROCESS_MAX_FD, None); 566004e86ffSlogin 567004e86ffSlogin // 初始化文件描述符数组结构体 5681496ba7bSLoGin return FileDescriptorVec { fds: data }; 569004e86ffSlogin } 570004e86ffSlogin 57164aea4b3SGou Ngai /// @brief 克隆一个文件描述符数组 57264aea4b3SGou Ngai /// 5731496ba7bSLoGin /// @return FileDescriptorVec 克隆后的文件描述符数组 5741496ba7bSLoGin pub fn clone(&self) -> FileDescriptorVec { 5751496ba7bSLoGin let mut res = FileDescriptorVec::new(); 57664aea4b3SGou Ngai for i in 0..FileDescriptorVec::PROCESS_MAX_FD { 57764aea4b3SGou Ngai if let Some(file) = &self.fds[i] { 578dfe53cf0SGnoCiYeH if let Some(file) = file.try_clone() { 579dfe53cf0SGnoCiYeH res.fds[i] = Some(Arc::new(file)); 5801496ba7bSLoGin } 58164aea4b3SGou Ngai } 58264aea4b3SGou Ngai } 58364aea4b3SGou Ngai return res; 58464aea4b3SGou Ngai } 58564aea4b3SGou Ngai 5863d4cd853Sdonjuanplatinum /// 返回 `已经打开的` 文件描述符的数量 5873d4cd853Sdonjuanplatinum pub fn fd_open_count(&self) -> usize { 5883d4cd853Sdonjuanplatinum let mut size = 0; 5893d4cd853Sdonjuanplatinum for fd in &self.fds { 5903d4cd853Sdonjuanplatinum if fd.is_some() { 5913d4cd853Sdonjuanplatinum size += 1; 5923d4cd853Sdonjuanplatinum } 5933d4cd853Sdonjuanplatinum } 5943d4cd853Sdonjuanplatinum return size; 5953d4cd853Sdonjuanplatinum } 5963d4cd853Sdonjuanplatinum 597004e86ffSlogin /// @brief 判断文件描述符序号是否合法 598004e86ffSlogin /// 599004e86ffSlogin /// @return true 合法 600004e86ffSlogin /// 601004e86ffSlogin /// @return false 不合法 602004e86ffSlogin #[inline] 603004e86ffSlogin pub fn validate_fd(fd: i32) -> bool { 604b5b571e0SLoGin return !(fd < 0 || fd as usize > FileDescriptorVec::PROCESS_MAX_FD); 605004e86ffSlogin } 6061496ba7bSLoGin 6071496ba7bSLoGin /// 申请文件描述符,并把文件对象存入其中。 6081496ba7bSLoGin /// 6091496ba7bSLoGin /// ## 参数 6101496ba7bSLoGin /// 6111496ba7bSLoGin /// - `file` 要存放的文件对象 6121496ba7bSLoGin /// - `fd` 如果为Some(i32),表示指定要申请这个文件描述符,如果这个文件描述符已经被使用,那么返回EBADF 6131496ba7bSLoGin /// 6141496ba7bSLoGin /// ## 返回值 6151496ba7bSLoGin /// 6161496ba7bSLoGin /// - `Ok(i32)` 申请成功,返回申请到的文件描述符 6171496ba7bSLoGin /// - `Err(SystemError)` 申请失败,返回错误码,并且,file对象将被drop掉 6181496ba7bSLoGin pub fn alloc_fd(&mut self, file: File, fd: Option<i32>) -> Result<i32, SystemError> { 619b5b571e0SLoGin if let Some(new_fd) = fd { 6201496ba7bSLoGin let x = &mut self.fds[new_fd as usize]; 6211496ba7bSLoGin if x.is_none() { 622dfe53cf0SGnoCiYeH *x = Some(Arc::new(file)); 6231496ba7bSLoGin return Ok(new_fd); 6241496ba7bSLoGin } else { 6251496ba7bSLoGin return Err(SystemError::EBADF); 6261496ba7bSLoGin } 6271496ba7bSLoGin } else { 6281496ba7bSLoGin // 没有指定要申请的文件描述符编号 6291496ba7bSLoGin for i in 0..FileDescriptorVec::PROCESS_MAX_FD { 6301496ba7bSLoGin if self.fds[i].is_none() { 631dfe53cf0SGnoCiYeH self.fds[i] = Some(Arc::new(file)); 6321496ba7bSLoGin return Ok(i as i32); 6331496ba7bSLoGin } 6341496ba7bSLoGin } 6351496ba7bSLoGin return Err(SystemError::EMFILE); 6361496ba7bSLoGin } 6371496ba7bSLoGin } 6381496ba7bSLoGin 6391496ba7bSLoGin /// 根据文件描述符序号,获取文件结构体的Arc指针 6401496ba7bSLoGin /// 6411496ba7bSLoGin /// ## 参数 6421496ba7bSLoGin /// 6431496ba7bSLoGin /// - `fd` 文件描述符序号 644dfe53cf0SGnoCiYeH pub fn get_file_by_fd(&self, fd: i32) -> Option<Arc<File>> { 6451496ba7bSLoGin if !FileDescriptorVec::validate_fd(fd) { 6461496ba7bSLoGin return None; 6471496ba7bSLoGin } 6486046f775S裕依 self.fds[fd as usize].clone() 6491496ba7bSLoGin } 6501496ba7bSLoGin 6511496ba7bSLoGin /// 释放文件描述符,同时关闭文件。 6521496ba7bSLoGin /// 6531496ba7bSLoGin /// ## 参数 6541496ba7bSLoGin /// 6551496ba7bSLoGin /// - `fd` 文件描述符序号 656*4afc5b7bSlinfeng pub fn drop_fd(&mut self, fd: i32) -> Result<Arc<File>, SystemError> { 65771474bc6SLoGin self.get_file_by_fd(fd).ok_or(SystemError::EBADF)?; 6581496ba7bSLoGin 6591496ba7bSLoGin // 把文件描述符数组对应位置设置为空 6601496ba7bSLoGin let file = self.fds[fd as usize].take().unwrap(); 66134e6d6c8Syuyi2439 6621496ba7bSLoGin assert!(Arc::strong_count(&file) == 1); 663*4afc5b7bSlinfeng return Ok(file); 6641496ba7bSLoGin } 665876cb89eSGnoCiYeH 666bf4a4899SLoGin #[allow(dead_code)] 667876cb89eSGnoCiYeH pub fn iter(&self) -> FileDescriptorIterator { 668876cb89eSGnoCiYeH return FileDescriptorIterator::new(self); 669876cb89eSGnoCiYeH } 670876cb89eSGnoCiYeH 671876cb89eSGnoCiYeH pub fn close_on_exec(&mut self) { 672876cb89eSGnoCiYeH for i in 0..FileDescriptorVec::PROCESS_MAX_FD { 673876cb89eSGnoCiYeH if let Some(file) = &self.fds[i] { 674dfe53cf0SGnoCiYeH let to_drop = file.close_on_exec(); 675876cb89eSGnoCiYeH if to_drop { 6764ad52e57S裕依2439 if let Err(r) = self.drop_fd(i as i32) { 6772eab6dd7S曾俊 error!( 678876cb89eSGnoCiYeH "Failed to close file: pid = {:?}, fd = {}, error = {:?}", 679876cb89eSGnoCiYeH ProcessManager::current_pcb().pid(), 680876cb89eSGnoCiYeH i, 681876cb89eSGnoCiYeH r 682876cb89eSGnoCiYeH ); 683876cb89eSGnoCiYeH } 684876cb89eSGnoCiYeH } 685876cb89eSGnoCiYeH } 686876cb89eSGnoCiYeH } 687876cb89eSGnoCiYeH } 688876cb89eSGnoCiYeH } 689876cb89eSGnoCiYeH 690876cb89eSGnoCiYeH #[derive(Debug)] 691876cb89eSGnoCiYeH pub struct FileDescriptorIterator<'a> { 692876cb89eSGnoCiYeH fds: &'a FileDescriptorVec, 693876cb89eSGnoCiYeH index: usize, 694876cb89eSGnoCiYeH } 695876cb89eSGnoCiYeH 696876cb89eSGnoCiYeH impl<'a> FileDescriptorIterator<'a> { 697876cb89eSGnoCiYeH pub fn new(fds: &'a FileDescriptorVec) -> Self { 698876cb89eSGnoCiYeH return Self { fds, index: 0 }; 699876cb89eSGnoCiYeH } 700876cb89eSGnoCiYeH } 701876cb89eSGnoCiYeH 702876cb89eSGnoCiYeH impl<'a> Iterator for FileDescriptorIterator<'a> { 703dfe53cf0SGnoCiYeH type Item = (i32, Arc<File>); 704876cb89eSGnoCiYeH 705876cb89eSGnoCiYeH fn next(&mut self) -> Option<Self::Item> { 706876cb89eSGnoCiYeH while self.index < FileDescriptorVec::PROCESS_MAX_FD { 707876cb89eSGnoCiYeH let fd = self.index as i32; 708876cb89eSGnoCiYeH self.index += 1; 709876cb89eSGnoCiYeH if let Some(file) = self.fds.get_file_by_fd(fd) { 710876cb89eSGnoCiYeH return Some((fd, file)); 711876cb89eSGnoCiYeH } 712876cb89eSGnoCiYeH } 713876cb89eSGnoCiYeH return None; 714876cb89eSGnoCiYeH } 715004e86ffSlogin } 716