From d383cfb595327f320a614db4a78062cc53682d65 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 --- Cargo.toml | 2 ++ kernel/lib.rs | 9 ++++++--- kernel/scheme/mod.rs | 15 ++++++++++++++- kernel/syscall/fs.rs | 22 ++++++++++++++++++---- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b0c6c2..9e59f9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ crate-type = ["staticlib"] [dependencies] bitflags = "*" +lazy_static = "*" +spin = "*" [dev-dependencies] arch_test = { path = "arch/test" } diff --git a/kernel/lib.rs b/kernel/lib.rs index 257c9dd..0768a61 100644 --- a/kernel/lib.rs +++ b/kernel/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/kernel/scheme/mod.rs b/kernel/scheme/mod.rs index b99cc72..176407b 100644 --- a/kernel/scheme/mod.rs +++ b/kernel/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/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index e632b75..1deedc8 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/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