Rename struct Path to struct DentryMnt

Signed-off-by: Zhenchen Wang <m202372036@hust.edu.cn>
This commit is contained in:
plucky
2024-04-15 20:08:04 +08:00
committed by Tate, Hongliang Tian
parent 6d486c6c01
commit 60fa4d104a
35 changed files with 250 additions and 237 deletions

View File

@ -4,7 +4,7 @@ use crate::{
fs::{ fs::{
devpts::DevPts, devpts::DevPts,
fs_resolver::{FsPath, FsResolver}, fs_resolver::{FsPath, FsResolver},
utils::{Inode, InodeMode, InodeType, Path}, utils::{DentryMnt, Inode, InodeMode, InodeType},
}, },
prelude::*, prelude::*,
}; };
@ -15,7 +15,7 @@ mod pty;
pub use pty::{PtyMaster, PtySlave}; pub use pty::{PtyMaster, PtySlave};
use spin::Once; use spin::Once;
static DEV_PTS: Once<Arc<Path>> = Once::new(); static DEV_PTS: Once<Arc<DentryMnt>> = Once::new();
pub fn init() -> Result<()> { pub fn init() -> Result<()> {
let fs = FsResolver::new(); let fs = FsResolver::new();
@ -26,8 +26,8 @@ pub fn init() -> Result<()> {
dev.dentry() dev.dentry()
.create("pts", InodeType::Dir, InodeMode::from_bits_truncate(0o755))?; .create("pts", InodeType::Dir, InodeMode::from_bits_truncate(0o755))?;
let devpts_mount_node = let devpts_mount_node =
Path::new(dev.mount_node().clone(), devpts_dentry.clone()).mount(DevPts::new())?; DentryMnt::new(dev.mount_node().clone(), devpts_dentry.clone()).mount(DevPts::new())?;
let devpts = Path::new( let devpts = DentryMnt::new(
devpts_mount_node.clone(), devpts_mount_node.clone(),
devpts_mount_node.root_dentry().clone(), devpts_mount_node.root_dentry().clone(),
); );

View File

@ -85,11 +85,11 @@ impl From<DeviceId> for u64 {
/// If the parent path is not existing, `mkdir -p` the parent path. /// If the parent path is not existing, `mkdir -p` the parent path.
/// This function is used in registering device. /// This function is used in registering device.
pub fn add_node(device: Arc<dyn Device>, pathname: &str) -> Result<Arc<Dentry>> { pub fn add_node(device: Arc<dyn Device>, pathname: &str) -> Result<Arc<Dentry>> {
let mut path = { let mut dentrymnt = {
let fs_resolver = FsResolver::new(); let fs_resolver = FsResolver::new();
fs_resolver.lookup(&FsPath::try_from("/dev").unwrap())? fs_resolver.lookup(&FsPath::try_from("/dev").unwrap())?
}; };
let mut dentry = path.dentry().clone(); let mut dentry = dentrymnt.dentry().clone();
let mut relative_path = { let mut relative_path = {
let relative_path = pathname.trim_start_matches('/'); let relative_path = pathname.trim_start_matches('/');
@ -107,24 +107,24 @@ pub fn add_node(device: Arc<dyn Device>, pathname: &str) -> Result<Arc<Dentry>>
(relative_path, "") (relative_path, "")
}; };
match path.lookup(next_name) { match dentrymnt.lookup(next_name) {
Ok(next_path) => { Ok(next_dentrymnt) => {
if path_remain.is_empty() { if path_remain.is_empty() {
return_errno_with_message!(Errno::EEXIST, "device node is existing"); return_errno_with_message!(Errno::EEXIST, "device node is existing");
} }
path = next_path; dentrymnt = next_dentrymnt;
} }
Err(_) => { Err(_) => {
if path_remain.is_empty() { if path_remain.is_empty() {
// Create the device node // Create the device node
dentry = path.dentry().mknod( dentry = dentrymnt.dentry().mknod(
next_name, next_name,
InodeMode::from_bits_truncate(0o666), InodeMode::from_bits_truncate(0o666),
device.clone(), device.clone(),
)?; )?;
} else { } else {
// Mkdir parent path // Mkdir parent path
dentry = path.dentry().create( dentry = dentrymnt.dentry().create(
next_name, next_name,
InodeType::Dir, InodeType::Dir,
InodeMode::from_bits_truncate(0o755), InodeMode::from_bits_truncate(0o755),
@ -150,11 +150,11 @@ pub fn delete_node(pathname: &str) -> Result<()> {
String::from("/dev") + "/" + device_path String::from("/dev") + "/" + device_path
}; };
let (parent_path, name) = { let (parent_dentrymnt, name) = {
let fs_resolver = FsResolver::new(); let fs_resolver = FsResolver::new();
fs_resolver.lookup_dir_and_base_name(&FsPath::try_from(abs_path.as_str()).unwrap())? fs_resolver.lookup_dir_and_base_name(&FsPath::try_from(abs_path.as_str()).unwrap())?
}; };
parent_path.dentry().unlink(&name)?; parent_dentrymnt.dentry().unlink(&name)?;
Ok(()) Ok(())
} }

View File

@ -7,15 +7,16 @@ use super::{
inode_handle::InodeHandle, inode_handle::InodeHandle,
rootfs::root_mount, rootfs::root_mount,
utils::{ utils::{
AccessMode, CreationFlags, InodeMode, InodeType, Path, StatusFlags, PATH_MAX, SYMLINKS_MAX, AccessMode, CreationFlags, DentryMnt, InodeMode, InodeType, StatusFlags, PATH_MAX,
SYMLINKS_MAX,
}, },
}; };
use crate::prelude::*; use crate::prelude::*;
#[derive(Debug)] #[derive(Debug)]
pub struct FsResolver { pub struct FsResolver {
root: Arc<Path>, root: Arc<DentryMnt>,
cwd: Arc<Path>, cwd: Arc<DentryMnt>,
} }
impl Clone for FsResolver { impl Clone for FsResolver {
@ -36,29 +37,29 @@ impl Default for FsResolver {
impl FsResolver { impl FsResolver {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
root: Path::new(root_mount().clone(), root_mount().root_dentry().clone()), root: DentryMnt::new(root_mount().clone(), root_mount().root_dentry().clone()),
cwd: Path::new(root_mount().clone(), root_mount().root_dentry().clone()), cwd: DentryMnt::new(root_mount().clone(), root_mount().root_dentry().clone()),
} }
} }
/// Get the root directory /// Get the root directory
pub fn root(&self) -> &Arc<Path> { pub fn root(&self) -> &Arc<DentryMnt> {
&self.root &self.root
} }
/// Get the current working directory /// Get the current working directory
pub fn cwd(&self) -> &Arc<Path> { pub fn cwd(&self) -> &Arc<DentryMnt> {
&self.cwd &self.cwd
} }
/// Set the current working directory. /// Set the current working directory.
pub fn set_cwd(&mut self, path: Arc<Path>) { pub fn set_cwd(&mut self, dentrymnt: Arc<DentryMnt>) {
self.cwd = path; self.cwd = dentrymnt;
} }
/// Set the root directory /// Set the root directory
pub fn set_root(&mut self, path: Arc<Path>) { pub fn set_root(&mut self, dentrymnt: Arc<DentryMnt>) {
self.root = path; self.root = dentrymnt;
} }
/// Open or create a file inode handler. /// Open or create a file inode handler.
@ -71,9 +72,9 @@ impl FsResolver {
let follow_tail_link = !(creation_flags.contains(CreationFlags::O_NOFOLLOW) let follow_tail_link = !(creation_flags.contains(CreationFlags::O_NOFOLLOW)
|| creation_flags.contains(CreationFlags::O_CREAT) || creation_flags.contains(CreationFlags::O_CREAT)
&& creation_flags.contains(CreationFlags::O_EXCL)); && creation_flags.contains(CreationFlags::O_EXCL));
let path = match self.lookup_inner(pathname, follow_tail_link) { let dentrymnt = match self.lookup_inner(pathname, follow_tail_link) {
Ok(path) => { Ok(dentrymnt) => {
let inode = path.dentry().inode(); let inode = dentrymnt.dentry().inode();
if inode.type_() == InodeType::SymLink if inode.type_() == InodeType::SymLink
&& creation_flags.contains(CreationFlags::O_NOFOLLOW) && creation_flags.contains(CreationFlags::O_NOFOLLOW)
&& !status_flags.contains(StatusFlags::O_PATH) && !status_flags.contains(StatusFlags::O_PATH)
@ -93,7 +94,7 @@ impl FsResolver {
"O_DIRECTORY is specified but file is not a directory" "O_DIRECTORY is specified but file is not a directory"
); );
} }
path dentrymnt
} }
Err(e) Err(e)
if e.error() == Errno::ENOENT if e.error() == Errno::ENOENT
@ -102,39 +103,39 @@ impl FsResolver {
if creation_flags.contains(CreationFlags::O_DIRECTORY) { if creation_flags.contains(CreationFlags::O_DIRECTORY) {
return_errno_with_message!(Errno::ENOTDIR, "cannot create directory"); return_errno_with_message!(Errno::ENOTDIR, "cannot create directory");
} }
let (dir_path, file_name) = let (dir_dentrymnt, file_name) =
self.lookup_dir_and_base_name_inner(pathname, follow_tail_link)?; self.lookup_dir_and_base_name_inner(pathname, follow_tail_link)?;
if file_name.ends_with('/') { if file_name.ends_with('/') {
return_errno_with_message!(Errno::EISDIR, "path refers to a directory"); return_errno_with_message!(Errno::EISDIR, "path refers to a directory");
} }
if !dir_path.dentry().mode()?.is_writable() { if !dir_dentrymnt.dentry().mode()?.is_writable() {
return_errno_with_message!(Errno::EACCES, "file cannot be created"); return_errno_with_message!(Errno::EACCES, "file cannot be created");
} }
let dir_dentry = let dir_dentry =
dir_path dir_dentrymnt
.dentry() .dentry()
.create(&file_name, InodeType::File, inode_mode)?; .create(&file_name, InodeType::File, inode_mode)?;
Path::new(dir_path.mount_node().clone(), dir_dentry.clone()) DentryMnt::new(dir_dentrymnt.mount_node().clone(), dir_dentry.clone())
} }
Err(e) => return Err(e), Err(e) => return Err(e),
}; };
let inode_handle = InodeHandle::new(path, access_mode, status_flags)?; let inode_handle = InodeHandle::new(dentrymnt, access_mode, status_flags)?;
Ok(inode_handle) Ok(inode_handle)
} }
/// Lookup path according to FsPath, always follow symlinks /// Lookup dentrymnt according to FsPath, always follow symlinks
pub fn lookup(&self, pathname: &FsPath) -> Result<Arc<Path>> { pub fn lookup(&self, pathname: &FsPath) -> Result<Arc<DentryMnt>> {
self.lookup_inner(pathname, true) self.lookup_inner(pathname, true)
} }
/// Lookup path according to FsPath, do not follow it if last component is a symlink /// Lookup dentrymnt according to FsPath, do not follow it if last component is a symlink
pub fn lookup_no_follow(&self, pathname: &FsPath) -> Result<Arc<Path>> { pub fn lookup_no_follow(&self, pathname: &FsPath) -> Result<Arc<DentryMnt>> {
self.lookup_inner(pathname, false) self.lookup_inner(pathname, false)
} }
fn lookup_inner(&self, pathname: &FsPath, follow_tail_link: bool) -> Result<Arc<Path>> { fn lookup_inner(&self, pathname: &FsPath, follow_tail_link: bool) -> Result<Arc<DentryMnt>> {
let path = match pathname.inner { let dentrymnt = match pathname.inner {
FsPathInner::Absolute(pathname) => self.lookup_from_parent( FsPathInner::Absolute(pathname) => self.lookup_from_parent(
&self.root, &self.root,
pathname.trim_start_matches('/'), pathname.trim_start_matches('/'),
@ -151,7 +152,7 @@ impl FsResolver {
FsPathInner::Fd(fd) => self.lookup_from_fd(fd)?, FsPathInner::Fd(fd) => self.lookup_from_fd(fd)?,
}; };
Ok(path) Ok(dentrymnt)
} }
/// Lookup dentry from parent /// Lookup dentry from parent
@ -167,10 +168,10 @@ impl FsResolver {
/// Symlinks in earlier components of the path will always be followed. /// Symlinks in earlier components of the path will always be followed.
fn lookup_from_parent( fn lookup_from_parent(
&self, &self,
parent: &Arc<Path>, parent: &Arc<DentryMnt>,
relative_path: &str, relative_path: &str,
follow_tail_link: bool, follow_tail_link: bool,
) -> Result<Arc<Path>> { ) -> Result<Arc<DentryMnt>> {
debug_assert!(!relative_path.starts_with('/')); debug_assert!(!relative_path.starts_with('/'));
if relative_path.len() > PATH_MAX { if relative_path.len() > PATH_MAX {
@ -181,8 +182,8 @@ impl FsResolver {
let mut link_path = String::new(); let mut link_path = String::new();
let mut follows = 0; let mut follows = 0;
// Initialize the first path and the relative path // Initialize the first dentrymnt and the relative path
let (mut path, mut relative_path) = (parent.clone(), relative_path); let (mut dentrymnt, mut relative_path) = (parent.clone(), relative_path);
while !relative_path.is_empty() { while !relative_path.is_empty() {
let (next_name, path_remain, must_be_dir) = let (next_name, path_remain, must_be_dir) =
@ -194,8 +195,8 @@ impl FsResolver {
}; };
// Iterate next dentry // Iterate next dentry
let next_path = path.lookup(next_name)?; let next_dentrymnt = dentrymnt.lookup(next_name)?;
let next_dentry = next_path.dentry(); let next_dentry = next_dentrymnt.dentry();
let next_type = next_dentry.type_(); let next_type = next_dentry.type_();
let next_is_tail = path_remain.is_empty(); let next_is_tail = path_remain.is_empty();
@ -218,9 +219,9 @@ impl FsResolver {
tmp_link_path tmp_link_path
}; };
// Change the path and relative path according to symlink // Change the dentrymnt and relative path according to symlink
if link_path_remain.starts_with('/') { if link_path_remain.starts_with('/') {
path = self.root.clone(); dentrymnt = self.root.clone();
} }
link_path.clear(); link_path.clear();
link_path.push_str(link_path_remain.trim_start_matches('/')); link_path.push_str(link_path_remain.trim_start_matches('/'));
@ -231,12 +232,12 @@ impl FsResolver {
if must_be_dir && next_type != InodeType::Dir { if must_be_dir && next_type != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "inode is not dir"); return_errno_with_message!(Errno::ENOTDIR, "inode is not dir");
} }
path = next_path; dentrymnt = next_dentrymnt;
relative_path = path_remain; relative_path = path_remain;
} }
} }
Ok(path) Ok(dentrymnt)
} }
/// Lookup dentry from the giving fd /// Lookup dentry from the giving fd
@ -247,13 +248,13 @@ impl FsResolver {
.get_file(fd)? .get_file(fd)?
.downcast_ref::<InodeHandle>() .downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?; .ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
Ok(inode_handle.path().clone()) Ok(inode_handle.dentrymnt().clone())
} }
/// Lookup the dir path and base file name of the giving pathname. /// Lookup the dir dentrymnt and base file name of the giving pathname.
/// ///
/// If the last component is a symlink, do not deference it /// If the last component is a symlink, do not deference it
pub fn lookup_dir_and_base_name(&self, pathname: &FsPath) -> Result<(Arc<Path>, String)> { pub fn lookup_dir_and_base_name(&self, pathname: &FsPath) -> Result<(Arc<DentryMnt>, String)> {
self.lookup_dir_and_base_name_inner(pathname, false) self.lookup_dir_and_base_name_inner(pathname, false)
} }
@ -261,8 +262,8 @@ impl FsResolver {
&self, &self,
pathname: &FsPath, pathname: &FsPath,
follow_tail_link: bool, follow_tail_link: bool,
) -> Result<(Arc<Path>, String)> { ) -> Result<(Arc<DentryMnt>, String)> {
let (mut dir_path, mut base_name) = match pathname.inner { let (mut dir_dentrymnt, mut base_name) = match pathname.inner {
FsPathInner::Absolute(pathname) => { FsPathInner::Absolute(pathname) => {
let (dir, file_name) = split_path(pathname); let (dir, file_name) = split_path(pathname);
( (
@ -288,15 +289,15 @@ impl FsResolver {
_ => return_errno!(Errno::ENOENT), _ => return_errno!(Errno::ENOENT),
}; };
if !follow_tail_link { if !follow_tail_link {
return Ok((dir_path, base_name)); return Ok((dir_dentrymnt, base_name));
} }
// Dereference the tail symlinks if needed // Dereference the tail symlinks if needed
loop { loop {
match dir_path.lookup(base_name.trim_end_matches('/')) { match dir_dentrymnt.lookup(base_name.trim_end_matches('/')) {
Ok(path) if path.dentry().type_() == InodeType::SymLink => { Ok(dentrymnt) if dentrymnt.dentry().type_() == InodeType::SymLink => {
let link = { let link = {
let mut link = path.dentry().inode().read_link()?; let mut link = dentrymnt.dentry().inode().read_link()?;
if link.is_empty() { if link.is_empty() {
return_errno_with_message!(Errno::ENOENT, "invalid symlink"); return_errno_with_message!(Errno::ENOENT, "invalid symlink");
} }
@ -307,11 +308,11 @@ impl FsResolver {
}; };
let (dir, file_name) = split_path(&link); let (dir, file_name) = split_path(&link);
if dir.starts_with('/') { if dir.starts_with('/') {
dir_path = dir_dentrymnt =
self.lookup_from_parent(&self.root, dir.trim_start_matches('/'), true)?; self.lookup_from_parent(&self.root, dir.trim_start_matches('/'), true)?;
base_name = String::from(file_name); base_name = String::from(file_name);
} else { } else {
dir_path = self.lookup_from_parent(&dir_path, dir, true)?; dir_dentrymnt = self.lookup_from_parent(&dir_dentrymnt, dir, true)?;
base_name = String::from(file_name); base_name = String::from(file_name);
} }
} }
@ -319,7 +320,7 @@ impl FsResolver {
} }
} }
Ok((dir_path, base_name)) Ok((dir_dentrymnt, base_name))
} }
} }

View File

@ -8,11 +8,11 @@ use crate::prelude::*;
impl InodeHandle<Rights> { impl InodeHandle<Rights> {
pub fn new( pub fn new(
path: Arc<Path>, dentrymnt: Arc<DentryMnt>,
access_mode: AccessMode, access_mode: AccessMode,
status_flags: StatusFlags, status_flags: StatusFlags,
) -> Result<Self> { ) -> Result<Self> {
let inode = path.dentry().inode(); let inode = dentrymnt.dentry().inode();
if access_mode.is_readable() && !inode.mode()?.is_readable() { if access_mode.is_readable() && !inode.mode()?.is_readable() {
return_errno_with_message!(Errno::EACCES, "File is not readable"); return_errno_with_message!(Errno::EACCES, "File is not readable");
} }
@ -30,7 +30,7 @@ impl InodeHandle<Rights> {
}; };
let inner = Arc::new(InodeHandle_ { let inner = Arc::new(InodeHandle_ {
path, dentrymnt,
file_io, file_io,
offset: Mutex::new(0), offset: Mutex::new(0),
access_mode, access_mode,
@ -116,6 +116,6 @@ impl FileLike for InodeHandle<Rights> {
} }
fn as_device(&self) -> Option<Arc<dyn Device>> { fn as_device(&self) -> Option<Arc<dyn Device>> {
self.0.path.dentry().inode().as_device() self.0.dentrymnt.dentry().inode().as_device()
} }
} }

View File

@ -16,8 +16,8 @@ use crate::{
device::Device, device::Device,
file_handle::FileLike, file_handle::FileLike,
utils::{ utils::{
AccessMode, DirentVisitor, InodeMode, InodeType, IoctlCmd, Metadata, Path, SeekFrom, AccessMode, DentryMnt, DirentVisitor, InodeMode, InodeType, IoctlCmd, Metadata,
StatusFlags, SeekFrom, StatusFlags,
}, },
}, },
prelude::*, prelude::*,
@ -28,7 +28,7 @@ use crate::{
pub struct InodeHandle<R = Rights>(Arc<InodeHandle_>, R); pub struct InodeHandle<R = Rights>(Arc<InodeHandle_>, R);
struct InodeHandle_ { struct InodeHandle_ {
path: Arc<Path>, dentrymnt: Arc<DentryMnt>,
/// `file_io` is Similar to `file_private` field in `file` structure in linux. If /// `file_io` is Similar to `file_private` field in `file` structure in linux. If
/// `file_io` is Some, typical file operations including `read`, `write`, `poll`, /// `file_io` is Some, typical file operations including `read`, `write`, `poll`,
/// `ioctl` will be provided by `file_io`, instead of `dentry`. /// `ioctl` will be provided by `file_io`, instead of `dentry`.
@ -47,9 +47,12 @@ impl InodeHandle_ {
} }
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) { let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
self.path.dentry().inode().read_direct_at(*offset, buf)? self.dentrymnt
.dentry()
.inode()
.read_direct_at(*offset, buf)?
} else { } else {
self.path.dentry().inode().read_at(*offset, buf)? self.dentrymnt.dentry().inode().read_at(*offset, buf)?
}; };
*offset += len; *offset += len;
@ -64,12 +67,15 @@ impl InodeHandle_ {
} }
if self.status_flags().contains(StatusFlags::O_APPEND) { if self.status_flags().contains(StatusFlags::O_APPEND) {
*offset = self.path.dentry().size(); *offset = self.dentrymnt.dentry().size();
} }
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) { let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
self.path.dentry().inode().write_direct_at(*offset, buf)? self.dentrymnt
.dentry()
.inode()
.write_direct_at(*offset, buf)?
} else { } else {
self.path.dentry().inode().write_at(*offset, buf)? self.dentrymnt.dentry().inode().write_at(*offset, buf)?
}; };
*offset += len; *offset += len;
@ -82,9 +88,9 @@ impl InodeHandle_ {
} }
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) { let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
self.path.dentry().inode().read_direct_all(buf)? self.dentrymnt.dentry().inode().read_direct_all(buf)?
} else { } else {
self.path.dentry().inode().read_all(buf)? self.dentrymnt.dentry().inode().read_all(buf)?
}; };
Ok(len) Ok(len)
} }
@ -99,7 +105,7 @@ impl InodeHandle_ {
off as isize off as isize
} }
SeekFrom::End(off /* as isize */) => { SeekFrom::End(off /* as isize */) => {
let file_size = self.path.dentry().size() as isize; let file_size = self.dentrymnt.dentry().size() as isize;
assert!(file_size >= 0); assert!(file_size >= 0);
file_size file_size
.checked_add(off) .checked_add(off)
@ -127,7 +133,7 @@ impl InodeHandle_ {
if self.status_flags().contains(StatusFlags::O_APPEND) { if self.status_flags().contains(StatusFlags::O_APPEND) {
return_errno_with_message!(Errno::EPERM, "can not resize append-only file"); return_errno_with_message!(Errno::EPERM, "can not resize append-only file");
} }
self.path.dentry().resize(new_size) self.dentrymnt.dentry().resize(new_size)
} }
pub fn access_mode(&self) -> AccessMode { pub fn access_mode(&self) -> AccessMode {
@ -146,7 +152,11 @@ impl InodeHandle_ {
pub fn readdir(&self, visitor: &mut dyn DirentVisitor) -> Result<usize> { pub fn readdir(&self, visitor: &mut dyn DirentVisitor) -> Result<usize> {
let mut offset = self.offset.lock(); let mut offset = self.offset.lock();
let read_cnt = self.path.dentry().inode().readdir_at(*offset, visitor)?; let read_cnt = self
.dentrymnt
.dentry()
.inode()
.readdir_at(*offset, visitor)?;
*offset += read_cnt; *offset += read_cnt;
Ok(read_cnt) Ok(read_cnt)
} }
@ -156,7 +166,7 @@ impl InodeHandle_ {
return file_io.poll(mask, poller); return file_io.poll(mask, poller);
} }
self.path.dentry().inode().poll(mask, poller) self.dentrymnt.dentry().inode().poll(mask, poller)
} }
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> { fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
@ -164,11 +174,11 @@ impl InodeHandle_ {
return file_io.ioctl(cmd, arg); return file_io.ioctl(cmd, arg);
} }
self.path.dentry().inode().ioctl(cmd, arg) self.dentrymnt.dentry().inode().ioctl(cmd, arg)
} }
} }
#[inherit_methods(from = "self.path.dentry()")] #[inherit_methods(from = "self.dentrymnt.dentry()")]
impl InodeHandle_ { impl InodeHandle_ {
pub fn size(&self) -> usize; pub fn size(&self) -> usize;
pub fn metadata(&self) -> Metadata; pub fn metadata(&self) -> Metadata;
@ -183,7 +193,7 @@ impl InodeHandle_ {
impl Debug for InodeHandle_ { impl Debug for InodeHandle_ {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_struct("InodeHandle_") f.debug_struct("InodeHandle_")
.field("path", &self.path) .field("dentrymnt", &self.dentrymnt)
.field("offset", &self.offset()) .field("offset", &self.offset())
.field("access_mode", &self.access_mode()) .field("access_mode", &self.access_mode())
.field("status_flags", &self.status_flags()) .field("status_flags", &self.status_flags())
@ -193,8 +203,8 @@ impl Debug for InodeHandle_ {
/// Methods for both dyn and static /// Methods for both dyn and static
impl<R> InodeHandle<R> { impl<R> InodeHandle<R> {
pub fn path(&self) -> &Arc<Path> { pub fn dentrymnt(&self) -> &Arc<DentryMnt> {
&self.0.path &self.0.dentrymnt
} }
} }

View File

@ -77,7 +77,7 @@ impl FileSymOps {
impl SymOps for FileSymOps { impl SymOps for FileSymOps {
fn read_link(&self) -> Result<String> { fn read_link(&self) -> Result<String> {
let pathname = if let Some(inode_handle) = self.0.downcast_ref::<InodeHandle>() { let pathname = if let Some(inode_handle) = self.0.downcast_ref::<InodeHandle>() {
inode_handle.path().abs_path() inode_handle.dentrymnt().abs_path()
} else { } else {
// TODO: get the real path for other FileLike object // TODO: get the real path for other FileLike object
String::from("/dev/tty") String::from("/dev/tty")

View File

@ -75,11 +75,11 @@ pub fn init(initramfs_buf: &[u8]) -> Result<()> {
} }
} }
// Mount ProcFS // Mount ProcFS
let proc_path = fs.lookup(&FsPath::try_from("/proc")?)?; let proc_dentrymnt = fs.lookup(&FsPath::try_from("/proc")?)?;
proc_path.mount(ProcFS::new())?; proc_dentrymnt.mount(ProcFS::new())?;
// Mount DevFS // Mount DevFS
let dev_path = fs.lookup(&FsPath::try_from("/dev")?)?; let dev_dentrymnt = fs.lookup(&FsPath::try_from("/dev")?)?;
dev_path.mount(RamFS::new())?; dev_dentrymnt.mount(RamFS::new())?;
println!("[kernel] rootfs is ready"); println!("[kernel] rootfs is ready");
@ -87,8 +87,8 @@ pub fn init(initramfs_buf: &[u8]) -> Result<()> {
} }
pub fn mount_fs_at(fs: Arc<dyn FileSystem>, fs_path: &FsPath) -> Result<()> { pub fn mount_fs_at(fs: Arc<dyn FileSystem>, fs_path: &FsPath) -> Result<()> {
let target_path = FsResolver::new().lookup(fs_path)?; let target_dentrymnt = FsResolver::new().lookup(fs_path)?;
target_path.mount(fs)?; target_dentrymnt.mount(fs)?;
Ok(()) Ok(())
} }

View File

@ -3,15 +3,15 @@
use super::{Dentry, FileSystem, InodeType, MountNode, NAME_MAX}; use super::{Dentry, FileSystem, InodeType, MountNode, NAME_MAX};
use crate::prelude::*; use crate::prelude::*;
/// The Path can represent a location in the mount tree. /// The DentryMnt can represent a location in the mount tree.
#[derive(Debug)] #[derive(Debug)]
pub struct Path { pub struct DentryMnt {
mount_node: Arc<MountNode>, mount_node: Arc<MountNode>,
dentry: Arc<Dentry>, dentry: Arc<Dentry>,
this: Weak<Path>, this: Weak<DentryMnt>,
} }
impl Path { impl DentryMnt {
pub fn new(mount_node: Arc<MountNode>, dentry: Arc<Dentry>) -> Arc<Self> { pub fn new(mount_node: Arc<MountNode>, dentry: Arc<Dentry>) -> Arc<Self> {
Arc::new_cyclic(|weak_self| Self { Arc::new_cyclic(|weak_self| Self {
mount_node, mount_node,
@ -20,7 +20,7 @@ impl Path {
}) })
} }
/// Lookup a path. /// Lookup a dentrymnt.
pub fn lookup(&self, name: &str) -> Result<Arc<Self>> { pub fn lookup(&self, name: &str) -> Result<Arc<Self>> {
if self.dentry.inode().type_() != InodeType::Dir { if self.dentry.inode().type_() != InodeType::Dir {
return_errno!(Errno::ENOTDIR); return_errno!(Errno::ENOTDIR);
@ -32,22 +32,22 @@ impl Path {
return_errno!(Errno::ENAMETOOLONG); return_errno!(Errno::ENAMETOOLONG);
} }
let path = match name { let dentrymnt = match name {
"." => self.this(), "." => self.this(),
".." => self.effective_parent().unwrap_or(self.this()), ".." => self.effective_parent().unwrap_or(self.this()),
name => { name => {
let children_dentry = self.dentry.lookup_fast(name); let children_dentry = self.dentry.lookup_fast(name);
match children_dentry { match children_dentry {
Some(dentry) => Path::new(self.mount_node().clone(), dentry.clone()), Some(dentry) => Self::new(self.mount_node().clone(), dentry.clone()),
None => { None => {
let slow_dentry = self.dentry.lookup_slow(name)?; let slow_dentry = self.dentry.lookup_slow(name)?;
Path::new(self.mount_node().clone(), slow_dentry.clone()) Self::new(self.mount_node().clone(), slow_dentry.clone())
} }
} }
} }
}; };
let path = path.overlaid_path(); let dentrymnt = dentrymnt.overlaid_dentrymnt();
Ok(path) Ok(dentrymnt)
} }
// Get the absolute path. // Get the absolute path.
@ -55,21 +55,21 @@ impl Path {
// It will resolve the mountpoint automatically. // It will resolve the mountpoint automatically.
pub fn abs_path(&self) -> String { pub fn abs_path(&self) -> String {
let mut path = self.effective_name(); let mut path = self.effective_name();
let mut dir_path = self.this(); let mut dir_dentrymnt = self.this();
loop { loop {
match dir_path.effective_parent() { match dir_dentrymnt.effective_parent() {
None => break, None => break,
Some(parent_dir_path) => { Some(parent_dir_dentrymnt) => {
path = { path = {
let parent_name = parent_dir_path.effective_name(); let parent_name = parent_dir_dentrymnt.effective_name();
if parent_name != "/" { if parent_name != "/" {
parent_name + "/" + &path parent_name + "/" + &path
} else { } else {
parent_name + &path parent_name + &path
} }
}; };
dir_path = parent_dir_path; dir_dentrymnt = parent_dir_dentrymnt;
} }
} }
} }
@ -77,7 +77,7 @@ impl Path {
path path
} }
/// Get the effective name of path. /// Get the effective name of dentrymnt.
/// ///
/// If it is the root of mount, it will go up to the mountpoint to get the name /// If it is the root of mount, it will go up to the mountpoint to get the name
/// of the mountpoint recursively. /// of the mountpoint recursively.
@ -87,54 +87,53 @@ impl Path {
} }
if self.mount_node.parent().is_some() & self.mount_node.mountpoint_dentry().is_some() { if self.mount_node.parent().is_some() & self.mount_node.mountpoint_dentry().is_some() {
let parent_path = Path::new( let parent_dentrymnt = Self::new(
self.mount_node.parent().unwrap().upgrade().unwrap().clone(), self.mount_node.parent().unwrap().upgrade().unwrap().clone(),
self.mount_node.mountpoint_dentry().unwrap().clone(), self.mount_node.mountpoint_dentry().unwrap().clone(),
); );
parent_path.effective_name() parent_dentrymnt.effective_name()
} else { } else {
self.dentry.name() self.dentry.name()
} }
} }
/// Get the effective parent of path. /// Get the effective parent of dentrymnt.
/// ///
/// If it is the root of mount, it will go up to the mountpoint to get the parent /// If it is the root of mount, it will go up to the mountpoint to get the parent
/// of the mountpoint recursively. /// of the mountpoint recursively.
fn effective_parent(&self) -> Option<Arc<Self>> { fn effective_parent(&self) -> Option<Arc<Self>> {
if !self.dentry.is_root_of_mount() { if !self.dentry.is_root_of_mount() {
return Some(Path::new( return Some(Self::new(
self.mount_node.clone(), self.mount_node.clone(),
self.dentry.parent().unwrap().clone(), self.dentry.parent().unwrap().clone(),
)); ));
} }
if self.mount_node.parent().is_some() & self.mount_node.mountpoint_dentry().is_some() { if self.mount_node.parent().is_some() & self.mount_node.mountpoint_dentry().is_some() {
let parent_path = Path::new( let parent_dentrymnt = Self::new(
self.mount_node.parent().unwrap().upgrade().unwrap().clone(), self.mount_node.parent().unwrap().upgrade().unwrap().clone(),
self.mount_node.mountpoint_dentry().unwrap().clone(), self.mount_node.mountpoint_dentry().unwrap().clone(),
); );
parent_path.effective_parent() parent_dentrymnt.effective_parent()
} else { } else {
None None
} }
} }
/// Get the overlaid path of self. /// Get the overlaid dentrymnt of self.
/// ///
/// It will jump into the child mount if it is a mountpoint. /// It will jump into the child mount if it is a mountpoint.
fn overlaid_path(&self) -> Arc<Self> { fn overlaid_dentrymnt(&self) -> Arc<Self> {
if !self.dentry.is_mountpoint() { if !self.dentry.is_mountpoint() {
return self.this(); return self.this();
} }
match self.mount_node.get(self) { match self.mount_node.get(self) {
Some(child_mount) => { Some(child_mount) => Self::new(child_mount.clone(), child_mount.root_dentry().clone())
Path::new(child_mount.clone(), child_mount.root_dentry().clone()).overlaid_path() .overlaid_dentrymnt(),
}
None => self.this(), None => self.this(),
} }
} }
/// Mount the fs on this path. It will make this path's dentry to be a mountpoint. /// Mount the fs on this dentrymnt. It will make this dentrymnt's dentry to be a mountpoint.
/// ///
/// If the given mountpoint has already been mounted, then its mounted child mount /// If the given mountpoint has already been mounted, then its mounted child mount
/// will be updated. /// will be updated.
@ -167,14 +166,15 @@ impl Path {
}; };
let mountpoint_mount_node = mount_node.parent().unwrap().upgrade().unwrap(); let mountpoint_mount_node = mount_node.parent().unwrap().upgrade().unwrap();
let mountpoint_path = Path::new(mountpoint_mount_node.clone(), mountpoint_dentry.clone()); let mountpoint_dentrymnt =
Self::new(mountpoint_mount_node.clone(), mountpoint_dentry.clone());
let child_mount = mountpoint_mount_node.umount(&mountpoint_path)?; let child_mount = mountpoint_mount_node.umount(&mountpoint_dentrymnt)?;
mountpoint_dentry.clear_mountpoint(); mountpoint_dentry.clear_mountpoint();
Ok(child_mount) Ok(child_mount)
} }
/// Link a new name for the path's dentry by linking inode. /// Link a new name for the dentrymnt's dentry by linking inode.
pub fn link(&self, old: &Arc<Self>, name: &str) -> Result<()> { pub fn link(&self, old: &Arc<Self>, name: &str) -> Result<()> {
if self.dentry.inode().type_() != InodeType::Dir { if self.dentry.inode().type_() != InodeType::Dir {
return_errno!(Errno::ENOTDIR); return_errno!(Errno::ENOTDIR);
@ -198,12 +198,12 @@ impl Path {
self.this.upgrade().unwrap() self.this.upgrade().unwrap()
} }
/// Get the mount node of this path. /// Get the mount node of this dentrymnt.
pub fn mount_node(&self) -> &Arc<MountNode> { pub fn mount_node(&self) -> &Arc<MountNode> {
&self.mount_node &self.mount_node
} }
/// Get the dentry of this path. /// Get the dentry of this dentrymnt.
pub fn dentry(&self) -> &Arc<Dentry> { pub fn dentry(&self) -> &Arc<Dentry> {
&self.dentry &self.dentry
} }

View File

@ -6,6 +6,7 @@ pub use access_mode::AccessMode;
pub use channel::{Channel, Consumer, Producer}; pub use channel::{Channel, Consumer, Producer};
pub use creation_flags::CreationFlags; pub use creation_flags::CreationFlags;
pub use dentry::{Dentry, DentryKey}; pub use dentry::{Dentry, DentryKey};
pub use dentrymnt::DentryMnt;
pub use dirent_visitor::DirentVisitor; pub use dirent_visitor::DirentVisitor;
pub use direntry_vec::DirEntryVecExt; pub use direntry_vec::DirEntryVecExt;
pub use file_creation_mask::FileCreationMask; pub use file_creation_mask::FileCreationMask;
@ -14,7 +15,6 @@ pub use inode::{Inode, InodeMode, InodeType, Metadata};
pub use ioctl::IoctlCmd; pub use ioctl::IoctlCmd;
pub use mount::MountNode; pub use mount::MountNode;
pub use page_cache::{PageCache, PageCacheBackend}; pub use page_cache::{PageCache, PageCacheBackend};
pub use path::Path;
pub use random_test::{generate_random_operation, new_fs_in_memory}; pub use random_test::{generate_random_operation, new_fs_in_memory};
pub use status_flags::StatusFlags; pub use status_flags::StatusFlags;
@ -22,6 +22,7 @@ mod access_mode;
mod channel; mod channel;
mod creation_flags; mod creation_flags;
mod dentry; mod dentry;
mod dentrymnt;
mod dirent_visitor; mod dirent_visitor;
mod direntry_vec; mod direntry_vec;
mod file_creation_mask; mod file_creation_mask;
@ -30,7 +31,6 @@ mod inode;
mod ioctl; mod ioctl;
mod mount; mod mount;
mod page_cache; mod page_cache;
mod path;
mod random_test; mod random_test;
mod status_flags; mod status_flags;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use super::{Dentry, DentryKey, FileSystem, InodeType, Path}; use super::{Dentry, DentryKey, DentryMnt, FileSystem, InodeType};
use crate::prelude::*; use crate::prelude::*;
/// The MountNode can form a mount tree to maintain the mount information. /// The MountNode can form a mount tree to maintain the mount information.
@ -61,7 +61,7 @@ impl MountNode {
/// mountpoint. It is the fs's responsibility to ensure the data consistency. /// mountpoint. It is the fs's responsibility to ensure the data consistency.
/// ///
/// Return the mounted child mount. /// Return the mounted child mount.
pub fn mount(&self, fs: Arc<dyn FileSystem>, mountpoint: &Arc<Path>) -> Result<Arc<Self>> { pub fn mount(&self, fs: Arc<dyn FileSystem>, mountpoint: &Arc<DentryMnt>) -> Result<Arc<Self>> {
if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) { if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) {
return_errno_with_message!(Errno::EINVAL, "mountpoint not belongs to this"); return_errno_with_message!(Errno::EINVAL, "mountpoint not belongs to this");
} }
@ -82,7 +82,7 @@ impl MountNode {
/// Unmount a child mount node from the mountpoint and return it. /// Unmount a child mount node from the mountpoint and return it.
/// ///
/// The mountpoint should belong to this mount node, or an error is returned. /// The mountpoint should belong to this mount node, or an error is returned.
pub fn umount(&self, mountpoint: &Path) -> Result<Arc<Self>> { pub fn umount(&self, mountpoint: &DentryMnt) -> Result<Arc<Self>> {
if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) { if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) {
return_errno_with_message!(Errno::EINVAL, "mountpoint not belongs to this"); return_errno_with_message!(Errno::EINVAL, "mountpoint not belongs to this");
} }
@ -96,7 +96,7 @@ impl MountNode {
} }
/// Try to get a child mount node from the mountpoint. /// Try to get a child mount node from the mountpoint.
pub fn get(&self, mountpoint: &Path) -> Option<Arc<Self>> { pub fn get(&self, mountpoint: &DentryMnt) -> Option<Arc<Self>> {
if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) { if !Arc::ptr_eq(mountpoint.mount_node(), &self.this()) {
return None; return None;
} }

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use crate::{fs::utils::Path, net::socket::util::socket_addr::SocketAddr, prelude::*}; use crate::{fs::utils::DentryMnt, net::socket::util::socket_addr::SocketAddr, prelude::*};
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum UnixSocketAddr { pub enum UnixSocketAddr {
@ -10,7 +10,7 @@ pub enum UnixSocketAddr {
#[derive(Clone)] #[derive(Clone)]
pub(super) enum UnixSocketAddrBound { pub(super) enum UnixSocketAddrBound {
Path(Arc<Path>), Path(Arc<DentryMnt>),
Abstract(String), Abstract(String),
} }
@ -40,8 +40,8 @@ impl TryFrom<SocketAddr> for UnixSocketAddr {
impl From<UnixSocketAddrBound> for UnixSocketAddr { impl From<UnixSocketAddrBound> for UnixSocketAddr {
fn from(value: UnixSocketAddrBound) -> Self { fn from(value: UnixSocketAddrBound) -> Self {
match value { match value {
UnixSocketAddrBound::Path(path) => { UnixSocketAddrBound::Path(dentrymnt) => {
let abs_path = path.abs_path(); let abs_path = dentrymnt.abs_path();
Self::Path(abs_path) Self::Path(abs_path)
} }
UnixSocketAddrBound::Abstract(name) => Self::Abstract(name), UnixSocketAddrBound::Abstract(name) => Self::Abstract(name),

View File

@ -7,7 +7,7 @@ use crate::{
events::IoEvents, events::IoEvents,
fs::{ fs::{
fs_resolver::{split_path, FsPath}, fs_resolver::{split_path, FsPath},
utils::{InodeMode, InodeType, Path}, utils::{DentryMnt, InodeMode, InodeType},
}, },
net::socket::unix::addr::{UnixSocketAddr, UnixSocketAddrBound}, net::socket::unix::addr::{UnixSocketAddr, UnixSocketAddrBound},
prelude::*, prelude::*,
@ -38,8 +38,8 @@ impl Init {
let bound_addr = match addr_to_bind { let bound_addr = match addr_to_bind {
UnixSocketAddr::Abstract(_) => todo!(), UnixSocketAddr::Abstract(_) => todo!(),
UnixSocketAddr::Path(pathname) => { UnixSocketAddr::Path(pathname) => {
let path = create_socket_file(pathname)?; let dentrymnt = create_socket_file(pathname)?;
UnixSocketAddrBound::Path(path) UnixSocketAddrBound::Path(dentrymnt)
} }
}; };
@ -87,7 +87,7 @@ impl Init {
} }
} }
fn create_socket_file(pathname: &str) -> Result<Arc<Path>> { fn create_socket_file(pathname: &str) -> Result<Arc<DentryMnt>> {
let (parent_pathname, file_name) = split_path(pathname); let (parent_pathname, file_name) = split_path(pathname);
let parent = { let parent = {
let current = current!(); let current = current!();
@ -100,6 +100,6 @@ fn create_socket_file(pathname: &str) -> Result<Arc<Path>> {
InodeType::Socket, InodeType::Socket,
InodeMode::S_IRUSR | InodeMode::S_IWUSR, InodeMode::S_IRUSR | InodeMode::S_IWUSR,
)?; )?;
let path = Path::new(parent.mount_node().clone(), dentry.clone()); let dentrymnt = DentryMnt::new(parent.mount_node().clone(), dentry.clone());
Ok(path) Ok(dentrymnt)
} }

View File

@ -9,7 +9,7 @@ use crate::{
events::IoEvents, events::IoEvents,
fs::{ fs::{
file_handle::FileLike, file_handle::FileLike,
utils::{Inode, Path}, utils::{DentryMnt, Inode},
}, },
net::socket::{ net::socket::{
unix::addr::{UnixSocketAddr, UnixSocketAddrBound}, unix::addr::{UnixSocketAddr, UnixSocketAddrBound},
@ -91,10 +91,10 @@ impl BacklogTable {
fn add_backlog(&self, addr: &UnixSocketAddrBound, backlog: usize) -> Result<()> { fn add_backlog(&self, addr: &UnixSocketAddrBound, backlog: usize) -> Result<()> {
let inode = { let inode = {
let UnixSocketAddrBound::Path(path) = addr else { let UnixSocketAddrBound::Path(dentrymnt) = addr else {
todo!() todo!()
}; };
create_keyable_inode(path) create_keyable_inode(dentrymnt)
}; };
let mut backlog_sockets = self.backlog_sockets.write(); let mut backlog_sockets = self.backlog_sockets.write();
@ -108,10 +108,10 @@ impl BacklogTable {
fn get_backlog(&self, addr: &UnixSocketAddrBound) -> Result<Arc<Backlog>> { fn get_backlog(&self, addr: &UnixSocketAddrBound) -> Result<Arc<Backlog>> {
let inode = { let inode = {
let UnixSocketAddrBound::Path(path) = addr else { let UnixSocketAddrBound::Path(dentrymnt) = addr else {
todo!() todo!()
}; };
create_keyable_inode(path) create_keyable_inode(dentrymnt)
}; };
let backlog_sockets = self.backlog_sockets.read(); let backlog_sockets = self.backlog_sockets.read();
@ -162,11 +162,11 @@ impl BacklogTable {
} }
fn remove_backlog(&self, addr: &UnixSocketAddrBound) { fn remove_backlog(&self, addr: &UnixSocketAddrBound) {
let UnixSocketAddrBound::Path(dentry) = addr else { let UnixSocketAddrBound::Path(dentrymnt) = addr else {
todo!() todo!()
}; };
let inode = create_keyable_inode(dentry); let inode = create_keyable_inode(dentrymnt);
self.backlog_sockets.write().remove(&inode); self.backlog_sockets.write().remove(&inode);
} }
} }
@ -212,8 +212,8 @@ impl Backlog {
} }
} }
fn create_keyable_inode(path: &Arc<Path>) -> KeyableWeak<dyn Inode> { fn create_keyable_inode(dentrymnt: &Arc<DentryMnt>) -> KeyableWeak<dyn Inode> {
let weak_inode = Arc::downgrade(path.dentry().inode()); let weak_inode = Arc::downgrade(dentrymnt.dentry().inode());
KeyableWeak::from(weak_inode) KeyableWeak::from(weak_inode)
} }

View File

@ -11,7 +11,7 @@ use crate::{
fs::{ fs::{
file_handle::FileLike, file_handle::FileLike,
fs_resolver::FsPath, fs_resolver::FsPath,
utils::{InodeType, Path, StatusFlags}, utils::{DentryMnt, InodeType, StatusFlags},
}, },
net::socket::{ net::socket::{
unix::{addr::UnixSocketAddrBound, UnixSocketAddr}, unix::{addr::UnixSocketAddrBound, UnixSocketAddr},
@ -162,8 +162,8 @@ impl Socket for UnixStreamSocket {
UnixSocketAddrBound::Abstract(abstract_name) UnixSocketAddrBound::Abstract(abstract_name)
} }
UnixSocketAddr::Path(pathname) => { UnixSocketAddr::Path(pathname) => {
let path = lookup_socket_file(&pathname)?; let dentrymnt = lookup_socket_file(&pathname)?;
UnixSocketAddrBound::Path(path) UnixSocketAddrBound::Path(dentrymnt)
} }
} }
}; };
@ -287,20 +287,20 @@ impl Drop for UnixStreamSocket {
} }
} }
fn lookup_socket_file(pathname: &str) -> Result<Arc<Path>> { fn lookup_socket_file(pathname: &str) -> Result<Arc<DentryMnt>> {
let path = { let dentrymnt = {
let current = current!(); let current = current!();
let fs = current.fs().read(); let fs = current.fs().read();
let fs_path = FsPath::try_from(pathname)?; let fs_path = FsPath::try_from(pathname)?;
fs.lookup(&fs_path)? fs.lookup(&fs_path)?
}; };
if path.dentry().type_() != InodeType::Socket { if dentrymnt.dentry().type_() != InodeType::Socket {
return_errno_with_message!(Errno::ENOTSOCK, "not a socket file") return_errno_with_message!(Errno::ENOTSOCK, "not a socket file")
} }
if !path.dentry().mode()?.is_readable() || !path.dentry().mode()?.is_writable() { if !dentrymnt.dentry().mode()?.is_readable() || !dentrymnt.dentry().mode()?.is_writable() {
return_errno_with_message!(Errno::EACCES, "the socket cannot be read or written") return_errno_with_message!(Errno::EACCES, "the socket cannot be read or written")
} }
Ok(path) Ok(dentrymnt)
} }

View File

@ -12,7 +12,7 @@ use super::elf_file::Elf;
use crate::{ use crate::{
fs::{ fs::{
fs_resolver::{FsPath, FsResolver, AT_FDCWD}, fs_resolver::{FsPath, FsResolver, AT_FDCWD},
utils::{Dentry, Path}, utils::{Dentry, DentryMnt},
}, },
prelude::*, prelude::*,
process::{ process::{
@ -35,7 +35,7 @@ use crate::{
pub fn load_elf_to_vm( pub fn load_elf_to_vm(
process_vm: &ProcessVm, process_vm: &ProcessVm,
file_header: &[u8], file_header: &[u8],
elf_file: Arc<Path>, elf_file: Arc<DentryMnt>,
fs_resolver: &FsResolver, fs_resolver: &FsResolver,
argv: Vec<CString>, argv: Vec<CString>,
envp: Vec<CString>, envp: Vec<CString>,

View File

@ -11,7 +11,7 @@ use super::process_vm::ProcessVm;
use crate::{ use crate::{
fs::{ fs::{
fs_resolver::{FsPath, FsResolver, AT_FDCWD}, fs_resolver::{FsPath, FsResolver, AT_FDCWD},
utils::{Dentry, Path}, utils::{Dentry, DentryMnt},
}, },
prelude::*, prelude::*,
}; };
@ -25,7 +25,7 @@ use crate::{
/// because the interpreter is usually an elf binary(e.g., /bin/bash) /// because the interpreter is usually an elf binary(e.g., /bin/bash)
pub fn load_program_to_vm( pub fn load_program_to_vm(
process_vm: &ProcessVm, process_vm: &ProcessVm,
elf_file: Arc<Path>, elf_file: Arc<DentryMnt>,
argv: Vec<CString>, argv: Vec<CString>,
envp: Vec<CString>, envp: Vec<CString>,
fs_resolver: &FsResolver, fs_resolver: &FsResolver,

View File

@ -16,7 +16,7 @@ pub fn sys_chdir(pathname_addr: Vaddr) -> Result<SyscallReturn> {
let current = current!(); let current = current!();
let mut fs = current.fs().write(); let mut fs = current.fs().write();
let path = { let dentrymnt = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
@ -24,10 +24,10 @@ pub fn sys_chdir(pathname_addr: Vaddr) -> Result<SyscallReturn> {
let fs_path = FsPath::try_from(pathname.as_ref())?; let fs_path = FsPath::try_from(pathname.as_ref())?;
fs.lookup(&fs_path)? fs.lookup(&fs_path)?
}; };
if path.dentry().type_() != InodeType::Dir { if dentrymnt.dentry().type_() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "must be directory"); return_errno_with_message!(Errno::ENOTDIR, "must be directory");
} }
fs.set_cwd(path); fs.set_cwd(dentrymnt);
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }
@ -36,17 +36,17 @@ pub fn sys_fchdir(fd: FileDesc) -> Result<SyscallReturn> {
debug!("fd = {}", fd); debug!("fd = {}", fd);
let current = current!(); let current = current!();
let path = { let dentrymnt = {
let file_table = current.file_table().lock(); let file_table = current.file_table().lock();
let file = file_table.get_file(fd)?; let file = file_table.get_file(fd)?;
let inode_handle = file let inode_handle = file
.downcast_ref::<InodeHandle>() .downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?; .ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
inode_handle.path().clone() inode_handle.dentrymnt().clone()
}; };
if path.dentry().type_() != InodeType::Dir { if dentrymnt.dentry().type_() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "must be directory"); return_errno_with_message!(Errno::ENOTDIR, "must be directory");
} }
current.fs().write().set_cwd(path); current.fs().write().set_cwd(dentrymnt);
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -35,22 +35,20 @@ pub fn sys_fchmodat(
/* flags: u32, */ /* flags: u32, */
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_FCHMODAT); log_syscall_entry!(SYS_FCHMODAT);
let pathname = read_cstring_from_user(path_ptr, PATH_MAX)?; let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
debug!( debug!("dirfd = {}, path = {:?}, mode = 0o{:o}", dirfd, path, mode,);
"dirfd = {}, path = {:?}, mode = 0o{:o}",
dirfd, pathname, mode,
);
let current = current!(); let current = current!();
let path = { let dentrymnt = {
let pathname = pathname.to_string_lossy(); let path = path.to_string_lossy();
if pathname.is_empty() { if path.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
} }
let fs_path = FsPath::new(dirfd, pathname.as_ref())?; let fs_path = FsPath::new(dirfd, path.as_ref())?;
current.fs().read().lookup(&fs_path)? current.fs().read().lookup(&fs_path)?
}; };
path.dentry() dentrymnt
.dentry()
.set_mode(InodeMode::from_bits_truncate(mode))?; .set_mode(InodeMode::from_bits_truncate(mode))?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -57,15 +57,15 @@ pub fn sys_fchownat(
flags: u32, flags: u32,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_FCHOWNAT); log_syscall_entry!(SYS_FCHOWNAT);
let pathname = read_cstring_from_user(path_ptr, PATH_MAX)?; let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
let flags = ChownFlags::from_bits(flags) let flags = ChownFlags::from_bits(flags)
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?; .ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid flags"))?;
debug!( debug!(
"dirfd = {}, path = {:?}, uid = {}, gid = {}, flags = {:?}", "dirfd = {}, path = {:?}, uid = {}, gid = {}, flags = {:?}",
dirfd, pathname, uid, gid, flags dirfd, path, uid, gid, flags
); );
if pathname.is_empty() { if path.is_empty() {
if !flags.contains(ChownFlags::AT_EMPTY_PATH) { if !flags.contains(ChownFlags::AT_EMPTY_PATH) {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
} }
@ -79,9 +79,9 @@ pub fn sys_fchownat(
} }
let current = current!(); let current = current!();
let path = { let dentrymnt = {
let pathname = pathname.to_string_lossy(); let path = path.to_string_lossy();
let fs_path = FsPath::new(dirfd, pathname.as_ref())?; let fs_path = FsPath::new(dirfd, path.as_ref())?;
let fs = current.fs().read(); let fs = current.fs().read();
if flags.contains(ChownFlags::AT_SYMLINK_NOFOLLOW) { if flags.contains(ChownFlags::AT_SYMLINK_NOFOLLOW) {
fs.lookup_no_follow(&fs_path)? fs.lookup_no_follow(&fs_path)?
@ -90,10 +90,10 @@ pub fn sys_fchownat(
} }
}; };
if let Some(uid) = uid { if let Some(uid) = uid {
path.dentry().set_owner(uid)?; dentrymnt.dentry().set_owner(uid)?;
} }
if let Some(gid) = gid { if let Some(gid) = gid {
path.dentry().set_group(gid)?; dentrymnt.dentry().set_group(gid)?;
} }
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -16,7 +16,7 @@ pub fn sys_chroot(pathname_addr: Vaddr) -> Result<SyscallReturn> {
let current = current!(); let current = current!();
let mut fs = current.fs().write(); let mut fs = current.fs().write();
let path = { let dentrymnt = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
@ -24,9 +24,9 @@ pub fn sys_chroot(pathname_addr: Vaddr) -> Result<SyscallReturn> {
let fs_path = FsPath::try_from(pathname.as_ref())?; let fs_path = FsPath::try_from(pathname.as_ref())?;
fs.lookup(&fs_path)? fs.lookup(&fs_path)?
}; };
if path.dentry().type_() != InodeType::Dir { if dentrymnt.dentry().type_() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "must be directory"); return_errno_with_message!(Errno::ENOTDIR, "must be directory");
} }
fs.set_root(path); fs.set_root(dentrymnt);
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -8,7 +8,7 @@ use crate::{
fs::{ fs::{
file_table::FileDesc, file_table::FileDesc,
fs_resolver::{FsPath, AT_FDCWD}, fs_resolver::{FsPath, AT_FDCWD},
utils::{Dentry, InodeType, Path}, utils::{Dentry, DentryMnt, InodeType},
}, },
log_syscall_entry, log_syscall_entry,
prelude::*, prelude::*,
@ -61,29 +61,29 @@ fn lookup_executable_file(
dfd: FileDesc, dfd: FileDesc,
filename: String, filename: String,
flags: OpenFlags, flags: OpenFlags,
) -> Result<Arc<Path>> { ) -> Result<Arc<DentryMnt>> {
let current = current!(); let current = current!();
let fs_resolver = current.fs().read(); let fs_resolver = current.fs().read();
let path = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() { let dentrymnt = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
fs_resolver.lookup_from_fd(dfd) fs_resolver.lookup_from_fd(dfd)
} else { } else {
let fs_path = FsPath::new(dfd, &filename)?; let fs_path = FsPath::new(dfd, &filename)?;
if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) { if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) {
let path = fs_resolver.lookup_no_follow(&fs_path)?; let dentrymnt = fs_resolver.lookup_no_follow(&fs_path)?;
if path.dentry().type_() == InodeType::SymLink { if dentrymnt.dentry().type_() == InodeType::SymLink {
return_errno_with_message!(Errno::ELOOP, "the executable file is a symlink"); return_errno_with_message!(Errno::ELOOP, "the executable file is a symlink");
} }
Ok(path) Ok(dentrymnt)
} else { } else {
fs_resolver.lookup(&fs_path) fs_resolver.lookup(&fs_path)
} }
}?; }?;
check_executable_file(path.dentry())?; check_executable_file(dentrymnt.dentry())?;
Ok(path) Ok(dentrymnt)
} }
fn do_execve( fn do_execve(
elf_file: Arc<Path>, elf_file: Arc<DentryMnt>,
argv_ptr_ptr: Vaddr, argv_ptr_ptr: Vaddr,
envp_ptr_ptr: Vaddr, envp_ptr_ptr: Vaddr,
context: &mut UserContext, context: &mut UserContext,

View File

@ -18,7 +18,7 @@ pub fn sys_fsync(fd: FileDesc) -> Result<SyscallReturn> {
let inode_handle = file let inode_handle = file
.downcast_ref::<InodeHandle>() .downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EINVAL, "not inode"))?; .ok_or(Error::with_message(Errno::EINVAL, "not inode"))?;
inode_handle.path().dentry().clone() inode_handle.dentrymnt().dentry().clone()
}; };
dentry.sync()?; dentry.sync()?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))

View File

@ -29,7 +29,7 @@ pub fn sys_getdents64(fd: FileDesc, buf_addr: Vaddr, buf_len: usize) -> Result<S
let inode_handle = file let inode_handle = file
.downcast_ref::<InodeHandle>() .downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?; .ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
if inode_handle.path().dentry().type_() != InodeType::Dir { if inode_handle.dentrymnt().dentry().type_() != InodeType::Dir {
return_errno!(Errno::ENOTDIR); return_errno!(Errno::ENOTDIR);
} }
let mut buffer = vec![0u8; buf_len]; let mut buffer = vec![0u8; buf_len];

View File

@ -30,7 +30,7 @@ pub fn sys_linkat(
); );
let current = current!(); let current = current!();
let (old_path, new_dir_path, new_name) = { let (old_dentrymnt, new_dir_dentrymnt, new_name) = {
let old_pathname = old_pathname.to_string_lossy(); let old_pathname = old_pathname.to_string_lossy();
if old_pathname.ends_with('/') { if old_pathname.ends_with('/') {
return_errno_with_message!(Errno::EPERM, "oldpath is dir"); return_errno_with_message!(Errno::EPERM, "oldpath is dir");
@ -46,15 +46,15 @@ pub fn sys_linkat(
let old_fs_path = FsPath::new(old_dirfd, old_pathname.as_ref())?; let old_fs_path = FsPath::new(old_dirfd, old_pathname.as_ref())?;
let new_fs_path = FsPath::new(new_dirfd, new_pathname.as_ref())?; let new_fs_path = FsPath::new(new_dirfd, new_pathname.as_ref())?;
let fs = current.fs().read(); let fs = current.fs().read();
let old_path = if flags.contains(LinkFlags::AT_SYMLINK_FOLLOW) { let old_dentrymnt = if flags.contains(LinkFlags::AT_SYMLINK_FOLLOW) {
fs.lookup(&old_fs_path)? fs.lookup(&old_fs_path)?
} else { } else {
fs.lookup_no_follow(&old_fs_path)? fs.lookup_no_follow(&old_fs_path)?
}; };
let (new_dir_path, new_name) = fs.lookup_dir_and_base_name(&new_fs_path)?; let (new_dir_dentrymnt, new_name) = fs.lookup_dir_and_base_name(&new_fs_path)?;
(old_path, new_dir_path, new_name) (old_dentrymnt, new_dir_dentrymnt, new_name)
}; };
new_dir_path.link(&old_path, &new_name)?; new_dir_dentrymnt.link(&old_dentrymnt, &new_name)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -22,7 +22,7 @@ pub fn sys_mkdirat(dirfd: FileDesc, pathname_addr: Vaddr, mode: u16) -> Result<S
); );
let current = current!(); let current = current!();
let (dir_path, name) = { let (dir_dentrymnt, name) = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
@ -35,9 +35,10 @@ pub fn sys_mkdirat(dirfd: FileDesc, pathname_addr: Vaddr, mode: u16) -> Result<S
let mask_mode = mode & !current.umask().read().get(); let mask_mode = mode & !current.umask().read().get();
InodeMode::from_bits_truncate(mask_mode) InodeMode::from_bits_truncate(mask_mode)
}; };
let _ = dir_path let _ =
.dentry() dir_dentrymnt
.create(name.trim_end_matches('/'), InodeType::Dir, inode_mode)?; .dentry()
.create(name.trim_end_matches('/'), InodeType::Dir, inode_mode)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -100,8 +100,8 @@ fn alloc_filebacked_vmo(
let current = current!(); let current = current!();
let page_cache_vmo = { let page_cache_vmo = {
let fs_resolver = current.fs().read(); let fs_resolver = current.fs().read();
let path = fs_resolver.lookup_from_fd(fd)?; let dentrymnt = fs_resolver.lookup_from_fd(fd)?;
let inode = path.dentry().inode(); let inode = dentrymnt.dentry().inode();
inode inode
.page_cache() .page_cache()
.ok_or(Error::with_message( .ok_or(Error::with_message(

View File

@ -26,7 +26,7 @@ pub fn sys_readlinkat(
); );
let current = current!(); let current = current!();
let path = { let dentrymnt = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
@ -34,7 +34,7 @@ pub fn sys_readlinkat(
let fs_path = FsPath::new(dirfd, pathname.as_ref())?; let fs_path = FsPath::new(dirfd, pathname.as_ref())?;
current.fs().read().lookup_no_follow(&fs_path)? current.fs().read().lookup_no_follow(&fs_path)?
}; };
let linkpath = path.dentry().inode().read_link()?; let linkpath = dentrymnt.dentry().inode().read_link()?;
let bytes = linkpath.as_bytes(); let bytes = linkpath.as_bytes();
let write_len = bytes.len().min(usr_buf_len); let write_len = bytes.len().min(usr_buf_len);
write_bytes_to_user(usr_buf_addr, &bytes[..write_len])?; write_bytes_to_user(usr_buf_addr, &bytes[..write_len])?;

View File

@ -30,7 +30,7 @@ pub fn sys_renameat(
let current = current!(); let current = current!();
let fs = current.fs().read(); let fs = current.fs().read();
let (old_dir_path, old_name) = { let (old_dir_dentrymnt, old_name) = {
let old_pathname = old_pathname.to_string_lossy(); let old_pathname = old_pathname.to_string_lossy();
if old_pathname.is_empty() { if old_pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "oldpath is empty"); return_errno_with_message!(Errno::ENOENT, "oldpath is empty");
@ -38,14 +38,14 @@ pub fn sys_renameat(
let old_fs_path = FsPath::new(old_dirfd, old_pathname.as_ref())?; let old_fs_path = FsPath::new(old_dirfd, old_pathname.as_ref())?;
fs.lookup_dir_and_base_name(&old_fs_path)? fs.lookup_dir_and_base_name(&old_fs_path)?
}; };
let old_path = old_dir_path.lookup(&old_name)?; let old_dentrymnt = old_dir_dentrymnt.lookup(&old_name)?;
let (new_dir_path, new_name) = { let (new_dir_dentrymnt, new_name) = {
let new_pathname = new_pathname.to_string_lossy(); let new_pathname = new_pathname.to_string_lossy();
if new_pathname.is_empty() { if new_pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "newpath is empty"); return_errno_with_message!(Errno::ENOENT, "newpath is empty");
} }
if new_pathname.ends_with('/') && old_path.dentry().type_() != InodeType::Dir { if new_pathname.ends_with('/') && old_dentrymnt.dentry().type_() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "oldpath is not dir"); return_errno_with_message!(Errno::ENOTDIR, "oldpath is not dir");
} }
let new_fs_path = FsPath::new(new_dirfd, new_pathname.as_ref().trim_end_matches('/'))?; let new_fs_path = FsPath::new(new_dirfd, new_pathname.as_ref().trim_end_matches('/'))?;
@ -53,8 +53,8 @@ pub fn sys_renameat(
}; };
// Check abs_path // Check abs_path
let old_abs_path = old_path.abs_path(); let old_abs_path = old_dentrymnt.abs_path();
let new_abs_path = new_dir_path.abs_path() + "/" + &new_name; let new_abs_path = new_dir_dentrymnt.abs_path() + "/" + &new_name;
if new_abs_path.starts_with(&old_abs_path) { if new_abs_path.starts_with(&old_abs_path) {
if new_abs_path.len() == old_abs_path.len() { if new_abs_path.len() == old_abs_path.len() {
return Ok(SyscallReturn::Return(0)); return Ok(SyscallReturn::Return(0));
@ -66,13 +66,16 @@ pub fn sys_renameat(
} }
} }
if !Arc::ptr_eq(old_dir_path.mount_node(), new_dir_path.mount_node()) { if !Arc::ptr_eq(
old_dir_dentrymnt.mount_node(),
new_dir_dentrymnt.mount_node(),
) {
return_errno_with_message!(Errno::EXDEV, "cannot cross mount"); return_errno_with_message!(Errno::EXDEV, "cannot cross mount");
} }
old_dir_path old_dir_dentrymnt
.dentry() .dentry()
.rename(&old_name, new_dir_path.dentry(), &new_name)?; .rename(&old_name, new_dir_dentrymnt.dentry(), &new_name)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -22,7 +22,7 @@ pub(super) fn sys_rmdirat(dirfd: FileDesc, pathname_addr: Vaddr) -> Result<Sysca
debug!("dirfd = {}, pathname = {:?}", dirfd, pathname); debug!("dirfd = {}, pathname = {:?}", dirfd, pathname);
let current = current!(); let current = current!();
let (dir_path, name) = { let (dir_dentrymnt, name) = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname == "/" { if pathname == "/" {
return_errno_with_message!(Errno::EBUSY, "is root directory"); return_errno_with_message!(Errno::EBUSY, "is root directory");
@ -30,6 +30,6 @@ pub(super) fn sys_rmdirat(dirfd: FileDesc, pathname_addr: Vaddr) -> Result<Sysca
let fs_path = FsPath::new(dirfd, pathname.as_ref())?; let fs_path = FsPath::new(dirfd, pathname.as_ref())?;
current.fs().read().lookup_dir_and_base_name(&fs_path)? current.fs().read().lookup_dir_and_base_name(&fs_path)?
}; };
dir_path.dentry().rmdir(name.trim_end_matches('/'))?; dir_dentrymnt.dentry().rmdir(name.trim_end_matches('/'))?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -63,7 +63,7 @@ pub fn sys_fstatat(
} }
let current = current!(); let current = current!();
let path = { let dentrymnt = {
let filename = filename.to_string_lossy(); let filename = filename.to_string_lossy();
let fs_path = FsPath::new(dirfd, filename.as_ref())?; let fs_path = FsPath::new(dirfd, filename.as_ref())?;
let fs = current.fs().read(); let fs = current.fs().read();
@ -73,7 +73,7 @@ pub fn sys_fstatat(
fs.lookup(&fs_path)? fs.lookup(&fs_path)?
} }
}; };
let stat = Stat::from(path.dentry().metadata()); let stat = Stat::from(dentrymnt.dentry().metadata());
write_val_to_user(stat_buf_ptr, &stat)?; write_val_to_user(stat_buf_ptr, &stat)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -42,7 +42,7 @@ pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr) -> Result<SyscallReturn>
let inode_handle = file let inode_handle = file
.downcast_ref::<InodeHandle>() .downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?; .ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
let dentry = inode_handle.path().dentry(); let dentry = inode_handle.dentrymnt().dentry();
let statfs = Statfs::from(dentry.fs().sb()); let statfs = Statfs::from(dentry.fs().sb());
write_val_to_user(statfs_buf_ptr, &statfs)?; write_val_to_user(statfs_buf_ptr, &statfs)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))

View File

@ -31,7 +31,7 @@ pub fn sys_symlinkat(
if target.is_empty() { if target.is_empty() {
return_errno_with_message!(Errno::ENOENT, "target is empty"); return_errno_with_message!(Errno::ENOENT, "target is empty");
} }
let (dir_path, link_name) = { let (dir_dentrymnt, link_name) = {
let linkpath = linkpath.to_string_lossy(); let linkpath = linkpath.to_string_lossy();
if linkpath.is_empty() { if linkpath.is_empty() {
return_errno_with_message!(Errno::ENOENT, "linkpath is empty"); return_errno_with_message!(Errno::ENOENT, "linkpath is empty");
@ -43,7 +43,7 @@ pub fn sys_symlinkat(
current.fs().read().lookup_dir_and_base_name(&fs_path)? current.fs().read().lookup_dir_and_base_name(&fs_path)?
}; };
let new_dentry = dir_path.dentry().create( let new_dentry = dir_dentrymnt.dentry().create(
&link_name, &link_name,
InodeType::SymLink, InodeType::SymLink,
InodeMode::from_bits_truncate(0o777), InodeMode::from_bits_truncate(0o777),

View File

@ -34,7 +34,7 @@ pub fn sys_truncate(path_ptr: Vaddr, len: isize) -> Result<SyscallReturn> {
check_length(len)?; check_length(len)?;
let current = current!(); let current = current!();
let path = { let dir_dentrymnt = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
@ -42,7 +42,7 @@ pub fn sys_truncate(path_ptr: Vaddr, len: isize) -> Result<SyscallReturn> {
let fs_path = FsPath::new(AT_FDCWD, pathname.as_ref())?; let fs_path = FsPath::new(AT_FDCWD, pathname.as_ref())?;
current.fs().read().lookup(&fs_path)? current.fs().read().lookup(&fs_path)?
}; };
path.dentry().resize(len as usize)?; dir_dentrymnt.dentry().resize(len as usize)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -24,7 +24,7 @@ pub fn sys_unlinkat(dirfd: FileDesc, pathname_addr: Vaddr, flags: u32) -> Result
debug!("dirfd = {}, pathname = {:?}", dirfd, pathname); debug!("dirfd = {}, pathname = {:?}", dirfd, pathname);
let current = current!(); let current = current!();
let (dir_path, name) = { let (dir_dentrymnt, name) = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty"); return_errno_with_message!(Errno::ENOENT, "path is empty");
@ -35,7 +35,7 @@ pub fn sys_unlinkat(dirfd: FileDesc, pathname_addr: Vaddr, flags: u32) -> Result
let fs_path = FsPath::new(dirfd, pathname.as_ref())?; let fs_path = FsPath::new(dirfd, pathname.as_ref())?;
current.fs().read().lookup_dir_and_base_name(&fs_path)? current.fs().read().lookup_dir_and_base_name(&fs_path)?
}; };
dir_path.dentry().unlink(&name)?; dir_dentrymnt.dentry().unlink(&name)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -61,7 +61,7 @@ pub fn sys_utimensat(
return Ok(SyscallReturn::Return(0)); return Ok(SyscallReturn::Return(0));
} }
let current = current!(); let current = current!();
let path = { let dentrymnt = {
let pathname = pathname.to_string_lossy(); let pathname = pathname.to_string_lossy();
if pathname.is_empty() { if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "pathname is empty"); return_errno_with_message!(Errno::ENOENT, "pathname is empty");
@ -75,10 +75,10 @@ pub fn sys_utimensat(
} }
}; };
if let Some(time) = atime { if let Some(time) = atime {
path.dentry().set_atime(Duration::from(time)); dentrymnt.dentry().set_atime(Duration::from(time));
} }
if let Some(time) = mtime { if let Some(time) = mtime {
path.dentry().set_mtime(Duration::from(time)); dentrymnt.dentry().set_mtime(Duration::from(time));
} }
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }