Remove `PathOrInode`

This commit is contained in:
Wang Siyuan 2025-12-26 12:19:53 +00:00
parent 0e291b692e
commit ec1d35e9e6
33 changed files with 137 additions and 300 deletions

View File

@ -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<dyn Inode> {
self.pseudo_path.inode()
fn path(&self) -> &Path {
&self.pseudo_path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {

View File

@ -97,7 +97,7 @@ pub trait FileLike: Pollable + Send + Sync + Any {
None
}
fn inode(&self) -> &Arc<dyn Inode>;
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")

View File

@ -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<Path> {
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<Path> {
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<PathOrInode> {
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<PathOrInode> {
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<dyn FileLike>`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<dyn Inode>),
}
impl PathOrInode {
pub fn into_path(self) -> Option<Path> {
match self {
PathOrInode::Path(path) => Some(path),
PathOrInode::Inode(_) => None,
}
}
pub fn inode(&self) -> &Arc<dyn Inode> {
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<PathOrInode> {
fn into_path(self) -> Result<Path> {
match self {
LookupResult::Resolved(target) => Ok(target),
LookupResult::AtParent(_) => Err(Error::with_message(

View File

@ -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<dyn Inode> {
self.path.inode()
fn path(&self) -> &Path {
&self.path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
@ -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())
}
}

View File

@ -359,8 +359,8 @@ impl FileLike for InotifyFile {
AccessMode::O_RDONLY
}
fn inode(&self) -> &Arc<dyn Inode> {
self.pseudo_path.inode()
fn path(&self) -> &Path {
&self.pseudo_path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {

View File

@ -240,16 +240,9 @@ define_atomic_version_of_integer_like_type!(FsEvents, {
/// Notifies that a file was accessed.
pub fn on_access(file: &Arc<dyn FileLike>) {
// 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<dyn FileLike>) {
/// Notifies that a file was modified.
pub fn on_modify(file: &Arc<dyn FileLike>) {
// 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<dyn FileLike>) {
/// 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<dyn Inode>, inode: &Arc<dyn Inode>, 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<dyn FileLike>) {
// 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<dyn FileLike>) {
/// Notifies that a file was closed.
pub fn on_close(file: &Arc<dyn FileLike>) {
// 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);

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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))
}
}

View File

@ -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::<InodeHandle>() {
SymbolicLink::Path(inode_handle.path().clone())
} else {
SymbolicLink::Inode(file.inode().clone())
};
Ok(res)
Ok(SymbolicLink::Path(file.path().clone()))
}
}

View File

@ -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<Result<Box<dyn FileIo>>> {
Some(Err(Error::with_message(
Errno::ENXIO,
"the pseudo inode is not re-openable",
)))
}
fn fs(&self) -> Arc<dyn FileSystem> {
self.fs.upgrade().unwrap()
}

View File

@ -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();

View File

@ -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<dyn FileLike>`s are associated
// with paths. We should add pseudo paths and dentries for these inodes,
// and eventually remove this variant.
Inode(Arc<dyn Inode>),
}
impl SymbolicLink {
#[cfg_attr(not(ktest), expect(dead_code))]
pub fn into_plain(self) -> Option<String> {
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(),
}
}
}

View File

@ -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<T: Socket + 'static> FileLike for T {
Some(self)
}
fn inode(&self) -> &Arc<dyn Inode> {
self.pseudo_path().inode()
fn path(&self) -> &Path {
self.pseudo_path()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
@ -201,7 +201,7 @@ impl<T: Socket + 'static> FileLike for T {
Box::new(FdInfo {
flags,
ino: self.inode().ino(),
ino: self.pseudo_path().inode().ino(),
})
}
}

View File

@ -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 = {

View File

@ -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<Vmar>,
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.

View File

@ -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<dyn Inode> {
self.pseudo_path.inode()
fn path(&self) -> &Path {
&self.pseudo_path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {

View File

@ -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;

View File

@ -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<Vmar> {
pub(super) fn new_vmar_and_map(executable_file: Path) -> Arc<Vmar> {
let new_vmar = Vmar::new(ProcessVm::new(executable_file));
new_vmar
.process_vm()

View File

@ -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())?;

View File

@ -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) {

View File

@ -16,10 +16,8 @@ pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result<SyscallRetur
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
file.inode().set_mode(InodeMode::from_bits_truncate(mode))?;
if let Some(path) = file.path() {
fs::notify::on_attr_change(path);
}
file.path().set_mode(InodeMode::from_bits_truncate(mode))?;
fs::notify::on_attr_change(file.path());
Ok(SyscallReturn::Return(0))
}
@ -63,7 +61,7 @@ fn do_fchmodat(
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(ChmodFlags::AT_EMPTY_PATH) && path_name.is_empty() {
FsPath::from_fd(dirfd)?
@ -74,18 +72,14 @@ fn do_fchmodat(
let fs_ref = ctx.thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
if flags.contains(ChmodFlags::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)?
}
};
path_or_inode
.inode()
.set_mode(InodeMode::from_bits_truncate(mode))?;
if let Some(path) = path_or_inode.into_path() {
fs::notify::on_attr_change(&path);
}
path.set_mode(InodeMode::from_bits_truncate(mode))?;
fs::notify::on_attr_change(&path);
Ok(SyscallReturn::Return(0))
}

View File

@ -22,11 +22,12 @@ pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, ctx: &Context) -> Result<Sys
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
let path = file.path();
if let Some(uid) = uid {
file.inode().set_owner(uid)?;
path.set_owner(uid)?;
}
if let Some(gid) = gid {
file.inode().set_group(gid)?;
path.set_group(gid)?;
}
Ok(SyscallReturn::Return(0))
}
@ -72,26 +73,24 @@ pub fn sys_fchownat(
return Ok(SyscallReturn::Return(0));
}
let path_or_inode = {
let path = {
let path_name = path_name.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(dirfd, &path_name)?;
let fs_ref = ctx.thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
if flags.contains(ChownFlags::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)?
}
};
let inode = path_or_inode.inode();
if let Some(uid) = uid {
inode.set_owner(uid)?;
path.set_owner(uid)?;
}
if let Some(gid) = gid {
inode.set_group(gid)?;
path.set_group(gid)?;
}
Ok(SyscallReturn::Return(0))
}

View File

@ -26,7 +26,7 @@ use crate::{
file_table::{FdFlags, FileDesc},
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode, StatusFlags},
utils::{CreationFlags, StatusFlags},
},
prelude::*,
process::signal::{PollHandle, Pollable, Pollee},
@ -235,8 +235,8 @@ impl FileLike for EventFile {
Ok(())
}
fn inode(&self) -> &Arc<dyn Inode> {
self.pseudo_path.inode()
fn path(&self) -> &Path {
&self.pseudo_path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {

View File

@ -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<PathOrInode> {
) -> Result<Path> {
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! {

View File

@ -253,7 +253,7 @@ fn from_c_flock_and_file(lock: &c_flock, file: &dyn FileLike) -> Result<FileRang
.checked_add(lock.l_start)
.ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?,
RangeLockWhence::SEEK_END => (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"))?,
}

View File

@ -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<dyn FileLike> = 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)

View File

@ -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<dyn Inode> {
self.pseudo_path.inode()
fn path(&self) -> &Path {
&self.pseudo_path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {

View File

@ -20,7 +20,7 @@ pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, ctx: &Context) -> Result<Sys
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
let stat = Stat::from(file.inode().metadata());
let stat = Stat::from(file.path().metadata());
ctx.user_space().write_val(stat_buf_ptr, &stat)?;
Ok(SyscallReturn::Return(0))
@ -60,20 +60,20 @@ pub fn sys_fstatat(
return self::sys_fstat(dirfd, stat_buf_ptr, ctx);
}
let path_or_inode = {
let path = {
let filename = filename.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(dirfd, &filename)?;
let fs_ref = ctx.thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
if flags.contains(StatFlags::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)?
}
};
let stat = Stat::from(path_or_inode.inode().metadata());
let stat = Stat::from(path.metadata());
user_space.write_val(stat_buf_ptr, &stat)?;
Ok(SyscallReturn::Return(0))
}

View File

@ -23,13 +23,13 @@ pub fn sys_statfs(path_ptr: Vaddr, statfs_buf_ptr: Vaddr, ctx: &Context) -> 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());

View File

@ -18,6 +18,6 @@ pub fn sys_syncfs(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
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))
}

View File

@ -20,9 +20,7 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize, ctx: &Context) -> Result<SyscallR
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
file.resize(len as usize)?;
if let Some(path) = file.path() {
fs::notify::on_change(path);
}
fs::notify::on_change(file.path());
Ok(SyscallReturn::Return(0))
}

View File

@ -16,7 +16,7 @@ use crate::{
file_table::FdFlags,
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode, StatusFlags},
utils::{CreationFlags, StatusFlags},
},
prelude::*,
process::signal::{PollHandle, Pollable, Pollee},
@ -256,8 +256,8 @@ impl FileLike for TimerfdFile {
Ok(())
}
fn inode(&self) -> &Arc<dyn Inode> {
self.pseudo_path.inode()
fn path(&self) -> &Path {
&self.pseudo_path
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {