Commit 9c2864e1 authored by Jeremy Soller's avatar Jeremy Soller

Merge fuse and scheme, add mkfs utility, remove old utility

parent f1073d0c
# Compiled files
*.o
*.so
*.rlib
*.dll
# Executables
*.exe
# Generated by Cargo
Cargo.lock
/target/
# Images
*.bin
target
image.bin
image
......@@ -2,7 +2,7 @@
name = "redoxfs"
description = "The Redox Filesystem"
repository = "https://github.com/redox-os/redoxfs"
version = "0.1.0"
version = "0.1.1"
license-file = "LICENSE"
readme = "README.md"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
......@@ -13,15 +13,11 @@ path = "src/lib.rs"
[[bin]]
name = "redoxfs"
path = "scheme/main.rs"
path = "mount/main.rs"
[[bin]]
name = "redoxfs-fuse"
path = "fuse/main.rs"
[[bin]]
name = "redoxfs-utility"
path = "utility/main.rs"
name = "redoxfs-mkfs"
path = "mkfs/main.rs"
[dependencies]
spin = "*"
......
image.bin:
dd if=/dev/zero of=image.bin bs=1M count=1024
cargo build --release --bin redoxfs-mkfs
target/release/redoxfs-mkfs image.bin
mount: image.bin FORCE
mkdir -p image
cargo build --release --bin redoxfs
target/release/redoxfs image.bin image
unmount: FORCE
sync
-fusermount -u image
rm -rf image
clean: FORCE
sync
-fusermount -u image
rm -rf image image.bin
cargo clean
FORCE:
#!/bin/bash
rm -f test.bin
cargo run --bin redoxfs-utility test.bin << "EOF"
mk a_file
mkdir a_directory
cd a_directory
ed b_file
B FILE
.
cat b_file
ed c_file
C FILE
.
cat c_file
ls
exit
EOF
use std::fs::File;
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use redoxfs::Disk;
use syscall::error::{Error, Result, EIO};
macro_rules! try_disk {
......@@ -21,7 +20,7 @@ pub struct Image {
impl Image {
pub fn open(path: &str) -> Result<Image> {
let file = try_disk!(File::open(path));
let file = try_disk!(OpenOptions::new().read(true).write(true).open(path));
Ok(Image {
file: file
})
......@@ -30,7 +29,6 @@ impl Image {
impl Disk for Image {
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
// println!("Image read at {}", block);
try_disk!(self.file.seek(SeekFrom::Start(block * 512)));
let count = try_disk!(self.file.read(buffer));
Ok(count)
......
#![deny(warnings)]
extern crate redoxfs;
extern crate syscall;
use std::env;
use std::str;
use redoxfs::FileSystem;
use image::Image;
pub mod image;
fn main() {
let mut args = env::args();
if let Some(path) = args.nth(1) {
//Open an existing image
match Image::open(&path) {
Ok(disk) => match FileSystem::create(Box::new(disk)) {
Ok(filesystem) => {
println!("redoxfs: created filesystem on {}, size {} MB", path, filesystem.header.1.size/1024/1024);
},
Err(err) => println!("redoxfs: failed to create filesystem on {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
} else {
println!("redoxfs: no disk image provided");
}
}
#!/bin/bash
mkdir -p test
cargo run --bin redoxfs-fuse test.bin test &
#![deny(warnings)]
extern crate fuse;
extern crate redoxfs;
extern crate syscall;
extern crate time;
use image::Image;
use std::env;
use redoxfs;
use std::path::Path;
use time::Timespec;
use fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyCreate, ReplyDirectory, ReplyEmpty, ReplyStatfs, ReplyWrite};
pub mod image;
use self::fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyCreate, ReplyDirectory, ReplyEmpty, ReplyStatfs, ReplyWrite};
use self::time::Timespec;
pub use self::fuse::mount;
const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second
const CREATE_TIME: Timespec = Timespec { sec: 0, nsec: 0 };
struct RedoxFS {
fs: redoxfs::FileSystem,
pub struct Fuse {
pub fs: redoxfs::FileSystem,
}
fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr {
......@@ -44,7 +40,7 @@ fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr {
}
}
impl Filesystem for RedoxFS {
impl Filesystem for Fuse {
fn lookup(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEntry) {
match self.fs.find_node(name.to_str().unwrap(), parent_block) {
Ok(node) => {
......@@ -257,64 +253,3 @@ impl Filesystem for RedoxFS {
}
}
}
#[cfg(target_os = "macos")]
fn main() {
use std::ffi::OsStr;
if let Some(path) = env::args().nth(1) {
//Open an existing image
match Image::open(&path) {
Ok(disk) => match redoxfs::FileSystem::open(Box::new(disk)) {
Ok(filesystem) => {
println!("redoxfs: opened filesystem {}", path);
if let Some(mountpoint) = env::args_os().nth(2) {
fuse::mount(RedoxFS {
fs: filesystem
}, &mountpoint, &[
// 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
// be `root`, thus that we need to allow `root` to have access.
OsStr::new("-o"),
OsStr::new("defer_permissions"),
]);
} else {
println!("redoxfs: no mount point provided");
}
},
Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
} else {
println!("redoxfs: no disk image provided");
}
}
#[cfg(not(target_os = "macos"))]
fn main() {
if let Some(path) = env::args().nth(1) {
//Open an existing image
match Image::open(&path) {
Ok(disk) => match redoxfs::FileSystem::open(Box::new(disk)) {
Ok(filesystem) => {
println!("redoxfs: opened filesystem {}", path);
if let Some(mountpoint) = env::args_os().nth(2) {
fuse::mount(RedoxFS {
fs: filesystem
}, &mountpoint, &[]);
} else {
println!("redoxfs: no mount point provided");
}
},
Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
} else {
println!("redoxfs: no disk image provided");
}
}
#![deny(warnings)]
#![cfg_attr(unix, feature(libc))]
#[cfg(unix)]
extern crate libc;
extern crate redoxfs;
extern crate syscall;
use std::env;
use std::fs::File;
use std::os::unix::io::FromRawFd;
use std::path::Path;
use std::process;
use cache::Cache;
use image::Image;
pub mod cache;
pub mod image;
#[cfg(unix)]
pub mod fuse;
#[cfg(target_os = "redox")]
pub mod redox;
#[cfg(unix)]
fn fork() -> isize {
unsafe { libc::fork() as isize }
}
#[cfg(unix)]
fn pipe(pipes: &mut [i32; 2]) -> isize {
unsafe { libc::pipe2(pipes.as_mut_ptr(), 0) as isize }
}
#[cfg(all(unix, target_os = "macos"))]
fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) {
use std::io::Write;
let _ = write.write(&[0]);
drop(write);
fuse::mount(fuse::Fuse {
fs: filesystem
}, mountpoint, &[
// 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
// be `root`, thus that we need to allow `root` to have access.
OsStr::new("-o"),
OsStr::new("defer_permissions"),
]);
}
#[cfg(all(unix, not(target_os = "macos")))]
fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) {
use std::io::Write;
let _ = write.write(&[0]);
drop(write);
fuse::mount(fuse::Fuse {
fs: filesystem
}, mountpoint, &[]);
}
#[cfg(target_os = "redox")]
fn fork() -> isize {
unsafe { syscall::Error::mux(syscall::clone(0)) as isize }
}
#[cfg(target_os = "redox")]
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 main() {
use std::io::{Read, Write};
let mut pipes = [0; 2];
if pipe(&mut pipes) == 0 {
let mut read = unsafe { File::from_raw_fd(pipes[0]) };
let mut write = unsafe { File::from_raw_fd(pipes[1]) };
let pid = fork();
if pid == 0 {
drop(read);
if let Some(path) = env::args().nth(1) {
//Open an existing image
match Image::open(&path).map(|image| Cache::new(image)) {
Ok(disk) => match redoxfs::FileSystem::open(Box::new(disk)) {
Ok(filesystem) => {
println!("redoxfs: opened filesystem {}", path);
if let Some(mountpoint) = env::args_os().nth(2) {
mount(filesystem, &mountpoint, write);
process::exit(0);
} else {
println!("redoxfs: no mount point provided");
}
},
Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
let _ = write.write(&[1]);
drop(write);
process::exit(1);
} else {
println!("redoxfs: no disk image provided");
}
} else if pid > 0 {
drop(write);
let mut res = [0];
read.read(&mut res).unwrap();
process::exit(res[0] as i32);
} else {
panic!("redoxfs: failed to fork");
}
} else {
panic!("redoxfs: failed to create pipe");
}
}
extern crate spin;
use redoxfs;
use syscall::{Packet, Scheme};
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use self::scheme::FileScheme;
pub mod resource;
pub mod scheme;
pub fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) {
let mountpoint = mountpoint.as_ref();
match File::create(format!(":{}", mountpoint.display())) {
Ok(mut socket) => {
println!("redoxfs: mounted filesystem on {}:", mountpoint.display());
let _ = write.write(&[0]);
drop(write);
let scheme = FileScheme::new(format!("{}", mountpoint.display()), filesystem);
loop {
let mut packet = Packet::default();
socket.read(&mut packet).unwrap();
scheme.handle(&mut packet);
socket.write(&packet).unwrap();
}
},
Err(err) => println!("redoxfs: failed to create {} scheme: {}", mountpoint.display(), err)
}
}
use resource::{Resource, DirResource, FileResource};
use redox::resource::{Resource, DirResource, FileResource};
use redox::spin::Mutex;
use redoxfs::{FileSystem, Node};
use spin::Mutex;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::str;
......@@ -13,14 +13,14 @@ use syscall::flag::{O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_
use syscall::scheme::Scheme;
pub struct FileScheme {
name: &'static str,
name: String,
fs: RefCell<FileSystem>,
next_id: AtomicUsize,
files: Mutex<BTreeMap<usize, Box<Resource>>>
}
impl FileScheme {
pub fn new(name: &'static str, fs: FileSystem) -> FileScheme {
pub fn new(name: String, fs: FileSystem) -> FileScheme {
FileScheme {
name: name,
fs: RefCell::new(fs),
......
#![deny(warnings)]
extern crate redoxfs;
extern crate spin;
extern crate syscall;
use std::{env, process};
use std::fs::File;
use std::io::{Read, Write};
use cache::Cache;
use image::Image;
use scheme::FileScheme;
use redoxfs::FileSystem;
use syscall::{Packet, Scheme};
pub mod cache;
pub mod image;
pub mod resource;
pub mod scheme;
fn main() {
if let Some(path) = env::args().nth(1) {
let mut pipes = [0; 2];
syscall::pipe2(&mut pipes, 0).unwrap();
// Daemonize
if unsafe { syscall::clone(0).unwrap() } == 0 {
let _ = syscall::close(pipes[0]);
match Image::open(&path).map(|image| Cache::new(image)) {
Ok(disk) => match FileSystem::open(Box::new(disk)) {
Ok(fs) => match File::create(":file") {
Ok(mut socket) => {
println!("redoxfs: mounted filesystem {} on file:", path);
let _ = syscall::write(pipes[1], &[1]);
let scheme = FileScheme::new("file", fs);
loop {
let mut packet = Packet::default();
socket.read(&mut packet).unwrap();
scheme.handle(&mut packet);
socket.write(&packet).unwrap();
}
},
Err(err) => println!("redoxfs: failed to create file scheme: {}", err)
},
Err(err) => println!("redoxfs: failed to open filesystem {}: {}", path, err)
},
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
let _ = syscall::write(pipes[1], &[0]);
let _ = syscall::close(pipes[1]);
} else {
let _ = syscall::close(pipes[1]);
let mut res = [0];
syscall::read(pipes[0], &mut res).unwrap();
let _ = syscall::close(pipes[0]);
process::exit(res[0] as i32);
}
} else {
println!("redoxfs: no disk image provided");
}
}
#!/bin/bash
fusermount -u test
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use redoxfs::Disk;
use syscall::error::{Error, Result, EIO};
macro_rules! try_disk {
($expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
println!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
}
})
}
pub struct Image {
file: File
}
impl Image {
pub fn open(path: &str) -> Result<Image> {
let file = try_disk!(OpenOptions::new().read(true).write(true).open(path));
Ok(Image {
file: file
})
}
pub fn create(path: &str, size: u64) -> Result<Image> {
let file = try_disk!(OpenOptions::new().read(true).write(true).create(true).open(path));
try_disk!(file.set_len(size));
Ok(Image {
file: file
})
}
}
impl Disk for Image {
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
try_disk!(self.file.seek(SeekFrom::Start(block * 512)));
let count = try_disk!(self.file.read(buffer));
Ok(count)
}
fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
try_disk!(self.file.seek(SeekFrom::Start(block * 512)));
let count = try_disk!(self.file.write(buffer));
Ok(count)
}
fn size(&mut self) -> Result<u64> {
let size = try_disk!(self.file.seek(SeekFrom::End(0)));
Ok(size)
}
}
#![deny(warnings)]
extern crate redoxfs;
extern crate syscall;
use std::env;
use std::io::{self, Write};
use std::path::Path;
use std::str;
use redoxfs::{FileSystem, Node};
use image::Image;