Cleanup to allow use of most functions when linking the library, including mounting and creating filesystems

This commit is contained in:
Jeremy Soller
2017-09-25 19:11:02 -06:00
parent b272cc2d19
commit 070aeb54ef
17 changed files with 116 additions and 153 deletions
Generated
+5 -4
View File
@@ -1,8 +1,9 @@
[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"
+4 -3
View File
@@ -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"
-47
View File
@@ -1,47 +0,0 @@
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)
}
}
+3 -8
View File
@@ -1,15 +1,10 @@
#![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);
},
+3 -47
View File
@@ -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);
+6 -7
View File
@@ -1,9 +1,8 @@
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);
+10 -10
View File
@@ -1,41 +1,41 @@
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));
+6
View File
@@ -1,5 +1,11 @@
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 -5
View File
@@ -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 {
+9 -7
View File
@@ -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;
+16 -13
View File
@@ -1,11 +1,14 @@
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()) {
+48
View File
@@ -0,0 +1,48 @@
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);
}
@@ -1,6 +1,5 @@
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) => {