diff --git a/src/libos/src/fs/file_ops/access.rs b/src/libos/src/fs/file_ops/access.rs index 263e89e5..84116fdf 100644 --- a/src/libos/src/fs/file_ops/access.rs +++ b/src/libos/src/fs/file_ops/access.rs @@ -50,7 +50,7 @@ pub fn do_faccessat( let inode = { let path = fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); if flags.contains(AccessibilityCheckFlags::AT_SYMLINK_NOFOLLOW) { fs.lookup_inode_no_follow(&path)? } else { diff --git a/src/libos/src/fs/file_ops/chmod.rs b/src/libos/src/fs/file_ops/chmod.rs index ed2289d2..d25a45a0 100644 --- a/src/libos/src/fs/file_ops/chmod.rs +++ b/src/libos/src/fs/file_ops/chmod.rs @@ -61,7 +61,7 @@ pub fn do_fchmodat(fs_path: &FsPath, mode: FileMode) -> Result<()> { let inode = { let path = fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode(&path)? }; let mut info = inode.metadata()?; diff --git a/src/libos/src/fs/file_ops/chown.rs b/src/libos/src/fs/file_ops/chown.rs index c269ec8c..f0b56f4e 100644 --- a/src/libos/src/fs/file_ops/chown.rs +++ b/src/libos/src/fs/file_ops/chown.rs @@ -16,7 +16,7 @@ pub fn do_fchownat(fs_path: &FsPath, uid: u32, gid: u32, flags: ChownFlags) -> R let inode = { let path = fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); if flags.contains(ChownFlags::AT_SYMLINK_NOFOLLOW) { fs.lookup_inode_no_follow(&path)? } else { diff --git a/src/libos/src/fs/file_ops/fspath.rs b/src/libos/src/fs/file_ops/fspath.rs index a0f3b84f..290553db 100644 --- a/src/libos/src/fs/file_ops/fspath.rs +++ b/src/libos/src/fs/file_ops/fspath.rs @@ -74,12 +74,12 @@ impl<'a> FsPath<'a> { FsPathInner::Fd(fd) => get_abs_path_by_fd(*fd)?, FsPathInner::CwdRelative(path) => { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.convert_to_abs_path(path) } FsPathInner::Cwd => { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.cwd().to_owned() } }; diff --git a/src/libos/src/fs/file_ops/link.rs b/src/libos/src/fs/file_ops/link.rs index d8a81176..499f5a10 100644 --- a/src/libos/src/fs/file_ops/link.rs +++ b/src/libos/src/fs/file_ops/link.rs @@ -18,7 +18,7 @@ pub fn do_linkat(old_fs_path: &FsPath, new_fs_path: &FsPath, flags: LinkFlags) - let (inode, new_dir_inode) = { let oldpath = old_fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); let inode = if flags.contains(LinkFlags::AT_SYMLINK_FOLLOW) { fs.lookup_inode(&oldpath)? } else { diff --git a/src/libos/src/fs/file_ops/mkdir.rs b/src/libos/src/fs/file_ops/mkdir.rs index 11ffc2b4..cb0bd255 100644 --- a/src/libos/src/fs/file_ops/mkdir.rs +++ b/src/libos/src/fs/file_ops/mkdir.rs @@ -7,7 +7,7 @@ pub fn do_mkdirat(fs_path: &FsPath, mode: usize) -> Result<()> { let (dir_path, file_name) = split_path(&path); let inode = { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode(dir_path)? }; if inode.find(file_name).is_ok() { diff --git a/src/libos/src/fs/file_ops/open.rs b/src/libos/src/fs/file_ops/open.rs index 6c7a40af..98a79a89 100644 --- a/src/libos/src/fs/file_ops/open.rs +++ b/src/libos/src/fs/file_ops/open.rs @@ -8,7 +8,7 @@ pub fn do_openat(fs_path: &FsPath, flags: u32, mode: u32) -> Result { let path = fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); let file_ref: Arc = fs.open_file(&path, flags, mode)?; diff --git a/src/libos/src/fs/file_ops/rename.rs b/src/libos/src/fs/file_ops/rename.rs index a673ab20..4812583b 100644 --- a/src/libos/src/fs/file_ops/rename.rs +++ b/src/libos/src/fs/file_ops/rename.rs @@ -9,7 +9,7 @@ pub fn do_renameat(old_fs_path: &FsPath, new_fs_path: &FsPath) -> Result<()> { let oldpath = old_fs_path.to_abs_path()?; let newpath = new_fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); let (old_dir_path, old_file_name) = split_path(&oldpath); let (new_dir_path, new_file_name) = split_path(&newpath); diff --git a/src/libos/src/fs/file_ops/rmdir.rs b/src/libos/src/fs/file_ops/rmdir.rs index 0e02cadf..def94478 100644 --- a/src/libos/src/fs/file_ops/rmdir.rs +++ b/src/libos/src/fs/file_ops/rmdir.rs @@ -6,7 +6,7 @@ pub fn do_rmdir(path: &str) -> Result<()> { let (dir_path, file_name) = split_path(&path); let dir_inode = { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode(dir_path)? }; let file_inode = dir_inode.find(file_name)?; diff --git a/src/libos/src/fs/file_ops/stat.rs b/src/libos/src/fs/file_ops/stat.rs index 48ce754d..5efcbd18 100644 --- a/src/libos/src/fs/file_ops/stat.rs +++ b/src/libos/src/fs/file_ops/stat.rs @@ -147,7 +147,7 @@ pub fn do_fstatat(fs_path: &FsPath, flags: StatFlags) -> Result { let inode = { let path = fs_path.to_abs_path()?; let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); if flags.contains(StatFlags::AT_SYMLINK_NOFOLLOW) { fs.lookup_inode_no_follow(&path)? } else { diff --git a/src/libos/src/fs/file_ops/symlink.rs b/src/libos/src/fs/file_ops/symlink.rs index 07b34571..b90e33af 100644 --- a/src/libos/src/fs/file_ops/symlink.rs +++ b/src/libos/src/fs/file_ops/symlink.rs @@ -7,7 +7,7 @@ pub fn do_readlinkat(fs_path: &FsPath, buf: &mut [u8]) -> Result { let file_path = { let inode = { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode_no_follow(&path)? }; if inode.metadata()?.type_ != FileType::SymLink { @@ -38,7 +38,7 @@ pub fn do_symlinkat(target: &str, link_path: &FsPath) -> Result { let (dir_path, link_name) = split_path(&link_path); let dir_inode = { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode(dir_path)? }; if !dir_inode.allow_write()? { diff --git a/src/libos/src/fs/file_ops/truncate.rs b/src/libos/src/fs/file_ops/truncate.rs index 63c85fdd..745e81db 100644 --- a/src/libos/src/fs/file_ops/truncate.rs +++ b/src/libos/src/fs/file_ops/truncate.rs @@ -4,7 +4,7 @@ pub fn do_truncate(path: &str, len: usize) -> Result<()> { debug!("truncate: path: {:?}, len: {}", path, len); let inode = { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode(&path)? }; inode.resize(len)?; diff --git a/src/libos/src/fs/file_ops/unlink.rs b/src/libos/src/fs/file_ops/unlink.rs index bafcbe56..927bc0c2 100644 --- a/src/libos/src/fs/file_ops/unlink.rs +++ b/src/libos/src/fs/file_ops/unlink.rs @@ -10,7 +10,7 @@ fn do_unlink(path: &str) -> Result<()> { let (dir_path, file_name) = split_path(&path); let dir_inode = { let current = current!(); - let fs = current.fs().lock().unwrap(); + let fs = current.fs().read().unwrap(); fs.lookup_inode(dir_path)? }; let file_inode = dir_inode.find(file_name)?; diff --git a/src/libos/src/fs/fs_ops/chdir.rs b/src/libos/src/fs/fs_ops/chdir.rs index 4efa4472..88b112b9 100644 --- a/src/libos/src/fs/fs_ops/chdir.rs +++ b/src/libos/src/fs/fs_ops/chdir.rs @@ -4,14 +4,15 @@ pub fn do_chdir(path: &str) -> Result<()> { debug!("chdir: path: {:?}", path); let current = current!(); - let mut fs = current.fs().lock().unwrap(); - - let inode = fs.lookup_inode(path)?; + let inode = { + let fs = current.fs().read().unwrap(); + fs.lookup_inode(path)? + }; let info = inode.metadata()?; if info.type_ != FileType::Dir { return_errno!(ENOTDIR, "cwd must be directory"); } - fs.set_cwd(path)?; + current.fs().write().unwrap().set_cwd(path)?; Ok(()) } diff --git a/src/libos/src/fs/fs_ops/getcwd.rs b/src/libos/src/fs/fs_ops/getcwd.rs index cc0f98a5..0a436665 100644 --- a/src/libos/src/fs/fs_ops/getcwd.rs +++ b/src/libos/src/fs/fs_ops/getcwd.rs @@ -3,7 +3,7 @@ use super::*; pub fn do_getcwd() -> Result { debug!("getcwd"); let thread = current!(); - let fs = thread.fs().lock().unwrap(); + let fs = thread.fs().read().unwrap(); let cwd = fs.cwd().to_owned(); Ok(cwd) } diff --git a/src/libos/src/fs/procfs/pid_inode.rs b/src/libos/src/fs/procfs/pid_inode.rs index a1b01502..5c756fc9 100644 --- a/src/libos/src/fs/procfs/pid_inode.rs +++ b/src/libos/src/fs/procfs/pid_inode.rs @@ -165,7 +165,7 @@ impl ProcCwdSymINode { impl ProcINode for ProcCwdSymINode { fn generate_data_in_bytes(&self) -> vfs::Result> { let main_thread = self.0.main_thread().ok_or(FsError::EntryNotFound)?; - let fs = main_thread.fs().lock().unwrap(); + let fs = main_thread.fs().read().unwrap(); Ok(fs.cwd().to_owned().into_bytes()) } } @@ -181,7 +181,7 @@ impl ProcRootSymINode { impl ProcINode for ProcRootSymINode { fn generate_data_in_bytes(&self) -> vfs::Result> { let main_thread = self.0.main_thread().ok_or(FsError::EntryNotFound)?; - let fs = main_thread.fs().lock().unwrap(); + let fs = main_thread.fs().read().unwrap(); Ok(fs.root().to_owned().into_bytes()) } } diff --git a/src/libos/src/net/socket/unix/addr.rs b/src/libos/src/net/socket/unix/addr.rs index 6f082e08..397b2851 100644 --- a/src/libos/src/net/socket/unix/addr.rs +++ b/src/libos/src/net/socket/unix/addr.rs @@ -126,7 +126,7 @@ impl UnixPath { None } else { let thread = current!(); - let fs = thread.fs().lock().unwrap(); + let fs = thread.fs().read().unwrap(); let cwd = fs.cwd().to_owned(); Some(cwd) diff --git a/src/libos/src/process/do_spawn/exec_loader.rs b/src/libos/src/process/do_spawn/exec_loader.rs index 9abf5303..7ac35ea9 100644 --- a/src/libos/src/process/do_spawn/exec_loader.rs +++ b/src/libos/src/process/do_spawn/exec_loader.rs @@ -75,7 +75,7 @@ pub fn load_file_hdr_to_vec( ) -> Result<(Arc, Vec, Option)> { let inode = current_ref .fs() - .lock() + .read() .unwrap() .lookup_inode(file_path) .map_err(|e| errno!(e.errno(), "cannot find the file"))?; diff --git a/src/libos/src/process/do_spawn/mod.rs b/src/libos/src/process/do_spawn/mod.rs index 1d89311d..4216c494 100644 --- a/src/libos/src/process/do_spawn/mod.rs +++ b/src/libos/src/process/do_spawn/mod.rs @@ -185,7 +185,7 @@ fn new_process( let files = init_files(current_ref, file_actions, host_stdio_fds)?; Arc::new(SgxMutex::new(files)) }; - let fs_ref = Arc::new(SgxMutex::new(current_ref.fs().lock().unwrap().clone())); + let fs_ref = Arc::new(RwLock::new(current_ref.fs().read().unwrap().clone())); let sched_ref = Arc::new(SgxMutex::new(current_ref.sched().lock().unwrap().clone())); let rlimit_ref = Arc::new(SgxMutex::new(current_ref.rlimits().lock().unwrap().clone())); @@ -254,7 +254,7 @@ fn init_files( let file_ref = current_ref .fs() - .lock() + .read() .unwrap() .open_file(path.as_str(), oflag, mode)?; let creation_flags = CreationFlags::from_bits_truncate(oflag); diff --git a/src/libos/src/process/mod.rs b/src/libos/src/process/mod.rs index 070cbc1a..915c0e77 100644 --- a/src/libos/src/process/mod.rs +++ b/src/libos/src/process/mod.rs @@ -62,6 +62,6 @@ pub type ProcessRef = Arc; pub type ThreadRef = Arc; pub type FileTableRef = Arc>; pub type ProcessVMRef = Arc; -pub type FsViewRef = Arc>; +pub type FsViewRef = Arc>; pub type SchedAgentRef = Arc>; pub type ResourceLimitsRef = Arc>; diff --git a/src/libos/src/util/sync/rw_lock/mod.rs b/src/libos/src/util/sync/rw_lock/mod.rs index f1452410..0d7382e1 100644 --- a/src/libos/src/util/sync/rw_lock/mod.rs +++ b/src/libos/src/util/sync/rw_lock/mod.rs @@ -106,6 +106,12 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock { } } +impl Default for RwLock { + fn default() -> RwLock { + RwLock::new(Default::default()) + } +} + impl fmt::Debug for RwLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RwLock") diff --git a/test/procfs/main.c b/test/procfs/main.c index 0a1ee0c9..21670678 100644 --- a/test/procfs/main.c +++ b/test/procfs/main.c @@ -76,6 +76,19 @@ static int test_readlink_from_proc_self_root() { return 0; } +static int test_create_and_unlink_file_from_proc_self_root() { + const char *proc_root_file = "/proc/self/root/test_file"; + int fd = open(proc_root_file, O_RDONLY | O_CREAT | O_TRUNC, 00666); + if (fd < 0) { + THROW_ERROR("failed to create a file"); + } + close(fd); + if (unlink(proc_root_file) < 0) { + THROW_ERROR("failed to unlink the created file"); + } + return 0; +} + static int test_read_from_proc_self_cmdline() { char absolute_path[PATH_MAX] = { 0 }; const char *proc_cmdline = "/proc/self/cmdline"; @@ -137,6 +150,7 @@ static test_case_t test_cases[] = { TEST_CASE(test_readlink_from_proc_self_exe), TEST_CASE(test_readlink_from_proc_self_cwd), TEST_CASE(test_readlink_from_proc_self_root), + TEST_CASE(test_create_and_unlink_file_from_proc_self_root), TEST_CASE(test_read_from_proc_self_cmdline), TEST_CASE(test_read_from_proc_meminfo), TEST_CASE(test_read_from_proc_cpuinfo),