Skip to content

Commit

Permalink
Fix compilation on Redox
Browse files Browse the repository at this point in the history
  • Loading branch information
jackpot51 committed Sep 27, 2017
1 parent dfd2dd8 commit dc0b0c5
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 68 deletions.
15 changes: 7 additions & 8 deletions src/bin/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#[cfg(unix)]
extern crate libc;

#[cfg(target_os = "redox")]
extern crate syscall;

extern crate redoxfs;

use std::env;
Expand Down Expand Up @@ -33,11 +36,6 @@ fn pipe(pipes: &mut [usize; 2]) -> isize {
syscall::Error::mux(syscall::pipe2(pipes, 0)) as isize
}

#[cfg(target_os = "redox")]
fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, write: File) {
redox::mount(filesystem, mountpoint, write);
}

fn usage() {
println!("redoxfs [disk] [mountpoint]");
}
Expand All @@ -62,13 +60,15 @@ fn main() {
println!("redoxfs: opened filesystem {}", path);

if let Some(mountpoint) = env::args().nth(2) {
match mount(filesystem, &mountpoint, write) {
match mount(filesystem, &mountpoint, || {
println!("redoxfs: mounted filesystem on {}:", mountpoint);
let _ = write.write(&[0]);
}) {
Ok(()) => {
process::exit(0);
},
Err(err) => {
println!("redoxfs: failed to mount {} to {}: {}", path, mountpoint, err);
process::exit(1);
}
}
} else {
Expand All @@ -82,7 +82,6 @@ fn main() {
}

let _ = write.write(&[1]);
drop(write);
process::exit(1);
} else {
println!("redoxfs: no disk image provided");
Expand Down
8 changes: 3 additions & 5 deletions src/mount/fuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ extern crate fuse;
extern crate time;

use std::ffi::OsStr;
use std::fs::File;
use std::io::{self, Write};
use std::io;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};
Expand All @@ -19,13 +18,12 @@ const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second

const NULL_TIME: Timespec = Timespec { sec: 0, nsec: 0 };

pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mountpoint: &P, mut write: File, options: &[&OsStr]) -> io::Result<()> {
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: filesystem::FileSystem<D>, mountpoint: &P, mut callback: F, options: &[&OsStr]) -> io::Result<()> {
let mut session = Session::new(Fuse {
fs: filesystem
}, mountpoint.as_ref(), options)?;

let _ = write.write(&[0]);
drop(write);
callback();

session.run()
}
Expand Down
13 changes: 6 additions & 7 deletions src/mount/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::io;
use std::fs::File;
use std::path::Path;

use disk::Disk;
Expand All @@ -12,10 +11,10 @@ mod fuse;
mod redox;

#[cfg(all(unix, target_os = "macos"))]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) -> io::Result<()> {
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, callback: F) -> io::Result<()> {
use std::ffi::OsStr;

fuse::mount(filesystem, mountpoint, write, &[
fuse::mount(filesystem, mountpoint, callback, &[
// One of the uses of this redoxfs fuse wrapper is to populate a filesystem
// while building the Redox OS kernel. This means that we need to write on
// a filesystem that belongs to `root`, which in turn means that we need to
Expand All @@ -26,11 +25,11 @@ pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P,
}

#[cfg(all(unix, not(target_os = "macos")))]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) -> io::Result<()> {
fuse::mount(filesystem, mountpoint, write, &[])
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, callback: F) -> io::Result<()> {
fuse::mount(filesystem, mountpoint, callback, &[])
}

#[cfg(target_os = "redox")]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) -> io::Result<()> {
redox::mount(filesystem, mountpoint, write)
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, callback: F) -> io::Result<()> {
redox::mount(filesystem, mountpoint, callback)
}
10 changes: 3 additions & 7 deletions src/mount/redox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ use std::io::{self, Read, Write};
use std::path::Path;

use disk::Disk;
use filesystem::FileSystem;

use self::scheme::FileScheme;

pub mod resource;
pub mod scheme;

pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mountpoint: &P, mut write: File) -> io::Result<()> {
pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, mut callback: F) -> io::Result<()> {
let mountpoint = mountpoint.as_ref();
let mut socket = File::create(format!(":{}", mountpoint.display()))?;

println!("redoxfs: mounted filesystem on {}:", mountpoint.display());

let _ = write.write(&[0]);
drop(write);
callback();

let scheme = FileScheme::new(format!("{}", mountpoint.display()), filesystem);
loop {
Expand All @@ -28,6 +26,4 @@ pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mou
scheme.handle(&mut packet);
socket.write(&packet).unwrap();
}

Ok(())
}
53 changes: 27 additions & 26 deletions src/mount/redox/resource.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use redoxfs::FileSystem;

use std::cmp::{min, max};
use std::time::{SystemTime, UNIX_EPOCH};

Expand All @@ -8,17 +6,20 @@ use syscall::error::{Error, Result, EBADF, EINVAL, EISDIR};
use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL};
use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END};

pub trait Resource {
fn dup(&self) -> Result<Box<Resource>>;
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result<usize>;
fn write(&mut self, buf: &[u8], fs: &mut FileSystem) -> Result<usize>;
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem) -> Result<usize>;
use disk::Disk;
use filesystem::FileSystem;

pub trait Resource<D: Disk> {
fn dup(&self) -> Result<Box<Resource<D>>>;
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem<D>) -> Result<usize>;
fn write(&mut self, buf: &[u8], fs: &mut FileSystem<D>) -> Result<usize>;
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem<D>) -> Result<usize>;
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize>;
fn path(&self, buf: &mut [u8]) -> Result<usize>;
fn stat(&self, _stat: &mut Stat, fs: &mut FileSystem) -> Result<usize>;
fn stat(&self, _stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize>;
fn sync(&mut self) -> Result<usize>;
fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize>;
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem) -> Result<usize>;
fn truncate(&mut self, len: usize, fs: &mut FileSystem<D>) -> Result<usize>;
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem<D>) -> Result<usize>;
}

pub struct DirResource {
Expand All @@ -39,8 +40,8 @@ impl DirResource {
}
}

impl Resource for DirResource {
fn dup(&self) -> Result<Box<Resource>> {
impl<D: Disk> Resource<D> for DirResource {
fn dup(&self) -> Result<Box<Resource<D>>> {
Ok(Box::new(DirResource {
path: self.path.clone(),
block: self.block,
Expand All @@ -49,7 +50,7 @@ impl Resource for DirResource {
}))
}

fn read(&mut self, buf: &mut [u8], _fs: &mut FileSystem) -> Result<usize> {
fn read(&mut self, buf: &mut [u8], _fs: &mut FileSystem<D>) -> Result<usize> {
let data = self.data.as_ref().ok_or(Error::new(EISDIR))?;
let mut i = 0;
while i < buf.len() && self.seek < data.len() {
Expand All @@ -60,11 +61,11 @@ impl Resource for DirResource {
Ok(i)
}

fn write(&mut self, _buf: &[u8], _fs: &mut FileSystem) -> Result<usize> {
fn write(&mut self, _buf: &[u8], _fs: &mut FileSystem<D>) -> Result<usize> {
Err(Error::new(EBADF))
}

fn seek(&mut self, offset: usize, whence: usize, _fs: &mut FileSystem) -> Result<usize> {
fn seek(&mut self, offset: usize, whence: usize, _fs: &mut FileSystem<D>) -> Result<usize> {
let data = self.data.as_ref().ok_or(Error::new(EBADF))?;
self.seek = match whence {
SEEK_SET => max(0, min(data.len() as isize, offset as isize)) as usize,
Expand Down Expand Up @@ -92,7 +93,7 @@ impl Resource for DirResource {
Ok(i)
}

fn stat(&self, stat: &mut Stat, fs: &mut FileSystem) -> Result<usize> {
fn stat(&self, stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize> {
let node = fs.node(self.block)?;

*stat = Stat {
Expand All @@ -117,11 +118,11 @@ impl Resource for DirResource {
Err(Error::new(EBADF))
}

fn truncate(&mut self, _len: usize, _fs: &mut FileSystem) -> Result<usize> {
fn truncate(&mut self, _len: usize, _fs: &mut FileSystem<D>) -> Result<usize> {
Err(Error::new(EBADF))
}

fn utimens(&mut self, _times: &[TimeSpec], _fs: &mut FileSystem) -> Result<usize> {
fn utimens(&mut self, _times: &[TimeSpec], _fs: &mut FileSystem<D>) -> Result<usize> {
Err(Error::new(EBADF))
}
}
Expand All @@ -146,8 +147,8 @@ impl FileResource {
}
}

impl Resource for FileResource {
fn dup(&self) -> Result<Box<Resource>> {
impl<D: Disk> Resource<D> for FileResource {
fn dup(&self) -> Result<Box<Resource<D>>> {
Ok(Box::new(FileResource {
path: self.path.clone(),
block: self.block,
Expand All @@ -157,7 +158,7 @@ impl Resource for FileResource {
}))
}

fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem) -> Result<usize> {
fn read(&mut self, buf: &mut [u8], fs: &mut FileSystem<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_RDONLY {
let count = fs.read_node(self.block, self.seek, buf)?;
self.seek += count as u64;
Expand All @@ -167,7 +168,7 @@ impl Resource for FileResource {
}
}

fn write(&mut self, buf: &[u8], fs: &mut FileSystem) -> Result<usize> {
fn write(&mut self, buf: &[u8], fs: &mut FileSystem<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let count = fs.write_node(self.block, self.seek, buf, mtime.as_secs(), mtime.subsec_nanos())?;
Expand All @@ -178,7 +179,7 @@ impl Resource for FileResource {
}
}

fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem) -> Result<usize> {
fn seek(&mut self, offset: usize, whence: usize, fs: &mut FileSystem<D>) -> Result<usize> {
let size = fs.node_len(self.block)?;

self.seek = match whence {
Expand Down Expand Up @@ -214,7 +215,7 @@ impl Resource for FileResource {
Ok(i)
}

fn stat(&self, stat: &mut Stat, fs: &mut FileSystem) -> Result<usize> {
fn stat(&self, stat: &mut Stat, fs: &mut FileSystem<D>) -> Result<usize> {
let node = fs.node(self.block)?;

*stat = Stat {
Expand All @@ -239,7 +240,7 @@ impl Resource for FileResource {
Ok(0)
}

fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize> {
fn truncate(&mut self, len: usize, fs: &mut FileSystem<D>) -> Result<usize> {
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
fs.node_set_len(self.block, len as u64)?;
Ok(0)
Expand All @@ -248,7 +249,7 @@ impl Resource for FileResource {
}
}

fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem) -> Result<usize> {
fn utimens(&mut self, times: &[TimeSpec], fs: &mut FileSystem<D>) -> Result<usize> {
let mut node = fs.node(self.block)?;

if node.1.uid == self.uid || self.uid == 0 {
Expand Down
31 changes: 16 additions & 15 deletions src/mount/redox/scheme.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
use redox::resource::{Resource, DirResource, FileResource};
use redox::spin::Mutex;

use redoxfs::{FileSystem, Node};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::str;
Expand All @@ -13,26 +9,31 @@ use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOE
use syscall::flag::{O_APPEND, O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM, O_SYMLINK, O_NOFOLLOW};
use syscall::scheme::Scheme;

pub struct FileScheme {
use disk::Disk;
use filesystem::FileSystem;
use node::Node;

use super::resource::{Resource, DirResource, FileResource};
use super::spin::Mutex;

pub struct FileScheme<D: Disk> {
name: String,
fs: RefCell<FileSystem>,
fs: RefCell<FileSystem<D>>,
next_id: AtomicUsize,
files: Mutex<BTreeMap<usize, Box<Resource>>>
files: Mutex<BTreeMap<usize, Box<Resource<D>>>>
}

impl FileScheme {
pub fn new(name: String, fs: FileSystem) -> FileScheme {
impl<D: Disk> FileScheme<D> {
pub fn new(name: String, fs: FileSystem<D>) -> FileScheme<D> {
FileScheme {
name: name,
fs: RefCell::new(fs),
next_id: AtomicUsize::new(1),
files: Mutex::new(BTreeMap::new())
}
}
}

impl FileScheme {
fn resolve_symlink(&self, fs: &mut FileSystem, uid: u32, gid: u32, url: &[u8], node: (u64, Node), nodes: &mut Vec<(u64, Node)>) -> Result<Vec<u8>> {
fn resolve_symlink(&self, fs: &mut FileSystem<D>, uid: u32, gid: u32, url: &[u8], node: (u64, Node), nodes: &mut Vec<(u64, Node)>) -> Result<Vec<u8>> {
let mut node = node;
for _ in 1..10 { // XXX What should the limit be?
let mut buf = [0; 4096];
Expand All @@ -59,7 +60,7 @@ impl FileScheme {
Err(Error::new(ELOOP))
}

fn path_nodes(&self, fs: &mut FileSystem, path: &str, uid: u32, gid: u32, nodes: &mut Vec<(u64, Node)>) -> Result<Option<(u64, Node)>> {
fn path_nodes(&self, fs: &mut FileSystem<D>, path: &str, uid: u32, gid: u32, nodes: &mut Vec<(u64, Node)>) -> Result<Option<(u64, Node)>> {
let mut parts = path.split('/').filter(|part| ! part.is_empty());
let mut part_opt = None;
let mut block = fs.header.1.root;
Expand Down Expand Up @@ -175,7 +176,7 @@ pub fn canonicalize(current: &[u8], path: &[u8]) -> Vec<u8> {
}
}

impl Scheme for FileScheme {
impl<D: Disk> Scheme for FileScheme<D> {
fn open(&self, url: &[u8], flags: usize, uid: u32, gid: u32) -> Result<usize> {
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');

Expand All @@ -185,7 +186,7 @@ impl Scheme for FileScheme {

let mut nodes = Vec::new();
let node_opt = self.path_nodes(&mut fs, path, uid, gid, &mut nodes)?;
let resource: Box<Resource> = match node_opt {
let resource: Box<Resource<D>> = match node_opt {
Some(node) => if flags & (O_CREAT | O_EXCL) == O_CREAT | O_EXCL {
return Err(Error::new(EEXIST));
} else if node.1.is_dir() {
Expand Down

0 comments on commit dc0b0c5

Please sign in to comment.