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