diff --git a/Cargo.toml b/Cargo.toml index 853435157c4cfeecef5ab56072b9c5f8bc2510cc..09ee5d605990c18b930a361eb75074f3bdd2c098 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,10 @@ authors = ["Jeremy Soller <jackpot51@gmail.com>"] name = "redoxfs" path = "src/lib.rs" +[[bin]] +name = "redoxfs" +path = "scheme/main.rs" + [[bin]] name = "redoxfs-fuse" path = "fuse/main.rs" @@ -20,6 +24,9 @@ name = "redoxfs-utility" path = "utility/main.rs" [dependencies] -redox-system = {path = "../system/"} +spin = "*" +syscall = {path = "../../syscall/"} + +[target.'cfg(unix)'.dependencies] fuse = "0.2" time = "*" diff --git a/scheme/cache/mod.rs b/scheme/cache/mod.rs index 0798592a064d12293904feb8fb74edf6a663aca0..3df653b21db2afd1ba96c2deacc9921c5bf6d8a7 100644 --- a/scheme/cache/mod.rs +++ b/scheme/cache/mod.rs @@ -2,7 +2,7 @@ use std::{cmp, ptr}; use redoxfs::Disk; -use system::error::Result; +use syscall::error::Result; use self::lru_cache::LruCache; diff --git a/scheme/image.rs b/scheme/image.rs index 169727095b20294fe1478512b14c5e10ab1854a8..b589c5cb69ff142a24fa96b5bb93ac4603d8fc1d 100644 --- a/scheme/image.rs +++ b/scheme/image.rs @@ -3,7 +3,7 @@ use std::io::{Read, Write, Seek, SeekFrom}; use redoxfs::Disk; -use system::error::{Error, Result, EIO}; +use syscall::error::{Error, Result, EIO}; macro_rules! try_disk { ($expr:expr) => (match $expr { diff --git a/scheme/main.rs b/scheme/main.rs index e82005a9a955337db434f4f1932fd58b984205e0..d739091a6441c2ef982fa031fcefc3856b854dc1 100644 --- a/scheme/main.rs +++ b/scheme/main.rs @@ -1,16 +1,16 @@ #![deny(warnings)] extern crate redoxfs; - -extern crate system; +extern crate spin; +extern crate syscall; use std::env; use std::fs::File; use std::io::{Read, Write}; use std::mem::size_of; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::thread; -use std::time::Duration; +use spin::Mutex; use cache::Cache; use image::Image; @@ -18,7 +18,7 @@ use scheme::FileScheme; use redoxfs::FileSystem; -use system::scheme::{Packet, Scheme}; +use syscall::{Packet, Scheme}; pub mod cache; pub mod image; @@ -43,9 +43,9 @@ fn main() { Ok(mut socket) => { println!("redoxfs: mounted filesystem {} on file:", path); - *status_daemon.lock().unwrap() = Status::Running; + *status_daemon.lock() = Status::Running; - let mut scheme = FileScheme::new(fs); + let scheme = FileScheme::new(fs); loop { let mut packet = Packet::default(); while socket.read(&mut packet).unwrap() == size_of::<Packet>() { @@ -61,17 +61,17 @@ fn main() { Err(err) => println!("redoxfs: failed to open image {}: {}", path, err) } - *status_daemon.lock().unwrap() = Status::Stopping; + *status_daemon.lock() = Status::Stopping; }); 'waiting: loop { - match *status_mutex.lock().unwrap() { + match *status_mutex.lock() { Status::Starting => (), Status::Running => break 'waiting, Status::Stopping => break 'waiting, } - thread::sleep(Duration::new(0, 30000000)); + thread::yield_now(); } } else { println!("redoxfs: no disk image provided"); diff --git a/scheme/resource.rs b/scheme/resource.rs index 9f4071302e7d64c0804cd5f329096797801ab0c3..4a584eba5f1569ee6afd214d23fab60b69b9d448 100644 --- a/scheme/resource.rs +++ b/scheme/resource.rs @@ -2,8 +2,8 @@ use redoxfs::FileSystem; use std::cmp::{min, max}; -use system::error::{Error, Result, EINVAL}; -use system::syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END, MODE_DIR, MODE_FILE}; +use syscall::error::{Error, Result, EINVAL}; +use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END, MODE_DIR, MODE_FILE}; pub trait Resource { fn dup(&self) -> Result<Box<Resource>>; @@ -17,15 +17,15 @@ pub trait Resource { } pub struct DirResource { - path: String, + path: Vec<u8>, data: Vec<u8>, seek: usize, } impl DirResource { - pub fn new(path: &str, data: Vec<u8>) -> DirResource { + pub fn new(path: &[u8], data: Vec<u8>) -> DirResource { DirResource { - path: path.to_string(), + path: path.to_vec(), data: data, seek: 0, } @@ -67,9 +67,8 @@ impl Resource for DirResource { fn path(&self, buf: &mut [u8]) -> Result<usize> { let mut i = 0; - let path = self.path.as_bytes(); - while i < buf.len() && i < path.len() { - buf[i] = path[i]; + while i < buf.len() && i < self.path.len() { + buf[i] = self.path[i]; i += 1; } Ok(i) @@ -91,16 +90,16 @@ impl Resource for DirResource { } pub struct FileResource { - path: String, + path: Vec<u8>, block: u64, seek: u64, size: u64, } impl FileResource { - pub fn new(path: &str, block: u64, size: u64) -> FileResource { + pub fn new(path: &[u8], block: u64, size: u64) -> FileResource { FileResource { - path: path.to_string(), + path: path.to_vec(), block: block, seek: 0, size: size, @@ -146,9 +145,8 @@ impl Resource for FileResource { fn path(&self, buf: &mut [u8]) -> Result<usize> { let mut i = 0; - let path = self.path.as_bytes(); - while i < buf.len() && i < path.len() { - buf[i] = path[i]; + while i < buf.len() && i < self.path.len() { + buf[i] = self.path[i]; i += 1; } Ok(i) diff --git a/scheme/scheme.rs b/scheme/scheme.rs index 7deb198b79f6812cc6e7d661047d61db07d5e0af..627ced349fa4902d8272f72c0680ee7443f0e138 100644 --- a/scheme/scheme.rs +++ b/scheme/scheme.rs @@ -1,41 +1,46 @@ use resource::{Resource, DirResource, FileResource}; use redoxfs::{FileSystem, Node}; - +use spin::Mutex; +use std::cell::RefCell; use std::collections::BTreeMap; +use std::str; +use std::sync::atomic::{AtomicUsize, Ordering}; -use system::error::{Error, Result, EEXIST, EISDIR, ENOTDIR, EPERM, ENOENT, EBADF}; -use system::scheme::Scheme; -use system::syscall::{Stat, O_CREAT, O_TRUNC}; +use syscall::error::{Error, Result, EEXIST, EISDIR, ENOTDIR, EPERM, ENOENT, EBADF}; +use syscall::scheme::Scheme; +use syscall::{Stat, O_CREAT, O_TRUNC}; pub struct FileScheme { - fs: FileSystem, - next_id: isize, - files: BTreeMap<usize, Box<Resource>> + fs: RefCell<FileSystem>, + next_id: AtomicUsize, + files: Mutex<BTreeMap<usize, Box<Resource>>> } impl FileScheme { pub fn new(fs: FileSystem) -> FileScheme { FileScheme { - fs: fs, - next_id: 1, - files: BTreeMap::new() + fs: RefCell::new(fs), + next_id: AtomicUsize::new(1), + files: Mutex::new(BTreeMap::new()) } } - fn open_inner(&mut self, url: &str, flags: usize) -> Result<Box<Resource>> { - let path = url.split(':').nth(1).unwrap_or("").trim_matches('/'); + fn open_inner(&self, url: &[u8], flags: usize) -> Result<Box<Resource>> { + let path = str::from_utf8(url).unwrap_or("").trim_matches('/'); // println!("Open '{}' {:X}", path, flags); + let mut fs = self.fs.borrow_mut(); + let mut nodes = Vec::new(); - let node_result = self.fs.path_nodes(path, &mut nodes); + let node_result = fs.path_nodes(path, &mut nodes); match node_result { Ok(node) => if node.1.is_dir() { let mut data = Vec::new(); let mut children = Vec::new(); - try!(self.fs.child_nodes(&mut children, node.0)); + try!(fs.child_nodes(&mut children, node.0)); for child in children.iter() { if let Ok(name) = child.1.name() { if ! data.is_empty() { @@ -51,9 +56,9 @@ impl FileScheme { } else { if flags & O_TRUNC == O_TRUNC { // println!("Truncate {}", path); - try!(self.fs.node_set_len(node.0, 0)); + try!(fs.node_set_len(node.0, 0)); } - let size = try!(self.fs.node_len(node.0)); + let size = try!(fs.node_len(node.0)); return Ok(Box::new(FileResource::new(url, node.0, size))); }, Err(err) => if err.errno == ENOENT && flags & O_CREAT == O_CREAT { @@ -65,7 +70,7 @@ impl FileScheme { } if ! last_part.is_empty() { if let Some(parent) = nodes.last() { - let node = try!(self.fs.create_node(Node::MODE_FILE, &last_part, parent.0)); + let node = try!(fs.create_node(Node::MODE_FILE, &last_part, parent.0)); return Ok(Box::new(FileResource::new(url, node.0, 0))); } else { return Err(Error::new(EPERM)); @@ -81,27 +86,24 @@ impl FileScheme { } impl Scheme for FileScheme { - fn open(&mut self, url: &str, flags: usize) -> Result<usize> { + fn open(&self, url: &[u8], flags: usize) -> Result<usize> { let resource = try!(self.open_inner(url, flags)); - let id = self.next_id as usize; - self.next_id += 1; - if self.next_id < 0 { - self.next_id = 1; - } - - self.files.insert(id, resource); + let id = self.next_id.fetch_add(1, Ordering::SeqCst); + self.files.lock().insert(id, resource); Ok(id) } - fn mkdir(&mut self, url: &str, _mode: usize) -> Result<usize> { - let path = url.split(':').nth(1).unwrap_or("").trim_matches('/'); + fn mkdir(&self, url: &[u8], _mode: usize) -> Result<usize> { + let path = str::from_utf8(url).unwrap_or("").trim_matches('/'); // println!("Mkdir '{}'", path); + let mut fs = self.fs.borrow_mut(); + let mut nodes = Vec::new(); - match self.fs.path_nodes(path, &mut nodes) { + match fs.path_nodes(path, &mut nodes) { Ok(_node) => Err(Error::new(EEXIST)), Err(err) => if err.errno == ENOENT { let mut last_part = String::new(); @@ -112,7 +114,7 @@ impl Scheme for FileScheme { } if ! last_part.is_empty() { if let Some(parent) = nodes.last() { - self.fs.create_node(Node::MODE_DIR, &last_part, parent.0).and(Ok(0)) + fs.create_node(Node::MODE_DIR, &last_part, parent.0).and(Ok(0)) } else { Err(Error::new(EPERM)) } @@ -125,17 +127,19 @@ impl Scheme for FileScheme { } } - fn rmdir(&mut self, url: &str) -> Result<usize> { - let path = url.split(':').nth(1).unwrap_or("").trim_matches('/'); + fn rmdir(&self, url: &[u8]) -> Result<usize> { + let path = str::from_utf8(url).unwrap_or("").trim_matches('/'); // println!("Rmdir '{}'", path); + let mut fs = self.fs.borrow_mut(); + let mut nodes = Vec::new(); - let child = try!(self.fs.path_nodes(path, &mut nodes)); + let child = try!(fs.path_nodes(path, &mut nodes)); if let Some(parent) = nodes.last() { if child.1.is_dir() { if let Ok(child_name) = child.1.name() { - self.fs.remove_node(Node::MODE_DIR, child_name, parent.0).and(Ok(0)) + fs.remove_node(Node::MODE_DIR, child_name, parent.0).and(Ok(0)) } else { Err(Error::new(ENOENT)) } @@ -147,22 +151,19 @@ impl Scheme for FileScheme { } } - fn stat(&mut self, url: &str, stat: &mut Stat) -> Result<usize> { - let resource = try!(self.open_inner(url, 0)); - resource.stat(stat) - } - - fn unlink(&mut self, url: &str) -> Result<usize> { - let path = url.split(':').nth(1).unwrap_or("").trim_matches('/'); + fn unlink(&self, url: &[u8]) -> Result<usize> { + let path = str::from_utf8(url).unwrap_or("").trim_matches('/'); // println!("Unlink '{}'", path); + let mut fs = self.fs.borrow_mut(); + let mut nodes = Vec::new(); - let child = try!(self.fs.path_nodes(path, &mut nodes)); + let child = try!(fs.path_nodes(path, &mut nodes)); if let Some(parent) = nodes.last() { if ! child.1.is_dir() { if let Ok(child_name) = child.1.name() { - self.fs.remove_node(Node::MODE_FILE, child_name, parent.0).and(Ok(0)) + fs.remove_node(Node::MODE_FILE, child_name, parent.0).and(Ok(0)) } else { Err(Error::new(ENOENT)) } @@ -176,44 +177,43 @@ impl Scheme for FileScheme { /* Resource operations */ #[allow(unused_variables)] - fn dup(&mut self, old_id: usize) -> Result<usize> { + fn dup(&self, old_id: usize) -> Result<usize> { // println!("Dup {}", old_id); - let resource = try!(try!(self.files.get(&old_id).ok_or(Error::new(EBADF))).dup()); - - let id = self.next_id as usize; - self.next_id += 1; - if self.next_id < 0 { - self.next_id = 1; - } + let mut files = self.files.lock(); + let resource = try!(try!(files.get(&old_id).ok_or(Error::new(EBADF))).dup()); - self.files.insert(id, resource); + let id = self.next_id.fetch_add(1, Ordering::SeqCst); + files.insert(id, resource); Ok(id) } #[allow(unused_variables)] - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> { + fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> { // println!("Read {}, {:X} {}", id, buf.as_ptr() as usize, buf.len()); - if let Some(mut file) = self.files.get_mut(&id) { - file.read(buf, &mut self.fs) + let mut files = self.files.lock(); + if let Some(mut file) = files.get_mut(&id) { + file.read(buf, &mut self.fs.borrow_mut()) } else { Err(Error::new(EBADF)) } } - fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> { + fn write(&self, id: usize, buf: &[u8]) -> Result<usize> { // println!("Write {}, {:X} {}", id, buf.as_ptr() as usize, buf.len()); - if let Some(mut file) = self.files.get_mut(&id) { - file.write(buf, &mut self.fs) + let mut files = self.files.lock(); + if let Some(mut file) = files.get_mut(&id) { + file.write(buf, &mut self.fs.borrow_mut()) } else { Err(Error::new(EBADF)) } } - fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> { + fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> { // println!("Seek {}, {} {}", id, pos, whence); - if let Some(mut file) = self.files.get_mut(&id) { + let mut files = self.files.lock(); + if let Some(mut file) = files.get_mut(&id) { file.seek(pos, whence) } else { Err(Error::new(EBADF)) @@ -222,7 +222,8 @@ impl Scheme for FileScheme { fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { // println!("Fpath {}, {:X} {}", id, buf.as_ptr() as usize, buf.len()); - if let Some(file) = self.files.get(&id) { + let files = self.files.lock(); + if let Some(file) = files.get(&id) { file.path(buf) } else { Err(Error::new(EBADF)) @@ -231,34 +232,38 @@ impl Scheme for FileScheme { fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> { // println!("Fstat {}, {:X}", id, stat as *mut Stat as usize); - if let Some(file) = self.files.get(&id) { + let files = self.files.lock(); + if let Some(file) = files.get(&id) { file.stat(stat) } else { Err(Error::new(EBADF)) } } - fn fsync(&mut self, id: usize) -> Result<usize> { + fn fsync(&self, id: usize) -> Result<usize> { // println!("Fsync {}", id); - if let Some(mut file) = self.files.get_mut(&id) { + let mut files = self.files.lock(); + if let Some(mut file) = files.get_mut(&id) { file.sync() } else { Err(Error::new(EBADF)) } } - fn ftruncate(&mut self, id: usize, len: usize) -> Result<usize> { + fn ftruncate(&self, id: usize, len: usize) -> Result<usize> { // println!("Ftruncate {}, {}", id, len); - if let Some(mut file) = self.files.get_mut(&id) { - file.truncate(len, &mut self.fs) + let mut files = self.files.lock(); + if let Some(mut file) = files.get_mut(&id) { + file.truncate(len, &mut self.fs.borrow_mut()) } else { Err(Error::new(EBADF)) } } - fn close(&mut self, id: usize) -> Result<usize> { + fn close(&self, id: usize) -> Result<usize> { // println!("Close {}", id); - if self.files.remove(&id).is_some() { + let mut files = self.files.lock(); + if files.remove(&id).is_some() { Ok(0) } else { Err(Error::new(EBADF)) diff --git a/src/disk.rs b/src/disk.rs index 75a9e58ae8c064608e0259b595c50801ebc8c42d..e345ee82cfa71b6bc7809d3223a2639cb81b76aa 100644 --- a/src/disk.rs +++ b/src/disk.rs @@ -1,4 +1,4 @@ -use system::error::Result; +use syscall::error::Result; /// A disk pub trait Disk { diff --git a/src/filesystem.rs b/src/filesystem.rs index bd2b96c8bf55dc657e734c81e4f74fc125170354..1c36f83b29dda73ca643fd4ffb850545e405cdb3 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -1,6 +1,6 @@ use std::cmp::min; -use system::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY}; +use syscall::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY}; use super::{Disk, ExNode, Extent, Header, Node}; diff --git a/src/lib.rs b/src/lib.rs index fcf352966f4137b3547951ec516c085fab620f4e..f4106c3994d2726411638b20f19b2d64833f0314 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ #![deny(warnings)] -extern crate system; +extern crate syscall; pub use self::disk::Disk; pub use self::ex_node::ExNode;