From 708cc1c5ae349ef6fc13d25d17ccc3cbbd763298 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 13 Jun 2024 16:30:13 +0200 Subject: [PATCH] Use SYS_READ2 and SYS_WRITE2 for disk IO. --- src/disk/file.rs | 88 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/src/disk/file.rs b/src/disk/file.rs index d65c2a0e71..700d5ba8a9 100644 --- a/src/disk/file.rs +++ b/src/disk/file.rs @@ -1,59 +1,93 @@ use std::fs::{File, OpenOptions}; use std::io::{Read, Seek, SeekFrom, Write}; use std::path::Path; -use syscall::error::{Error, Result, EIO}; +use syscall::error::{Result, Error, EIO}; + +#[cfg(target_os = "redox")] +use std::os::fd::AsRawFd; use crate::disk::Disk; use crate::BLOCK_SIZE; -macro_rules! try_disk { - ($expr:expr) => { - match $expr { - Ok(val) => val, - Err(err) => { - eprintln!("Disk I/O Error: {}", err); - return Err(Error::new(EIO)); - } - } - }; -} - pub struct DiskFile { pub file: File, } +trait ResultExt { + type T; + fn or_eio(self) -> Result; +} +impl ResultExt for Result { + type T = T; + fn or_eio(self) -> Result { + match self { + Ok(t) => Ok(t), + Err(err) => { + eprintln!("RedoxFS: IO ERROR: {err}"); + Err(Error::new(EIO)) + } + } + } +} +impl ResultExt for std::io::Result { + type T = T; + fn or_eio(self) -> Result { + match self { + Ok(t) => Ok(t), + Err(err) => { + eprintln!("RedoxFS: IO ERROR: {err}"); + Err(Error::new(EIO)) + } + } + } +} + impl DiskFile { - pub fn open>(path: P) -> Result { - let file = try_disk!(OpenOptions::new().read(true).write(true).open(path)); + pub fn open(path: impl AsRef) -> Result { + let file = OpenOptions::new().read(true).write(true).open(path).or_eio()?; Ok(DiskFile { file }) } - pub fn create>(path: P, size: u64) -> Result { - let file = try_disk!(OpenOptions::new() + pub fn create(path: impl AsRef, size: u64) -> Result { + let file = OpenOptions::new() .read(true) .write(true) .create(true) - .open(path)); - try_disk!(file.set_len(size)); + .open(path) + .or_eio()?; + file.set_len(size).or_eio()?; Ok(DiskFile { file }) } } impl Disk for DiskFile { unsafe fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result { - try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE))); - let count = try_disk!(self.file.read(buffer)); - Ok(count) + #[cfg(target_os = "redox")] + unsafe { + syscall::syscall5(syscall::SYS_READ2, self.file.as_raw_fd() as usize, buffer.as_mut_ptr() as usize, buffer.len(), (block * BLOCK_SIZE) as usize, 0) + .or_eio() + } + #[cfg(not(target_os = "redox"))] + { + self.file.seek(SeekFrom::Start(block * BLOCK_SIZE)).or_eio()?; + self.file.read(buffer).or_eio() + } } unsafe fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result { - try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE))); - let count = try_disk!(self.file.write(buffer)); - Ok(count) + #[cfg(target_os = "redox")] + unsafe { + syscall::syscall5(syscall::SYS_WRITE2, self.file.as_raw_fd() as usize, buffer.as_ptr() as usize, buffer.len(), (block * BLOCK_SIZE) as usize, 0) + .or_eio() + } + #[cfg(not(target_os = "redox"))] + { + self.file.seek(SeekFrom::Start(block * BLOCK_SIZE)).or_eio()?; + self.file.write(buffer).or_eio() + } } fn size(&mut self) -> Result { - let size = try_disk!(self.file.seek(SeekFrom::End(0))); - Ok(size) + self.file.seek(SeekFrom::End(0)).or_eio() } }