Skip to content

Commit

Permalink
Fixes offset related code (obhq#793)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuchAFuriousDeath committed Apr 1, 2024
1 parent 39175cc commit b36ca2f
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 48 deletions.
37 changes: 16 additions & 21 deletions src/kernel/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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<i64>, // 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),
}
}

Expand All @@ -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<usize, Box<dyn Errno>> {
pub fn do_read(&self, mut uio: UioMut, td: Option<&VThread>) -> Result<usize, Box<dyn Errno>> {
if uio.bytes_left == 0 {
return Ok(0);
}
Expand All @@ -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<usize, Box<dyn Errno>> {
pub fn do_write(&self, mut uio: Uio, td: Option<&VThread>) -> Result<usize, Box<dyn Errno>> {
// TODO: consider implementing ktrace.
// TODO: implement bwillwrite.

Expand Down Expand Up @@ -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!()
Expand All @@ -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<u64> {
if let Ok(offset) = self.offset.try_into() {
if let Ok(offset) = (*self.offset.read()).try_into() {
Ok(offset)
} else {
todo!()
Expand All @@ -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);
Expand All @@ -195,7 +190,7 @@ impl Read for VFile {
let read = total - uio.bytes_left;

if let Ok(read) = TryInto::<i64>::try_into(read) {
self.offset += read;
*offset += read;
} else {
todo!()
}
Expand Down
61 changes: 40 additions & 21 deletions src/kernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,35 +516,31 @@ 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<SysOut, SysErr> {
fn readv(&self, fd: i32, uio: UioMut, td: &VThread) -> Result<usize, SysErr> {
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<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
let fd: i32 = i.args[0].try_into().unwrap();
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<SysOut, SysErr> {
fn writev(&self, fd: i32, uio: Uio, td: &VThread) -> Result<usize, SysErr> {
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<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
Expand Down Expand Up @@ -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<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
Expand All @@ -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<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
Expand All @@ -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<SysOut, SysErr> {
fn preadv(&self, fd: i32, uio: UioMut, td: &VThread) -> Result<usize, SysErr> {
let file = td.proc().files().get_for_read(fd)?;

let vnode = file.seekable_vnode().ok_or(SysErr::Raw(ESPIPE))?;
Expand All @@ -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<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
Expand All @@ -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<SysOut, SysErr> {
fn pwritev(&self, fd: i32, uio: Uio, td: &VThread) -> Result<usize, SysErr> {
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<Self>, td: &VThread, i: &SysIn) -> Result<SysOut, SysErr> {
Expand Down Expand Up @@ -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()?;

Expand Down
29 changes: 23 additions & 6 deletions src/kernel/src/fs/uio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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<Self, CopyInUioError> {
pub unsafe fn copyin(
first: *const IoVec<'a>,
count: u32,
offset: i64,
) -> Result<Self, CopyInUioError> {
if count > UIO_MAXIOV {
return Err(CopyInUioError::TooManyVecs);
}
Expand All @@ -73,7 +78,11 @@ impl<'a> Uio<'a> {
}
})?;

Ok(Self { vecs, bytes_left })
Ok(Self {
vecs,
bytes_left,
offset,
})
}
}

Expand All @@ -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<Self, CopyInUioError> {
pub unsafe fn copyin(
first: *mut IoVec<'a>,
count: u32,
offset: i64,
) -> Result<Self, CopyInUioError> {
if count > UIO_MAXIOV {
return Err(CopyInUioError::TooManyVecs);
}
Expand All @@ -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 {
Expand All @@ -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;
}

Expand Down

0 comments on commit b36ca2f

Please sign in to comment.