From 581bb3524a6baa0a94c91cdb688b2d9f52817292 Mon Sep 17 00:00:00 2001 From: pjht Date: Fri, 4 Oct 2024 12:34:30 -0500 Subject: [PATCH] Use Errno as RPC error type --- Cargo.lock | 30 +++++++++++-------------- Cargo.toml | 4 ++++ src/ext2.rs | 16 ++++++------- src/ext2/block_group_table.rs | 11 ++++----- src/ext2/block_reader.rs | 9 ++++---- src/ext2/dir.rs | 23 +++++++++---------- src/ext2/file.rs | 17 +++++++------- src/ext2/structs.rs | 15 +++++++------ src/main.rs | 42 +++++++++++++++++------------------ 9 files changed, 81 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57eb766..0c218fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "binread" @@ -165,9 +165,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "lock_api" @@ -247,9 +247,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] @@ -283,22 +283,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +version = "1.0.210" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +version = "1.0.210" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -335,9 +331,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -362,9 +358,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "vfs_rpc" diff --git a/Cargo.toml b/Cargo.toml index 7cf5ae1..c8234b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,7 @@ itertools = "0.13.0" parking_lot = "0.12.3" syslog_rpc = { version = "0.1.0", path = "../syslog/syslog_rpc" } vfs_rpc = { version = "0.1.0", path = "../vfs/vfs_rpc" } + +[patch.crates-io] +serde = { path = "../serde/serde" } +serde_derive = { path = "../serde/serde_derive" } diff --git a/src/ext2.rs b/src/ext2.rs index 2a8094e..5f47548 100644 --- a/src/ext2.rs +++ b/src/ext2.rs @@ -10,6 +10,7 @@ use block_reader::BlockReader; use parking_lot::RwLock; use std::collections::HashMap; use std::io; +use std::os::mikros::Errno; use std::path::{Path, PathBuf}; use structs::{DirEntryDisk, Inode, Superblock}; @@ -28,7 +29,7 @@ pub struct Ext2 { } impl Ext2 { - pub fn new(mut disk: StdFile) -> io::Result { + pub fn new(mut disk: StdFile) -> Result { let superblock = Superblock::read_from_disk(&mut disk)?; let reader = BlockReader::new(disk, &superblock); Ok(Self { @@ -40,7 +41,7 @@ impl Ext2 { }) } - pub fn path_inode>(&self, path: P) -> io::Result { + pub fn path_inode>(&self, path: P) -> Result { let path = path.as_ref(); let dentry = { self.dentry_cache.read().get(path).cloned() }; if let Some(dentry) = dentry { @@ -49,10 +50,7 @@ impl Ext2 { } else if let Some(parent) = path.parent() { //println!("Dentry {}: Not in cache", path.display()); let file_name = path.file_name().ok_or_else(|| { - io::Error::new( - io::ErrorKind::Other, - "A path ending in .. or . was passed to path_inode", - ) + io::Error::from_raw_os_error(Errno::EINVAL) })?; let dir_inode = self.path_inode(parent)?; let dir = ReadDir::read_inode(self, dir_inode, parent.to_owned())?; @@ -64,19 +62,19 @@ impl Ext2 { } #[allow(unused)] - pub fn read_dir>(&self, path: P) -> io::Result { + pub fn read_dir>(&self, path: P) -> Result { let path = path.as_ref(); let inode = self.path_inode(path)?; ReadDir::read_inode(self, inode, path.to_owned()) } #[allow(unused)] - pub fn open>(&self, path: P) -> io::Result { + pub fn open>(&self, path: P) -> Result { File::from_inode(Inode::read(self, self.path_inode(path)?)?, self) } #[allow(unused)] - pub fn metadata>(&self, path: P) -> io::Result { + pub fn metadata>(&self, path: P) -> Result { Inode::read(self, self.path_inode(path)?).map(|x| Metadata::from_inode(&x)) } } diff --git a/src/ext2/block_group_table.rs b/src/ext2/block_group_table.rs index 40331d4..c917580 100644 --- a/src/ext2/block_group_table.rs +++ b/src/ext2/block_group_table.rs @@ -3,7 +3,7 @@ use super::{ structs::{BlockGroupDescriptor, Inode, Superblock}, }; use binread::prelude::*; -use std::io; +use std::{io, os::mikros::Errno}; use std::vec::Vec; const INODE_SIZE: usize = 256; @@ -20,7 +20,7 @@ pub struct BlockGroupDescriptorTable { } impl BlockGroupDescriptorTable { - pub fn new(superblock: &Superblock, reader: &BlockReader) -> io::Result { + pub fn new(superblock: &Superblock, reader: &BlockReader) -> Result { let num_block_groups = superblock .total_blocks .div_ceil(superblock.block_group_block_count) as usize; @@ -69,15 +69,12 @@ pub struct InodeLoc { } impl InodeLoc { - pub fn read(&self, reader: &BlockReader) -> io::Result { + pub fn read(&self, reader: &BlockReader) -> Result { //println!("InodeLoc::read"); reader .read_block_offset(self.block, self.byte_offset as u32)? .read_le_args((self.num,)) - .map_err(|err| match err { - binread::Error::Io(_) => io::Error::new(io::ErrorKind::Other, "Binread IO error"), - _ => io::Error::new(io::ErrorKind::InvalidData, "Inode data was invalid"), - }) + .map_err(|_| Errno::EIO) //println!("InodeLoc::read done"); } } diff --git a/src/ext2/block_reader.rs b/src/ext2/block_reader.rs index c6948cb..d964263 100644 --- a/src/ext2/block_reader.rs +++ b/src/ext2/block_reader.rs @@ -1,8 +1,9 @@ +use std::os::mikros::Errno; use std::vec::Vec; use super::structs::Superblock; use std::fs::File as StdFile; -use std::io::{self, Cursor, Read, Seek, SeekFrom}; +use std::io::{Cursor, Read, Seek, SeekFrom}; #[derive(Debug)] pub struct BlockReader { @@ -18,7 +19,7 @@ impl BlockReader { } } - pub fn read_block(&self, block: u32) -> io::Result>> { + pub fn read_block(&self, block: u32) -> Result>, Errno> { //println!("Read block {}", block); let mut disk = &self.disk; let start = self.block_to_byte_offset(block); @@ -29,13 +30,13 @@ impl BlockReader { Ok(Cursor::new(vec)) } - pub fn read_block_offset(&self, block: u32, offset: u32) -> io::Result>> { + pub fn read_block_offset(&self, block: u32, offset: u32) -> Result>, Errno> { let block = self.read_block(block)?.into_inner(); let trunc_block = block[(offset as usize)..].to_vec(); Ok(Cursor::new(trunc_block)) } - pub fn read_blocks(&self, block: u32, count: usize) -> io::Result>> { + pub fn read_blocks(&self, block: u32, count: usize) -> Result>, Errno> { let mut disk = &self.disk; let start = self.block_to_byte_offset(block); let size = self.block_size * count; diff --git a/src/ext2/dir.rs b/src/ext2/dir.rs index 9498d7c..9aeb38e 100644 --- a/src/ext2/dir.rs +++ b/src/ext2/dir.rs @@ -4,7 +4,7 @@ use super::{ structs::{DirEntryDisk, Inode}, Ext2, }; -use std::string::String; +use std::{os::mikros::Errno, string::String}; use std::{ffi::OsStr, io, os::mikros::ffi::OsStrExt}; use std::{io::BufReader, path::PathBuf}; @@ -73,11 +73,11 @@ impl<'a> DirEntry<'a> { self.directory_path.join(self.name.clone()) } - pub fn open(&self) -> io::Result { + pub fn open(&self) -> Result { File::from_inode(Inode::read(self.fs, self.inode)?, self.fs) } - pub fn read_dir(&self) -> io::Result> { + pub fn read_dir(&self) -> Result, Errno> { ReadDir::read_inode(self.fs, self.inode, self.path()) } } @@ -105,7 +105,7 @@ pub struct ReadDir<'a> { } impl<'a> ReadDir<'a> { - pub fn read_inode(fs: &'a Ext2, inode: u32, path: PathBuf) -> io::Result> { + pub fn read_inode(fs: &'a Ext2, inode: u32, path: PathBuf) -> Result, Errno> { Ok(Self { fs, file: BufReader::with_capacity( @@ -116,7 +116,7 @@ impl<'a> ReadDir<'a> { }) } - pub(super) fn get_entry(mut self, name: &OsStr) -> io::Result> { + pub(super) fn get_entry(mut self, name: &OsStr) -> Result, Errno> { self.find(|entry| { if let Ok(entry) = entry { entry.name.as_bytes() == name.as_bytes() @@ -124,14 +124,14 @@ impl<'a> ReadDir<'a> { true } }) - .unwrap_or_else(|| Err(io::Error::new(io::ErrorKind::NotFound, "File not found"))) + .unwrap_or_else(|| Err(Errno::ENOENT)) } - fn next_impl(&mut self) -> io::Result>> { + fn next_impl(&mut self) -> Result>, Errno> { let entry: DirEntryDisk = match DirEntryDisk::read(&mut self.file) { Ok(entry) => entry, Err(error) => { - return if error.kind() == io::ErrorKind::UnexpectedEof { + return if error == Errno::EEOF { Ok(None) } else { Err(error) @@ -139,10 +139,7 @@ impl<'a> ReadDir<'a> { } }; let name = String::from_utf8(entry.name.clone()).map_err(|_| { - io::Error::new( - io::ErrorKind::InvalidData, - "Non UTF-8 directory entry names are unspported", - ) + io::Error::from_raw_os_error(Errno::EINVAL) })?; if name == "." || name == ".." || entry.inode == 0 { return self.next_impl(); @@ -163,7 +160,7 @@ impl<'a> ReadDir<'a> { } impl<'a> Iterator for ReadDir<'a> { - type Item = io::Result>; + type Item = Result, Errno>; fn next(&mut self) -> Option { self.next_impl().transpose() } diff --git a/src/ext2/file.rs b/src/ext2/file.rs index 7b441f1..824c27a 100644 --- a/src/ext2/file.rs +++ b/src/ext2/file.rs @@ -2,6 +2,7 @@ use super::Ext2; use super::{structs::Inode, Metadata}; use std::cmp::Ordering; use std::io::{self, Read}; +use std::os::mikros::Errno; /// A reference to an open file on the filesystem. /// @@ -18,9 +19,9 @@ pub struct File { } impl File { - pub(super) fn from_inode(inode: Inode, fs: &Ext2) -> io::Result { + pub(super) fn from_inode(inode: Inode, fs: &Ext2) -> Result { if !Metadata::from_inode(&inode).file_type().is_file() { - return Err(io::Error::new(io::ErrorKind::Other, "Not a file")); + return Err(Errno::EISDIR); } Ok(Self { block_size: fs.reader.block_size, @@ -30,9 +31,9 @@ impl File { /// This version of `from_inode` skips checks that the provided inode is a directory, not a file. It /// should, only be used by `ReadDir::read_inode` to read the raw directory data. - pub(super) fn from_inode_dir(inode: Inode, fs: &Ext2) -> io::Result { + pub(super) fn from_inode_dir(inode: Inode, fs: &Ext2) -> Result { if !Metadata::from_inode(&inode).file_type().is_dir() { - return Err(io::Error::new(io::ErrorKind::Other, "Not a directory")); + return Err(Errno::ENOTDIR); } Ok(Self { block_size: fs.reader.block_size, @@ -46,7 +47,7 @@ impl File { Metadata::from_inode(&self.inode) } - pub fn read_at(&self, buf: &mut [u8], pos: u64, fs: &Ext2) -> io::Result { + pub fn read_at(&self, buf: &mut [u8], pos: u64, fs: &Ext2) -> Result { let bytes_to_end = u64::from(self.inode.size_lower32).saturating_sub(pos); if bytes_to_end == 0 { return Ok(0); @@ -114,7 +115,7 @@ impl<'a> FileReader<'a> { } impl io::Seek for FileReader<'_> { - fn seek(&mut self, pos: io::SeekFrom) -> io::Result { + fn seek(&mut self, pos: io::SeekFrom) -> Result { match pos { io::SeekFrom::Start(x) => self.pos = x, io::SeekFrom::End(x) => match x.cmp(&0) { @@ -135,11 +136,11 @@ impl io::Seek for FileReader<'_> { } impl io::Read for FileReader<'_> { - fn read(&mut self, buf: &mut [u8]) -> io::Result { + fn read(&mut self, buf: &mut [u8]) -> Result { let res = self.file.read_at(buf, self.pos, &self.fs); if let Ok(bytes_read) = res { self.pos += bytes_read as u64; } - res + Ok(res?) } } diff --git a/src/ext2/structs.rs b/src/ext2/structs.rs index 8551049..98d1e28 100644 --- a/src/ext2/structs.rs +++ b/src/ext2/structs.rs @@ -2,6 +2,7 @@ use super::{block_reader::BlockReader, Ext2}; use binread::prelude::*; use itertools::Itertools; use std::io::{self, Cursor, Read, Seek, SeekFrom}; +use std::os::mikros::Errno; use std::vec::Vec; use std::fs::File as StdFile; @@ -56,10 +57,10 @@ pub struct Superblock { } impl Superblock { - pub fn read_from_disk(disk: &mut StdFile) -> io::Result { - disk.seek(SeekFrom::Start(1024))?; + pub fn read_from_disk(disk: &mut StdFile) -> Result { + disk.seek(SeekFrom::Start(1024)).map_err(|e| e.raw_os_error().unwrap())?; let mut bytes = vec![0; 1024]; - disk.read_exact(&mut bytes)?; + disk.read_exact(&mut bytes).map_err(|e| e.raw_os_error().unwrap())?; let sblock = Cursor::new(bytes).read_le().unwrap(); //dbg!(&sblock); Ok(sblock) @@ -88,7 +89,7 @@ pub struct DirEntryDisk { } impl DirEntryDisk { - pub fn read(reader: &mut (impl Read + Seek)) -> io::Result { + pub fn read(reader: &mut (impl Read + Seek)) -> Result { let mut inode = [0u8; 4]; reader.read_exact(&mut inode)?; let inode = u32::from_le_bytes(inode); @@ -102,7 +103,7 @@ impl DirEntryDisk { reader.read_exact(&mut high_len_or_type)?; let high_len_or_type = high_len_or_type[0]; let mut name = vec![0; name_len as usize]; - reader.read_exact(&mut name)?; + reader.read_exact(&mut name).map_err(|e| e.raw_os_error().unwrap())?; reader.seek_relative(i64::from(entry_size - u16::from(name_len) - 8))?; //dbg!(inode, entry_size, &name); Ok(Self { @@ -145,7 +146,7 @@ pub struct Inode { } impl Inode { - pub(super) fn read(fs: &Ext2, inode_num: u32) -> io::Result { + pub(super) fn read(fs: &Ext2, inode_num: u32) -> Result { if let Some(ino) = fs.inode_cache.read().get(&inode_num) { //println!("Inode {}: In cache", inode_num); return Ok(ino.clone()); @@ -156,7 +157,7 @@ impl Inode { Ok(ino) } - pub fn pointer_block_blocks(&self, block_no: u32, fs: &Ext2) -> io::Result> { + pub fn pointer_block_blocks(&self, block_no: u32, fs: &Ext2) -> Result, Errno> { if let Some(block) = fs.ind_block_cache.read().get(&block_no) { return Ok(block.clone()); } diff --git a/src/main.rs b/src/main.rs index afbc1be..7f96dd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ mod ext2; use std::{ borrow::Cow, fs::File, - os::mikros::{ipc, syscalls}, + os::mikros::{ipc, syscalls, Errno}, sync::Arc, usize, }; @@ -26,18 +26,18 @@ struct Serv { } impl fs_rpc::Server for Serv { - fn mount(&self, dev: &std::path::Path) -> Result { - let disk = File::open(dev).map_err(|_| ())?; - let fs = Ext2::new(disk).map_err(|_| ())?; + fn mount(&self, dev: &std::path::Path) -> Result { + let disk = File::open(dev)?; + let fs = Ext2::new(disk)?; self.mounts.write().push(fs); let res = Ok((self.mounts.read().len() - 1) as u64); res } - fn open(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option, u64), ()> { + fn open(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option, u64), Errno> { let mounts = self.mounts.read(); let mount = &mounts[mount_id as usize]; - let file = mount.open(path).map_err(|_| ())?; + let file = mount.open(path)?; self.files.write().push(OpenFile { file, pos: 0, @@ -47,10 +47,10 @@ impl fs_rpc::Server for Serv { res } - fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option, u64), ()> { + fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option, u64), Errno> { let mounts = self.mounts.read(); let mount = &mounts[mount_id as usize]; - let entries = mount.read_dir(path).map_err(|_| ())?.map_ok(|x| x.file_name()).collect::, _>>().map_err(|_| ())?; + let entries = mount.read_dir(path)?.map_ok(|x| x.file_name()).collect::, _>>()?; self.dirs .write() .push((entries, 0)); @@ -60,39 +60,39 @@ impl fs_rpc::Server for Serv { } impl file_rpc::Server for Serv { - fn read(&self, fd: u64, len: usize) -> Result, ()> { + fn read(&self, fd: u64, len: usize) -> Result, Errno> { let files = self.files.read(); let file = &files[fd as usize]; let mounts = self.mounts.read(); let mount = &mounts[file.mount_id]; let mut buf = vec![0; len]; - let read_len = file.file.read_at(&mut buf, file.pos, mount).map_err(|_| ())?; + let read_len = file.file.read_at(&mut buf, file.pos, mount)?; buf.truncate(read_len); std::mem::drop(files); self.files.write()[fd as usize].pos += read_len as u64; Ok(buf.into()) } - fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> { - Err(()) + fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), Errno> { + Err(Errno::ENOTSUP) } - fn close(&self, _fd: u64) {} + fn close(&self, _fd: u64) -> Result<(), Errno> { Ok(()) } - fn size(&self, fd: u64) -> Option { + fn size(&self, fd: u64) -> Result { let files = self.files.read(); let file = &files[fd as usize]; - Some(file.file.metadata().len()) + Ok(file.file.metadata().len()) } - fn dup(&self, fd: u64) -> Option { + fn dup(&self, fd: u64) -> Result { let mut files = self.files.write(); let file = files[fd as usize].clone(); files.push(file); - Some((files.len() - 1) as u64) + Ok((files.len() - 1) as u64) } - fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> u64 { + fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> Result { let mut files = self.files.write(); let file = &mut files[fd as usize]; match pos { @@ -117,12 +117,12 @@ impl file_rpc::Server for Serv { } }, } - file.pos + Ok(file.pos) } } impl dir_rpc::Server for Serv { - fn next_entry(&self, fd: u64) -> Result, ()> { + fn next_entry(&self, fd: u64) -> Result, Errno> { let dirs = self.dirs.write(); let &(ref entries, entry_no) = &dirs[fd as usize]; if entry_no == entries.len() { @@ -134,7 +134,7 @@ impl dir_rpc::Server for Serv { Ok(Some(entry)) } - fn close(&self, _fd: u64) {} + fn close(&self, _fd: u64) -> Result<(), Errno> { Ok(()) } } fn main() {