From 9f79abe5427cbad0b80ef9635dca444c61bcb17a Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 16 Aug 2016 11:04:14 -0600 Subject: [PATCH] Lazy static init of schemes --- lib.rs | 9 ++++++--- scheme/mod.rs | 15 ++++++++++++++- syscall/fs.rs | 22 ++++++++++++++++++---- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/lib.rs b/lib.rs index 257c9dd..0768a61 100644 --- a/lib.rs +++ b/lib.rs @@ -70,9 +70,6 @@ #![feature(question_mark)] #![no_std] -#[macro_use] -extern crate bitflags; - use arch::interrupt::{enable_interrupts, halt}; /// Architecture specific items (test) @@ -89,6 +86,12 @@ extern crate alloc; #[macro_use] extern crate collections; +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate lazy_static; +extern crate spin; + /// Context management pub mod context; diff --git a/scheme/mod.rs b/scheme/mod.rs index b99cc72..176407b 100644 --- a/scheme/mod.rs +++ b/scheme/mod.rs @@ -6,6 +6,13 @@ //! The kernel validates paths and file descriptors before they are passed to schemes, //! also stripping the scheme identifier of paths if necessary. +use alloc::arc::Arc; +use alloc::boxed::Box; + +use collections::BTreeMap; + +use spin::{Mutex, RwLock}; + use syscall::Result; use self::debug::DebugScheme; @@ -14,7 +21,13 @@ use self::debug::DebugScheme; pub mod debug; /// Schemes list -pub static mut SCHEME: DebugScheme = DebugScheme; +lazy_static! { + pub static ref SCHEMES: RwLock, Arc>>>> = { + let mut map: BTreeMap, Arc>>> = BTreeMap::new(); + map.insert(Box::new(*b"debug"), Arc::new(Mutex::new(Box::new(DebugScheme)))); + RwLock::new(map) + }; +} /// A scheme trait, implemented by a scheme handler pub trait Scheme { diff --git a/syscall/fs.rs b/syscall/fs.rs index e632b75..1deedc8 100644 --- a/syscall/fs.rs +++ b/syscall/fs.rs @@ -1,7 +1,5 @@ //! Filesystem syscalls -use scheme::Scheme; - use super::{Error, Result}; /// Read syscall @@ -28,8 +26,24 @@ pub fn write(fd: usize, buf: &[u8]) -> Result { /// Open syscall pub fn open(path: &[u8], flags: usize) -> Result { - println!("Open {:?}: {:X}", ::core::str::from_utf8(path), flags); - let file = unsafe { &mut ::scheme::SCHEME }.open(path, flags)?; + let mut parts = path.splitn(2, |&b| b == b':'); + let namespace_opt = parts.next(); + let reference_opt = parts.next(); + println!("Open namespace {:?} reference {:?}: {:X}", namespace_opt.map(::core::str::from_utf8), reference_opt.map(::core::str::from_utf8), flags); + + let file = { + if let Some(namespace) = namespace_opt { + let schemes = ::scheme::SCHEMES.read(); + if let Some(scheme_mutex) = schemes.get(namespace) { + scheme_mutex.lock().open(reference_opt.unwrap_or(b""), flags) + } else { + Err(Error::NoEntry) + } + } else { + Err(Error::NoEntry) + } + }?; + if let Some(fd) = unsafe { &mut ::context::CONTEXT }.add_file(::context::file::File { scheme: 0, number: file