Commit 070aeb54 authored by Jeremy Soller's avatar Jeremy Soller

Cleanup to allow use of most functions when linking the library, including...

Cleanup to allow use of most functions when linking the library, including mounting and creating filesystems
parent b272cc2d
[root]
name = "redoxfs"
version = "0.1.2"
version = "0.2.0"
dependencies = [
"fuse 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.4.5 (git+https://github.com/messense/spin-rs?rev=020f1b3f)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -36,7 +37,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.30"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -70,7 +71,7 @@ version = "0.1.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -89,7 +90,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum fuse 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "adf08478eb39cff95e34daa7a2743a256d1c18388c0328d2f717e8ef748001f6"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
"checksum libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "2370ca07ec338939e356443dac2296f581453c35fe1e3a3ed06023c49435f915"
"checksum libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "d1419b2939a0bc44b77feb34661583c7546b532b192feab36249ab584b86856c"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
......
......@@ -2,7 +2,7 @@
name = "redoxfs"
description = "The Redox Filesystem"
repository = "https://github.com/redox-os/redoxfs"
version = "0.1.2"
version = "0.2.0"
license-file = "LICENSE"
readme = "README.md"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
......@@ -13,11 +13,11 @@ path = "src/lib.rs"
[[bin]]
name = "redoxfs"
path = "mount/main.rs"
path = "src/bin/mount.rs"
[[bin]]
name = "redoxfs-mkfs"
path = "mkfs/main.rs"
path = "src/bin/mkfs.rs"
[dependencies]
spin = { git = "https://github.com/messense/spin-rs", rev = "020f1b3f" }
......@@ -25,4 +25,5 @@ redox_syscall = "0.1"
[target.'cfg(unix)'.dependencies]
fuse = "0.2"
libc = "0.2"
time = "0.1"
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
})
}
}
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, process, time};
use redoxfs::FileSystem;
use image::Image;
pub mod image;
use redoxfs::{FileSystem, DiskFile};
fn main() {
let mut args = env::args();
......@@ -17,8 +12,8 @@ fn main() {
let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
//Open an existing image
match Image::open(&path) {
Ok(disk) => match FileSystem::create(Box::new(disk), ctime.as_secs(), ctime.subsec_nanos()) {
match DiskFile::open(&path) {
Ok(disk) => match FileSystem::create(disk, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(filesystem) => {
println!("redoxfs-mkfs: created filesystem on {}, size {} MB", path, filesystem.header.1.size/1024/1024);
},
......
......@@ -5,25 +5,13 @@
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;
use redoxfs::{DiskCache, DiskFile, mount};
#[cfg(unix)]
fn fork() -> isize {
......@@ -35,38 +23,6 @@ fn pipe(pipes: &mut [i32; 2]) -> isize {
unsafe { libc::pipe(pipes.as_mut_ptr()) as isize }
}
#[cfg(all(unix, target_os = "macos"))]
fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) {
use std::ffi::OsStr;
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 }
......@@ -100,8 +56,8 @@ fn main() {
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)) {
match DiskFile::open(&path).map(|image| DiskCache::new(image)) {
Ok(disk) => match redoxfs::FileSystem::open(disk) {
Ok(filesystem) => {
println!("redoxfs: opened filesystem {}", path);
......
use std::{cmp, ptr};
use redoxfs::Disk;
use syscall::error::Result;
use disk::Disk;
use self::lru_cache::LruCache;
mod linked_hash_map;
......@@ -15,21 +14,21 @@ fn copy_memory(src: &[u8], dest: &mut [u8]) -> usize {
len
}
pub struct Cache<T> {
pub struct DiskCache<T> {
inner: T,
cache: LruCache<u64, [u8; 512]>,
}
impl<T: Disk> Cache<T> {
impl<T: Disk> DiskCache<T> {
pub fn new(inner: T) -> Self {
Cache {
DiskCache {
inner: inner,
cache: LruCache::new(65536) // 32 MB cache
}
}
}
impl<T: Disk> Disk for Cache<T> {
impl<T: Disk> Disk for DiskCache<T> {
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
// println!("Cache read at {}", block);
......
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use redoxfs::Disk;
use syscall::error::{Error, Result, EIO};
use disk::Disk;
macro_rules! try_disk {
($expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
println!("Disk I/O Error: {}", err);
eprintln!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
}
})
}
pub struct Image {
pub struct DiskFile {
file: File
}
impl Image {
pub fn open(path: &str) -> Result<Image> {
impl DiskFile {
pub fn open(path: &str) -> Result<DiskFile> {
let file = try_disk!(OpenOptions::new().read(true).write(true).open(path));
Ok(Image {
Ok(DiskFile {
file: file
})
}
pub fn create(path: &str, size: u64) -> Result<Image> {
pub fn create(path: &str, size: u64) -> Result<DiskFile> {
let file = try_disk!(OpenOptions::new().read(true).write(true).create(true).open(path));
try_disk!(file.set_len(size));
Ok(Image {
Ok(DiskFile {
file: file
})
}
}
impl Disk for Image {
impl Disk for DiskFile {
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));
......
use syscall::error::Result;
pub use self::cache::DiskCache;
pub use self::file::DiskFile;
mod cache;
mod file;
/// A disk
pub trait Disk {
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize>;
......
......@@ -5,15 +5,15 @@ use syscall::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENO
use super::{Disk, ExNode, Extent, Header, Node};
/// A file system
pub struct FileSystem {
pub disk: Box<Disk>,
pub struct FileSystem<D: Disk> {
pub disk: D,
pub block: u64,
pub header: (u64, Header)
}
impl FileSystem {
impl<D: Disk> FileSystem<D> {
/// Open a file system on a disk
pub fn open(mut disk: Box<Disk>) -> Result<Self> {
pub fn open(mut disk: D) -> Result<Self> {
for block in 0..65536 {
let mut header = (0, Header::default());
disk.read_at(block + header.0, &mut header.1)?;
......@@ -37,7 +37,7 @@ impl FileSystem {
}
/// Create a file system on a disk
pub fn create(mut disk: Box<Disk>, ctime: u64, ctime_nsec: u32) -> Result<Self> {
pub fn create(mut disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> {
let size = disk.size()?;
if size >= 4 * 512 {
......
......@@ -5,16 +5,18 @@
extern crate syscall;
pub use self::disk::Disk;
pub use self::disk::{Disk, DiskCache, DiskFile};
pub use self::ex_node::ExNode;
pub use self::extent::Extent;
pub use self::filesystem::FileSystem;
pub use self::header::Header;
pub use self::mount::mount;
pub use self::node::Node;
pub mod disk;
pub mod ex_node;
pub mod extent;
pub mod filesystem;
pub mod header;
pub mod node;
mod disk;
mod ex_node;
mod extent;
mod filesystem;
mod header;
mod mount;
mod node;
extern crate fuse;
extern crate time;
use redoxfs;
use std::path::Path;
use std::os::unix::ffi::OsStrExt;
use std::time::{SystemTime, UNIX_EPOCH};
use disk::Disk;
use filesystem;
use node::Node;
use self::fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyCreate, ReplyDirectory, ReplyEmpty, ReplyStatfs, ReplyWrite};
use self::time::Timespec;
......@@ -15,11 +18,11 @@ const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second
const NULL_TIME: Timespec = Timespec { sec: 0, nsec: 0 };
pub struct Fuse {
pub fs: redoxfs::FileSystem,
pub struct Fuse<D: Disk> {
pub fs: filesystem::FileSystem<D>,
}
fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr {
fn node_attr(node: &(u64, Node)) -> FileAttr {
FileAttr {
ino: node.0,
size: node.1.extents[0].length,
......@@ -41,7 +44,7 @@ fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr {
} else {
FileType::RegularFile
},
perm: node.1.mode & redoxfs::Node::MODE_PERM,
perm: node.1.mode & Node::MODE_PERM,
nlink: 1,
uid: node.1.uid,
gid: node.1.gid,
......@@ -50,7 +53,7 @@ fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr {
}
}
impl Filesystem for Fuse {
impl<D: Disk> Filesystem for Fuse<D> {
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) => {
......@@ -80,9 +83,9 @@ impl Filesystem for Fuse {
_flags: Option<u32>, reply: ReplyAttr) {
if let Some(mode) = mode {
match self.fs.node(block) {
Ok(mut node) => if node.1.mode & redoxfs::Node::MODE_PERM != mode as u16 & redoxfs::Node::MODE_PERM {
Ok(mut node) => if node.1.mode & Node::MODE_PERM != mode as u16 & Node::MODE_PERM {
// println!("Chmod {:?}:{:o}:{:o}", node.1.name(), node.1.mode, mode);
node.1.mode = (node.1.mode & redoxfs::Node::MODE_TYPE) | (mode as u16 & redoxfs::Node::MODE_PERM);
node.1.mode = (node.1.mode & Node::MODE_TYPE) | (mode as u16 & Node::MODE_PERM);
if let Err(err) = self.fs.write_at(node.0, &node.1) {
reply.error(err.errno as i32);
return;
......@@ -234,7 +237,7 @@ impl Filesystem for Fuse {
fn create(&mut self, _req: &Request, parent_block: u64, name: &Path, mode: u32, flags: u32, reply: ReplyCreate) {
let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
match self.fs.create_node(redoxfs::Node::MODE_FILE | (mode as u16 & redoxfs::Node::MODE_PERM), name.to_str().unwrap(), parent_block, ctime.as_secs(), ctime.subsec_nanos()) {
match self.fs.create_node(Node::MODE_FILE | (mode as u16 & Node::MODE_PERM), name.to_str().unwrap(), parent_block, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(node) => {
// println!("Create {:?}:{:o}:{:o}", node.1.name(), node.1.mode, mode);
reply.created(&TTL, &node_attr(&node), 0, 0, flags);
......@@ -247,7 +250,7 @@ impl Filesystem for Fuse {
fn mkdir(&mut self, _req: &Request, parent_block: u64, name: &Path, mode: u32, reply: ReplyEntry) {
let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
match self.fs.create_node(redoxfs::Node::MODE_DIR | (mode as u16 & redoxfs::Node::MODE_PERM), name.to_str().unwrap(), parent_block, ctime.as_secs(), ctime.subsec_nanos()) {
match self.fs.create_node(Node::MODE_DIR | (mode as u16 & Node::MODE_PERM), name.to_str().unwrap(), parent_block, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(node) => {
// println!("Mkdir {:?}:{:o}:{:o}", node.1.name(), node.1.mode, mode);
reply.entry(&TTL, &node_attr(&node), 0);
......@@ -259,7 +262,7 @@ impl Filesystem for Fuse {
}
fn rmdir(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEmpty) {
match self.fs.remove_node(redoxfs::Node::MODE_DIR, name.to_str().unwrap(), parent_block) {
match self.fs.remove_node(Node::MODE_DIR, name.to_str().unwrap(), parent_block) {
Ok(()) => {
reply.ok();
},
......@@ -270,7 +273,7 @@ impl Filesystem for Fuse {
}
fn unlink(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEmpty) {
match self.fs.remove_node(redoxfs::Node::MODE_FILE, name.to_str().unwrap(), parent_block) {
match self.fs.remove_node(Node::MODE_FILE, name.to_str().unwrap(), parent_block) {
Ok(()) => {
reply.ok();
},
......@@ -297,7 +300,7 @@ impl Filesystem for Fuse {
fn symlink(&mut self, _req: &Request, parent_block: u64, name: &Path, link: &Path, reply: ReplyEntry) {
let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
match self.fs.create_node(redoxfs::Node::MODE_SYMLINK | 0o777, name.to_str().unwrap(), parent_block, ctime.as_secs(), ctime.subsec_nanos()) {
match self.fs.create_node(Node::MODE_SYMLINK | 0o777, name.to_str().unwrap(), parent_block, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(node) => {
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
match self.fs.write_node(node.0, 0, link.as_os_str().as_bytes(), mtime.as_secs(), mtime.subsec_nanos()) {
......
use std::fs::File;
use std::path::Path;
use disk::Disk;
use filesystem::FileSystem;
#[cfg(unix)]
mod fuse;
#[cfg(target_os = "redox")]
mod redox;
#[cfg(all(unix, target_os = "macos"))]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, mut write: File) {
use std::ffi::OsStr;
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")))]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, 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")]
pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P, write: File) {
redox::mount(filesystem, mountpoint, write);
}
extern crate spin;
use redoxfs;
use syscall::{Packet, Scheme};
use std::fs::File;
use std::io::{Read, Write};
......@@ -11,7 +10,7 @@ use self::scheme::FileScheme;
pub mod resource;
pub mod scheme;
pub fn mount<P: AsRef<Path>>(filesystem: redoxfs::FileSystem, mountpoint: &P, mut write: File) {
pub fn mount<P: AsRef<Path>>(filesystem: filesystem::FileSystem, mountpoint: &P, mut write: File) {
let mountpoint = mountpoint.as_ref();
match File::create(format!(":{}", mountpoint.display())) {
Ok(mut socket) => {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment