Commit f96d3309 authored by Liam Naddell's avatar Liam Naddell

wip implementation of unmounting and dirty bits for redoxfs

parent 6126bfee
This diff is collapsed.
......@@ -10,6 +10,7 @@ use redoxfs::{FileSystem, DiskFile};
use uuid::Uuid;
fn main() {
println!("HI");
let mut args = env::args().skip(1);
let disk_path = if let Some(path) = args.next() {
......
#![deny(warnings)]
//#![deny(warnings)]
#![cfg_attr(unix, feature(libc))]
#[cfg(unix)]
......@@ -15,10 +15,28 @@ use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::FromRawFd;
use std::process;
use redoxfs::FileSystem;
use redoxfs::{DiskCache, DiskFile, mount};
use std::sync::atomic::{AtomicUsize, Ordering};
use redoxfs::{DiskCache, DiskFile, mount,Disk};
use uuid::Uuid;
#[cfg(target_os = "redox")]
use syscall::{sigaction,sigreturn,SigAction,SIGKILL};
use redoxfs::IS_UMT;
#[cfg(target_os = "redox")]
//set up a signal handler on redox, this implements unmounting. I have no idea what sa_flags is
//for, so I put 2. I don't think 0,0 is a valid sa_mask. I don't know what i'm doing here. When u
//send it a sigkill, it shuts off the filesystem
fn setsig() {
sigaction(SIGKILL,Some(&SigAction{sa_handler:hi,sa_mask:[0,0],sa_flags:2}),None).unwrap();
}
#[cfg(unix)]
// on linux, this is implemented properly, so no need for this unscrupulous nonsense!
fn setsig() {
()
}
#[cfg(unix)]
fn fork() -> isize {
unsafe { libc::fork() as isize }
......@@ -124,6 +142,7 @@ fn daemon(disk_id: &DiskId, mountpoint: &str, mut write: File) -> ! {
true
};
setsig();
if matches {
match mount(filesystem, &mountpoint, || {
println!("redoxfs: mounted filesystem on {} to {}", path, mountpoint);
......@@ -158,6 +177,7 @@ fn daemon(disk_id: &DiskId, mountpoint: &str, mut write: File) -> ! {
}
fn main() {
println!("It just works");
let mut args = env::args().skip(1);
let disk_id = match args.next() {
......@@ -206,7 +226,6 @@ fn main() {
let pid = fork();
if pid == 0 {
drop(read);
daemon(&disk_id, &mountpoint, write);
} else if pid > 0 {
drop(write);
......@@ -222,3 +241,9 @@ fn main() {
panic!("redoxfs: failed to create pipe");
}
}
#[cfg(target_os = "redox")]
extern "C" fn hi(s:usize) {
println!("{}",s);
IS_UMT.store(1, Ordering::Relaxed);
sigreturn().unwrap();
}
......@@ -19,6 +19,8 @@ impl<D: Disk> FileSystem<D> {
disk.read_at(block + header.0, &mut header.1)?;
if header.1.valid() {
header.1.dirty=true;
disk.write_at(header.0, &header.1)?;
let mut root = (header.1.root, Node::default());
disk.read_at(block + root.0, &mut root.1)?;
......@@ -35,6 +37,11 @@ impl<D: Disk> FileSystem<D> {
Err(Error::new(ENOENT))
}
pub fn close(&mut self) -> Result<()> {
self.header.1.dirty=false;
self.disk.write_at(self.header.0, &self.header.1)?;
Ok(())
}
/// Create a file system on a disk
pub fn create(disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> {
......
......@@ -20,8 +20,9 @@ pub struct Header {
pub root: u64,
/// Block of free space node
pub free: u64,
pub dirty: bool,
/// Padding
pub padding: [u8; BLOCK_SIZE as usize - 56]
pub padding: [u8; BLOCK_SIZE as usize - 57]
}
impl Header {
......@@ -33,7 +34,8 @@ impl Header {
size: 0,
root: 0,
free: 0,
padding: [0; BLOCK_SIZE as usize - 56]
dirty:false,
padding: [0; BLOCK_SIZE as usize - 57]
}
}
......@@ -46,7 +48,8 @@ impl Header {
size: size,
root: root,
free: free,
padding: [0; BLOCK_SIZE as usize - 56]
dirty:false,
padding: [0; BLOCK_SIZE as usize - 57]
}
}
......
......@@ -9,6 +9,7 @@ extern crate uuid;
pub const BLOCK_SIZE: u64 = 4096;
pub const SIGNATURE: &'static [u8; 8] = b"RedoxFS\0";
pub const VERSION: u64 = 3;
pub static IS_UMT: AtomicUsize = AtomicUsize::new(0);
pub use self::disk::{Disk, DiskCache, DiskFile};
pub use self::ex_node::ExNode;
......@@ -17,7 +18,7 @@ pub use self::filesystem::FileSystem;
pub use self::header::Header;
pub use self::mount::mount;
pub use self::node::Node;
use std::sync::atomic::AtomicUsize;
mod disk;
mod ex_node;
mod extent;
......
......@@ -7,6 +7,7 @@ use std::io;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};
use std::io::{ErrorKind,Error};
use BLOCK_SIZE;
use disk::Disk;
......@@ -27,7 +28,9 @@ pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: filesystem::FileSy
callback();
session.run()
session.run()?;
session.filesystem.fs.close().map_err(|e| Error::new(ErrorKind::Interrupted,format!("{}",e)))
}
pub struct Fuse<D: Disk> {
......
......@@ -2,18 +2,19 @@ use std::cell::RefCell;
use std::collections::BTreeMap;
use std::result::Result as StdResult;
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
use syscall::data::{Stat, StatVfs, TimeSpec};
use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, ENOTEMPTY, EPERM, ENOENT, EBADF, ELOOP, EINVAL};
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;
use std::sync::atomic::{AtomicUsize, Ordering};
use syscall::EINTR;
use BLOCK_SIZE;
use disk::Disk;
use filesystem::FileSystem;
use node::Node;
use IS_UMT;
use super::resource::{Resource, DirResource, FileResource};
use super::spin::Mutex;
......@@ -251,8 +252,8 @@ pub fn canonicalize(current: &[u8], path: &[u8]) -> Vec<u8> {
impl<D: Disk> Scheme for FileScheme<D> {
fn open(&self, url: &[u8], flags: usize, uid: u32, gid: u32) -> Result<usize> {
//WE ARE NOT GOING TO BLOCK THE OPEN CALL AT ALL
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
// println!("Open '{}' {:X}", path, flags);
let mut fs = self.fs.borrow_mut();
......@@ -387,6 +388,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn chmod(&self, url: &[u8], mode: u16, uid: u32, gid: u32) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
// println!("Chmod '{}'", path);
......@@ -408,6 +413,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn rmdir(&self, url: &[u8], uid: u32, gid: u32) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
// println!("Rmdir '{}'", path);
......@@ -445,6 +454,11 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn unlink(&self, url: &[u8], uid: u32, gid: u32) -> Result<usize> {
//block
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
// println!("Unlink '{}'", path);
......@@ -488,6 +502,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
/* Resource operations */
#[allow(unused_variables)]
fn dup(&self, old_id: usize, buf: &[u8]) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Dup {}", old_id);
if ! buf.is_empty() {
......@@ -509,6 +527,13 @@ impl<D: Disk> Scheme for FileScheme<D> {
#[allow(unused_variables)]
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Read {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......@@ -519,6 +544,15 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
//block
// println!("Write {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......@@ -529,6 +563,13 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Seek {}, {} {}", id, pos, whence);
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......@@ -539,6 +580,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn fchmod(&self, id: usize, mode: u16) -> Result<usize> {
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
//block
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
file.fchmod(mode, &mut self.fs.borrow_mut())
......@@ -548,6 +593,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn fchown(&self, id: usize, uid: u32, gid: u32) -> Result<usize> {
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
//block
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
file.fchown(uid, gid, &mut self.fs.borrow_mut())
......@@ -557,6 +606,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
file.fcntl(cmd, arg)
......@@ -566,6 +619,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Fpath {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
let files = self.files.lock();
if let Some(file) = files.get(&id) {
......@@ -592,6 +649,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn frename(&self, id: usize, url: &[u8], uid: u32, gid: u32) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
// println!("Frename {}, {} from {}, {}", id, path, uid, gid);
......@@ -720,6 +781,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn fsync(&self, id: usize) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Fsync {}", id);
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......@@ -730,6 +795,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn ftruncate(&self, id: usize, len: usize) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Ftruncate {}, {}", id, len);
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......@@ -740,6 +809,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn futimens(&self, id: usize, times: &[TimeSpec]) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Futimens {}, {}", id, times.len());
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......@@ -750,6 +823,10 @@ impl<D: Disk> Scheme for FileScheme<D> {
}
fn fmap(&self, id: usize, offset: usize, size: usize) -> Result<usize> {
//block
if 1 == IS_UMT.load(Ordering::Relaxed) {
return Err(Error::new(EINTR));
}
// println!("Fmap {}, {}, {}", id, offset, size);
let mut files = self.files.lock();
if let Some(file) = files.get_mut(&id) {
......
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