diff --git a/kernel/src/fs/epoll/file.rs b/kernel/src/fs/epoll/file.rs index 7bcdc4fee..e35e150dd 100644 --- a/kernel/src/fs/epoll/file.rs +++ b/kernel/src/fs/epoll/file.rs @@ -17,7 +17,7 @@ use crate::{ file_table::{FdFlags, FileDesc, get_file_fast}, path::Path, pseudofs::AnonInodeFs, - utils::{CreationFlags, Inode}, + utils::CreationFlags, }, prelude::*, process::{ @@ -274,8 +274,8 @@ impl FileLike for EpollFile { return_errno_with_message!(Errno::ENOTTY, "epoll files do not support ioctl"); } - fn inode(&self) -> &Arc { - self.pseudo_path.inode() + fn path(&self) -> &Path { + &self.pseudo_path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { diff --git a/kernel/src/fs/file_handle.rs b/kernel/src/fs/file_handle.rs index a00bffa04..6c2712ad4 100644 --- a/kernel/src/fs/file_handle.rs +++ b/kernel/src/fs/file_handle.rs @@ -97,7 +97,7 @@ pub trait FileLike: Pollable + Send + Sync + Any { None } - fn inode(&self) -> &Arc; + fn path(&self) -> &Path; /// Dumps information to appear in the `fdinfo` file under procfs. /// @@ -144,12 +144,6 @@ impl dyn FileLike { .ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the file is not a socket")) } - pub fn path(&self) -> Option<&Path> { - self.as_inode_handle_or_err() - .ok() - .map(|inode_handle| inode_handle.path()) - } - pub fn as_inode_handle_or_err(&self) -> Result<&InodeHandle> { self.downcast_ref().ok_or_else(|| { Error::with_message(Errno::EINVAL, "the file is not related to an inode") diff --git a/kernel/src/fs/fs_resolver.rs b/kernel/src/fs/fs_resolver.rs index e1bf7543c..1e4f92e1e 100644 --- a/kernel/src/fs/fs_resolver.rs +++ b/kernel/src/fs/fs_resolver.rs @@ -10,10 +10,7 @@ use super::{ utils::{InodeType, PATH_MAX, SYMLINKS_MAX}, }; use crate::{ - fs::{ - path::MountNamespace, - utils::{Inode, SymbolicLink}, - }, + fs::{path::MountNamespace, utils::SymbolicLink}, prelude::*, process::posix_thread::AsThreadLocal, }; @@ -92,35 +89,17 @@ impl FsResolver { /// /// Symlinks are always followed. pub fn lookup(&self, fs_path: &FsPath) -> Result { - self.lookup_inode(fs_path)? - .into_path() - .ok_or_else(|| Error::with_message(Errno::EPERM, "the path refers to a pseudo file")) + self.lookup_unresolved(fs_path)?.into_path() } /// Lookups the target `Path` according to the `fs_path`. /// /// If the last component is a symlink, it will not be followed. pub fn lookup_no_follow(&self, fs_path: &FsPath) -> Result { - self.lookup_inode_no_follow(fs_path)? - .into_path() - .ok_or_else(|| Error::with_message(Errno::EPERM, "the path refers to a pseudo file")) + self.lookup_unresolved_no_follow(fs_path)?.into_path() } - /// Lookups the target `PathOrInode` according to the `fs_path`. - /// - /// Symlinks are always followed. - pub fn lookup_inode(&self, fs_path: &FsPath) -> Result { - self.lookup_inner(fs_path, true)?.into_path_or_inode() - } - - /// Lookups the target `PathOrInode` according to the `fs_path`. - /// - /// If the last component is a symlink, it will not be followed. - pub fn lookup_inode_no_follow(&self, fs_path: &FsPath) -> Result { - self.lookup_inner(fs_path, false)?.into_path_or_inode() - } - - /// Lookups the target `PathOrInode` according to the `fs_path` and leaves + /// Lookups the target `Path` according to the `fs_path` and leaves /// the result unresolved. /// /// An unresolved result may indicate either successful full-path resolution, @@ -132,7 +111,7 @@ impl FsResolver { self.lookup_inner(fs_path, true) } - /// Lookups the target `PathOrInode` according to the `fs_path` and leaves + /// Lookups the target `Path` according to the `fs_path` and leaves /// the result unresolved. /// /// An unresolved result may indicate either successful full-path resolution, @@ -152,7 +131,7 @@ impl FsResolver { FsPathInner::CwdRelative(path) => { self.lookup_from_parent(&self.cwd, path, follow_tail_link)? } - FsPathInner::Cwd => LookupResult::Resolved(PathOrInode::Path(self.cwd.clone())), + FsPathInner::Cwd => LookupResult::Resolved(self.cwd.clone()), FsPathInner::FdRelative(fd, path) => { let task = Task::current().unwrap(); let mut file_table = task.as_thread_local().unwrap().borrow_file_table_mut(); @@ -164,12 +143,7 @@ impl FsResolver { let task = Task::current().unwrap(); let mut file_table = task.as_thread_local().unwrap().borrow_file_table_mut(); let file = get_file_fast!(&mut file_table, fd); - let path_or_inode = if let Ok(inode_handle) = file.as_inode_handle_or_err() { - PathOrInode::Path(inode_handle.path().clone()) - } else { - PathOrInode::Inode(file.inode().clone()) - }; - LookupResult::Resolved(path_or_inode) + LookupResult::Resolved(file.path().clone()) } }; @@ -200,7 +174,7 @@ impl FsResolver { return_errno_with_message!(Errno::ENAMETOOLONG, "the path is too long"); } if relative_path.is_empty() { - return Ok(LookupResult::Resolved(PathOrInode::Path(parent.clone()))); + return Ok(LookupResult::Resolved(parent.clone())); } // To handle symlinks @@ -275,18 +249,6 @@ impl FsResolver { relative_path = path_remain; follows += 1; } - SymbolicLink::Inode(inode) => { - debug_assert!( - inode.type_() != InodeType::Dir && inode.type_() != InodeType::SymLink - ); - if !next_is_tail { - return_errno_with_message!( - Errno::ENOTDIR, - "the inode is not a directory" - ); - } - return Ok(LookupResult::Resolved(PathOrInode::Inode(inode))); - } } } else { // If path ends with `/`, the inode must be a directory @@ -298,7 +260,7 @@ impl FsResolver { } } - Ok(LookupResult::Resolved(PathOrInode::Path(current_path))) + Ok(LookupResult::Resolved(current_path)) } } @@ -377,62 +339,16 @@ impl<'a> TryFrom<&'a str> for FsPath<'a> { } } -/// An item in the file system. -// FIXME: Each item in the file system should have a `Path`. This struct exists -// because not all `Arc`s are associated with paths. We should -// introduce `PipeFs`, `SocketFs`, and `AnonInodeFs`, add pseudo paths and dentries -// for these pseudo inodes, and eventually remove this struct. -#[derive(Clone)] -pub enum PathOrInode { - Path(Path), - Inode(Arc), -} - -impl PathOrInode { - pub fn into_path(self) -> Option { - match self { - PathOrInode::Path(path) => Some(path), - PathOrInode::Inode(_) => None, - } - } - - pub fn inode(&self) -> &Arc { - match self { - PathOrInode::Path(path) => path.inode(), - PathOrInode::Inode(inode) => inode, - } - } - - pub fn display_name(&self) -> String { - match self { - PathOrInode::Path(path) => path.abs_path(), - PathOrInode::Inode(_) => { - // FIXME: Add pseudo dentries to store the correct name. - String::from("[pseudo inode]") - } - } - } -} - -impl Debug for PathOrInode { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - PathOrInode::Path(path) => write!(f, "PathOrInode::Path({})", path.abs_path()), - PathOrInode::Inode(inode) => write!(f, "PathOrInode::Inode({:p})", inode.as_ref()), - } - } -} - // A result type for lookup operations. pub enum LookupResult { - /// The entire path was resolved to a final `PathOrInode`. - Resolved(PathOrInode), + /// The entire path was resolved to a final `Path`. + Resolved(Path), /// The path resolution stopped at a parent directory. AtParent(LookupParentResult), } impl LookupResult { - fn into_path_or_inode(self) -> Result { + fn into_path(self) -> Result { match self { LookupResult::Resolved(target) => Ok(target), LookupResult::AtParent(_) => Err(Error::with_message( diff --git a/kernel/src/fs/inode_handle.rs b/kernel/src/fs/inode_handle.rs index 199dd9960..d11572476 100644 --- a/kernel/src/fs/inode_handle.rs +++ b/kernel/src/fs/inode_handle.rs @@ -18,8 +18,8 @@ use crate::{ path::Path, pipe::PipeHandle, utils::{ - AccessMode, CreationFlags, DirentVisitor, FallocMode, FileRange, FlockItem, Inode, - InodeType, OFFSET_MAX, RangeLockItem, RangeLockType, SeekFrom, StatusFlags, + AccessMode, CreationFlags, DirentVisitor, FallocMode, FileRange, FlockItem, InodeType, + OFFSET_MAX, RangeLockItem, RangeLockType, SeekFrom, StatusFlags, }, }, prelude::*, @@ -452,8 +452,8 @@ impl FileLike for InodeHandle { inode.fallocate(mode, offset, len) } - fn inode(&self) -> &Arc { - self.path.inode() + fn path(&self) -> &Path { + &self.path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { @@ -471,8 +471,8 @@ impl FileLike for InodeHandle { writeln!(f, "pos:\t{}", self.inner.offset())?; writeln!(f, "flags:\t0{:o}", flags)?; - writeln!(f, "mnt_id:\t{}", self.inner.path().mount_node().id())?; - writeln!(f, "ino:\t{}", self.inner.inode().ino()) + writeln!(f, "mnt_id:\t{}", self.inner.path.mount_node().id())?; + writeln!(f, "ino:\t{}", self.inner.path.inode().ino()) } } diff --git a/kernel/src/fs/notify/inotify.rs b/kernel/src/fs/notify/inotify.rs index cfe33c08d..37567920b 100644 --- a/kernel/src/fs/notify/inotify.rs +++ b/kernel/src/fs/notify/inotify.rs @@ -359,8 +359,8 @@ impl FileLike for InotifyFile { AccessMode::O_RDONLY } - fn inode(&self) -> &Arc { - self.pseudo_path.inode() + fn path(&self) -> &Path { + &self.pseudo_path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { diff --git a/kernel/src/fs/notify/mod.rs b/kernel/src/fs/notify/mod.rs index abbdb7bd5..39b05a5b6 100644 --- a/kernel/src/fs/notify/mod.rs +++ b/kernel/src/fs/notify/mod.rs @@ -240,16 +240,9 @@ define_atomic_version_of_integer_like_type!(FsEvents, { /// Notifies that a file was accessed. pub fn on_access(file: &Arc) { // TODO: Check fmode flags (FMODE_NONOTIFY, FMODE_NONOTIFY_PERM). - let Some(path) = file.path() else { - return; - }; + let path = file.path(); - if !path - .inode() - .fs() - .fs_event_subscriber_stats() - .has_any_subscribers() - { + if !path.fs().fs_event_subscriber_stats().has_any_subscribers() { return; } notify_parent(path, FsEvents::ACCESS); @@ -258,16 +251,9 @@ pub fn on_access(file: &Arc) { /// Notifies that a file was modified. pub fn on_modify(file: &Arc) { // TODO: Check fmode flags (FMODE_NONOTIFY, FMODE_NONOTIFY_PERM). - let Some(path) = file.path() else { - return; - }; + let path = file.path(); - if !path - .inode() - .fs() - .fs_event_subscriber_stats() - .has_any_subscribers() - { + if !path.fs().fs_event_subscriber_stats().has_any_subscribers() { return; } notify_parent(path, FsEvents::MODIFY); @@ -275,12 +261,7 @@ pub fn on_modify(file: &Arc) { /// Notifies that a path's content was changed. pub fn on_change(path: &Path) { - if !path - .inode() - .fs() - .fs_event_subscriber_stats() - .has_any_subscribers() - { + if !path.fs().fs_event_subscriber_stats().has_any_subscribers() { return; } notify_parent(path, FsEvents::MODIFY); @@ -339,7 +320,6 @@ pub fn on_link(dir_inode: &Arc, inode: &Arc, name: impl Fn /// Notifies that a directory was created. pub fn on_mkdir(dir_path: &Path, name: impl FnOnce() -> String) { if !dir_path - .inode() .fs() .fs_event_subscriber_stats() .has_any_subscribers() @@ -352,7 +332,6 @@ pub fn on_mkdir(dir_path: &Path, name: impl FnOnce() -> String) { /// Notifies that a file was created. pub fn on_create(file_path: &Path, name: impl FnOnce() -> String) { if !file_path - .inode() .fs() .fs_event_subscriber_stats() .has_any_subscribers() @@ -365,16 +344,9 @@ pub fn on_create(file_path: &Path, name: impl FnOnce() -> String) { /// Notifies that a file was opened. pub fn on_open(file: &Arc) { // TODO: Check fmode flags (FMODE_NONOTIFY, FMODE_NONOTIFY_PERM). - let Some(path) = file.path() else { - return; - }; + let path = file.path(); - if !path - .inode() - .fs() - .fs_event_subscriber_stats() - .has_any_subscribers() - { + if !path.fs().fs_event_subscriber_stats().has_any_subscribers() { return; } notify_parent(path, FsEvents::OPEN); @@ -383,31 +355,21 @@ pub fn on_open(file: &Arc) { /// Notifies that a file was closed. pub fn on_close(file: &Arc) { // TODO: Check fmode flags (FMODE_NONOTIFY, FMODE_NONOTIFY_PERM). - if let Some(path) = file.path() { - if !path - .inode() - .fs() - .fs_event_subscriber_stats() - .has_any_subscribers() - { - return; - } - let events = match file.access_mode() { - AccessMode::O_RDONLY => FsEvents::CLOSE_NOWRITE, - _ => FsEvents::CLOSE_WRITE, - }; - notify_parent(path, events); + let path = file.path(); + + if !path.fs().fs_event_subscriber_stats().has_any_subscribers() { + return; } + let events = match file.access_mode() { + AccessMode::O_RDONLY => FsEvents::CLOSE_NOWRITE, + _ => FsEvents::CLOSE_WRITE, + }; + notify_parent(path, events); } /// Notifies that a file's attributes changed. pub fn on_attr_change(path: &Path) { - if !path - .inode() - .fs() - .fs_event_subscriber_stats() - .has_any_subscribers() - { + if !path.fs().fs_event_subscriber_stats().has_any_subscribers() { return; } notify_parent(path, FsEvents::ATTRIB); diff --git a/kernel/src/fs/overlayfs/fs.rs b/kernel/src/fs/overlayfs/fs.rs index 546fc54b9..46db59d97 100644 --- a/kernel/src/fs/overlayfs/fs.rs +++ b/kernel/src/fs/overlayfs/fs.rs @@ -1486,9 +1486,6 @@ mod tests { let link = d1.create("link", InodeType::SymLink, mode).unwrap(); let link_str = "link_to_somewhere"; link.write_link(link_str).unwrap(); - assert_eq!( - link.read_link().unwrap().into_plain().unwrap(), - link_str.to_string() - ); + assert_eq!(link.read_link().unwrap().to_string(), link_str.to_string()); } } diff --git a/kernel/src/fs/procfs/pid/task/comm.rs b/kernel/src/fs/procfs/pid/task/comm.rs index d7727ee06..52683dd5e 100644 --- a/kernel/src/fs/procfs/pid/task/comm.rs +++ b/kernel/src/fs/procfs/pid/task/comm.rs @@ -33,7 +33,7 @@ impl FileOps for CommFileOps { return Ok(0); }; - let exe_path = vmar.process_vm().executable_file().display_name(); + let exe_path = vmar.process_vm().executable_file().abs_path(); let last_component = exe_path.rsplit('/').next().unwrap_or(&exe_path); let mut comm = last_component.as_bytes().to_vec(); comm.truncate(TASK_COMM_LEN - 1); diff --git a/kernel/src/fs/procfs/pid/task/exe.rs b/kernel/src/fs/procfs/pid/task/exe.rs index dedb36a1b..a5fdabc67 100644 --- a/kernel/src/fs/procfs/pid/task/exe.rs +++ b/kernel/src/fs/procfs/pid/task/exe.rs @@ -3,7 +3,6 @@ use super::TidDirOps; use crate::{ fs::{ - fs_resolver::PathOrInode, procfs::{ProcSymBuilder, SymOps}, utils::{Inode, SymbolicLink, mkmod}, }, @@ -33,11 +32,8 @@ impl SymOps for ExeSymOps { let Some(vmar) = vmar_guard.as_ref() else { return_errno_with_message!(Errno::ENOENT, "the process has exited"); }; + let path = vmar.process_vm().executable_file().clone(); - let res = match vmar.process_vm().executable_file().clone() { - PathOrInode::Path(path) => SymbolicLink::Path(path), - PathOrInode::Inode(inode) => SymbolicLink::Inode(inode), - }; - Ok(res) + Ok(SymbolicLink::Path(path)) } } diff --git a/kernel/src/fs/procfs/pid/task/fd.rs b/kernel/src/fs/procfs/pid/task/fd.rs index ebcb521eb..b494404ad 100644 --- a/kernel/src/fs/procfs/pid/task/fd.rs +++ b/kernel/src/fs/procfs/pid/task/fd.rs @@ -10,7 +10,6 @@ use crate::{ fs::{ file_handle::FileLike, file_table::FileDesc, - inode_handle::InodeHandle, procfs::{ DirOps, ProcDir, ProcDirBuilder, ProcSymBuilder, SymOps, template::{FileOps, ProcFile, ProcFileBuilder, ProcSym}, @@ -232,13 +231,7 @@ impl SymOps for FileSymOps { .get_file(self.file_desc) .map_err(|_| Error::with_message(Errno::ENOENT, "the file does not exist"))?; - let res = if let Some(inode_handle) = file.downcast_ref::() { - SymbolicLink::Path(inode_handle.path().clone()) - } else { - SymbolicLink::Inode(file.inode().clone()) - }; - - Ok(res) + Ok(SymbolicLink::Path(file.path().clone())) } } diff --git a/kernel/src/fs/pseudofs.rs b/kernel/src/fs/pseudofs.rs index d518c05c6..edbf44941 100644 --- a/kernel/src/fs/pseudofs.rs +++ b/kernel/src/fs/pseudofs.rs @@ -11,12 +11,13 @@ use spin::Once; use super::utils::{Extension, InodeIo, StatusFlags}; use crate::{ fs::{ + inode_handle::FileIo, path::{Mount, Path}, pipe::AnonPipeInode, registry::{FsProperties, FsType}, utils::{ - FileSystem, FsEventSubscriberStats, FsFlags, Inode, InodeMode, InodeType, Metadata, - NAME_MAX, SuperBlock, mkmod, + AccessMode, FileSystem, FsEventSubscriberStats, FsFlags, Inode, InodeMode, InodeType, + Metadata, NAME_MAX, SuperBlock, mkmod, }, }, prelude::*, @@ -431,6 +432,17 @@ impl Inode for PseudoInode { self.metadata.lock().ctime = time; } + fn open( + &self, + _access_mode: AccessMode, + _status_flags: StatusFlags, + ) -> Option>> { + Some(Err(Error::with_message( + Errno::ENXIO, + "the pseudo inode is not re-openable", + ))) + } + fn fs(&self) -> Arc { self.fs.upgrade().unwrap() } diff --git a/kernel/src/fs/sysfs/test.rs b/kernel/src/fs/sysfs/test.rs index 2da742b38..5bf27af72 100644 --- a/kernel/src/fs/sysfs/test.rs +++ b/kernel/src/fs/sysfs/test.rs @@ -436,7 +436,7 @@ fn test_sysfs_read_link() { // the path provided by the underlying mock systree symlink node's target_path method. let target = link1_inode.read_link().expect("read_link failed"); - assert_eq!(target.into_plain().unwrap(), "../branch1/leaf1"); + assert_eq!(target.to_string(), "../branch1/leaf1"); // read_link on non-symlink should fail (expect EINVAL as per inode.rs) let branch1_inode = root_inode.lookup("branch1").unwrap(); diff --git a/kernel/src/fs/utils/inode.rs b/kernel/src/fs/utils/inode.rs index 2431add2e..c45e9edd5 100644 --- a/kernel/src/fs/utils/inode.rs +++ b/kernel/src/fs/utils/inode.rs @@ -16,7 +16,6 @@ use super::{ use crate::{ fs::{ device::{Device, DeviceType}, - fs_resolver::PathOrInode, inode_handle::FileIo, path::Path, utils::StatusFlags, @@ -605,33 +604,14 @@ pub enum SymbolicLink { /// This variant is intended to support the special ProcFS symbolic links, /// such as `/proc/[pid]/fd/[fd]` and `/proc/[pid]/exe`. Path(Path), - /// An inode object without a FS path. - // FIXME: - // This variant exists because not all `Arc`s are associated - // with paths. We should add pseudo paths and dentries for these inodes, - // and eventually remove this variant. - Inode(Arc), -} - -impl SymbolicLink { - #[cfg_attr(not(ktest), expect(dead_code))] - pub fn into_plain(self) -> Option { - match self { - SymbolicLink::Plain(s) => Some(s), - _ => None, - } - } } #[expect(clippy::to_string_trait_impl)] impl ToString for SymbolicLink { fn to_string(&self) -> String { - let path_or_inode = match self.clone() { - SymbolicLink::Plain(s) => return s, - SymbolicLink::Path(path) => PathOrInode::Path(path), - SymbolicLink::Inode(inode) => PathOrInode::Inode(inode), - }; - - path_or_inode.display_name() + match self { + SymbolicLink::Plain(s) => s.clone(), + SymbolicLink::Path(path) => path.abs_path(), + } } } diff --git a/kernel/src/net/socket/mod.rs b/kernel/src/net/socket/mod.rs index d02e78b8a..e0e766a46 100644 --- a/kernel/src/net/socket/mod.rs +++ b/kernel/src/net/socket/mod.rs @@ -11,7 +11,7 @@ use crate::{ file_table::FdFlags, path::Path, pseudofs::SockFs, - utils::{CreationFlags, Inode, StatusFlags}, + utils::{CreationFlags, StatusFlags}, }, prelude::*, util::{MultiRead, MultiWrite}, @@ -175,8 +175,8 @@ impl FileLike for T { Some(self) } - fn inode(&self) -> &Arc { - self.pseudo_path().inode() + fn path(&self) -> &Path { + self.pseudo_path() } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { @@ -201,7 +201,7 @@ impl FileLike for T { Box::new(FdInfo { flags, - ino: self.inode().ino(), + ino: self.pseudo_path().inode().ino(), }) } } diff --git a/kernel/src/process/clone.rs b/kernel/src/process/clone.rs index 3ea39a6e6..52d14ec7a 100644 --- a/kernel/src/process/clone.rs +++ b/kernel/src/process/clone.rs @@ -499,7 +499,7 @@ fn clone_child_process( let child = { let mut child_thread_builder = { let child_thread_name = ThreadName::new_from_executable_path( - &child_vmar.process_vm().executable_file().display_name(), + &child_vmar.process_vm().executable_file().abs_path(), ); let credentials = { diff --git a/kernel/src/process/execve.rs b/kernel/src/process/execve.rs index 103b6de30..56865c68c 100644 --- a/kernel/src/process/execve.rs +++ b/kernel/src/process/execve.rs @@ -10,7 +10,7 @@ use ostd::{ use super::process_vm::activate_vmar; use crate::{ - fs::{fs_resolver::PathOrInode, utils::Inode}, + fs::{path::Path, utils::Inode}, prelude::*, process::{ ContextUnshareAdminApi, Credentials, Process, @@ -27,7 +27,7 @@ use crate::{ }; pub fn do_execve( - elf_file: PathOrInode, + elf_file: Path, argv_ptr_ptr: Vaddr, envp_ptr_ptr: Vaddr, ctx: &Context, @@ -42,7 +42,7 @@ pub fn do_execve( let envp = read_cstring_vec(envp_ptr_ptr, MAX_NR_STRING_ARGS, MAX_LEN_STRING_ARG, ctx)?; debug!( "filename: {:?}, argv = {:?}, envp = {:?}", - elf_file.display_name(), + elf_file.abs_path(), argv, envp ); @@ -128,7 +128,7 @@ fn read_cstring_vec( fn do_execve_no_return( ctx: &Context, user_context: &mut UserContext, - elf_file: PathOrInode, + elf_file: Path, new_vmar: Arc, elf_load_info: &ElfLoadInfo, ) -> Result<()> { @@ -165,7 +165,7 @@ fn do_execve_no_return( unshare_and_close_files(ctx); // Update the process's executable path and set the thread name - let executable_path = elf_file.display_name(); + let executable_path = elf_file.abs_path(); *posix_thread.thread_name().lock() = ThreadName::new_from_executable_path(&executable_path); // Unshare and reset signal dispositions to their default actions. diff --git a/kernel/src/process/pid_file.rs b/kernel/src/process/pid_file.rs index 0dd1d2384..11a34bfb9 100644 --- a/kernel/src/process/pid_file.rs +++ b/kernel/src/process/pid_file.rs @@ -12,7 +12,7 @@ use crate::{ file_table::FdFlags, path::Path, pseudofs::AnonInodeFs, - utils::{CreationFlags, Inode, StatusFlags}, + utils::{CreationFlags, StatusFlags}, }, prelude::*, process::{ @@ -99,8 +99,8 @@ impl FileLike for PidFile { } } - fn inode(&self) -> &Arc { - self.pseudo_path.inode() + fn path(&self) -> &Path { + &self.pseudo_path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { diff --git a/kernel/src/process/process/init_proc.rs b/kernel/src/process/process/init_proc.rs index e291b6f0d..5c80f06f6 100644 --- a/kernel/src/process/process/init_proc.rs +++ b/kernel/src/process/process/init_proc.rs @@ -7,7 +7,7 @@ use ostd::{arch::cpu::context::UserContext, task::Task, user::UserContextApi}; use super::Process; use crate::{ fs::{ - fs_resolver::{FsPath, PathOrInode}, + fs_resolver::FsPath, path::{MountNamespace, Path}, thread_info::ThreadFsInfo, }, @@ -56,7 +56,7 @@ fn create_init_process( let elf_path = fs.resolver().read().lookup(&fs_path)?; let pid = allocate_posix_tid(); - let process_vm = new_vmar_and_map(PathOrInode::Path(elf_path.clone())); + let process_vm = new_vmar_and_map(elf_path.clone()); let resource_limits = new_resource_limits_for_init(); let nice = Nice::default(); let oom_score_adj = 0; diff --git a/kernel/src/process/process_vm/mod.rs b/kernel/src/process/process_vm/mod.rs index 3535c3264..cb2bd1561 100644 --- a/kernel/src/process/process_vm/mod.rs +++ b/kernel/src/process/process_vm/mod.rs @@ -24,7 +24,7 @@ pub use self::{ aux_vec::{AuxKey, AuxVec}, }, }; -use crate::{fs::fs_resolver::PathOrInode, prelude::*, vm::vmar::Vmar}; +use crate::{fs::path::Path, prelude::*, vm::vmar::Vmar}; /* * The user's virtual memory space layout looks like below. @@ -68,8 +68,8 @@ pub struct ProcessVm { init_stack: InitStack, /// The user heap heap: Heap, - /// The executable `PathOrInode`. - executable_file: PathOrInode, + /// The executable file. + executable_file: Path, /// The base address for vDSO segment #[cfg(target_arch = "riscv64")] vdso_base: AtomicUsize, @@ -77,7 +77,7 @@ pub struct ProcessVm { impl ProcessVm { /// Creates a new `ProcessVm` without mapping anything. - fn new(executable_file: PathOrInode) -> Self { + fn new(executable_file: Path) -> Self { Self { init_stack: InitStack::new(), heap: Heap::new(), @@ -108,8 +108,8 @@ impl ProcessVm { &self.heap } - /// Returns a reference to the executable `PathOrInode`. - pub fn executable_file(&self) -> &PathOrInode { + /// Returns a reference to the executable `Path`. + pub fn executable_file(&self) -> &Path { &self.executable_file } @@ -203,7 +203,7 @@ impl<'a> ProcessVmarGuard<'a> { /// Creates a new VMAR and map the heap. /// /// This method should only be used to create a VMAR for the init process. -pub(super) fn new_vmar_and_map(executable_file: PathOrInode) -> Arc { +pub(super) fn new_vmar_and_map(executable_file: Path) -> Arc { let new_vmar = Vmar::new(ProcessVm::new(executable_file)); new_vmar .process_vm() diff --git a/kernel/src/process/program_loader/mod.rs b/kernel/src/process/program_loader/mod.rs index 9bf1edf95..5a287abcd 100644 --- a/kernel/src/process/program_loader/mod.rs +++ b/kernel/src/process/program_loader/mod.rs @@ -64,7 +64,7 @@ impl ProgramToLoad { let interpreter = { let filename = new_argv[0].to_str()?.to_string(); let fs_path = FsPath::try_from(filename.as_str())?; - fs_resolver.lookup_inode(&fs_path)? + fs_resolver.lookup(&fs_path)? }; check_executable_inode(interpreter.inode().as_ref())?; diff --git a/kernel/src/syscall/access.rs b/kernel/src/syscall/access.rs index 1ef685d54..7167bf85b 100644 --- a/kernel/src/syscall/access.rs +++ b/kernel/src/syscall/access.rs @@ -81,7 +81,7 @@ pub fn do_faccessat( dirfd, path_name, mode, flags ); - let path_or_inode = { + let path = { let path_name = path_name.to_string_lossy(); let fs_path = if flags.contains(FaccessatFlags::AT_EMPTY_PATH) && path_name.is_empty() { FsPath::from_fd(dirfd)? @@ -92,9 +92,9 @@ pub fn do_faccessat( let fs_ref = ctx.thread_local.borrow_fs(); let fs = fs_ref.resolver().read(); if flags.contains(FaccessatFlags::AT_SYMLINK_NOFOLLOW) { - fs.lookup_inode_no_follow(&fs_path)? + fs.lookup_no_follow(&fs_path)? } else { - fs.lookup_inode(&fs_path)? + fs.lookup(&fs_path)? } }; @@ -103,7 +103,7 @@ pub fn do_faccessat( return Ok(SyscallReturn::Return(0)); } - let inode = path_or_inode.inode(); + let inode = path.inode(); // FIXME: The current implementation is dummy if mode.contains(AccessMode::R_OK) { diff --git a/kernel/src/syscall/chmod.rs b/kernel/src/syscall/chmod.rs index 87b4edc8c..321567e33 100644 --- a/kernel/src/syscall/chmod.rs +++ b/kernel/src/syscall/chmod.rs @@ -16,10 +16,8 @@ pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result Result &Arc { - self.pseudo_path.inode() + fn path(&self) -> &Path { + &self.pseudo_path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { diff --git a/kernel/src/syscall/execve.rs b/kernel/src/syscall/execve.rs index 9c342038a..45cb03d8c 100644 --- a/kernel/src/syscall/execve.rs +++ b/kernel/src/syscall/execve.rs @@ -6,7 +6,8 @@ use super::{SyscallReturn, constants::*}; use crate::{ fs::{ file_table::FileDesc, - fs_resolver::{AT_FDCWD, FsPath, PathOrInode}, + fs_resolver::{AT_FDCWD, FsPath}, + path::Path, }, prelude::*, process::do_execve, @@ -52,12 +53,12 @@ fn lookup_executable_file( filename_ptr: Vaddr, flags: OpenFlags, ctx: &Context, -) -> Result { +) -> Result { let filename = ctx .user_space() .read_cstring(filename_ptr, MAX_FILENAME_LEN)?; - let path_or_inode = { + let path = { let filename = filename.to_string_lossy(); let fs_path = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() { FsPath::from_fd(dfd)? @@ -68,13 +69,13 @@ fn lookup_executable_file( let fs_ref = ctx.thread_local.borrow_fs(); let fs_resolver = fs_ref.resolver().read(); if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) { - fs_resolver.lookup_inode_no_follow(&fs_path)? + fs_resolver.lookup_no_follow(&fs_path)? } else { - fs_resolver.lookup_inode(&fs_path)? + fs_resolver.lookup(&fs_path)? } }; - Ok(path_or_inode) + Ok(path) } bitflags::bitflags! { diff --git a/kernel/src/syscall/fcntl.rs b/kernel/src/syscall/fcntl.rs index f15d8dfd2..0d78443ce 100644 --- a/kernel/src/syscall/fcntl.rs +++ b/kernel/src/syscall/fcntl.rs @@ -253,7 +253,7 @@ fn from_c_flock_and_file(lock: &c_flock, file: &dyn FileLike) -> Result (file.inode().metadata().size as off_t) + RangeLockWhence::SEEK_END => (file.path().inode().metadata().size as off_t) .checked_add(lock.l_start) .ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?, } diff --git a/kernel/src/syscall/open.rs b/kernel/src/syscall/open.rs index 4d5318970..d0f77c916 100644 --- a/kernel/src/syscall/open.rs +++ b/kernel/src/syscall/open.rs @@ -6,7 +6,7 @@ use crate::{ fs::{ file_handle::FileLike, file_table::{FdFlags, FileDesc}, - fs_resolver::{AT_FDCWD, FsPath, FsResolver, LookupResult, PathOrInode}, + fs_resolver::{AT_FDCWD, FsPath, FsResolver, LookupResult}, inode_handle::InodeHandle, utils::{AccessMode, CreationFlags, InodeMode, InodeType, OpenArgs, StatusFlags}, }, @@ -88,12 +88,7 @@ fn do_open( }; let file_handle: Arc = match lookup_res { - LookupResult::Resolved(target) => match target { - PathOrInode::Path(path) => Arc::new(path.open(open_args)?), - PathOrInode::Inode(_) => { - return_errno_with_message!(Errno::ENXIO, "the inode is not re-openable") - } - }, + LookupResult::Resolved(path) => Arc::new(path.open(open_args)?), LookupResult::AtParent(result) => { if !open_args.creation_flags.contains(CreationFlags::O_CREAT) || open_args.status_flags.contains(StatusFlags::O_PATH) diff --git a/kernel/src/syscall/signalfd.rs b/kernel/src/syscall/signalfd.rs index 04ba69615..abe8eb712 100644 --- a/kernel/src/syscall/signalfd.rs +++ b/kernel/src/syscall/signalfd.rs @@ -22,7 +22,7 @@ use crate::{ file_table::{FdFlags, FileDesc, get_file_fast}, path::Path, pseudofs::AnonInodeFs, - utils::{CreationFlags, Inode, StatusFlags}, + utils::{CreationFlags, StatusFlags}, }, prelude::*, process::{ @@ -268,8 +268,8 @@ impl FileLike for SignalFile { Ok(()) } - fn inode(&self) -> &Arc { - self.pseudo_path.inode() + fn path(&self) -> &Path { + &self.pseudo_path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box { diff --git a/kernel/src/syscall/stat.rs b/kernel/src/syscall/stat.rs index 111cd820e..7b5cca458 100644 --- a/kernel/src/syscall/stat.rs +++ b/kernel/src/syscall/stat.rs @@ -20,7 +20,7 @@ pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, ctx: &Context) -> Result Resu let fs = { let path_name = path_name.to_string_lossy(); let fs_path = FsPath::try_from(path_name.as_ref())?; - let path_or_inode = ctx + let path = ctx .thread_local .borrow_fs() .resolver() .read() - .lookup_inode(&fs_path)?; - path_or_inode.inode().fs() + .lookup(&fs_path)?; + path.fs() }; let statfs = Statfs::from(fs.sb()); @@ -43,7 +43,7 @@ pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr, ctx: &Context) -> Result let fs = { let mut file_table = ctx.thread_local.borrow_file_table_mut(); let file = get_file_fast!(&mut file_table, fd); - file.inode().fs() + file.path().fs() }; let statfs = Statfs::from(fs.sb()); diff --git a/kernel/src/syscall/sync.rs b/kernel/src/syscall/sync.rs index cbf165aa3..714ee6d2a 100644 --- a/kernel/src/syscall/sync.rs +++ b/kernel/src/syscall/sync.rs @@ -18,6 +18,6 @@ pub fn sys_syncfs(fd: FileDesc, ctx: &Context) -> Result { let mut file_table = ctx.thread_local.borrow_file_table_mut(); let file = get_file_fast!(&mut file_table, fd); - file.inode().fs().sync()?; + file.path().fs().sync()?; Ok(SyscallReturn::Return(0)) } diff --git a/kernel/src/syscall/truncate.rs b/kernel/src/syscall/truncate.rs index 26816835a..2ae2a928d 100644 --- a/kernel/src/syscall/truncate.rs +++ b/kernel/src/syscall/truncate.rs @@ -20,9 +20,7 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize, ctx: &Context) -> Result &Arc { - self.pseudo_path.inode() + fn path(&self) -> &Path { + &self.pseudo_path } fn dump_proc_fdinfo(self: Arc, fd_flags: FdFlags) -> Box {