Replace syscall::Scheme with KernelScheme.

This commit is contained in:
4lDO2
2023-11-04 18:04:31 +01:00
parent 192d663d84
commit 036a4bdee4
19 changed files with 332 additions and 349 deletions
+4 -1
View File
@@ -20,7 +20,7 @@ use crate::context::memory::AddrSpace;
use crate::ipi::{ipi, IpiKind, IpiTarget};
use crate::paging::{RmmA, RmmArch};
use crate::memory::{RaiiFrame, Frame};
use crate::scheme::{SchemeNamespace, FileHandle};
use crate::scheme::{SchemeNamespace, FileHandle, CallerCtx};
use crate::sync::WaitMap;
use crate::syscall::data::SigAction;
@@ -472,6 +472,9 @@ impl Context {
0
); 128]))
}
pub fn caller_ctx(&self) -> CallerCtx {
CallerCtx { pid: self.id.into(), uid: self.euid, gid: self.egid }
}
}
/// Wrapper struct for borrowing the syscall head or tail buf.
+6 -7
View File
@@ -32,7 +32,7 @@ pub struct FileDescriptor {
impl FileDescription {
/// Try closing a file, although at this point the description will be destroyed anyway, if
/// doing so fails.
pub fn try_close(self) -> Result<usize> {
pub fn try_close(self) -> Result<()> {
event::unregister_file(self.scheme, self.number);
let scheme = Arc::clone(
@@ -44,11 +44,10 @@ impl FileDescription {
}
impl FileDescriptor {
pub fn close(self) -> Result<usize> {
let Ok(file) = Arc::try_unwrap(self.description) else {
return Ok(0);
};
file.into_inner().try_close()
pub fn close(self) -> Result<()> {
if let Ok(file) = Arc::try_unwrap(self.description) {
file.into_inner().try_close()?;
}
Ok(())
}
}
+12 -13
View File
@@ -20,10 +20,11 @@ use crate::syscall::flag::{
O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_STAT, O_SYMLINK,
SEEK_SET, SEEK_CUR, SEEK_END,
};
use crate::syscall::scheme::Scheme;
use crate::syscall::error::{Error, Result};
use crate::syscall::usercopy::{UserSliceRo, UserSliceWo};
use super::{KernelScheme, CallerCtx, OpenResult};
/// A scheme used to access the RSDT or XSDT, which is needed for e.g. `acpid` to function.
pub struct AcpiScheme;
@@ -113,11 +114,11 @@ impl AcpiScheme {
}
}
impl Scheme for AcpiScheme {
fn open(&self, path: &str, flags: usize, opener_uid: u32, _opener_gid: u32) -> Result<usize> {
impl KernelScheme for AcpiScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
let path = path.trim_start_matches('/');
if opener_uid != 0 {
if ctx.uid != 0 {
return Err(Error::new(EACCES));
}
if flags & O_CREAT == O_CREAT {
@@ -161,9 +162,9 @@ impl Scheme for AcpiScheme {
stat: flags & O_STAT == O_STAT,
});
Ok(fd)
Ok(OpenResult::SchemeLocal(fd))
}
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
let mut handles = HANDLES.write();
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
@@ -194,7 +195,7 @@ impl Scheme for AcpiScheme {
handle.offset = new_offset;
Ok(new_offset as isize)
Ok(new_offset)
}
// TODO
fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> {
@@ -207,14 +208,12 @@ impl Scheme for AcpiScheme {
Ok(EventFlags::empty())
}
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
if HANDLES.write().remove(&id).is_none() {
return Err(Error::new(EBADF));
}
Ok(0)
Ok(())
}
}
impl crate::scheme::KernelScheme for AcpiScheme {
fn kwrite(&self, _id: usize, _buf: UserSliceRo) -> Result<usize> {
Err(Error::new(EBADF))
}
@@ -260,7 +259,7 @@ impl crate::scheme::KernelScheme for AcpiScheme {
Ok(bytes_copied)
}
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
let handles = HANDLES.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
@@ -286,6 +285,6 @@ impl crate::scheme::KernelScheme for AcpiScheme {
},
})?;
Ok(0)
Ok(())
}
}
+20 -35
View File
@@ -1,12 +1,11 @@
use core::sync::atomic::{AtomicUsize, Ordering};
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use spin::{Once, RwLock};
use crate::arch::debug::Writer;
use crate::event;
use crate::scheme::*;
use crate::sync::WaitQueue;
use crate::syscall::flag::{EventFlags, EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK};
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::UserSliceRo;
use crate::syscall::usercopy::UserSliceWo;
@@ -22,19 +21,7 @@ struct Handle {
flags: usize,
}
static HANDLES: Once<RwLock<BTreeMap<usize, Handle>>> = Once::new();
fn init_handles() -> RwLock<BTreeMap<usize, Handle>> {
RwLock::new(BTreeMap::new())
}
fn handles() -> RwLockReadGuard<'static, BTreeMap<usize, Handle>> {
HANDLES.call_once(init_handles).read()
}
fn handles_mut() -> RwLockWriteGuard<'static, BTreeMap<usize, Handle>> {
HANDLES.call_once(init_handles).write()
}
static HANDLES: RwLock<BTreeMap<usize, Handle>> = RwLock::new(BTreeMap::new());
/// Add to the input queue
pub fn debug_input(data: u8) {
@@ -47,7 +34,7 @@ pub fn debug_notify() {
return;
};
for (id, _handle) in handles().iter() {
for (id, _handle) in HANDLES.read().iter() {
event::trigger(scheme_id, *id, EVENT_READ);
}
}
@@ -61,9 +48,9 @@ impl DebugScheme {
}
}
impl Scheme for DebugScheme {
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid != 0 {
impl KernelScheme for DebugScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
if ctx.uid != 0 {
return Err(Error::new(EPERM));
}
@@ -71,16 +58,16 @@ impl Scheme for DebugScheme {
return Err(Error::new(ENOENT));
}
let id = NEXT_ID.fetch_add(1, Ordering::SeqCst);
handles_mut().insert(id, Handle {
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
HANDLES.write().insert(id, Handle {
flags: flags & ! O_ACCMODE
});
Ok(id)
Ok(OpenResult::SchemeLocal(id))
}
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
let mut handles = handles_mut();
let mut handles = HANDLES.write();
if let Some(handle) = handles.get_mut(&id) {
match cmd {
F_GETFL => Ok(handle.flags),
@@ -97,36 +84,34 @@ impl Scheme for DebugScheme {
fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> {
let _handle = {
let handles = handles();
let handles = HANDLES.read();
*handles.get(&id).ok_or(Error::new(EBADF))?
};
Ok(EventFlags::empty())
}
fn fsync(&self, id: usize) -> Result<usize> {
fn fsync(&self, id: usize) -> Result<()> {
let _handle = {
let handles = handles();
let handles = HANDLES.read();
*handles.get(&id).ok_or(Error::new(EBADF))?
};
Ok(0)
Ok(())
}
/// Close the file `number`
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
let _handle = {
let mut handles = handles_mut();
let mut handles = HANDLES.write();
handles.remove(&id).ok_or(Error::new(EBADF))?
};
Ok(0)
Ok(())
}
}
impl crate::scheme::KernelScheme for DebugScheme {
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let handle = {
let handles = handles();
let handles = HANDLES.read();
*handles.get(&id).ok_or(Error::new(EBADF))?
};
@@ -136,7 +121,7 @@ impl crate::scheme::KernelScheme for DebugScheme {
fn kwrite(&self, id: usize, buf: UserSliceRo) -> Result<usize> {
let _handle = {
let handles = handles();
let handles = HANDLES.read();
*handles.get(&id).ok_or(Error::new(EBADF))?
};
@@ -156,7 +141,7 @@ impl crate::scheme::KernelScheme for DebugScheme {
}
fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let _handle = {
let handles = handles();
let handles = HANDLES.read();
*handles.get(&id).ok_or(Error::new(EBADF))?
};
+9 -11
View File
@@ -4,20 +4,20 @@ use core::mem;
use crate::event::{EventQueue, EventQueueId, next_queue_id, queues, queues_mut};
use crate::syscall::data::Event;
use crate::syscall::error::*;
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
use super::{KernelScheme, CallerCtx, OpenResult};
pub struct EventScheme;
impl Scheme for EventScheme {
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
impl KernelScheme for EventScheme {
fn kopen(&self, _path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
let id = next_queue_id();
queues_mut().insert(id, Arc::new(EventQueue::new(id)));
Ok(id.into())
Ok(OpenResult::SchemeLocal(id.get()))
}
fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
let id = EventQueueId::from(id);
@@ -25,19 +25,17 @@ impl Scheme for EventScheme {
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
}
fn fsync(&self, id: usize) -> Result<usize> {
fn fsync(&self, id: usize) -> Result<()> {
let id = EventQueueId::from(id);
let handles = queues();
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(()))
}
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
let id = EventQueueId::from(id);
queues_mut().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
queues_mut().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
}
}
impl crate::scheme::KernelScheme for EventScheme {
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let id = EventQueueId::from(id);
+17 -17
View File
@@ -16,9 +16,10 @@ use crate::scheme::SchemeId;
use crate::syscall::data::Stat;
use crate::syscall::error::*;
use crate::syscall::flag::{EventFlags, EVENT_READ, O_DIRECTORY, O_CREAT, O_STAT, MODE_CHR, MODE_DIR};
use crate::syscall::scheme::{calc_seek_offset_usize, Scheme};
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
use super::{OpenResult, CallerCtx, calc_seek_offset};
pub static IRQ_SCHEME_ID: Once<SchemeId> = Once::new();
/// IRQ queues
@@ -146,9 +147,9 @@ const fn vector_to_irq(vector: u8) -> u8 {
vector - 32
}
impl Scheme for IrqScheme {
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid != 0 { return Err(Error::new(EACCES)) }
impl crate::scheme::KernelScheme for IrqScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
if ctx.uid != 0 { return Err(Error::new(EACCES)) }
let path_str = path.trim_start_matches('/');
@@ -213,21 +214,21 @@ impl Scheme for IrqScheme {
return Err(Error::new(ENOENT));
}
};
let fd = self.next_fd.fetch_add(1, Ordering::SeqCst);
let fd = self.next_fd.fetch_add(1, Ordering::Relaxed);
HANDLES.write().as_mut().unwrap().insert(fd, handle);
Ok(fd)
Ok(OpenResult::SchemeLocal(fd))
}
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
let handles_guard = HANDLES.read();
let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?;
match handle {
&Handle::Avail(_, ref buf, ref offset) | &Handle::TopLevel(ref buf, ref offset) => {
let cur_offset = offset.load(Ordering::SeqCst);
let new_offset = calc_seek_offset_usize(cur_offset, pos, whence, buf.len())?;
let new_offset = calc_seek_offset(cur_offset, pos, whence, buf.len())?;
offset.store(new_offset as usize, Ordering::SeqCst);
Ok(new_offset)
Ok(new_offset as usize)
}
_ => Err(Error::new(ESPIPE)),
}
@@ -243,11 +244,11 @@ impl Scheme for IrqScheme {
}
fn fsync(&self, _file: usize) -> Result<usize> {
Ok(0)
fn fsync(&self, _file: usize) -> Result<()> {
Ok(())
}
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
let handles_guard = HANDLES.read();
let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?;
@@ -256,10 +257,8 @@ impl Scheme for IrqScheme {
set_reserved(LogicalCpuId::BSP, irq_to_vector(handle_irq), false);
}
}
Ok(0)
Ok(())
}
}
impl crate::scheme::KernelScheme for IrqScheme {
fn kwrite(&self, file: usize, buffer: UserSliceRo) -> Result<usize> {
let handles_guard = HANDLES.read();
let handle = handles_guard.as_ref().unwrap().get(&file).ok_or(Error::new(EBADF))?;
@@ -283,7 +282,7 @@ impl crate::scheme::KernelScheme for IrqScheme {
}
}
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
let handles_guard = HANDLES.read();
let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?;
@@ -321,7 +320,8 @@ impl crate::scheme::KernelScheme for IrqScheme {
..Default::default()
},
})?;
Ok(0)
Ok(())
}
fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let handles_guard = HANDLES.read();
+10 -11
View File
@@ -6,9 +6,10 @@ use spin::RwLock;
use crate::syscall::data::ITimerSpec;
use crate::syscall::error::*;
use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC, EventFlags};
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
use super::{KernelScheme, CallerCtx, OpenResult};
pub struct ITimerScheme {
next_id: AtomicUsize,
handles: RwLock<BTreeMap<usize, usize>>
@@ -23,8 +24,8 @@ impl ITimerScheme {
}
}
impl Scheme for ITimerScheme {
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
impl KernelScheme for ITimerScheme {
fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
let clock = path.parse::<usize>().or(Err(Error::new(ENOENT)))?;
match clock {
@@ -33,10 +34,10 @@ impl Scheme for ITimerScheme {
_ => return Err(Error::new(ENOENT))
}
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.handles.write().insert(id, clock);
Ok(id)
Ok(OpenResult::SchemeLocal(id))
}
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
@@ -48,16 +49,14 @@ impl Scheme for ITimerScheme {
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(EventFlags::empty()))
}
fn fsync(&self, id: usize) -> Result<usize> {
fn fsync(&self, id: usize) -> Result<()> {
let handles = self.handles.read();
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(()))
}
fn close(&self, id: usize) -> Result<usize> {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
fn close(&self, id: usize) -> Result<()> {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
}
}
impl crate::scheme::KernelScheme for ITimerScheme {
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let _clock = {
let handles = self.handles.read();
+9 -12
View File
@@ -15,10 +15,9 @@ use crate::paging::entry::EntryFlags;
use crate::syscall::data::{Map, StatVfs};
use crate::syscall::flag::MapFlags;
use crate::syscall::error::*;
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::UserSliceWo;
use super::KernelScheme;
use super::{KernelScheme, CallerCtx, OpenResult};
pub struct MemoryScheme;
@@ -118,8 +117,8 @@ impl MemoryScheme {
}
}
impl Scheme for MemoryScheme {
fn open(&self, path: &str, _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
impl KernelScheme for MemoryScheme {
fn kopen(&self, path: &str, _flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
let intended_handle = match path.trim_start_matches('/') {
"" => Handle::Anonymous,
"physical" | "physical@wb" => Handle::PhysicalWb,
@@ -129,22 +128,20 @@ impl Scheme for MemoryScheme {
_ => return Err(Error::new(ENOENT)),
};
if uid != 0 && !matches!(intended_handle, Handle::Anonymous) {
if ctx.uid != 0 && !matches!(intended_handle, Handle::Anonymous) {
return Err(Error::new(EACCES));
}
Ok(intended_handle as usize)
Ok(OpenResult::SchemeLocal(intended_handle as usize))
}
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
Ok(0)
}
fn close(&self, _id: usize) -> Result<usize> {
Ok(0)
fn close(&self, _id: usize) -> Result<()> {
Ok(())
}
}
impl KernelScheme for MemoryScheme {
fn kfmap(&self, id: usize, addr_space: &Arc<RwLock<AddrSpace>>, map: &Map, _consume: bool) -> Result<usize> {
match Handle::from_raw(id).ok_or(Error::new(EBADF))? {
Handle::Anonymous => Self::fmap_anonymous(addr_space, map),
@@ -163,7 +160,7 @@ impl KernelScheme for MemoryScheme {
};
dst.copy_common_bytes_from_slice(src.as_bytes())
}
fn kfstatvfs(&self, _file: usize, dst: UserSliceWo) -> Result<usize> {
fn kfstatvfs(&self, _file: usize, dst: UserSliceWo) -> Result<()> {
let used = used_frames() as u64;
let free = free_frames() as u64;
@@ -175,6 +172,6 @@ impl KernelScheme for MemoryScheme {
};
dst.copy_exactly(&stat)?;
Ok(0)
Ok(())
}
}
+54 -11
View File
@@ -13,14 +13,13 @@ use alloc::{
sync::Arc,
vec::Vec,
};
use syscall::{CallerCtx, MunmapFlags, SendFdFlags};
use syscall::{MunmapFlags, SendFdFlags, EventFlags, SEEK_SET, SEEK_CUR, SEEK_END};
use core::sync::atomic::AtomicUsize;
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use crate::context::file::FileDescription;
use crate::context::{memory::AddrSpace, file::FileDescriptor};
use crate::syscall::error::*;
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::{UserSliceRo, UserSliceWo};
#[cfg(all(feature = "acpi", any(target_arch = "x86", target_arch = "x86_64")))]
@@ -299,7 +298,11 @@ pub fn schemes_mut() -> RwLockWriteGuard<'static, SchemeList> {
}
#[allow(unused_variables)]
pub trait KernelScheme: Scheme + Send + Sync + 'static {
pub trait KernelScheme: Send + Sync + 'static {
fn kopen(&self, path: &str, flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
Err(Error::new(ENOENT))
}
fn as_filetable(&self, number: usize) -> Result<Arc<RwLock<Vec<Option<FileDescriptor>>>>> {
Err(Error::new(EBADF))
}
@@ -317,9 +320,6 @@ pub trait KernelScheme: Scheme + Send + Sync + 'static {
Err(Error::new(EOPNOTSUPP))
}
fn kopen(&self, path: &str, flags: usize, caller: CallerCtx) -> Result<OpenResult> {
self.open(path, flags, caller.uid, caller.gid).map(OpenResult::SchemeLocal)
}
fn kdup(&self, old_id: usize, buf: UserSliceRo, _caller: CallerCtx) -> Result<OpenResult> {
Err(Error::new(EOPNOTSUPP))
}
@@ -335,10 +335,10 @@ pub trait KernelScheme: Scheme + Send + Sync + 'static {
fn kfutimens(&self, id: usize, buf: UserSliceRo) -> Result<usize> {
Err(Error::new(EBADF))
}
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
Err(Error::new(EBADF))
}
fn kfstatvfs(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstatvfs(&self, id: usize, buf: UserSliceWo) -> Result<()> {
Err(Error::new(EBADF))
}
@@ -346,6 +346,40 @@ pub trait KernelScheme: Scheme + Send + Sync + 'static {
Err(Error::new(EOPNOTSUPP))
}
fn fsync(&self, id: usize) -> Result<()> {
Err(Error::new(EBADF))
}
fn ftruncate(&self, id: usize, len: usize) -> Result<()> {
Err(Error::new(EBADF))
}
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
Err(Error::new(ESPIPE))
}
fn fchmod(&self, id: usize, new_mode: u16) -> Result<()> {
Err(Error::new(EBADF))
}
fn fchown(&self, id: usize, new_uid: u32, new_gid: u32) -> Result<()> {
Err(Error::new(EBADF))
}
fn fevent(&self, id: usize, flags: EventFlags) -> Result<EventFlags> {
Err(Error::new(EBADF))
}
fn frename(&self, id: usize, new_path: &str, caller_ctx: CallerCtx) -> Result<()> {
Err(Error::new(EBADF))
}
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
Err(Error::new(EBADF))
}
fn rmdir(&self, path: &str, ctx: CallerCtx) -> Result<()> {
Err(Error::new(ENOENT))
}
fn unlink(&self, path: &str, ctx: CallerCtx) -> Result<()> {
Err(Error::new(ENOENT))
}
fn close(&self, id: usize) -> Result<()> {
Err(Error::new(EBADF))
}
// TODO: This demonstrates why we need to transition away from a dyn trait.
fn as_user_inner(&self) -> Option<Result<Arc<UserInner>>> { None }
}
@@ -355,9 +389,18 @@ pub enum OpenResult {
SchemeLocal(usize),
External(Arc<RwLock<FileDescription>>),
}
pub struct CallerCtx {
pub pid: usize,
pub uid: u32,
pub gid: u32,
}
pub fn current_caller_ctx() -> Result<CallerCtx> {
match crate::context::current()?.read() {
ref context => Ok(CallerCtx { pid: context.id.into(), uid: context.euid, gid: context.egid }),
pub fn calc_seek_offset(cur_pos: usize, rel_pos: isize, whence: usize, len: usize) -> Result<usize> {
match whence {
SEEK_SET => usize::try_from(rel_pos).map_err(|_| Error::new(EINVAL)),
SEEK_CUR => cur_pos.checked_add_signed(rel_pos).ok_or(Error::new(EOVERFLOW)),
SEEK_END => len.checked_add_signed(rel_pos).ok_or(Error::new(EOVERFLOW)),
_ => return Err(Error::new(EINVAL)),
}
}
+20 -25
View File
@@ -10,11 +10,10 @@ use crate::scheme::SchemeId;
use crate::sync::WaitCondition;
use crate::syscall::error::{Error, Result, EAGAIN, EBADF, EINTR, EINVAL, ENOENT, EPIPE, ESPIPE};
use crate::syscall::flag::{EventFlags, EVENT_READ, EVENT_WRITE, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO};
use crate::syscall::scheme::{CallerCtx, Scheme};
use crate::syscall::data::Stat;
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
use super::{KernelScheme, OpenResult};
use super::{KernelScheme, OpenResult, CallerCtx};
// TODO: Preallocate a number of scheme IDs, since there can only be *one* root namespace, and
// therefore only *one* pipe scheme.
@@ -65,8 +64,7 @@ impl PipeScheme {
}
}
impl Scheme for PipeScheme {
impl KernelScheme for PipeScheme {
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
let (is_writer_not_reader, key) = from_raw_id(id);
let pipe = Arc::clone(PIPES.read().get(&key).ok_or(Error::new(EBADF))?);
@@ -106,11 +104,11 @@ impl Scheme for PipeScheme {
Err(Error::new(EBADF))
}
fn fsync(&self, _id: usize) -> Result<usize> {
Ok(0)
fn fsync(&self, _id: usize) -> Result<()> {
Ok(())
}
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
let (is_write_not_read, key) = from_raw_id(id);
let pipe = Arc::clone(PIPES.read().get(&key).ok_or(Error::new(EBADF))?);
@@ -136,26 +134,12 @@ impl Scheme for PipeScheme {
let _ = PIPES.write().remove(&key);
}
Ok(0)
Ok(())
}
fn seek(&self, _id: usize, _pos: isize, _whence: usize) -> Result<isize> {
fn seek(&self, _id: usize, _pos: isize, _whence: usize) -> Result<usize> {
Err(Error::new(ESPIPE))
}
}
pub struct Pipe {
read_flags: AtomicUsize, // fcntl read flags
write_flags: AtomicUsize, // fcntl write flags
read_condition: WaitCondition, // signals whether there are available bytes to read
write_condition: WaitCondition, // signals whether there is room for additional bytes
queue: Mutex<VecDeque<u8>>,
reader_is_alive: AtomicBool, // starts set, unset when reader closes
writer_is_alive: AtomicBool, // starts set, unset when writer closes
has_run_dup: AtomicBool,
}
impl KernelScheme for PipeScheme {
fn kdup(&self, old_id: usize, user_buf: UserSliceRo, _ctx: CallerCtx) -> Result<OpenResult> {
let (is_writer_not_reader, key) = from_raw_id(old_id);
@@ -277,12 +261,23 @@ impl KernelScheme for PipeScheme {
}
}
}
fn kfstat(&self, _id: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstat(&self, _id: usize, buf: UserSliceWo) -> Result<()> {
buf.copy_exactly(&Stat {
st_mode: MODE_FIFO | 0o666,
..Default::default()
})?;
Ok(0)
Ok(())
}
}
pub struct Pipe {
read_flags: AtomicUsize, // fcntl read flags
write_flags: AtomicUsize, // fcntl write flags
read_condition: WaitCondition, // signals whether there are available bytes to read
write_condition: WaitCondition, // signals whether there is room for additional bytes
queue: Mutex<VecDeque<u8>>,
reader_is_alive: AtomicBool, // starts set, unset when reader closes
writer_is_alive: AtomicBool, // starts set, unset when writer closes
has_run_dup: AtomicBool,
}
+8 -11
View File
@@ -11,7 +11,6 @@ use crate::{
data::{GrantDesc, Map, PtraceEvent, SigAction, Stat},
error::*,
flag::*,
scheme::{CallerCtx, Scheme},
self, usercopy::{UserSliceWo, UserSliceRo},
}, LogicalCpuId, LogicalCpuSet,
};
@@ -31,7 +30,7 @@ use core::{
};
use spin::{Once, RwLock};
use super::OpenResult;
use super::{OpenResult, CallerCtx};
fn read_from(dst: UserSliceWo, src: &[u8], offset: &mut usize) -> Result<usize> {
let avail_src = src.get(*offset..).unwrap_or(&[]);
@@ -514,8 +513,8 @@ impl ProcScheme {
}
}
impl Scheme for ProcScheme {
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
impl KernelScheme for ProcScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
let mut parts = path.splitn(2, '/');
let pid_str = parts.next()
.ok_or(Error::new(ENOENT))?;
@@ -530,7 +529,7 @@ impl Scheme for ProcScheme {
ContextId::new(pid_str.parse().map_err(|_| Error::new(ENOENT))?)
};
self.open_inner(pid, parts.next(), flags, uid, gid)
self.open_inner(pid, parts.next(), flags, ctx.uid, ctx.gid).map(OpenResult::SchemeLocal)
}
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
@@ -557,7 +556,7 @@ impl Scheme for ProcScheme {
}
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
let mut handle = self.handles.write().remove(&id).ok_or(Error::new(EBADF))?;
handle.continue_ignored_children();
@@ -617,10 +616,8 @@ impl Scheme for ProcScheme {
}
_ => (),
}
Ok(0)
Ok(())
}
}
impl KernelScheme for ProcScheme {
fn as_addrspace(&self, number: usize) -> Result<Arc<RwLock<AddrSpace>>> {
if let Operation::AddrSpace { ref addrspace } = self.handles.read().get(&number).ok_or(Error::new(EBADF))?.info.operation {
Ok(Arc::clone(addrspace))
@@ -1094,7 +1091,7 @@ impl KernelScheme for ProcScheme {
buf.copy_common_bytes_from_slice(path.as_bytes())
}
fn kfstat(&self, id: usize, buffer: UserSliceWo) -> Result<usize> {
fn kfstat(&self, id: usize, buffer: UserSliceWo) -> Result<()> {
let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
@@ -1108,7 +1105,7 @@ impl KernelScheme for ProcScheme {
..Stat::default()
})?;
Ok(0)
Ok(())
}
/// Dup is currently used to implement clone() and execve().
+44 -61
View File
@@ -13,11 +13,12 @@ use crate::context;
use crate::syscall::data::Stat;
use crate::syscall::error::*;
use crate::syscall::flag::{EventFlags, O_CREAT, MODE_FILE, MODE_DIR};
use crate::syscall::scheme::{calc_seek_offset_usize, Scheme};
use crate::scheme::{self, SchemeNamespace, SchemeId};
use crate::scheme::user::{UserInner, UserScheme};
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
use super::{KernelScheme, CallerCtx, OpenResult, calc_seek_offset};
struct FolderInner {
data: Box<[u8]>,
pos: Mutex<usize>
@@ -34,9 +35,9 @@ impl FolderInner {
Ok(bytes_read)
}
fn seek(&self, pos: isize, whence: usize) -> Result<isize> {
fn seek(&self, pos: isize, whence: usize) -> Result<usize> {
let mut seek = self.pos.lock();
let new_offset = calc_seek_offset_usize(*seek, pos, whence, self.data.len())?;
let new_offset = calc_seek_offset(*seek, pos, whence, self.data.len())?;
*seek = new_offset as usize;
Ok(new_offset)
}
@@ -67,13 +68,13 @@ impl RootScheme {
}
}
impl Scheme for RootScheme {
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
let path = path.trim_matches('/');
impl KernelScheme for RootScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
let path = path.trim_start_matches('/');
//TODO: Make this follow standards for flags and errors
if flags & O_CREAT == O_CREAT {
if uid != 0 {
if ctx.uid != 0 {
return Err(Error::new(EACCES));
};
@@ -103,7 +104,7 @@ impl Scheme for RootScheme {
self.handles.write().insert(id, Handle::Scheme(inner));
Ok(id)
Ok(OpenResult::SchemeLocal(id))
} else if path.is_empty() {
let scheme_ns = {
let contexts = context::contexts();
@@ -126,47 +127,46 @@ impl Scheme for RootScheme {
pos: Mutex::new(0)
});
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.handles.write().insert(id, Handle::Folder(inner));
Ok(id)
Ok(OpenResult::SchemeLocal(id))
} else {
let inner = Arc::new(
path.as_bytes().to_vec().into_boxed_slice()
);
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.handles.write().insert(id, Handle::File(inner));
Ok(id)
Ok(OpenResult::SchemeLocal(id))
}
}
fn unlink(&self, path: &str, uid: u32, _gid: u32) -> Result<usize> {
fn unlink(&self, path: &str, ctx: CallerCtx) -> Result<()> {
let path = path.trim_matches('/');
if uid == 0 {
let inner = {
let handles = self.handles.read();
handles.iter().find_map(|(_id, handle)| {
match handle {
Handle::Scheme(inner) => {
if path == inner.name.as_ref() {
return Some(inner.clone());
}
},
_ => (),
}
None
}).ok_or(Error::new(ENOENT))?
};
inner.unmount()
} else {
Err(Error::new(EACCES))
if ctx.uid != 0 {
return Err(Error::new(EACCES));
}
let inner = {
let handles = self.handles.read();
handles.iter().find_map(|(_id, handle)| {
match handle {
Handle::Scheme(inner) => {
if path == inner.name.as_ref() {
return Some(inner.clone());
}
},
_ => (),
}
None
}).ok_or(Error::new(ENOENT))?
};
inner.unmount()
}
fn seek(&self, file: usize, pos: isize, whence: usize) -> Result<isize> {
fn seek(&self, file: usize, pos: isize, whence: usize) -> Result<usize> {
let handle = {
let handles = self.handles.read();
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
@@ -206,45 +206,30 @@ impl Scheme for RootScheme {
}
}
fn fpath(&self, file: usize, buf: &mut [u8]) -> Result<usize> {
fn kfpath(&self, file: usize, mut buf: UserSliceWo) -> Result<usize> {
let handle = {
let handles = self.handles.read();
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
handle.clone()
};
let mut i = 0;
let scheme_path = b":";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
let mut bytes_copied = buf.copy_common_bytes_from_slice(b":")?;
buf = buf.advance(bytes_copied).ok_or(Error::new(EINVAL))?;
match handle {
Handle::Scheme(inner) => {
let name = inner.name.as_bytes();
let mut j = 0;
while i < buf.len() && j < name.len() {
buf[i] = name[j];
i += 1;
j += 1;
}
bytes_copied += buf.copy_common_bytes_from_slice(inner.name.as_bytes())?;
},
Handle::File(inner) => {
let mut j = 0;
while i < buf.len() && j < inner.len() {
buf[i] = inner[j];
i += 1;
j += 1;
}
bytes_copied += buf.copy_common_bytes_from_slice(&inner)?;
},
Handle::Folder(_) => ()
}
Ok(i)
Ok(bytes_copied)
}
fn fsync(&self, file: usize) -> Result<usize> {
fn fsync(&self, file: usize) -> Result<()> {
let handle = {
let handles = self.handles.read();
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
@@ -264,7 +249,7 @@ impl Scheme for RootScheme {
}
}
fn close(&self, file: usize) -> Result<usize> {
fn close(&self, file: usize) -> Result<()> {
let handle = self.handles.write().remove(&file).ok_or(Error::new(EBADF))?;
match handle {
Handle::Scheme(inner) => {
@@ -272,10 +257,8 @@ impl Scheme for RootScheme {
},
_ => ()
}
Ok(0)
Ok(())
}
}
impl crate::scheme::KernelScheme for RootScheme {
fn kread(&self, file: usize, buf: UserSliceWo) -> Result<usize> {
let handle = {
let handles = self.handles.read();
@@ -316,7 +299,7 @@ impl crate::scheme::KernelScheme for RootScheme {
}
}
fn kfstat(&self, file: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstat(&self, file: usize, buf: UserSliceWo) -> Result<()> {
let handle = {
let handles = self.handles.read();
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
@@ -347,7 +330,7 @@ impl crate::scheme::KernelScheme for RootScheme {
}
})?;
Ok(0)
Ok(())
}
}
+8 -11
View File
@@ -9,7 +9,6 @@ use crate::event;
use crate::scheme::*;
use crate::sync::WaitQueue;
use crate::syscall::flag::{EventFlags, EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK};
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::UserSliceWo;
static SCHEME_ID: Once<SchemeId> = Once::new();
@@ -49,9 +48,9 @@ impl SerioScheme {
}
}
impl Scheme for SerioScheme {
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid != 0 {
impl KernelScheme for SerioScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
if ctx.uid != 0 {
return Err(Error::new(EPERM));
}
@@ -68,7 +67,7 @@ impl Scheme for SerioScheme {
flags: flags & ! O_ACCMODE
});
Ok(id)
Ok(OpenResult::SchemeLocal(id))
}
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
@@ -96,26 +95,24 @@ impl Scheme for SerioScheme {
Ok(EventFlags::empty())
}
fn fsync(&self, id: usize) -> Result<usize> {
fn fsync(&self, id: usize) -> Result<()> {
let _handle = {
let handles = HANDLES.read();
*handles.get(&id).ok_or(Error::new(EBADF))?
};
Ok(0)
Ok(())
}
/// Close the file `number`
fn close(&self, id: usize) -> Result<usize> {
fn close(&self, id: usize) -> Result<()> {
let _handle = {
let mut handles = HANDLES.write();
handles.remove(&id).ok_or(Error::new(EBADF))?
};
Ok(0)
Ok(())
}
}
impl crate::scheme::KernelScheme for SerioScheme {
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let handle = {
let handles = HANDLES.read();
+3 -3
View File
@@ -1,8 +1,6 @@
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt::Write;
use core::str;
use crate::context;
use crate::scheme;
use crate::syscall::error::Result;
@@ -33,7 +31,7 @@ pub fn resource() -> Result<Vec<u8>> {
let description = file.description.read();
let scheme = {
let _scheme = {
let schemes = scheme::schemes();
match schemes.get(description.scheme) {
Some(scheme) => scheme.clone(),
@@ -44,6 +42,7 @@ pub fn resource() -> Result<Vec<u8>> {
}
};
/*
let mut fpath = [0; 4096];
match scheme.fpath(description.number, &mut fpath) {
Ok(path_len) => {
@@ -54,6 +53,7 @@ pub fn resource() -> Result<Vec<u8>> {
let _ = writeln!(string, "{:>6}: {:>8} {:>8} {:>08X}: {}", fd, description.scheme.get(), description.number, description.flags, err);
}
}
*/
}
}
}
+16 -17
View File
@@ -7,10 +7,11 @@ use spin::RwLock;
use crate::syscall::data::Stat;
use crate::syscall::error::{Error, EBADF, ENOENT, Result};
use crate::syscall::flag::{MODE_DIR, MODE_FILE};
use crate::syscall::scheme::{calc_seek_offset_usize, Scheme};
use crate::arch::interrupt;
use crate::syscall::usercopy::UserSliceWo;
use super::{KernelScheme, CallerCtx, OpenResult, calc_seek_offset};
mod block;
mod context;
mod cpu;
@@ -74,8 +75,8 @@ impl SysScheme {
}
}
impl Scheme for SysScheme {
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
impl KernelScheme for SysScheme {
fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
let path = path.trim_matches('/');
if path.is_empty() {
@@ -87,19 +88,19 @@ impl Scheme for SysScheme {
data.extend_from_slice(entry.0.as_bytes());
}
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.handles.write().insert(id, Handle {
path: "",
data,
mode: MODE_DIR | 0o444,
seek: 0
});
return Ok(id)
return Ok(OpenResult::SchemeLocal(id))
} else {
//Have to iterate to get the path without allocation
for entry in self.files.iter() {
if entry.0 == &path {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
let data = entry.1()?;
self.handles.write().insert(id, Handle {
path: entry.0,
@@ -107,7 +108,7 @@ impl Scheme for SysScheme {
mode: MODE_FILE | 0o444,
seek: 0
});
return Ok(id)
return Ok(OpenResult::SchemeLocal(id));
}
}
}
@@ -115,24 +116,22 @@ impl Scheme for SysScheme {
Err(Error::new(ENOENT))
}
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
let mut handles = self.handles.write();
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, handle.data.len())?;
let new_offset = calc_seek_offset(handle.seek, pos, whence, handle.data.len())?;
handle.seek = new_offset as usize;
Ok(new_offset)
}
fn fsync(&self, _id: usize) -> Result<usize> {
Ok(0)
fn fsync(&self, _id: usize) -> Result<()> {
Ok(())
}
fn close(&self, id: usize) -> Result<usize> {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
fn close(&self, id: usize) -> Result<()> {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
}
}
impl crate::scheme::KernelScheme for SysScheme {
fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
@@ -159,7 +158,7 @@ impl crate::scheme::KernelScheme for SysScheme {
Ok(byte_count)
}
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
let handles = self.handles.read();
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
@@ -171,6 +170,6 @@ impl crate::scheme::KernelScheme for SysScheme {
..Default::default()
})?;
Ok(0)
Ok(())
}
}
+12 -13
View File
@@ -8,10 +8,11 @@ use crate::scheme::SchemeId;
use crate::syscall::data::TimeSpec;
use crate::syscall::error::*;
use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC, EventFlags};
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
use crate::time;
use super::{KernelScheme, CallerCtx, OpenResult};
pub struct TimeScheme {
scheme_id: SchemeId,
next_id: AtomicUsize,
@@ -28,9 +29,9 @@ impl TimeScheme {
}
}
impl Scheme for TimeScheme {
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let clock = path.parse::<usize>().or(Err(Error::new(ENOENT)))?;
impl KernelScheme for TimeScheme {
fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
let clock = path.parse::<usize>().map_err(|_| Error::new(ENOENT))?;
match clock {
CLOCK_REALTIME => (),
@@ -38,10 +39,10 @@ impl Scheme for TimeScheme {
_ => return Err(Error::new(ENOENT))
}
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.handles.write().insert(id, clock);
Ok(id)
Ok(OpenResult::SchemeLocal(id))
}
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
@@ -53,16 +54,14 @@ impl Scheme for TimeScheme {
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(EventFlags::empty()))
}
fn fsync(&self, id: usize) -> Result<usize> {
let handles = self.handles.read();
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
fn fsync(&self, id: usize) -> Result<()> {
self.handles.read().get(&id).ok_or(Error::new(EBADF))?;
Ok(())
}
fn close(&self, id: usize) -> Result<usize> {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
fn close(&self, id: usize) -> Result<()> {
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
}
}
impl crate::scheme::KernelScheme for TimeScheme {
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
let clock = {
let handles = self.handles.read();
+45 -55
View File
@@ -3,12 +3,11 @@ use alloc::sync::{Arc, Weak};
use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use syscall::{SKMSG_FRETURNFD, CallerCtx, SKMSG_PROVIDE_MMAP, MAP_FIXED_NOREPLACE, MunmapFlags, SKMSG_FOBTAINFD, FobtainFdFlags, SendFdFlags};
use syscall::{SKMSG_FRETURNFD, SKMSG_PROVIDE_MMAP, MAP_FIXED_NOREPLACE, MunmapFlags, SKMSG_FOBTAINFD, FobtainFdFlags, SendFdFlags};
use core::mem::size_of;
use core::num::NonZeroUsize;
use core::sync::atomic::{AtomicBool, Ordering};
use core::{mem, usize};
use core::convert::TryFrom;
use spin::{Mutex, RwLock};
use crate::context::context::HardBlockedReason;
@@ -25,10 +24,9 @@ use crate::syscall::data::{Map, Packet};
use crate::syscall::error::*;
use crate::syscall::flag::{EventFlags, EVENT_READ, O_NONBLOCK, PROT_READ, PROT_WRITE, MapFlags};
use crate::syscall::number::*;
use crate::syscall::scheme::Scheme;
use crate::syscall::usercopy::{UserSlice, UserSliceWo, UserSliceRo};
use super::{FileHandle, OpenResult, KernelScheme, current_caller_ctx};
use super::{FileHandle, OpenResult, KernelScheme, CallerCtx};
pub struct UserInner {
root_id: SchemeId,
@@ -74,7 +72,7 @@ impl UserInner {
}
}
pub fn unmount(&self) -> Result<usize> {
pub fn unmount(&self) -> Result<()> {
// First, block new requests and prepare to return EOF
self.unmounting.store(true, Ordering::SeqCst);
@@ -85,7 +83,7 @@ impl UserInner {
event::trigger(self.root_id, self.handle_id, EVENT_READ);
//TODO: wait for all todo and done to be processed?
Ok(0)
Ok(())
}
fn next_id(&self) -> u64 {
@@ -96,7 +94,8 @@ impl UserInner {
}
pub fn call(&self, a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
match self.call_extended(current_caller_ctx()?, None, [a, b, c, d])? {
let ctx = context::current()?.read().caller_ctx();
match self.call_extended(ctx, None, [a, b, c, d])? {
Response::Regular(code) => Error::demux(code),
Response::Fd(_) => {
if a & SYS_RET_FILE == SYS_RET_FILE {
@@ -555,8 +554,8 @@ impl UserInner {
Ok(EventFlags::empty())
}
pub fn fsync(&self) -> Result<usize> {
Ok(0)
pub fn fsync(&self) -> Result<()> {
Ok(())
}
fn fmap_inner(&self, dst_addr_space: Arc<RwLock<AddrSpace>>, file: usize, map: &Map) -> Result<usize> {
@@ -758,45 +757,41 @@ impl UserScheme {
}
}
fn handle_open_res(res: OpenResult) -> Result<usize> {
match res {
OpenResult::SchemeLocal(num) => Ok(num),
OpenResult::External(_) => {
log::warn!("Used Scheme::open when forwarding fd!");
Err(Error::new(EIO))
impl KernelScheme for UserScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.copy_and_capture_tail(path.as_bytes())?;
match inner.call_extended(ctx, None, [SYS_OPEN, address.base(), address.len(), flags])? {
Response::Regular(code) => Error::demux(code).map(OpenResult::SchemeLocal),
Response::Fd(desc) => Ok(OpenResult::External(desc)),
}
}
}
impl Scheme for UserScheme {
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
self.kopen(path, flags, CallerCtx { uid, gid, pid: context::context_id().into() }).and_then(handle_open_res)
}
fn rmdir(&self, path: &str, _uid: u32, _gid: u32) -> Result<usize> {
fn rmdir(&self, path: &str, _ctx: CallerCtx) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.copy_and_capture_tail(path.as_bytes())?;
inner.call(SYS_RMDIR, address.base(), address.len(), 0)
inner.call(SYS_RMDIR, address.base(), address.len(), 0)?;
Ok(())
}
fn unlink(&self, path: &str, _uid: u32, _gid: u32) -> Result<usize> {
fn unlink(&self, path: &str, _ctx: CallerCtx) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.copy_and_capture_tail(path.as_bytes())?;
inner.call(SYS_UNLINK, address.base(), address.len(), 0)
inner.call(SYS_UNLINK, address.base(), address.len(), 0)?;
Ok(())
}
fn seek(&self, file: usize, position: isize, whence: usize) -> Result<isize> {
fn seek(&self, file: usize, position: isize, whence: usize) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let new_offset = inner.call(SYS_LSEEK, file, position as usize, whence)?;
isize::try_from(new_offset).or_else(|_| Err(Error::new(EOVERFLOW)))
inner.call(SYS_LSEEK, file, position as usize, whence)
}
fn fchmod(&self, file: usize, mode: u16) -> Result<usize> {
fn fchmod(&self, file: usize, mode: u16) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
inner.call(SYS_FCHMOD, file, mode as usize, 0)
inner.call(SYS_FCHMOD, file, mode as usize, 0)?;
Ok(())
}
fn fchown(&self, file: usize, uid: u32, gid: u32) -> Result<usize> {
fn fchown(&self, file: usize, uid: u32, gid: u32) -> Result<()> {
{
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -809,7 +804,8 @@ impl Scheme for UserScheme {
}
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
inner.call(SYS_FCHOWN, file, uid as usize, gid as usize)
inner.call(SYS_FCHOWN, file, uid as usize, gid as usize)?;
Ok(())
}
fn fcntl(&self, file: usize, cmd: usize, arg: usize) -> Result<usize> {
@@ -867,35 +863,29 @@ impl Scheme for UserScheme {
}
*/
fn frename(&self, file: usize, path: &str, _uid: u32, _gid: u32) -> Result<usize> {
fn frename(&self, file: usize, path: &str, _ctx: CallerCtx) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.copy_and_capture_tail(path.as_bytes())?;
inner.call(SYS_FRENAME, file, address.base(), address.len())
inner.call(SYS_FRENAME, file, address.base(), address.len())?;
Ok(())
}
fn fsync(&self, file: usize) -> Result<usize> {
fn fsync(&self, file: usize) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
inner.call(SYS_FSYNC, file, 0, 0)
inner.call(SYS_FSYNC, file, 0, 0)?;
Ok(())
}
fn ftruncate(&self, file: usize, len: usize) -> Result<usize> {
fn ftruncate(&self, file: usize, len: usize) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
inner.call(SYS_FTRUNCATE, file, len, 0)
inner.call(SYS_FTRUNCATE, file, len, 0)?;
Ok(())
}
fn close(&self, file: usize) -> Result<usize> {
fn close(&self, file: usize) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
inner.call(SYS_CLOSE, file, 0, 0)
}
}
impl KernelScheme for UserScheme {
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.copy_and_capture_tail(path.as_bytes())?;
match inner.call_extended(ctx, None, [SYS_OPEN, address.base(), address.len(), flags])? {
Response::Regular(code) => Error::demux(code).map(OpenResult::SchemeLocal),
Response::Fd(desc) => Ok(OpenResult::External(desc)),
}
inner.call(SYS_CLOSE, file, 0, 0)?;
Ok(())
}
fn kdup(&self, file: usize, buf: UserSliceRo, ctx: CallerCtx) -> Result<OpenResult> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
@@ -939,19 +929,19 @@ impl KernelScheme for UserScheme {
address.release()?;
result
}
fn kfstat(&self, file: usize, stat: UserSliceWo) -> Result<usize> {
fn kfstat(&self, file: usize, stat: UserSliceWo) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture_user(stat)?;
let result = inner.call(SYS_FSTAT, file, address.base(), address.len());
address.release()?;
result
result.map(|_| ())
}
fn kfstatvfs(&self, file: usize, stat: UserSliceWo) -> Result<usize> {
fn kfstatvfs(&self, file: usize, stat: UserSliceWo) -> Result<()> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture_user(stat)?;
let result = inner.call(SYS_FSTATVFS, file, address.base(), address.len());
address.release()?;
result
result.map(|_| ())
}
fn kfmap(&self, file: usize, addr_space: &Arc<RwLock<AddrSpace>>, map: &Map, _consume: bool) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
+23 -23
View File
@@ -7,11 +7,10 @@ use crate::context::file::{FileDescriptor, FileDescription};
use crate::context;
use crate::context::memory::{PageSpan, AddrSpace};
use crate::paging::{PAGE_SIZE, VirtualAddress, Page};
use crate::scheme::{self, FileHandle, OpenResult, current_caller_ctx, KernelScheme, SchemeId};
use crate::scheme::{self, FileHandle, OpenResult, KernelScheme, SchemeId, CallerCtx};
use crate::syscall::data::Stat;
use crate::syscall::error::*;
use crate::syscall::flag::*;
use crate::syscall::scheme::CallerCtx;
use super::usercopy::{UserSlice, UserSliceWo, UserSliceRo};
@@ -87,9 +86,9 @@ pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
}
/// rmdir syscall
pub fn rmdir(raw_path: UserSliceRo) -> Result<usize> {
let (uid, gid, scheme_ns) = match context::current()?.read() {
ref context => (context.euid, context.egid, context.ens),
pub fn rmdir(raw_path: UserSliceRo) -> Result<()> {
let (scheme_ns, caller_ctx) = match context::current()?.read() {
ref context => (context.ens, context.caller_ctx()),
};
/*
@@ -107,13 +106,13 @@ pub fn rmdir(raw_path: UserSliceRo) -> Result<usize> {
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
Arc::clone(scheme)
};
scheme.rmdir(reference, uid, gid)
scheme.rmdir(reference, caller_ctx)
}
/// Unlink syscall
pub fn unlink(raw_path: UserSliceRo) -> Result<usize> {
let (uid, gid, scheme_ns) = match context::current()?.read() {
ref context => (context.euid, context.egid, context.ens),
pub fn unlink(raw_path: UserSliceRo) -> Result<()> {
let (scheme_ns, caller_ctx) = match context::current()?.read() {
ref context => (context.ens, context.caller_ctx()),
};
/*
let mut path_buf = BorrowedHtBuf::head()?;
@@ -130,11 +129,11 @@ pub fn unlink(raw_path: UserSliceRo) -> Result<usize> {
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
Arc::clone(scheme)
};
scheme.unlink(reference, uid, gid)
scheme.unlink(reference, caller_ctx)
}
/// Close syscall
pub fn close(fd: FileHandle) -> Result<usize> {
pub fn close(fd: FileHandle) -> Result<()> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -146,8 +145,9 @@ pub fn close(fd: FileHandle) -> Result<usize> {
}
fn duplicate_file(fd: FileHandle, user_buf: UserSliceRo) -> Result<FileDescriptor> {
let file = context::current()?.read()
.get_file(fd).ok_or(Error::new(EBADF))?;
let (file, caller_ctx) = match context::current()?.read() {
ref context => (context.get_file(fd).ok_or(Error::new(EBADF))?, context.caller_ctx()),
};
if user_buf.is_empty() {
Ok(FileDescriptor {
@@ -164,7 +164,7 @@ fn duplicate_file(fd: FileHandle, user_buf: UserSliceRo) -> Result<FileDescripto
Arc::clone(scheme)
};
match scheme.kdup(description.number, user_buf, current_caller_ctx()?)? {
match scheme.kdup(description.number, user_buf, caller_ctx)? {
OpenResult::SchemeLocal(number) => Arc::new(RwLock::new(FileDescription {
namespace: description.namespace,
scheme: description.scheme,
@@ -309,9 +309,9 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize) -> Result<usize> {
}
}
pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<usize> {
let (file, uid, gid, scheme_ns) = match context::current()?.read() {
ref context => (context.get_file(fd).ok_or(Error::new(EBADF))?, context.euid, context.egid, context.ens),
pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<()> {
let (file, caller_ctx, scheme_ns) = match context::current()?.read() {
ref context => (context.get_file(fd).ok_or(Error::new(EBADF))?, CallerCtx { uid: context.euid, gid: context.egid, pid: context.id.get() }, context.ens),
};
/*
@@ -332,15 +332,15 @@ pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<usize> {
let description = file.description.read();
if scheme_id == description.scheme {
scheme.frename(description.number, reference, uid, gid)
} else {
Err(Error::new(EXDEV))
if scheme_id != description.scheme {
return Err(Error::new(EXDEV));
}
scheme.frename(description.number, reference, caller_ctx)
}
/// File status
pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<usize> {
pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<()> {
file_op_generic_ext(fd, |scheme, scheme_id, _, number| {
scheme.kfstat(number, user_buf)?;
@@ -350,7 +350,7 @@ pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<usize> {
let st_dev = scheme_id.get().try_into().map_err(|_| Error::new(EOVERFLOW))?;
user_buf.advance(memoffset::offset_of!(Stat, st_dev)).and_then(|b| b.limit(8)).ok_or(Error::new(EIO))?.copy_from_slice(&u64::to_ne_bytes(st_dev))?;
Ok(0)
Ok(())
})
}
+12 -12
View File
@@ -16,7 +16,6 @@ pub use self::syscall::{
io,
number,
ptrace_event,
scheme,
};
pub use self::driver::*;
@@ -91,8 +90,8 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
SYS_ARG_MSLICE => match a {
SYS_READ => file_op_generic(fd, |scheme, _, number| scheme.kread(number, UserSlice::wo(c, d)?)),
SYS_FPATH => file_op_generic(fd, |scheme, _, number| scheme.kfpath(number, UserSlice::wo(c, d)?)),
SYS_FSTAT => fstat(fd, UserSlice::wo(c, d)?),
SYS_FSTATVFS => file_op_generic(fd, |scheme, _, number| scheme.kfstatvfs(number, UserSlice::wo(c, d)?)),
SYS_FSTAT => fstat(fd, UserSlice::wo(c, d)?).map(|()| 0),
SYS_FSTATVFS => file_op_generic(fd, |scheme, _, number| scheme.kfstatvfs(number, UserSlice::wo(c, d)?).map(|()| 0)),
_ => return Err(Error::new(ENOSYS)),
},
@@ -106,18 +105,19 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
#[cfg(target_pointer_width = "64")]
SYS_SENDFD => sendfd(fd, FileHandle::from(c), d, e as u64),
SYS_LSEEK => file_op_generic(fd, |scheme, _, number| Ok(scheme.seek(number, c as isize, d)? as usize)),
SYS_FCHMOD => file_op_generic(fd, |scheme, _, number| scheme.fchmod(number, c as u16)),
SYS_FCHOWN => file_op_generic(fd, |scheme, _, number| scheme.fchown(number, c as u32, d as u32)),
SYS_LSEEK => file_op_generic(fd, |scheme, _, number| scheme.seek(number, c as isize, d)),
SYS_FCHMOD => file_op_generic(fd, |scheme, _, number| scheme.fchmod(number, c as u16).map(|()| 0)),
SYS_FCHOWN => file_op_generic(fd, |scheme, _, number| scheme.fchown(number, c as u32, d as u32).map(|()| 0)),
SYS_FCNTL => fcntl(fd, c, d),
SYS_FEVENT => file_op_generic(fd, |scheme, _, number| Ok(scheme.fevent(number, EventFlags::from_bits_truncate(c))?.bits())),
SYS_FRENAME => frename(fd, UserSlice::ro(c, d)?),
SYS_FRENAME => frename(fd, UserSlice::ro(c, d)?).map(|()| 0),
SYS_FUNMAP => funmap(b, c),
SYS_FSYNC => file_op_generic(fd, |scheme, _, number| scheme.fsync(number)),
SYS_FTRUNCATE => file_op_generic(fd, |scheme, _, number| scheme.ftruncate(number, c)),
SYS_FSYNC => file_op_generic(fd, |scheme, _, number| scheme.fsync(number).map(|()| 0)),
// TODO: 64-bit lengths on 32-bit platforms
SYS_FTRUNCATE => file_op_generic(fd, |scheme, _, number| scheme.ftruncate(number, c).map(|()| 0)),
SYS_CLOSE => close(fd),
SYS_CLOSE => close(fd).map(|()| 0),
_ => return Err(Error::new(ENOSYS)),
}
@@ -125,8 +125,8 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
},
SYS_CLASS_PATH => match a {
SYS_OPEN => open(UserSlice::ro(b, c)?, d).map(FileHandle::into),
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?),
SYS_UNLINK => unlink(UserSlice::ro(b, c)?),
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?).map(|()| 0),
SYS_UNLINK => unlink(UserSlice::ro(b, c)?).map(|()| 0),
_ => Err(Error::new(ENOSYS))
},
_ => match a {