Use Errno as RPC error type

This commit is contained in:
pjht 2024-10-04 12:34:30 -05:00
parent 55de5d8841
commit 581bb3524a
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
9 changed files with 81 additions and 86 deletions

30
Cargo.lock generated
View File

@ -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"

View File

@ -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" }

View File

@ -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<Self> {
pub fn new(mut disk: StdFile) -> Result<Self, Errno> {
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<P: AsRef<Path>>(&self, path: P) -> io::Result<u32> {
pub fn path_inode<P: AsRef<Path>>(&self, path: P) -> Result<u32, Errno> {
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<P: AsRef<Path>>(&self, path: P) -> io::Result<ReadDir> {
pub fn read_dir<P: AsRef<Path>>(&self, path: P) -> Result<ReadDir, Errno> {
let path = path.as_ref();
let inode = self.path_inode(path)?;
ReadDir::read_inode(self, inode, path.to_owned())
}
#[allow(unused)]
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
pub fn open<P: AsRef<Path>>(&self, path: P) -> Result<File, Errno> {
File::from_inode(Inode::read(self, self.path_inode(path)?)?, self)
}
#[allow(unused)]
pub fn metadata<P: AsRef<Path>>(&self, path: P) -> io::Result<Metadata> {
pub fn metadata<P: AsRef<Path>>(&self, path: P) -> Result<Metadata, Errno> {
Inode::read(self, self.path_inode(path)?).map(|x| Metadata::from_inode(&x))
}
}

View File

@ -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<Self> {
pub fn new(superblock: &Superblock, reader: &BlockReader) -> Result<Self, Errno> {
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<Inode> {
pub fn read(&self, reader: &BlockReader) -> Result<Inode, Errno> {
//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");
}
}

View File

@ -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<Cursor<Vec<u8>>> {
pub fn read_block(&self, block: u32) -> Result<Cursor<Vec<u8>>, 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<Cursor<Vec<u8>>> {
pub fn read_block_offset(&self, block: u32, offset: u32) -> Result<Cursor<Vec<u8>>, 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<Cursor<Vec<u8>>> {
pub fn read_blocks(&self, block: u32, count: usize) -> Result<Cursor<Vec<u8>>, Errno> {
let mut disk = &self.disk;
let start = self.block_to_byte_offset(block);
let size = self.block_size * count;

View File

@ -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<File> {
pub fn open(&self) -> Result<File, Errno> {
File::from_inode(Inode::read(self.fs, self.inode)?, self.fs)
}
pub fn read_dir(&self) -> io::Result<ReadDir<'a>> {
pub fn read_dir(&self) -> Result<ReadDir<'a>, 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<ReadDir<'a>> {
pub fn read_inode(fs: &'a Ext2, inode: u32, path: PathBuf) -> Result<ReadDir<'a>, 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<DirEntry<'a>> {
pub(super) fn get_entry(mut self, name: &OsStr) -> Result<DirEntry<'a>, 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<Option<DirEntry<'a>>> {
fn next_impl(&mut self) -> Result<Option<DirEntry<'a>>, 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<DirEntry<'a>>;
type Item = Result<DirEntry<'a>, Errno>;
fn next(&mut self) -> Option<Self::Item> {
self.next_impl().transpose()
}

View File

@ -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<Self> {
pub(super) fn from_inode(inode: Inode, fs: &Ext2) -> Result<Self, Errno> {
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<Self> {
pub(super) fn from_inode_dir(inode: Inode, fs: &Ext2) -> Result<Self, Errno> {
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<usize> {
pub fn read_at(&self, buf: &mut [u8], pos: u64, fs: &Ext2) -> Result<usize, Errno> {
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<u64> {
fn seek(&mut self, pos: io::SeekFrom) -> Result<u64, io::Error> {
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<usize> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
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?)
}
}

View File

@ -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<Self> {
disk.seek(SeekFrom::Start(1024))?;
pub fn read_from_disk(disk: &mut StdFile) -> Result<Self, Errno> {
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<Self> {
pub fn read(reader: &mut (impl Read + Seek)) -> Result<Self, Errno> {
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<Self> {
pub(super) fn read(fs: &Ext2, inode_num: u32) -> Result<Self, Errno> {
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<Vec<u32>> {
pub fn pointer_block_blocks(&self, block_no: u32, fs: &Ext2) -> Result<Vec<u32>, Errno> {
if let Some(block) = fs.ind_block_cache.read().get(&block_no) {
return Ok(block.clone());
}

View File

@ -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<u64, ()> {
let disk = File::open(dev).map_err(|_| ())?;
let fs = Ext2::new(disk).map_err(|_| ())?;
fn mount(&self, dev: &std::path::Path) -> Result<u64, Errno> {
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>, u64), ()> {
fn open(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option<u64>, 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>, u64), ()> {
fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option<u64>, 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::<Result<Vec<_>, _>>().map_err(|_| ())?;
let entries = mount.read_dir(path)?.map_ok(|x| x.file_name()).collect::<Result<Vec<_>, _>>()?;
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<Cow<'_, [u8]>, ()> {
fn read(&self, fd: u64, len: usize) -> Result<Cow<'_, [u8]>, 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<u64> {
fn size(&self, fd: u64) -> Result<u64, Errno> {
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<u64> {
fn dup(&self, fd: u64) -> Result<u64, Errno> {
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<u64, Errno> {
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<Option<String>, ()> {
fn next_entry(&self, fd: u64) -> Result<Option<String>, 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() {