From 87ecce9e4459ae40a87c49712aa11280a5914dff Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> Date: Sat, 8 Dec 2018 08:10:23 -0700 Subject: [PATCH] Cleanup and use unmount flag inside of Redox scheme processing function --- src/bin/mkfs.rs | 1 - src/bin/mount.rs | 32 ++++++++------- src/filesystem.rs | 5 ++- src/header.rs | 1 + src/lib.rs | 4 +- src/mount/fuse.rs | 5 ++- src/mount/redox/mod.rs | 37 ++++++++++++++--- src/mount/redox/scheme.rs | 85 ++------------------------------------- 8 files changed, 64 insertions(+), 106 deletions(-) diff --git a/src/bin/mkfs.rs b/src/bin/mkfs.rs index df612b4..b32a4e6 100644 --- a/src/bin/mkfs.rs +++ b/src/bin/mkfs.rs @@ -10,7 +10,6 @@ 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() { diff --git a/src/bin/mount.rs b/src/bin/mount.rs index 0cffb01..833d239 100644 --- a/src/bin/mount.rs +++ b/src/bin/mount.rs @@ -10,26 +10,34 @@ extern crate syscall; extern crate redoxfs; extern crate uuid; +use redoxfs::{DiskCache, DiskFile, mount}; use std::env; use std::fs::File; use std::io::{Read, Write}; use std::os::unix::io::FromRawFd; use std::process; -use redoxfs::FileSystem; - -use std::sync::atomic::{AtomicUsize, Ordering}; -use redoxfs::{DiskCache, DiskFile, mount,Disk}; +use std::sync::atomic::Ordering; use uuid::Uuid; + #[cfg(target_os = "redox")] -use syscall::{sigaction,sigreturn,SigAction,SIGKILL}; +use syscall::{sigaction, SigAction, SIGKILL}; use redoxfs::IS_UMT; +#[cfg(target_os = "redox")] +extern "C" fn unmount_handler(_s: usize) { + IS_UMT.store(1, Ordering::SeqCst); +} + #[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(); + sigaction(SIGKILL,Some(&SigAction{ + sa_handler: unmount_handler, + sa_mask: [0,0], + sa_flags: 0, + }),None).unwrap(); } #[cfg(unix)] @@ -37,6 +45,7 @@ fn setsig() { fn setsig() { () } + #[cfg(unix)] fn fork() -> isize { unsafe { libc::fork() as isize } @@ -109,6 +118,8 @@ fn disk_paths(paths: &mut Vec<String>) { } fn daemon(disk_id: &DiskId, mountpoint: &str, mut write: File) -> ! { + setsig(); + let mut paths = vec![]; let mut uuid_opt = None; @@ -142,7 +153,6 @@ 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); @@ -177,7 +187,6 @@ 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() { @@ -226,6 +235,7 @@ fn main() { let pid = fork(); if pid == 0 { drop(read); + daemon(&disk_id, &mountpoint, write); } else if pid > 0 { drop(write); @@ -241,9 +251,3 @@ 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(); -} diff --git a/src/filesystem.rs b/src/filesystem.rs index 5bc979f..da1745e 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -19,7 +19,7 @@ impl<D: Disk> FileSystem<D> { disk.read_at(block + header.0, &mut header.1)?; if header.1.valid() { - header.1.dirty=true; + 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)?; @@ -37,8 +37,9 @@ impl<D: Disk> FileSystem<D> { Err(Error::new(ENOENT)) } + pub fn close(&mut self) -> Result<()> { - self.header.1.dirty=false; + self.header.1.dirty = false; self.disk.write_at(self.header.0, &self.header.1)?; Ok(()) } diff --git a/src/header.rs b/src/header.rs index 2a8167e..5abe4c4 100644 --- a/src/header.rs +++ b/src/header.rs @@ -20,6 +20,7 @@ pub struct Header { pub root: u64, /// Block of free space node pub free: u64, + /// True if the filesystem is currently mounted pub dirty: bool, /// Padding pub padding: [u8; BLOCK_SIZE as usize - 57] diff --git a/src/lib.rs b/src/lib.rs index b23a283..a92ea06 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,8 @@ extern crate syscall; extern crate uuid; +use std::sync::atomic::AtomicUsize; + pub const BLOCK_SIZE: u64 = 4096; pub const SIGNATURE: &'static [u8; 8] = b"RedoxFS\0"; pub const VERSION: u64 = 3; @@ -18,7 +20,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; diff --git a/src/mount/fuse.rs b/src/mount/fuse.rs index f6af702..4380373 100644 --- a/src/mount/fuse.rs +++ b/src/mount/fuse.rs @@ -4,10 +4,10 @@ extern crate time; use std::cmp; use std::ffi::OsStr; use std::io; +use std::io::{ErrorKind, Error}; 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; @@ -29,8 +29,9 @@ pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: filesystem::FileSy callback(); session.run()?; + session.filesystem.fs.close().map_err(|e| Error::new(ErrorKind::Interrupted,format!("{}",e))) - + } pub struct Fuse<D: Disk> { diff --git a/src/mount/redox/mod.rs b/src/mount/redox/mod.rs index c4e004e..b0a03be 100644 --- a/src/mount/redox/mod.rs +++ b/src/mount/redox/mod.rs @@ -3,9 +3,11 @@ extern crate spin; use syscall; use syscall::{Packet, Scheme}; use std::fs::File; -use std::io::{self, Read, Write}; +use std::io::{Error, ErrorKind, Read, Result, Write}; use std::path::Path; +use std::sync::atomic::Ordering; +use IS_UMT; use disk::Disk; use filesystem::FileSystem; @@ -14,7 +16,7 @@ use self::scheme::FileScheme; pub mod resource; pub mod scheme; -pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, mut callback: F) -> io::Result<()> { +pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mountpoint: &P, mut callback: F) -> Result<()> { let mountpoint = mountpoint.as_ref(); let mut socket = File::create(format!(":{}", mountpoint.display()))?; @@ -23,10 +25,35 @@ pub fn mount<D: Disk, P: AsRef<Path>, F: FnMut()>(filesystem: FileSystem<D>, mou syscall::setrens(0, 0).expect("redoxfs: failed to enter null namespace"); let scheme = FileScheme::new(format!("{}", mountpoint.display()), filesystem); - loop { + let res = loop { + if IS_UMT.load(Ordering::SeqCst) > 0 { + break Ok(()); + } + let mut packet = Packet::default(); - socket.read(&mut packet).unwrap(); + match socket.read(&mut packet) { + Ok(_ok) => (), + Err(err) => if err.kind() == ErrorKind::Interrupted { + continue; + } else { + break Err(err); + } + } + scheme.handle(&mut packet); - socket.write(&packet).unwrap(); + + match socket.write(&packet) { + Ok(_ok) => (), + Err(err) => { + break Err(err); + } + } + }; + + { + let mut fs = scheme.fs.borrow_mut(); + fs.close().map_err(|e| Error::new(ErrorKind::Interrupted,format!("{}",e)))?; } + + res } diff --git a/src/mount/redox/scheme.rs b/src/mount/redox/scheme.rs index 5aedb34..2065a0b 100644 --- a/src/mount/redox/scheme.rs +++ b/src/mount/redox/scheme.rs @@ -2,19 +2,18 @@ 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; @@ -90,7 +89,7 @@ impl Fmaps { pub struct FileScheme<D: Disk> { name: String, - fs: RefCell<FileSystem<D>>, + pub(crate) fs: RefCell<FileSystem<D>>, next_id: AtomicUsize, files: Mutex<BTreeMap<usize, Box<Resource<D>>>>, fmaps: Mutex<Fmaps> @@ -252,8 +251,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(); @@ -388,10 +387,6 @@ 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); @@ -413,10 +408,6 @@ 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); @@ -454,11 +445,6 @@ 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); @@ -502,10 +488,6 @@ 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() { @@ -527,13 +509,6 @@ 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) { @@ -544,15 +519,6 @@ 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) { @@ -563,13 +529,6 @@ 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) { @@ -580,10 +539,6 @@ 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()) @@ -593,10 +548,6 @@ 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()) @@ -606,10 +557,6 @@ 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) @@ -619,10 +566,6 @@ 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) { @@ -649,10 +592,6 @@ 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); @@ -781,10 +720,6 @@ 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) { @@ -795,10 +730,6 @@ 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) { @@ -809,10 +740,6 @@ 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) { @@ -823,10 +750,6 @@ 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) { -- GitLab