diff --git a/src/kernel/src/fs/file.rs b/src/kernel/src/fs/file.rs index 6d0394854..9eb82052c 100644 --- a/src/kernel/src/fs/file.rs +++ b/src/kernel/src/fs/file.rs @@ -8,6 +8,7 @@ use crate::net::Socket; use crate::process::VThread; use crate::shm::SharedMemory; use bitflags::bitflags; +use gmtx::{Gutex, GutexGroup}; use macros::Errno; use std::fmt::Debug; use std::io::{ErrorKind, Read, Seek, SeekFrom}; @@ -17,17 +18,19 @@ use thiserror::Error; /// An implementation of `file` structure. #[derive(Debug)] pub struct VFile { - ty: VFileType, // f_type - flags: VFileFlags, // f_flag - offset: i64, // f_offset + ty: VFileType, // f_type + flags: VFileFlags, // f_flag + offset: Gutex, // f_offset } impl VFile { pub(super) fn new(ty: VFileType) -> Self { + let gg = GutexGroup::new(); + Self { ty, flags: VFileFlags::empty(), - offset: 0, + offset: gg.spawn(0), } } @@ -50,12 +53,7 @@ impl VFile { } /// See `dofileread` on the PS4 for a reference. - pub fn do_read( - &self, - mut uio: UioMut, - off: Offset, - td: Option<&VThread>, - ) -> Result> { + pub fn do_read(&self, mut uio: UioMut, td: Option<&VThread>) -> Result> { if uio.bytes_left == 0 { return Ok(0); } @@ -66,12 +64,7 @@ impl VFile { } /// See `dofilewrite` on the PS4 for a reference. - pub fn do_write( - &self, - mut uio: Uio, - off: Offset, - td: Option<&VThread>, - ) -> Result> { + pub fn do_write(&self, mut uio: Uio, td: Option<&VThread>) -> Result> { // TODO: consider implementing ktrace. // TODO: implement bwillwrite. @@ -154,7 +147,7 @@ impl Seek for VFile { } }; - self.offset = if let Ok(offset) = offset.try_into() { + *self.offset.write() = if let Ok(offset) = offset.try_into() { offset } else { todo!() @@ -164,13 +157,13 @@ impl Seek for VFile { } fn rewind(&mut self) -> std::io::Result<()> { - self.offset = 0; + *self.offset.write() = 0; Ok(()) } fn stream_position(&mut self) -> std::io::Result { - if let Ok(offset) = self.offset.try_into() { + if let Ok(offset) = (*self.offset.read()).try_into() { Ok(offset) } else { todo!() @@ -184,7 +177,9 @@ impl Read for VFile { let ref mut iovec = IoVec::from_slice(buf); - let mut uio = UioMut::from_single_vec(iovec, self.offset); + let mut offset = self.offset.write(); + + let mut uio = UioMut::from_single_vec(iovec, *offset); if let Err(e) = VFile::read(self, &mut uio, None) { println!("Error: {:?}", e); @@ -195,7 +190,7 @@ impl Read for VFile { let read = total - uio.bytes_left; if let Ok(read) = TryInto::::try_into(read) { - self.offset += read; + *offset += read; } else { todo!() } diff --git a/src/kernel/src/fs/mod.rs b/src/kernel/src/fs/mod.rs index dca97644d..c5747ae20 100644 --- a/src/kernel/src/fs/mod.rs +++ b/src/kernel/src/fs/mod.rs @@ -516,17 +516,15 @@ impl Fs { let iovec: *mut IoVec = i.args[1].into(); let count: u32 = i.args[2].try_into().unwrap(); - let uio = unsafe { UioMut::copyin(iovec, count) }?; - - self.readv(fd, uio, td) + todo!() } - fn readv(&self, fd: i32, uio: UioMut, td: &VThread) -> Result { + fn readv(&self, fd: i32, uio: UioMut, td: &VThread) -> Result { let file = td.proc().files().get_for_read(fd)?; - let read = file.do_read(uio, Offset::Current, Some(td))?; + let read = file.do_read(uio, Some(td))?; - Ok(read.into()) + Ok(read) } fn sys_writev(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -534,17 +532,15 @@ impl Fs { let iovec: *const IoVec = i.args[1].into(); let iovcnt: u32 = i.args[2].try_into().unwrap(); - let uio = unsafe { Uio::copyin(iovec, iovcnt) }?; - - self.writev(fd, uio, td) + todo!() } - fn writev(&self, fd: i32, uio: Uio, td: &VThread) -> Result { + fn writev(&self, fd: i32, uio: Uio, td: &VThread) -> Result { let file = td.proc().files().get_for_write(fd)?; - let written = file.do_write(uio, Offset::Current, Some(td))?; + let written = file.do_write(uio, Some(td))?; - Ok(written.into()) + Ok(written) } fn sys_stat(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -621,7 +617,9 @@ impl Fs { offset, }; - self.preadv(fd, uio, td) + let read = self.preadv(fd, uio, td)?; + + Ok(read.into()) } fn sys_pwrite(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -632,7 +630,15 @@ impl Fs { let iovec = unsafe { IoVec::try_from_raw_parts(ptr, len) }?; - todo!() + let uio = Uio { + vecs: &[iovec], + bytes_left: len, + offset, + }; + + let written = self.pwritev(fd, uio, td)?; + + Ok(written.into()) } fn sys_preadv(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -641,10 +647,14 @@ impl Fs { let count: u32 = i.args[2].try_into().unwrap(); let offset: i64 = i.args[3].into(); - todo!() + let uio = unsafe { UioMut::copyin(iovec, count, offset) }?; + + let read = self.preadv(fd, uio, td)?; + + Ok(read.into()) } - fn preadv(&self, fd: i32, uio: UioMut, td: &VThread) -> Result { + fn preadv(&self, fd: i32, uio: UioMut, td: &VThread) -> Result { let file = td.proc().files().get_for_read(fd)?; let vnode = file.seekable_vnode().ok_or(SysErr::Raw(ESPIPE))?; @@ -653,7 +663,9 @@ impl Fs { return Err(SysErr::Raw(EINVAL)); } - todo!() + let read = file.do_read(uio, Some(td))?; + + Ok(read) } fn sys_pwritev(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -662,19 +674,25 @@ impl Fs { let count: u32 = i.args[2].try_into().unwrap(); let offset: i64 = i.args[3].into(); - todo!() + let uio = unsafe { Uio::copyin(iovec, count, offset) }?; + + let written = self.pwritev(fd, uio, td)?; + + Ok(written.into()) } - fn pwritev(&self, fd: i32, uio: Uio, offset: i64, td: &VThread) -> Result { + fn pwritev(&self, fd: i32, uio: Uio, td: &VThread) -> Result { let file = td.proc().files().get_for_write(fd)?; let vnode = file.seekable_vnode().ok_or(SysErr::Raw(ESPIPE))?; - if offset < 0 && !vnode.is_character() { + if uio.offset < 0 && !vnode.is_character() { return Err(SysErr::Raw(EINVAL)); } - todo!() + let written = file.do_write(uio, Some(td))?; + + Ok(written) } fn sys_fstatat(self: &Arc, td: &VThread, i: &SysIn) -> Result { @@ -766,6 +784,7 @@ impl Fs { Ok(SysOut::ZERO) } + #[allow(unused_variables)] // Remove this when is implementing. fn truncate(&self, path: &VPath, length: i64, td: &VThread) -> Result<(), TruncateError> { let length: TruncateLength = length.try_into()?; diff --git a/src/kernel/src/fs/uio.rs b/src/kernel/src/fs/uio.rs index 0612bd678..847c22f44 100644 --- a/src/kernel/src/fs/uio.rs +++ b/src/kernel/src/fs/uio.rs @@ -9,7 +9,7 @@ const IOSIZE_MAX: usize = 0x7fffffff; pub struct IoVec<'a> { ptr: *const u8, len: usize, - _phantom: std::marker::PhantomData<&'a u8>, + _phantom: std::marker::PhantomData<&'a [u8]>, } impl<'a> IoVec<'a> { @@ -55,11 +55,16 @@ impl<'a> IoVec<'a> { pub struct Uio<'a> { pub(super) vecs: &'a [IoVec<'a>], // uio_iov + uio_iovcnt pub(super) bytes_left: usize, // uio_resid + pub(super) offset: i64, // uio_offset } impl<'a> Uio<'a> { /// See `copyinuio` on the PS4 for a reference. - pub unsafe fn copyin(first: *const IoVec<'a>, count: u32) -> Result { + pub unsafe fn copyin( + first: *const IoVec<'a>, + count: u32, + offset: i64, + ) -> Result { if count > UIO_MAXIOV { return Err(CopyInUioError::TooManyVecs); } @@ -73,7 +78,11 @@ impl<'a> Uio<'a> { } })?; - Ok(Self { vecs, bytes_left }) + Ok(Self { + vecs, + bytes_left, + offset, + }) } } @@ -85,7 +94,11 @@ pub struct UioMut<'a> { impl<'a> UioMut<'a> { /// See `copyinuio` on the PS4 for a reference. - pub unsafe fn copyin(first: *mut IoVec<'a>, count: u32) -> Result { + pub unsafe fn copyin( + first: *mut IoVec<'a>, + count: u32, + offset: i64, + ) -> Result { if count > UIO_MAXIOV { return Err(CopyInUioError::TooManyVecs); } @@ -99,7 +112,11 @@ impl<'a> UioMut<'a> { } })?; - todo!() + Ok(Self { + vecs, + bytes_left, + offset, + }) } pub fn from_single_vec(vec: &'a mut IoVec<'a>, offset: i64) -> Self { @@ -119,7 +136,7 @@ impl<'a> UioMut<'a> { for vec in self.vecs.iter_mut() { let written = func(vec, self.offset)?; - self.offset.checked_add_unsigned(written).unwrap(); + self.offset = self.offset.checked_add_unsigned(written).unwrap(); self.bytes_left -= written as usize; }