Port to new kernel
This commit is contained in:
+8
-1
@@ -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 = "*"
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ use std::{cmp, ptr};
|
||||
|
||||
use redoxfs::Disk;
|
||||
|
||||
use system::error::Result;
|
||||
use syscall::error::Result;
|
||||
|
||||
use self::lru_cache::LruCache;
|
||||
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+10
-10
@@ -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");
|
||||
|
||||
+12
-14
@@ -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)
|
||||
|
||||
+73
-68
@@ -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 mut files = self.files.lock();
|
||||
let resource = try!(try!(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;
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
use system::error::Result;
|
||||
use syscall::error::Result;
|
||||
|
||||
/// A disk
|
||||
pub trait Disk {
|
||||
|
||||
+1
-1
@@ -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};
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
extern crate system;
|
||||
extern crate syscall;
|
||||
|
||||
pub use self::disk::Disk;
|
||||
pub use self::ex_node::ExNode;
|
||||
|
||||
Reference in New Issue
Block a user