From 80afcc8879605601f5c47998c320fae8395a0ed6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 28 Apr 2017 15:40:15 +0200 Subject: [PATCH 1/6] Implement listing all schemes using `:` scheme --- src/scheme/root.rs | 55 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index cd08fd3..f89f56e 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -10,11 +10,17 @@ use syscall::scheme::Scheme; use scheme::{self, SchemeNamespace, SchemeId}; use scheme::user::{UserInner, UserScheme}; +#[derive(Clone)] +enum UserOrListHandle { + User(Arc), + List(AtomicUsize) +} + pub struct RootScheme { scheme_ns: SchemeNamespace, scheme_id: SchemeId, next_id: AtomicUsize, - handles: RwLock>> + handles: RwLock>, } impl RootScheme { @@ -30,7 +36,17 @@ impl RootScheme { impl Scheme for RootScheme { fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { + use syscall::*; if uid == 0 { + if flags & O_DIRECTORY = O_DIRECTORY { + if flags & O_ACCMODE != O_RDONLY { + return Err(Error::new(EACCES)); + } + let id = self.next_id.fetch_add(1, Ordering::SeqCst); + self.ls_handles.write().insert(id, UserOrListHandle::List(0)); + return Ok(id); + } + let context = { let contexts = context::contexts(); let context = contexts.current().ok_or(Error::new(ESRCH))?; @@ -50,7 +66,7 @@ impl Scheme for RootScheme { inner }; - self.handles.write().insert(id, inner); + self.handles.write().insert(id, UserOrListHandler::User(inner)); Ok(id) } else { @@ -77,8 +93,32 @@ impl Scheme for RootScheme { let inner = handles.get(&file).ok_or(Error::new(EBADF))?; inner.clone() }; - - inner.read(buf) + + match &*inner { + UserOrListInner::User(ref inner) => inner.read(buf), + UserOrListInner::List(ref num) => { + let scheme_ns = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.ens + }; + + let schemes = scheme::schemes(); + + let scheme_name = schemes.iterName(scheme_ns).nth(num.load(Ordering::SeqCst)).0.as_bytes(); + + let mut i = 0; + while i < buf.len() && i < scheme_name.len() { + buf[i] = scheme_name[i]; + i += 1; + } + + num.fetch_add(1, Ordering::SeqCst) + + Ok(i) + } + } } fn write(&self, file: usize, buf: &[u8]) -> Result { @@ -87,8 +127,11 @@ impl Scheme for RootScheme { let inner = handles.get(&file).ok_or(Error::new(EBADF))?; inner.clone() }; - - inner.write(buf) + + match &*inner { + UserOrListInner::User(ref inner) => inner.write(buf), + UserOrListInner::List(_) => Err(Error::new(::syscall::EBADF)) + } } fn fevent(&self, file: usize, flags: usize) -> Result { From 4c006bca48f2ba42358b8226be6bb03a039cfbd1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 28 Apr 2017 16:18:41 +0200 Subject: [PATCH 2/6] Remove UserOrListHandle --- src/scheme/root.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index f89f56e..40de21e 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -10,17 +10,12 @@ use syscall::scheme::Scheme; use scheme::{self, SchemeNamespace, SchemeId}; use scheme::user::{UserInner, UserScheme}; -#[derive(Clone)] -enum UserOrListHandle { - User(Arc), - List(AtomicUsize) -} - pub struct RootScheme { scheme_ns: SchemeNamespace, scheme_id: SchemeId, next_id: AtomicUsize, - handles: RwLock>, + handles: RwLock>>, + ls_handles: RwLock>, } impl RootScheme { @@ -29,21 +24,22 @@ impl RootScheme { scheme_ns: scheme_ns, scheme_id: scheme_id, next_id: AtomicUsize::new(0), - handles: RwLock::new(BTreeMap::new()) + handles: RwLock::new(BTreeMap::new()), + ls_handles: RwLock::new(BTreeMap::new()), } } } impl Scheme for RootScheme { fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { - use syscall::*; + use syscall::syscall::*; if uid == 0 { - if flags & O_DIRECTORY = O_DIRECTORY { + if flags & O_DIRECTORY == O_DIRECTORY { if flags & O_ACCMODE != O_RDONLY { return Err(Error::new(EACCES)); } let id = self.next_id.fetch_add(1, Ordering::SeqCst); - self.ls_handles.write().insert(id, UserOrListHandle::List(0)); + self.ls_handles.write().insert(id, AtomicUsize::new(0)); return Ok(id); } @@ -56,6 +52,7 @@ impl Scheme for RootScheme { let id = self.next_id.fetch_add(1, Ordering::SeqCst); let inner = { + use scheme; let path_box = path.to_vec().into_boxed_slice(); let mut schemes = scheme::schemes_mut(); let inner = Arc::new(UserInner::new(self.scheme_id, id, path_box.clone(), flags, context)); @@ -66,7 +63,7 @@ impl Scheme for RootScheme { inner }; - self.handles.write().insert(id, UserOrListHandler::User(inner)); + self.handles.write().insert(id, inner); Ok(id) } else { @@ -114,7 +111,7 @@ impl Scheme for RootScheme { i += 1; } - num.fetch_add(1, Ordering::SeqCst) + num.fetch_add(1, Ordering::SeqCst); Ok(i) } @@ -128,10 +125,7 @@ impl Scheme for RootScheme { inner.clone() }; - match &*inner { - UserOrListInner::User(ref inner) => inner.write(buf), - UserOrListInner::List(_) => Err(Error::new(::syscall::EBADF)) - } + inner.write(buf) } fn fevent(&self, file: usize, flags: usize) -> Result { From c9fdc4beaec63c29295fae2197369e89370cfcbd Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 28 Apr 2017 18:42:33 +0200 Subject: [PATCH 3/6] Make it working --- src/scheme/root.rs | 68 +++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index 40de21e..e19ecd5 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -32,7 +32,8 @@ impl RootScheme { impl Scheme for RootScheme { fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { - use syscall::syscall::*; + use syscall::flag::*; + if uid == 0 { if flags & O_DIRECTORY == O_DIRECTORY { if flags & O_ACCMODE != O_RDONLY { @@ -42,7 +43,7 @@ impl Scheme for RootScheme { self.ls_handles.write().insert(id, AtomicUsize::new(0)); return Ok(id); } - + let context = { let contexts = context::contexts(); let context = contexts.current().ok_or(Error::new(ESRCH))?; @@ -57,9 +58,9 @@ impl Scheme for RootScheme { let mut schemes = scheme::schemes_mut(); let inner = Arc::new(UserInner::new(self.scheme_id, id, path_box.clone(), flags, context)); schemes.insert(self.scheme_ns, path_box, |scheme_id| { - inner.scheme_id.store(scheme_id, Ordering::SeqCst); - Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner)))) - })?; + inner.scheme_id.store(scheme_id, Ordering::SeqCst); + Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner)))) + })?; inner }; @@ -87,33 +88,44 @@ impl Scheme for RootScheme { fn read(&self, file: usize, buf: &mut [u8]) -> Result { let inner = { let handles = self.handles.read(); - let inner = handles.get(&file).ok_or(Error::new(EBADF))?; - inner.clone() + handles.get(&file).map(Clone::clone) }; - - match &*inner { - UserOrListInner::User(ref inner) => inner.read(buf), - UserOrListInner::List(ref num) => { - let scheme_ns = { - let contexts = context::contexts(); - let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; - let context = context_lock.read(); - context.ens - }; - - let schemes = scheme::schemes(); - - let scheme_name = schemes.iterName(scheme_ns).nth(num.load(Ordering::SeqCst)).0.as_bytes(); - + + if let Some(inner) = inner { + inner.read(buf) + } else { + let scheme_ns = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.ens + }; + + let schemes = scheme::schemes(); + let mut schemes_iter = schemes.iter_name(scheme_ns); + + let num = { + let handles = self.ls_handles.read(); + let inner = handles.get(&file).ok_or(Error::new(EBADF))?; + inner.load(Ordering::SeqCst) + }; + + if let Some(scheme) = schemes_iter.nth(num) { let mut i = 0; - while i < buf.len() && i < scheme_name.len() { - buf[i] = scheme_name[i]; + while i < buf.len() && i < scheme.0.len() { + buf[i] = scheme.0[i]; i += 1; } - - num.fetch_add(1, Ordering::SeqCst); - + + { + let handles = self.ls_handles.read(); + let inner = handles.get(&file).ok_or(Error::new(EBADF))?; + inner.fetch_add(1, Ordering::SeqCst) + }; + Ok(i) + } else { + Ok(0) } } } @@ -124,7 +136,7 @@ impl Scheme for RootScheme { let inner = handles.get(&file).ok_or(Error::new(EBADF))?; inner.clone() }; - + inner.write(buf) } From 4441b750cf1b64c1b76446054c6efd4e633c9092 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 28 Apr 2017 18:43:39 +0200 Subject: [PATCH 4/6] Remove unnecessary change --- src/scheme/root.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index e19ecd5..9b84936 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -58,9 +58,9 @@ impl Scheme for RootScheme { let mut schemes = scheme::schemes_mut(); let inner = Arc::new(UserInner::new(self.scheme_id, id, path_box.clone(), flags, context)); schemes.insert(self.scheme_ns, path_box, |scheme_id| { - inner.scheme_id.store(scheme_id, Ordering::SeqCst); - Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner)))) - })?; + inner.scheme_id.store(scheme_id, Ordering::SeqCst); + Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner)))) + })?; inner }; From 8ffe704e7a7f47899c6d4e9f02e7b9e58bdfe51c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 28 Apr 2017 18:44:37 +0200 Subject: [PATCH 5/6] Remove yet another unnecessary change --- src/scheme/root.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index 9b84936..b34a504 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -53,7 +53,6 @@ impl Scheme for RootScheme { let id = self.next_id.fetch_add(1, Ordering::SeqCst); let inner = { - use scheme; let path_box = path.to_vec().into_boxed_slice(); let mut schemes = scheme::schemes_mut(); let inner = Arc::new(UserInner::new(self.scheme_id, id, path_box.clone(), flags, context)); From ca8b6f522eddd0e0e771f2b628c314c42bed1607 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 29 Apr 2017 10:43:50 +0200 Subject: [PATCH 6/6] Fix closing ls handle --- src/scheme/root.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/scheme/root.rs b/src/scheme/root.rs index b34a504..42bcaad 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -184,6 +184,9 @@ impl Scheme for RootScheme { } fn close(&self, file: usize) -> Result { - self.handles.write().remove(&file).ok_or(Error::new(EBADF)).and(Ok(0)) + if self.handles.write().remove(&file).is_none() { + self.ls_handles.write().remove(&file).ok_or(Error::new(EBADF))?; + } + Ok(0) } }