refactor: fix all warnings

This commit is contained in:
2022-02-09 18:51:41 +02:00
parent 0f9f8fc1bf
commit a7a1639ff7
30 changed files with 368 additions and 306 deletions
+161 -161
View File
@@ -1,162 +1,162 @@
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;
// extern crate proc_macro;
// extern crate syn;
// #[macro_use]
// extern crate quote;
//
// use proc_macro::TokenStream;
// use quote::ToTokens;
// use std::collections::HashSet;
// use syn::{parse_macro_input, ImplItem, ItemImpl, Ident};
use proc_macro::TokenStream;
use quote::ToTokens;
use std::collections::HashSet;
use syn::{parse_macro_input, ImplItem, ItemImpl, Ident};
fn impl_inode_fn<T: ToTokens>(name: &str, behavior: T) -> ImplItem {
// TODO somehow know if current crate is vfs or not?
ImplItem::Verbatim(match name {
"create" => quote! {
fn create(&mut self, _at: VnodeRef, _name: &str, kind: VnodeKind) ->
Result<VnodeRef, libsys::error::Errno>
{
#behavior
}
},
"remove" => quote! {
fn remove(&mut self, _at: VnodeRef, _name: &str) -> Result<(), libsys::error::Errno> {
#behavior
}
},
"lookup" => quote! {
fn lookup(&mut self, _at: VnodeRef, _name: &str) ->
Result<VnodeRef, libsys::error::Errno>
{
#behavior
}
},
"stat" => quote! {
fn stat(&mut self, _at: VnodeRef) ->
Result<libsys::stat::Stat, libsys::error::Errno>
{
#behavior
}
},
"truncate" => quote! {
fn truncate(&mut self, _node: VnodeRef, _size: usize) ->
Result<(), libsys::error::Errno>
{
#behavior
}
},
"size" => quote! {
fn size(&mut self, _node: VnodeRef) -> Result<usize, libsys::error::Errno> {
#behavior
}
},
"read" => quote! {
fn read(&mut self, _node: VnodeRef, _pos: usize, _data: &mut [u8]) ->
Result<usize, libsys::error::Errno>
{
#behavior
}
},
"write" => quote! {
fn write(&mut self, _node: VnodeRef, _pos: usize, _data: &[u8]) ->
Result<usize, libsys::error::Errno>
{
#behavior
}
},
"open" => quote! {
fn open(&mut self, _node: VnodeRef, _flags: libsys::stat::OpenFlags) ->
Result<usize, libsys::error::Errno>
{
#behavior
}
},
"close" => quote! {
fn close(&mut self, _node: VnodeRef) -> Result<(), libsys::error::Errno> {
#behavior
}
},
"ioctl" => quote! {
fn ioctl(
&mut self,
_node: VnodeRef,
_cmd: libsys::ioctl::IoctlCmd,
_ptr: usize,
_len: usize) ->
Result<usize, libsys::error::Errno>
{
#behavior
}
},
"is_ready" => quote! {
fn is_ready(&mut self, _node: VnodeRef, _write: bool) ->
Result<bool, libsys::error::Errno>
{
#behavior
}
},
"readdir" => quote! {
fn readdir(
&mut self,
_node: VnodeRef,
_pos: usize,
_entries: &mut [libsys::stat::DirectoryEntry]
) ->
Result<usize, libsys::error::Errno>
{
#behavior
}
},
_ => panic!("TODO implement {:?}", name),
})
}
#[proc_macro_attribute]
pub fn auto_inode(attr: TokenStream, input: TokenStream) -> TokenStream {
let mut impl_item = parse_macro_input!(input as ItemImpl);
let mut missing = HashSet::<String>::new();
let behavior = if attr.is_empty() {
"unimplemented".to_string()
} else {
parse_macro_input!(attr as Ident).to_string()
};
let behavior = match behavior.as_str() {
"unimplemented" => quote! { unimplemented!() },
"panic" => quote! { panic!() },
"error" => quote! { Err(libsys::error::Errno::NotImplemented) },
_ => panic!("Unknown #[auto_inode] behavior: {:?}", behavior)
};
missing.insert("create".to_string());
missing.insert("remove".to_string());
missing.insert("lookup".to_string());
missing.insert("open".to_string());
missing.insert("close".to_string());
missing.insert("truncate".to_string());
missing.insert("read".to_string());
missing.insert("write".to_string());
missing.insert("stat".to_string());
missing.insert("size".to_string());
missing.insert("ioctl".to_string());
missing.insert("is_ready".to_string());
missing.insert("readdir".to_string());
for item in &impl_item.items {
match item {
ImplItem::Method(method) => {
let name = &method.sig.ident.to_string();
if missing.contains(name) {
missing.remove(name);
}
}
_ => panic!("Unexpected impl item"),
}
}
for item in &missing {
impl_item
.items
.push(impl_inode_fn(item, behavior.clone()));
}
impl_item.to_token_stream().into()
}
//fn impl_inode_fn<T: ToTokens>(name: &str, behavior: T) -> ImplItem {
// // TODO somehow know if current crate is vfs or not?
// ImplItem::Verbatim(match name {
// "create" => quote! {
// fn create(&mut self, _at: VnodeRef, _name: &str, kind: VnodeKind) ->
// Result<VnodeRef, libsys::error::Errno>
// {
// #behavior
// }
// },
// "remove" => quote! {
// fn remove(&mut self, _at: VnodeRef, _name: &str) -> Result<(), libsys::error::Errno> {
// #behavior
// }
// },
// "lookup" => quote! {
// fn lookup(&mut self, _at: VnodeRef, _name: &str) ->
// Result<VnodeRef, libsys::error::Errno>
// {
// #behavior
// }
// },
// "stat" => quote! {
// fn stat(&mut self, _at: VnodeRef) ->
// Result<libsys::stat::Stat, libsys::error::Errno>
// {
// #behavior
// }
// },
// "truncate" => quote! {
// fn truncate(&mut self, _node: VnodeRef, _size: usize) ->
// Result<(), libsys::error::Errno>
// {
// #behavior
// }
// },
// "size" => quote! {
// fn size(&mut self, _node: VnodeRef) -> Result<usize, libsys::error::Errno> {
// #behavior
// }
// },
// "read" => quote! {
// fn read(&mut self, _node: VnodeRef, _pos: usize, _data: &mut [u8]) ->
// Result<usize, libsys::error::Errno>
// {
// #behavior
// }
// },
// "write" => quote! {
// fn write(&mut self, _node: VnodeRef, _pos: usize, _data: &[u8]) ->
// Result<usize, libsys::error::Errno>
// {
// #behavior
// }
// },
// "open" => quote! {
// fn open(&mut self, _node: VnodeRef, _flags: libsys::stat::OpenFlags) ->
// Result<usize, libsys::error::Errno>
// {
// #behavior
// }
// },
// "close" => quote! {
// fn close(&mut self, _node: VnodeRef) -> Result<(), libsys::error::Errno> {
// #behavior
// }
// },
// "ioctl" => quote! {
// fn ioctl(
// &mut self,
// _node: VnodeRef,
// _cmd: libsys::ioctl::IoctlCmd,
// _ptr: usize,
// _len: usize) ->
// Result<usize, libsys::error::Errno>
// {
// #behavior
// }
// },
// "is_ready" => quote! {
// fn is_ready(&mut self, _node: VnodeRef, _write: bool) ->
// Result<bool, libsys::error::Errno>
// {
// #behavior
// }
// },
// "readdir" => quote! {
// fn readdir(
// &mut self,
// _node: VnodeRef,
// _pos: usize,
// _entries: &mut [libsys::stat::DirectoryEntry]
// ) ->
// Result<usize, libsys::error::Errno>
// {
// #behavior
// }
// },
// _ => panic!("TODO implement {:?}", name),
// })
//}
//
//#[proc_macro_attribute]
//pub fn auto_inode(attr: TokenStream, input: TokenStream) -> TokenStream {
// let mut impl_item = parse_macro_input!(input as ItemImpl);
// let mut missing = HashSet::<String>::new();
// let behavior = if attr.is_empty() {
// "unimplemented".to_string()
// } else {
// parse_macro_input!(attr as Ident).to_string()
// };
// let behavior = match behavior.as_str() {
// "unimplemented" => quote! { unimplemented!() },
// "panic" => quote! { panic!() },
// "error" => quote! { Err(libsys::error::Errno::NotImplemented) },
// _ => panic!("Unknown #[auto_inode] behavior: {:?}", behavior)
// };
//
// missing.insert("create".to_string());
// missing.insert("remove".to_string());
// missing.insert("lookup".to_string());
// missing.insert("open".to_string());
// missing.insert("close".to_string());
// missing.insert("truncate".to_string());
// missing.insert("read".to_string());
// missing.insert("write".to_string());
// missing.insert("stat".to_string());
// missing.insert("size".to_string());
// missing.insert("ioctl".to_string());
// missing.insert("is_ready".to_string());
// missing.insert("readdir".to_string());
//
// for item in &impl_item.items {
// match item {
// ImplItem::Method(method) => {
// let name = &method.sig.ident.to_string();
// if missing.contains(name) {
// missing.remove(name);
// }
// }
// _ => panic!("Unexpected impl item"),
// }
// }
//
// for item in &missing {
// impl_item
// .items
// .push(impl_inode_fn(item, behavior.clone()));
// }
//
// impl_item.to_token_stream().into()
//}
+3
View File
@@ -11,6 +11,9 @@ pub struct BlockRef<'a, A: BlockAllocator + Copy> {
alloc: MaybeUninit<A>,
}
/// # Safety
///
/// This trait is unsafe to implement due to its direct memory management
pub unsafe trait BlockAllocator {
fn alloc(&self) -> *mut u8;
/// # Safety
+9 -10
View File
@@ -18,7 +18,6 @@ impl<A: BlockAllocator + Copy + 'static> VnodeDirectory for DirInode<A> {
let data = match kind {
VnodeCreateKind::Directory => VnodeData::Directory(RefCell::new(Some(Box::new(DirInode { alloc: self.alloc })))),
VnodeCreateKind::File => VnodeData::File(RefCell::new(Some(Box::new(FileInode::new(Bvec::new(self.alloc)))))),
_ => todo!()
};
Ok(Vnode::new(name, data, Vnode::SEEKABLE | Vnode::CACHE_READDIR))
// match kind {
@@ -38,9 +37,9 @@ impl<A: BlockAllocator + Copy + 'static> VnodeDirectory for DirInode<A> {
/// Read directory entries into target buffer
fn readdir(
&mut self,
node: VnodeRef,
pos: usize,
data: &mut [DirectoryEntry],
_node: VnodeRef,
_pos: usize,
_data: &mut [DirectoryEntry],
) -> Result<usize, Errno> {
todo!()
}
@@ -59,21 +58,21 @@ impl<A: BlockAllocator + Copy + 'static> VnodeCommon for DirInode<A> {
/// Performs filetype-specific request
fn ioctl(
&mut self,
node: VnodeRef,
cmd: IoctlCmd,
ptr: usize,
len: usize,
_node: VnodeRef,
_cmd: IoctlCmd,
_ptr: usize,
_len: usize,
) -> Result<usize, Errno> {
todo!()
}
/// Reports the size of this filesystem object in bytes
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno> {
fn size(&mut self, _node: VnodeRef) -> Result<usize, Errno> {
todo!()
}
/// Returns `true` if node is ready for an operation
fn is_ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno> {
fn ready(&mut self, _node: VnodeRef, _write: bool) -> Result<bool, Errno> {
todo!()
}
+5 -5
View File
@@ -35,16 +35,16 @@ impl<'a, A: BlockAllocator + Copy + 'static> VnodeCommon for FileInode<'a, A> {
/// Performs filetype-specific request
fn ioctl(
&mut self,
node: VnodeRef,
cmd: IoctlCmd,
ptr: usize,
len: usize,
_node: VnodeRef,
_cmd: IoctlCmd,
_ptr: usize,
_len: usize,
) -> Result<usize, Errno> {
todo!()
}
/// Returns `true` if node is ready for an operation
fn is_ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno> {
fn ready(&mut self, _node: VnodeRef, _write: bool) -> Result<bool, Errno> {
todo!()
}
}
+1 -5
View File
@@ -6,9 +6,6 @@ extern crate alloc;
#[macro_use]
extern crate std;
#[macro_use]
extern crate fs_macros;
use alloc::{boxed::Box, rc::Rc};
use core::any::Any;
use core::cell::{Ref, RefCell};
@@ -69,11 +66,10 @@ impl<A: BlockAllocator + Copy + 'static> Ramfs<A> {
VnodeData::Directory(RefCell::new(Some(Box::new(DirInode::new(self.alloc)))))
}
VnodeCreateKind::File => VnodeData::File(RefCell::new(None)),
_ => todo!(),
};
let node = Vnode::new(name, data, Vnode::SEEKABLE | Vnode::CACHE_READDIR);
node.props_mut().mode = tar.mode();
node.set_fs(self.clone());
node.set_fs(self);
node
}
+1 -2
View File
@@ -1,5 +1,5 @@
use libsys::{error::Errno, stat::FileMode};
use vfs::{VnodeData, VnodeCreateKind};
use vfs::VnodeCreateKind;
#[repr(packed)]
#[allow(dead_code)]
@@ -85,7 +85,6 @@ impl Tar {
let t = match self.node_create_kind() {
VnodeCreateKind::File => FileMode::S_IFREG,
VnodeCreateKind::Directory => FileMode::S_IFDIR,
_ => todo!()
};
FileMode::from_bits(from_octal(&self.mode) as u32).unwrap() | t
}
+4 -7
View File
@@ -128,13 +128,10 @@ impl Ioctx {
/// Changes current working directory of the process
pub fn chdir(&mut self, path: &str) -> Result<(), Errno> {
todo!()
// let node = self.find(None, path, true)?;
// if !node.is_directory() {
// return Err(Errno::NotADirectory);
// }
// self.cwd = node;
// Ok(())
let node = self.find(None, path, true)?;
let _dir = node.as_directory()?;
self.cwd = node;
Ok(())
}
}
+16 -1
View File
@@ -13,6 +13,7 @@ use libsys::{
pub type VnodeRef = Rc<Vnode>;
pub type VnodeKind = Discriminant<VnodeData>;
/// Trait implemented by both regular files and directories
pub trait VnodeCommon {
/// Performs filetype-specific request
fn ioctl(
@@ -30,7 +31,7 @@ pub trait VnodeCommon {
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno>;
/// Returns `true` if node is ready for an operation
fn is_ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno>;
fn ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno>;
/// Opens a vnode for access. Returns initial file position.
fn open(&mut self, node: VnodeRef, opts: OpenFlags) -> Result<usize, Errno>;
@@ -38,6 +39,7 @@ pub trait VnodeCommon {
fn close(&mut self, node: VnodeRef) -> Result<(), Errno>;
}
/// Regular file access interface
pub trait VnodeFile: VnodeCommon {
/// Changes file's underlying storage size
fn truncate(&mut self, node: VnodeRef, size: usize) -> Result<(), Errno>;
@@ -48,14 +50,18 @@ pub trait VnodeFile: VnodeCommon {
fn write(&mut self, node: VnodeRef, pos: usize, data: &[u8]) -> Result<usize, Errno>;
}
/// Directory access interface
pub trait VnodeDirectory: VnodeCommon {
/// Creates entry `name` of type `kind` in directory `at`
fn create(
&mut self,
at: VnodeRef,
name: &str,
kind: VnodeCreateKind,
) -> Result<VnodeRef, Errno>;
/// Removes entry `name` for directory `at`
fn remove(&mut self, at: VnodeRef, name: &str) -> Result<(), Errno>;
/// Loads an entry `name` in directory `at` from filesystem
fn lookup(&mut self, at: VnodeRef, name: &str) -> Result<VnodeRef, Errno>;
/// Read directory entries into target buffer
@@ -91,15 +97,22 @@ pub struct VnodeProps {
pub mode: FileMode,
}
/// Specific node implementation data
pub enum VnodeData {
/// Directory node
Directory(RefCell<Option<Box<dyn VnodeDirectory>>>),
/// Regular file node
File(RefCell<Option<Box<dyn VnodeFile>>>),
/// Character device node
Char(&'static dyn CharDevice)
}
/// Node types for create() calls
#[derive(Debug, Clone, Copy)]
pub enum VnodeCreateKind {
/// Directory node
Directory,
/// Regular file node
File,
}
@@ -173,6 +186,7 @@ impl Vnode {
*self.fs.borrow_mut() = Some(fs);
}
/// Returns node's directory implementation data
pub fn as_directory(&self) -> Result<&RefCell<Option<Box<dyn VnodeDirectory>>>, Errno> {
match &self.data {
VnodeData::Directory(data) => Ok(data),
@@ -180,6 +194,7 @@ impl Vnode {
}
}
/// Returns node's regular file implementation data
pub fn as_file(&self) -> Result<&RefCell<Option<Box<dyn VnodeFile>>>, Errno> {
match &self.data {
VnodeData::File(data) => Ok(data),
+1 -1
View File
@@ -83,7 +83,7 @@ extern "C" fn __aa64_bsp_main(fdt_base: usize) -> ! {
// Enable MMU
virt::enable().expect("Failed to initialize virtual memory");
let fdt = init_device_tree(fdt_base).expect("Device tree init failed");
let _fdt = init_device_tree(fdt_base).expect("Device tree init failed");
// Most basic machine init: initialize proper debug output
// physical memory
+1 -1
View File
@@ -4,7 +4,7 @@ use crate::arch::{machine, intrin};
use crate::debug::Level;
use crate::dev::irq::{IntController, IrqContext};
use crate::mem;
use crate::proc::{sched, Process, Thread};
use crate::proc::{sched, Thread};
use crate::syscall;
use cortex_a::registers::{ESR_EL1, FAR_EL1};
use libsys::{abi::SystemCall, signal::Signal, error::Errno};
+18 -1
View File
@@ -1,14 +1,31 @@
//! AArch64-specific assembly functions
use core::arch::asm;
/// Disables delievery of IRQs
///
/// # Safety
///
/// Unsafe: requires EL0
#[inline(always)]
pub unsafe fn irq_disable() {
asm!("msr daifset, {bits}", bits = const 2, options(nomem, nostack, preserves_flags));
}
/// Discards an entry related to `addr` from TLB cache
///
/// # Safety
///
/// Unsafe: requires EL0
#[inline(always)]
pub unsafe fn flush_tlb_virt(addr: usize) {
pub unsafe fn flush_tlb_virt(_addr: usize) {
todo!()
}
/// Discards all entries related to `asid` from TLB cache
///
/// # Safety
///
/// Only safe to use for known [Process]es and their ASIDs
// TODO non-portable
#[inline(always)]
pub unsafe fn flush_tlb_asid(asid: usize) {
-1
View File
@@ -1,6 +1,5 @@
//! aarch64 architecture implementation
use core::arch::asm;
use cortex_a::registers::DAIF;
use tock_registers::interfaces::{Readable, Writeable};
+5 -3
View File
@@ -8,13 +8,15 @@ use tock_registers::{
macro_rules! wrap_msr {
($struct_name:ident, $name:ident, $reg:literal, $fields:tt) => {
#[allow(missing_docs)]
pub struct $struct_name;
register_bitfields! {
u64,
#[allow(missing_docs)]
pub $name $fields
}
pub struct $struct_name;
impl Readable for $struct_name {
type T = u64;
type R = $name::Register;
@@ -41,11 +43,11 @@ macro_rules! wrap_msr {
}
}
#[allow(missing_docs)]
pub const $name: $struct_name = $struct_name;
};
}
/// EL1 Architectural Feature Access Control Register
wrap_msr!(CpacrEl1, CPACR_EL1, "cpacr_el1", [
/// Enable EL0 and EL1 SIMD/FP accesses to EL1
FPEN OFFSET(20) NUMBITS(2) [
+1
View File
@@ -16,6 +16,7 @@ use libsys::{debug::TraceLevel, error::Errno};
use core::convert::TryFrom;
use core::fmt;
/// Currently active print level
pub static LEVEL: Level = Level::Debug;
/// Kernel logging levels
+13 -19
View File
@@ -1,25 +1,14 @@
use crate::arch::machine::{self, IrqNumber};
use crate::dev::{
irq::{IntController, IntSource},
serial::SerialDevice,
tty::{CharRing, TtyDevice},
Device,
};
use crate::mem::virt::DeviceMemoryIo;
use crate::sync::IrqSafeSpinLock;
use crate::util::InitOnce;
use libsys::{error::Errno, ioctl::IoctlCmd};
//! Virtual (pseudo) device implemetation
use crate::dev::Device;
use core::sync::atomic::{AtomicU32, Ordering};
use tock_registers::{
interfaces::{ReadWriteable, Readable, Writeable},
register_bitfields, register_structs,
registers::{ReadOnly, ReadWrite, WriteOnly},
};
use libsys::{error::Errno, ioctl::IoctlCmd};
use vfs::CharDevice;
/// Pseudorandom number generator device
pub struct Random {
state: AtomicU32
state: AtomicU32,
}
/// Zero device
pub struct Zero;
impl Device for Random {
@@ -53,7 +42,6 @@ impl CharDevice for Random {
}
}
impl Device for Zero {
fn name(&self) -> &'static str {
"Zero device"
@@ -84,10 +72,12 @@ impl CharDevice for Zero {
}
impl Random {
/// Initializes PRNG with a seed value
pub fn set_state(&self, state: u32) {
self.state.store(state, Ordering::Release);
}
/// Returns a single pseudo-random value
pub fn read_single(&self) -> u32 {
let mut x = self.state.load(Ordering::Acquire);
x ^= x << 13;
@@ -98,5 +88,9 @@ impl Random {
}
}
pub static RANDOM: Random = Random { state: AtomicU32::new(0) };
/// Pseudorandom number generator device
pub static RANDOM: Random = Random {
state: AtomicU32::new(0),
};
/// Zero device
pub static ZERO: Zero = Zero;
+11 -6
View File
@@ -1,10 +1,10 @@
//! Device list pseudo-filesystem
use crate::util::InitOnce;
use alloc::boxed::Box;
use core::sync::atomic::{AtomicUsize, Ordering};
use libsys::{stat::FileMode, error::Errno};
use vfs::{CharDevice, Vnode, VnodeData, VnodeRef};
use core::cell::RefCell;
use vfs::CharDevice;
use core::sync::atomic::{AtomicUsize, Ordering};
use libsys::{error::Errno, stat::FileMode};
use vfs::{Vnode, VnodeData, VnodeRef};
/// Possible character device kinds
#[derive(Debug)]
@@ -17,7 +17,11 @@ static DEVFS_ROOT: InitOnce<VnodeRef> = InitOnce::new();
/// Initializes devfs
pub fn init() {
let node = Vnode::new("", VnodeData::Directory(RefCell::new(None)), Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
let node = Vnode::new(
"",
VnodeData::Directory(RefCell::new(None)),
Vnode::CACHE_READDIR | Vnode::CACHE_STAT,
);
// let node = Vnode::new("", VnodeKind::Directory, Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
node.props_mut().mode = FileMode::default_dir();
DEVFS_ROOT.init(node);
@@ -28,13 +32,14 @@ pub fn root() -> &'static VnodeRef {
DEVFS_ROOT.get()
}
/// Adds device `dev` to devfs with `name`
pub fn add_named_char_device(dev: &'static dyn CharDevice, name: &str) -> Result<(), Errno> {
infoln!("Add char device: {}", name);
let node = Vnode::new(name, VnodeData::Char(dev), Vnode::CACHE_STAT);
// let node = Vnode::new(name, VnodeKind::Char, Vnode::CACHE_STAT);
// node.set_data(Box::new(CharDeviceWrapper::new(dev)));
node.props_mut().mode = FileMode::from_bits(0o600).unwrap() | FileMode::S_IFCHR;
node.props_mut().mode = FileMode::from_bits(0o600).unwrap() | FileMode::S_IFCHR;
DEVFS_ROOT.get().attach(node);
+47 -27
View File
@@ -1,17 +1,16 @@
//! System control/info virtual filesystem
use crate::debug::{self, Level};
use crate::util::InitOnce;
use alloc::boxed::Box;
use core::cell::RefCell;
use core::fmt::{self, Write};
use core::str::FromStr;
use core::sync::atomic::{AtomicUsize, Ordering};
use fs_macros::auto_inode;
use libsys::{
error::Errno,
stat::{FileMode, OpenFlags, Stat},
ioctl::IoctlCmd,
stat::{FileMode, OpenFlags, Stat},
};
use vfs::{CharDevice, Vnode, VnodeCommon, VnodeData, VnodeFile, VnodeRef};
use vfs::{Vnode, VnodeCommon, VnodeData, VnodeFile, VnodeRef};
struct NodeData<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Errno>> {
read_func: R,
@@ -59,32 +58,33 @@ impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Err
/// Performs filetype-specific request
fn ioctl(
&mut self,
node: VnodeRef,
cmd: IoctlCmd,
ptr: usize,
len: usize,
_node: VnodeRef,
_cmd: IoctlCmd,
_ptr: usize,
_len: usize,
) -> Result<usize, Errno> {
todo!()
}
/// Retrieves file status
fn stat(&mut self, node: VnodeRef) -> Result<Stat, Errno> {
fn stat(&mut self, _node: VnodeRef) -> Result<Stat, Errno> {
todo!()
}
/// Reports the size of this filesystem object in bytes
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno> {
fn size(&mut self, _node: VnodeRef) -> Result<usize, Errno> {
todo!()
}
/// Returns `true` if node is ready for an operation
fn is_ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno> {
fn ready(&mut self, _node: VnodeRef, _write: bool) -> Result<bool, Errno> {
todo!()
}
}
impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Errno>> VnodeFile
for NodeData<R, W> {
for NodeData<R, W>
{
fn read(&mut self, _node: VnodeRef, pos: usize, data: &mut [u8]) -> Result<usize, Errno> {
if pos != 0 {
// TODO handle this
@@ -101,10 +101,10 @@ impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Err
(self.write_func)(data)
}
fn truncate(&mut self, node: VnodeRef, size: usize) -> Result<(), Errno> {
fn truncate(&mut self, _node: VnodeRef, _size: usize) -> Result<(), Errno> {
todo!()
}
}
}
impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Errno>>
NodeData<R, W>
{
@@ -117,7 +117,6 @@ impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Err
}
static SYSFS_ROOT: InitOnce<VnodeRef> = InitOnce::new();
static TEST_COUNTER: AtomicUsize = AtomicUsize::new(0);
// TODO subdirs
fn add_generic_node<R, W>(parent: Option<VnodeRef>, name: &str, mode: FileMode, read: R, write: W)
@@ -139,6 +138,7 @@ where
}
}
/// Adds a node with and `read` and `write` operations
pub fn add_read_write_node<R, W>(parent: Option<VnodeRef>, name: &str, read: R, write: W)
where
R: Fn(&mut [u8]) -> Result<usize, Errno> + 'static,
@@ -153,6 +153,7 @@ where
)
}
/// Adds `read`-only node
pub fn add_read_node<R>(parent: Option<VnodeRef>, name: &str, read: R)
where
R: Fn(&mut [u8]) -> Result<usize, Errno> + 'static,
@@ -166,8 +167,13 @@ where
)
}
/// Creates a directory in sysfs structure
pub fn add_directory(parent: Option<VnodeRef>, name: &str) -> Result<VnodeRef, Errno> {
let node = Vnode::new(name, VnodeData::Directory(RefCell::new(None)), Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
let node = Vnode::new(
name,
VnodeData::Directory(RefCell::new(None)),
Vnode::CACHE_READDIR | Vnode::CACHE_STAT,
);
node.props_mut().mode = FileMode::from_bits(0o500).unwrap() | FileMode::S_IFDIR;
if let Some(parent) = parent {
@@ -179,26 +185,39 @@ pub fn add_directory(parent: Option<VnodeRef>, name: &str) -> Result<VnodeRef, E
Ok(node)
}
/// Returns sysfs root node reference
pub fn root() -> &'static VnodeRef {
SYSFS_ROOT.get()
}
/// Sets up the sysfs tree
pub fn init() {
let node = Vnode::new("", VnodeData::Directory(RefCell::new(None)), Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
let node = Vnode::new(
"",
VnodeData::Directory(RefCell::new(None)),
Vnode::CACHE_READDIR | Vnode::CACHE_STAT,
);
node.props_mut().mode = FileMode::default_dir();
SYSFS_ROOT.init(node);
let debug_dir = add_directory(None, "debug").unwrap();
add_read_write_node(Some(debug_dir.clone()), "level", |buf| {
let mut writer = BufferWriter::new(buf);
write!(&mut writer, "{}\n", debug::LEVEL as u32).map_err(|_| Errno::InvalidArgument)?;
Ok(writer.count())
}, |buf| {
let s = core::str::from_utf8(buf).map_err(|_| Errno::InvalidArgument)?;
let value = u32::from_str(s).map_err(|_| Errno::InvalidArgument).and_then(Level::try_from)?;
todo!()
});
add_read_write_node(
Some(debug_dir),
"level",
|buf| {
let mut writer = BufferWriter::new(buf);
writeln!(&mut writer, "{}", debug::LEVEL as u32).map_err(|_| Errno::InvalidArgument)?;
Ok(writer.count())
},
|buf| {
let s = core::str::from_utf8(buf).map_err(|_| Errno::InvalidArgument)?;
let _value = u32::from_str(s)
.map_err(|_| Errno::InvalidArgument)
.and_then(Level::try_from)?;
todo!()
},
);
add_read_node(None, "uptime", |buf| {
use crate::arch::machine;
@@ -206,7 +225,8 @@ pub fn init() {
let mut writer = BufferWriter::new(buf);
let time = machine::local_timer().timestamp()?;
write!(&mut writer, "{} {}\n", time.as_secs(), time.subsec_nanos()).map_err(|_| Errno::InvalidArgument)?;
writeln!(&mut writer, "{} {}", time.as_secs(), time.subsec_nanos())
.map_err(|_| Errno::InvalidArgument)?;
Ok(writer.count())
});
}
-2
View File
@@ -37,8 +37,6 @@ pub mod sync;
pub mod syscall;
pub mod util;
use core::arch::asm;
#[panic_handler]
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
unsafe {
+1
View File
@@ -28,6 +28,7 @@ pub fn kernel_end_phys() -> usize {
}
// TODO cross-platform variant
/// Returns `true` if `virt` address is accessible for requested operation
#[inline(always)]
pub fn is_el0_accessible(virt: usize, write: bool) -> bool {
use core::arch::asm;
+3
View File
@@ -4,6 +4,9 @@ use crate::sync::IrqSafeSpinLock;
use core::mem;
use libsys::{error::Errno, mem::memcpy};
/// # Safety
///
/// Unsafe to implement because of direct memory manipulation
pub unsafe trait Manager {
fn alloc_page(&mut self, pu: PageUsage) -> Result<usize, Errno>;
fn alloc_contiguous_pages(&mut self, pu: PageUsage, count: usize) -> Result<usize, Errno>;
+14 -4
View File
@@ -1,7 +1,10 @@
//! Process file descriptors and I/O context
use alloc::collections::BTreeMap;
use libsys::{error::Errno, stat::{FileDescriptor, UserId, GroupId}};
use vfs::{FileRef, Ioctx, VnodeRef, VnodeData};
use libsys::{
error::Errno,
stat::{FileDescriptor, GroupId, UserId},
};
use vfs::{FileRef, Ioctx, VnodeRef};
/// Process I/O context. Contains file tables, root/cwd info etc.
pub struct ProcessIo {
@@ -74,7 +77,11 @@ impl ProcessIo {
}
/// Clones a file descriptor into an available slot or, if specified, requested one
pub fn duplicate_file(&mut self, src: FileDescriptor, dst: Option<FileDescriptor>) -> Result<FileDescriptor, Errno> {
pub fn duplicate_file(
&mut self,
src: FileDescriptor,
dst: Option<FileDescriptor>,
) -> Result<FileDescriptor, Errno> {
let file_ref = self.file(src)?;
if let Some(dst) = dst {
let idx = u32::from(dst);
@@ -91,7 +98,10 @@ impl ProcessIo {
/// Returns [File] struct referred to by file descriptor `idx`
pub fn file(&mut self, fd: FileDescriptor) -> Result<FileRef, Errno> {
self.files.get(&u32::from(fd)).cloned().ok_or(Errno::InvalidFile)
self.files
.get(&u32::from(fd))
.cloned()
.ok_or(Errno::InvalidFile)
}
/// Returns [Ioctx] structure reference of this I/O context
+2 -1
View File
@@ -10,7 +10,6 @@ use crate::proc::{
};
use crate::sync::IrqSafeSpinLock;
use alloc::{rc::Rc, vec::Vec};
use core::arch::asm;
use core::sync::atomic::{AtomicU32, Ordering};
use libsys::{
error::Errno,
@@ -463,10 +462,12 @@ impl Process {
Ok(base + offset)
}
/// Returns the process's address space ID
pub fn asid(&self) -> usize {
(self.id().asid() as usize) << 48
}
/// Flushes TLB cache for the process address space
pub fn invalidate_tlb(&self) {
unsafe {
intrin::flush_tlb_asid(self.asid());
-1
View File
@@ -5,7 +5,6 @@ use crate::arch::intrin;
use core::alloc::Layout;
use libsys::error::Errno;
use crate::proc::Process;
use core::arch::asm;
// TODO _mut() versions checking whether pages are actually writable
+2 -1
View File
@@ -251,7 +251,8 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
let path = arg::str_ref(args[1], args[2])?;
let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let flags = args[4] as u32;
// TODO honor this option
let _flags = args[4] as u32;
let proc = Process::current();
let mut io = proc.io.lock();
+2 -2
View File
@@ -198,9 +198,9 @@ unsafe impl GlobalAlloc for Allocator {
}
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
#[cfg(feature = "verbose")]
trace_debug!("free({:p}, {:?})", ptr, layout);
trace_debug!("free({:p}, {:?})", ptr, _layout);
assert!(!ptr.is_null());
let mut block = ptr.sub(size_of::<Block>()) as *mut Block;
let mut block_ref = &mut *block;
+3 -1
View File
@@ -1,7 +1,9 @@
#[cfg(feature = "verbose")]
use crate::trace;
use alloc::vec::Vec;
#[cfg(feature = "verbose")]
use libsys::debug::TraceLevel;
use libsys::{
debug::TraceLevel,
ProgramArgs,
};
+27 -25
View File
@@ -1,9 +1,11 @@
use crate::io::{Read, read_line};
use core::str::FromStr;
use core::fmt;
use crate::trace_debug;
use crate::file::File;
use libsys::{FixedStr, stat::{UserId, GroupId}};
use crate::io::{self, read_line};
use core::str::FromStr;
use libsys::{
stat::{GroupId, UserId},
error::Errno,
FixedStr,
};
#[derive(Debug, Clone, Copy)]
pub struct UserInfo {
@@ -35,11 +37,11 @@ impl UserInfo {
self.gid
}
pub fn find<F: Fn(&Self) -> bool>(pred: F) -> Result<Self, ()> {
let mut file = File::open("/etc/passwd").map_err(|_| ())?;
pub fn find<F: Fn(&Self) -> bool>(pred: F) -> Result<Self, io::Error> {
let mut file = File::open("/etc/passwd")?;
let mut buf = [0; 128];
loop {
let line = read_line(&mut file, &mut buf).map_err(|_| ())?;
let line = read_line(&mut file, &mut buf)?;
if let Some(line) = line {
let ent = UserInfo::from_str(line)?;
if pred(&ent) {
@@ -49,37 +51,37 @@ impl UserInfo {
break;
}
}
Err(())
Err(io::Error::from(Errno::InvalidArgument))
}
pub fn by_name(name: &str) -> Result<Self, ()> {
pub fn by_name(name: &str) -> Result<Self, io::Error> {
Self::find(|ent| ent.name() == name)
}
}
impl FromStr for UserInfo {
type Err = ();
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, ()> {
let mut iter = s.split(":");
fn from_str(s: &str) -> Result<Self, io::Error> {
let mut iter = s.split(':');
let name = iter.next().ok_or(())?;
let name = iter.next().ok_or_else(|| io::Error::from(Errno::InvalidArgument))?;
let uid = iter
.next()
.ok_or(())
.and_then(|e| u32::from_str(e).map_err(|_| ()))
.ok_or_else(|| io::Error::from(Errno::InvalidArgument))
.and_then(|e| u32::from_str(e).map_err(|_| io::Error::from(Errno::InvalidArgument)))
.map(UserId::from)?;
let gid = iter
.next()
.ok_or(())
.and_then(|e| u32::from_str(e).map_err(|_| ()))
.ok_or_else(|| io::Error::from(Errno::InvalidArgument))
.and_then(|e| u32::from_str(e).map_err(|_| io::Error::from(Errno::InvalidArgument)))
.map(GroupId::from)?;
let comment = iter.next().ok_or(())?;
let home = iter.next().ok_or(())?;
let shell = iter.next().ok_or(())?;
let _comment = iter.next().ok_or_else(|| io::Error::from(Errno::InvalidArgument))?;
let home = iter.next().ok_or_else(|| io::Error::from(Errno::InvalidArgument))?;
let shell = iter.next().ok_or_else(|| io::Error::from(Errno::InvalidArgument))?;
if iter.next().is_some() {
return Err(());
return Err(io::Error::from(Errno::InvalidArgument));
}
let mut res = Self {
@@ -90,9 +92,9 @@ impl FromStr for UserInfo {
shell: FixedStr::empty(),
};
res.name.copy_from_str(&name);
res.home.copy_from_str(&home);
res.shell.copy_from_str(&shell);
res.name.copy_from_str(name);
res.home.copy_from_str(home);
res.shell.copy_from_str(shell);
Ok(res)
}
+12 -13
View File
@@ -1,7 +1,7 @@
use crate::file::File;
use crate::io::{Read, read_line};
use crate::io::{self, read_line};
use core::str::FromStr;
use libsys::FixedStr;
use libsys::{FixedStr, error::Errno};
#[derive(Debug, Clone, Copy)]
pub struct UserShadow {
@@ -18,12 +18,11 @@ impl UserShadow {
self.password.as_str()
}
pub fn find<F: Fn(&Self) -> bool>(pred: F) -> Result<Self, ()> {
let mut file = File::open("/etc/shadow").map_err(|_| ())?;
pub fn find<F: Fn(&Self) -> bool>(pred: F) -> Result<Self, io::Error> {
let mut file = File::open("/etc/shadow")?;
let mut buf = [0; 128];
loop {
let line = read_line(&mut file, &mut buf).map_err(|_| ())?;
let line = read_line(&mut file, &mut buf)?;
if let Some(line) = line {
let ent = UserShadow::from_str(line)?;
if pred(&ent) {
@@ -33,25 +32,25 @@ impl UserShadow {
break;
}
}
Err(())
Err(io::Error::from(Errno::DoesNotExist))
}
pub fn by_name(name: &str) -> Result<Self, ()> {
pub fn by_name(name: &str) -> Result<Self, io::Error> {
Self::find(|ent| ent.name() == name)
}
}
impl FromStr for UserShadow {
type Err = ();
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, ()> {
fn from_str(s: &str) -> Result<Self, io::Error> {
let mut iter = s.split(':');
let name = iter.next().ok_or(())?;
let password = iter.next().ok_or(())?;
let name = iter.next().ok_or_else(|| io::Error::from(Errno::InvalidArgument))?;
let password = iter.next().ok_or_else(|| io::Error::from(Errno::InvalidArgument))?;
if iter.next().is_some() {
return Err(());
return Err(io::Error::from(Errno::InvalidArgument));
}
let mut res = Self {
+4 -4
View File
@@ -44,14 +44,14 @@ pub fn stat(pathname: &str) -> Result<Stat, Error> {
}
// TODO use BufRead instead once it's implemented
pub(crate) fn read_line<'a, F: Read>(f: &mut F, buf: &'a mut [u8]) -> Result<Option<&'a str>, ()> {
pub(crate) fn read_line<'a, F: Read>(f: &mut F, buf: &'a mut [u8]) -> Result<Option<&'a str>, Error> {
let mut pos = 0;
loop {
if pos == buf.len() {
return Err(());
return Err(Error::from(Errno::OutOfMemory));
}
let count = f.read(&mut buf[pos..=pos]).map_err(|_| ())?;
let count = f.read(&mut buf[pos..=pos])?;
if count == 0 {
if pos == 0 {
return Ok(None);
@@ -64,5 +64,5 @@ pub(crate) fn read_line<'a, F: Read>(f: &mut F, buf: &'a mut [u8]) -> Result<Opt
pos += 1;
}
core::str::from_utf8(&buf[..pos]).map_err(|_| ()).map(Some)
core::str::from_utf8(&buf[..pos]).map_err(|_| Error::from(Errno::InvalidArgument)).map(Some)
}
+1 -2
View File
@@ -15,7 +15,6 @@ use libsys::{
termios::{Termios, TermiosLflag},
};
use libusr::{env::{self, UserInfo, UserShadow}, io};
use core::str::FromStr;
struct HiddenInput {
fd: FileDescriptor,
@@ -158,6 +157,6 @@ fn main() -> i32 {
}
}
login_as(username);
login_as(username).ok();
}
}