diff --git a/Cargo.lock b/Cargo.lock index ca5e0dbab7..8556d43ca9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -123,6 +123,7 @@ dependencies = [ "fdt", "goblin", "hashbrown", + "indexmap", "linked_list_allocator 0.9.1", "log", "raw-cpuid", diff --git a/Cargo.toml b/Cargo.toml index 87ff6012c8..343c51336b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,8 @@ spinning_top = { version = "0.3", features = ["arc_lock"] } rmm = { path = "rmm", default-features = false } arrayvec = { version = "0.7.4", default-features = false } slab = { version = "0.4", default-features = false } +# TODO: Remove +indexmap = { version = "2.5.0", default-features = false } [dependencies.goblin] version = "0.2.1" diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs index ac92474acc..93d59ec571 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs @@ -6,9 +6,12 @@ //! The kernel validates paths and file descriptors before they are passed to schemes, //! also stripping the scheme identifier of paths if necessary. +// TODO: Move handling of the global namespace to userspace. + use alloc::{boxed::Box, collections::BTreeMap, string::ToString, sync::Arc, vec::Vec}; -use core::sync::atomic::AtomicUsize; -use hashbrown::HashMap; +use core::{hash::BuildHasherDefault, sync::atomic::AtomicUsize}; +use hashbrown::{hash_map::DefaultHashBuilder, HashMap}; +use indexmap::IndexMap; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; use syscall::{EventFlags, MunmapFlags, SendFdFlags}; @@ -89,7 +92,7 @@ int_like!(SchemeId, usize); int_like!(FileHandle, AtomicFileHandle, usize, AtomicUsize); pub struct SchemeIter<'a> { - inner: Option, SchemeId>>, + inner: Option, SchemeId>>, } impl<'a> Iterator for SchemeIter<'a> { @@ -103,7 +106,7 @@ impl<'a> Iterator for SchemeIter<'a> { /// Scheme list type pub struct SchemeList { map: HashMap, - pub(crate) names: HashMap, SchemeId>>, + pub(crate) names: HashMap, SchemeId, DefaultHashBuilder>>, next_ns: usize, next_id: usize, } @@ -157,7 +160,8 @@ impl SchemeList { /// Initialize the null namespace fn new_null(&mut self) { let ns = SchemeNamespace(0); - self.names.insert(ns, HashMap::new()); + self.names + .insert(ns, IndexMap::with_hasher(BuildHasherDefault::default())); //TODO: Only memory: is in the null namespace right now. It should be removed when //anonymous mmap's are implemented @@ -172,7 +176,8 @@ impl SchemeList { fn new_ns(&mut self) -> SchemeNamespace { let ns = SchemeNamespace(self.next_ns); self.next_ns += 1; - self.names.insert(ns, HashMap::new()); + self.names + .insert(ns, IndexMap::with_hasher(BuildHasherDefault::default())); self.insert(ns, "", |scheme_id| { KernelSchemes::Root(Arc::new(RootScheme::new(ns, scheme_id))) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index 8632cd76b2..f7f1059862 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -254,15 +254,16 @@ impl KernelScheme for RootScheme { let mut buf = DirentBuf::new(buf, header_size).ok_or(Error::new(EIO))?; { let schemes = scheme::schemes(); - for (name, scheme_id) in schemes + for (i, (name, _)) in schemes .iter_name(ens) - .filter(|(_, s)| opaque <= s.get() as u64) + .enumerate() + .skip_while(|(i, _)| (*i as u64) < opaque) { buf.entry(DirEntry { kind: DirentKind::Unspecified, name, inode: 0, - next_opaque_id: scheme_id.get() as u64 + 1, + next_opaque_id: i as u64 + 1, })?; } }