Clarify how `Path` inherits methods
This commit is contained in:
parent
9c8a8f8df9
commit
0636e1048e
|
|
@ -204,7 +204,7 @@ impl FileLike for InodeHandle {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
self.0.inode()
|
||||
self.0.path.inode()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ mod dyn_cap;
|
|||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
pub use dyn_cap::InodeHandle;
|
||||
use inherit_methods_macro::inherit_methods;
|
||||
|
||||
use crate::{
|
||||
events::IoEvents,
|
||||
|
|
@ -252,12 +251,6 @@ impl HandleInner {
|
|||
}
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.path")]
|
||||
impl HandleInner {
|
||||
pub(self) fn size(&self) -> usize;
|
||||
pub(self) fn inode(&self) -> &Arc<dyn Inode>;
|
||||
}
|
||||
|
||||
impl Debug for HandleInner {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
f.debug_struct("HandleInner")
|
||||
|
|
|
|||
|
|
@ -1,24 +1,14 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#![expect(dead_code)]
|
||||
|
||||
use core::{
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
time::Duration,
|
||||
};
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use inherit_methods_macro::inherit_methods;
|
||||
use ostd::sync::RwMutexWriteGuard;
|
||||
|
||||
use super::is_dot_or_dotdot;
|
||||
use crate::{
|
||||
fs::utils::{
|
||||
FileSystem, Inode, InodeMode, InodeType, Metadata, MknodType, XattrName, XattrNamespace,
|
||||
XattrSetFlags,
|
||||
},
|
||||
fs::utils::{Inode, InodeMode, InodeType, MknodType},
|
||||
prelude::*,
|
||||
process::{Gid, Uid},
|
||||
};
|
||||
|
||||
/// A `Dentry` represents a cached filesystem node in the VFS tree.
|
||||
|
|
@ -100,6 +90,12 @@ impl Dentry {
|
|||
&self.inode
|
||||
}
|
||||
|
||||
/// Returns whether the dentry can be cached.
|
||||
fn is_dentry_cacheable(&self) -> bool {
|
||||
// Should we store it as a dentry flag?
|
||||
self.inode.is_dentry_cacheable()
|
||||
}
|
||||
|
||||
fn flags(&self) -> DentryFlags {
|
||||
let flags = self.flags.load(Ordering::Relaxed);
|
||||
DentryFlags::from_bits(flags).unwrap()
|
||||
|
|
@ -355,48 +351,14 @@ impl Dentry {
|
|||
}
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.inode")]
|
||||
impl Dentry {
|
||||
pub(super) fn fs(&self) -> Arc<dyn FileSystem>;
|
||||
pub(super) fn sync_all(&self) -> Result<()>;
|
||||
pub(super) fn sync_data(&self) -> Result<()>;
|
||||
pub(super) fn metadata(&self) -> Metadata;
|
||||
pub(super) fn mode(&self) -> Result<InodeMode>;
|
||||
pub(super) fn set_mode(&self, mode: InodeMode) -> Result<()>;
|
||||
pub(super) fn size(&self) -> usize;
|
||||
pub(super) fn resize(&self, size: usize) -> Result<()>;
|
||||
pub(super) fn owner(&self) -> Result<Uid>;
|
||||
pub(super) fn set_owner(&self, uid: Uid) -> Result<()>;
|
||||
pub(super) fn group(&self) -> Result<Gid>;
|
||||
pub(super) fn set_group(&self, gid: Gid) -> Result<()>;
|
||||
pub(super) fn atime(&self) -> Duration;
|
||||
pub(super) fn set_atime(&self, time: Duration);
|
||||
pub(super) fn mtime(&self) -> Duration;
|
||||
pub(super) fn set_mtime(&self, time: Duration);
|
||||
pub(super) fn ctime(&self) -> Duration;
|
||||
pub(super) fn set_ctime(&self, time: Duration);
|
||||
pub(super) fn is_dentry_cacheable(&self) -> bool;
|
||||
pub(super) fn set_xattr(
|
||||
&self,
|
||||
name: XattrName,
|
||||
value_reader: &mut VmReader,
|
||||
flags: XattrSetFlags,
|
||||
) -> Result<()>;
|
||||
pub(super) fn get_xattr(&self, name: XattrName, value_writer: &mut VmWriter) -> Result<usize>;
|
||||
pub(super) fn list_xattr(
|
||||
&self,
|
||||
namespace: XattrNamespace,
|
||||
list_writer: &mut VmWriter,
|
||||
) -> Result<usize>;
|
||||
pub(super) fn remove_xattr(&self, name: XattrName) -> Result<()>;
|
||||
}
|
||||
|
||||
impl Debug for Dentry {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
f.debug_struct("Dentry")
|
||||
.field("inode", &self.inode)
|
||||
.field("flags", &self.flags())
|
||||
.finish()
|
||||
.field("type_", &self.type_)
|
||||
.field("flags", &self.flags)
|
||||
.field("mount_count", &self.mount_count)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -459,6 +421,7 @@ impl DentryChildren {
|
|||
}
|
||||
|
||||
/// Checks if a negative dentry with the given name exists.
|
||||
#[expect(dead_code)]
|
||||
fn contains_negative(&self, name: &str) -> bool {
|
||||
self.dentries.get(name).is_some_and(|child| child.is_none())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub use mount_namespace::MountNamespace;
|
|||
use crate::{
|
||||
fs::{
|
||||
inode_handle::InodeHandle,
|
||||
path::dentry::{Dentry, DentryKey},
|
||||
path::dentry::Dentry,
|
||||
utils::{
|
||||
CreationFlags, FileSystem, FsFlags, Inode, InodeMode, InodeType, Metadata, MknodType,
|
||||
OpenArgs, Permission, StatusFlags, XattrName, XattrNamespace, XattrSetFlags, NAME_MAX,
|
||||
|
|
@ -99,6 +99,23 @@ impl Path {
|
|||
Ok(target_path.get_top_path())
|
||||
}
|
||||
|
||||
/// Opens the `Path` with the given `OpenArgs`.
|
||||
///
|
||||
/// Returns an `InodeHandle` on success.
|
||||
pub fn open(&self, open_args: OpenArgs) -> Result<InodeHandle> {
|
||||
let inode = self.inode();
|
||||
check_open_util(inode.as_ref(), &open_args)?;
|
||||
|
||||
if inode.type_().is_regular_file()
|
||||
&& open_args.creation_flags.contains(CreationFlags::O_TRUNC)
|
||||
&& !open_args.status_flags.contains(StatusFlags::O_PATH)
|
||||
{
|
||||
self.resize(0)?;
|
||||
}
|
||||
|
||||
InodeHandle::new(self.clone(), open_args.access_mode, open_args.status_flags)
|
||||
}
|
||||
|
||||
/// Gets the absolute path.
|
||||
///
|
||||
/// It will resolve the mountpoint automatically.
|
||||
|
|
@ -195,6 +212,33 @@ impl Path {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks if the given `Inode` can be opened with the given `OpenArgs`.
|
||||
pub(super) fn check_open_util(inode: &dyn Inode, open_args: &OpenArgs) -> Result<()> {
|
||||
let inode_type = inode.type_();
|
||||
let creation_flags = &open_args.creation_flags;
|
||||
|
||||
if inode_type == InodeType::SymLink
|
||||
&& creation_flags.contains(CreationFlags::O_NOFOLLOW)
|
||||
&& !open_args.status_flags.contains(StatusFlags::O_PATH)
|
||||
{
|
||||
return_errno_with_message!(Errno::ELOOP, "the file is a symlink");
|
||||
}
|
||||
|
||||
if creation_flags.contains(CreationFlags::O_CREAT)
|
||||
&& creation_flags.contains(CreationFlags::O_EXCL)
|
||||
{
|
||||
return_errno_with_message!(Errno::EEXIST, "the file already exists");
|
||||
}
|
||||
if creation_flags.contains(CreationFlags::O_DIRECTORY) && inode_type != InodeType::Dir {
|
||||
return_errno_with_message!(
|
||||
Errno::ENOTDIR,
|
||||
"O_DIRECTORY is specified but the file is not a directory"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Path {
|
||||
/// Mounts a filesystem at the current path.
|
||||
///
|
||||
|
|
@ -394,6 +438,15 @@ impl Path {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Methods inherited from `Dentry`.
|
||||
#[inherit_methods(from = "self.dentry")]
|
||||
impl Path {
|
||||
pub fn inode(&self) -> &Arc<dyn Inode>;
|
||||
pub fn type_(&self) -> InodeType;
|
||||
pub fn unlink(&self, name: &str) -> Result<()>;
|
||||
pub fn rmdir(&self, name: &str) -> Result<()>;
|
||||
|
||||
/// Creates a `Path` by making an inode of the `type_` with the `mode`.
|
||||
pub fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result<Self> {
|
||||
|
|
@ -418,61 +471,15 @@ impl Path {
|
|||
|
||||
self.dentry.rename(old_name, &new_dir.dentry, new_name)
|
||||
}
|
||||
|
||||
/// Opens the `Path` with the given `OpenArgs`.
|
||||
///
|
||||
/// Returns an `InodeHandle` on success.
|
||||
pub fn open(&self, open_args: OpenArgs) -> Result<InodeHandle> {
|
||||
let inode = self.inode();
|
||||
check_open_util(inode.as_ref(), &open_args)?;
|
||||
|
||||
if inode.type_().is_regular_file()
|
||||
&& open_args.creation_flags.contains(CreationFlags::O_TRUNC)
|
||||
&& !open_args.status_flags.contains(StatusFlags::O_PATH)
|
||||
{
|
||||
self.resize(0)?;
|
||||
}
|
||||
|
||||
InodeHandle::new(self.clone(), open_args.access_mode, open_args.status_flags)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the given `Inode` can be opened with the given `OpenArgs`.
|
||||
pub fn check_open_util(inode: &dyn Inode, open_args: &OpenArgs) -> Result<()> {
|
||||
let inode_type = inode.type_();
|
||||
let creation_flags = &open_args.creation_flags;
|
||||
|
||||
if inode_type == InodeType::SymLink
|
||||
&& creation_flags.contains(CreationFlags::O_NOFOLLOW)
|
||||
&& !open_args.status_flags.contains(StatusFlags::O_PATH)
|
||||
{
|
||||
return_errno_with_message!(Errno::ELOOP, "the file is a symlink");
|
||||
}
|
||||
|
||||
if creation_flags.contains(CreationFlags::O_CREAT)
|
||||
&& creation_flags.contains(CreationFlags::O_EXCL)
|
||||
{
|
||||
return_errno_with_message!(Errno::EEXIST, "the file already exists");
|
||||
}
|
||||
if creation_flags.contains(CreationFlags::O_DIRECTORY) && inode_type != InodeType::Dir {
|
||||
return_errno_with_message!(
|
||||
Errno::ENOTDIR,
|
||||
"O_DIRECTORY is specified but the file is not a directory"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.dentry")]
|
||||
// Methods inherited from `Inode`.
|
||||
#[inherit_methods(from = "self.inode()")]
|
||||
impl Path {
|
||||
pub fn unlink(&self, name: &str) -> Result<()>;
|
||||
pub fn rmdir(&self, name: &str) -> Result<()>;
|
||||
pub fn fs(&self) -> Arc<dyn FileSystem>;
|
||||
pub fn sync_all(&self) -> Result<()>;
|
||||
pub fn sync_data(&self) -> Result<()>;
|
||||
pub fn metadata(&self) -> Metadata;
|
||||
pub fn type_(&self) -> InodeType;
|
||||
pub fn mode(&self) -> Result<InodeMode>;
|
||||
pub fn set_mode(&self, mode: InodeMode) -> Result<()>;
|
||||
pub fn size(&self) -> usize;
|
||||
|
|
@ -487,9 +494,6 @@ impl Path {
|
|||
pub fn set_mtime(&self, time: Duration);
|
||||
pub fn ctime(&self) -> Duration;
|
||||
pub fn set_ctime(&self, time: Duration);
|
||||
pub fn key(&self) -> DentryKey;
|
||||
pub fn inode(&self) -> &Arc<dyn Inode>;
|
||||
pub fn is_mountpoint(&self) -> bool;
|
||||
pub fn set_xattr(
|
||||
&self,
|
||||
name: XattrName,
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ impl Mount {
|
|||
|
||||
/// Attaches the mount node to the mountpoint.
|
||||
fn attach_to_path(&self, target_path: &Path) {
|
||||
let key = target_path.key();
|
||||
let key = target_path.dentry.key();
|
||||
target_path
|
||||
.mount_node()
|
||||
.children
|
||||
|
|
|
|||
Loading…
Reference in New Issue