mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 05:46:48 +00:00
Re-organize some systree-related code
This commit is contained in:
parent
a67bd8cdc9
commit
c56aee92f4
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -268,6 +268,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"component",
|
||||
"inherit-methods-macro",
|
||||
"ostd",
|
||||
"spin",
|
||||
]
|
||||
|
@ -9,6 +9,7 @@ edition = "2021"
|
||||
bitflags = "2.5"
|
||||
ostd = { path = "../../../ostd" }
|
||||
component = { path = "../../libs/comp-sys/component" }
|
||||
inherit-methods-macro = { git = "https://github.com/asterinas/inherit-methods-macro", rev = "98f7e3e"}
|
||||
spin = "0.9"
|
||||
|
||||
[lints]
|
||||
|
@ -37,9 +37,6 @@ pub struct SysAttr {
|
||||
name: SysStr,
|
||||
/// Flags defining the behavior and permissions of the attribute.
|
||||
flags: SysAttrFlags,
|
||||
// Potentially add read/write handler functions or trait objects later
|
||||
// read_handler: fn(...) -> Result<usize>,
|
||||
// write_handler: fn(...) -> Result<usize>,
|
||||
}
|
||||
|
||||
impl SysAttr {
|
||||
|
@ -7,7 +7,7 @@ use core::{
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
};
|
||||
|
||||
use ostd::mm::{VmReader, VmWriter};
|
||||
use ostd::mm::{FallibleVmWrite, VmReader, VmWriter};
|
||||
|
||||
use super::{Error, Result, SysAttrSet, SysStr};
|
||||
|
||||
@ -16,9 +16,9 @@ pub const MAX_ATTR_SIZE: usize = 4096;
|
||||
/// The three types of nodes in a `SysTree`.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SysNodeType {
|
||||
/// A branching node is one that may contain child nodes.
|
||||
/// A branching node is one that can have child nodes.
|
||||
Branch,
|
||||
/// A leaf node is one that may not contain child nodes.
|
||||
/// A leaf node is one that cannot have child nodes.
|
||||
Leaf,
|
||||
/// A symlink node,
|
||||
/// which ia a special kind of leaf node that points to another node,
|
||||
@ -27,6 +27,7 @@ pub enum SysNodeType {
|
||||
}
|
||||
|
||||
/// A trait that represents a branching node in a `SysTree`.
|
||||
#[expect(clippy::type_complexity)]
|
||||
pub trait SysBranchNode: SysNode {
|
||||
/// Visits a child node with the given name using a closure.
|
||||
///
|
||||
@ -49,7 +50,7 @@ pub trait SysBranchNode: SysNode {
|
||||
/// So the caller should do as little as possible inside the closure.
|
||||
/// In particular, the caller should _not_ invoke other methods
|
||||
/// on this object as this might cause deadlock.
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&dyn SysNode>));
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&Arc<dyn SysObj>>));
|
||||
|
||||
/// Visits child nodes with a minimum ID using a closure.
|
||||
///
|
||||
@ -75,7 +76,7 @@ pub trait SysBranchNode: SysNode {
|
||||
fn visit_children_with(
|
||||
&self,
|
||||
min_id: u64,
|
||||
f: &mut dyn for<'a> FnMut(&'a Arc<(dyn SysObj + 'static)>) -> Option<()>,
|
||||
f: &mut dyn for<'a> FnMut(&'a Arc<(dyn SysObj)>) -> Option<()>,
|
||||
);
|
||||
|
||||
/// Returns a child with a specified name.
|
||||
@ -182,18 +183,18 @@ pub trait SysObj: Any + Send + Sync + Debug + 'static {
|
||||
/// Returns a reference to this object as `Any` for downcasting.
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
/// Attempts to get an Arc to this object as a `SysSymlink`.
|
||||
fn arc_as_symlink(&self) -> Option<Arc<dyn SysSymlink>> {
|
||||
/// Casts this object to a trait object of `SysTree` symlink.
|
||||
fn cast_to_symlink(&self) -> Option<Arc<dyn SysSymlink>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Attempts to get an Arc to this object as a `SysNode`.
|
||||
fn arc_as_node(&self) -> Option<Arc<dyn SysNode>> {
|
||||
/// Casts this object to a trait object of a `SysTree` node.
|
||||
fn cast_to_node(&self) -> Option<Arc<dyn SysNode>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Attempts to get an Arc to this object as a `SysBranchNode`.
|
||||
fn arc_as_branch(&self) -> Option<Arc<dyn SysBranchNode>> {
|
||||
/// Casts this object to a trait object of a `SysTree` branch node.
|
||||
fn cast_to_branch(&self) -> Option<Arc<dyn SysBranchNode>> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -210,7 +211,7 @@ pub trait SysObj: Any + Send + Sync + Debug + 'static {
|
||||
///
|
||||
/// The root node of a `SysTree` has an empty name.
|
||||
/// All other inodes must have an non-empty name.
|
||||
fn name(&self) -> SysStr;
|
||||
fn name(&self) -> &SysStr;
|
||||
|
||||
/// Returns whether a node is the root of a `SysTree`.
|
||||
fn is_root(&self) -> bool {
|
||||
|
@ -6,22 +6,24 @@ use alloc::{
|
||||
sync::{Arc, Weak},
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{any::Any, fmt::Debug};
|
||||
use core::fmt::Debug;
|
||||
|
||||
use inherit_methods_macro::inherit_methods;
|
||||
use ostd::{
|
||||
mm::{FallibleVmRead, FallibleVmWrite, VmReader, VmWriter},
|
||||
prelude::ktest,
|
||||
};
|
||||
|
||||
use super::{
|
||||
Error, Result, SysAttrFlags, SysAttrSet, SysAttrSetBuilder, SysBranchNode, SysBranchNodeFields,
|
||||
SysNode, SysNodeId, SysNodeType, SysObj, SysStr, SysSymlink, SysTree,
|
||||
impl_cast_methods_for_branch, impl_cast_methods_for_symlink, Error, Result, SysAttrFlags,
|
||||
SysAttrSet, SysAttrSetBuilder, SysBranchNode, SysBranchNodeFields, SysNode, SysNodeId,
|
||||
SysNodeType, SysObj, SysStr, SysSymlink, SysTree,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DeviceNode {
|
||||
fields: SysBranchNodeFields<dyn SysObj>,
|
||||
self_ref: Weak<Self>,
|
||||
weak_self: Weak<Self>,
|
||||
}
|
||||
|
||||
impl DeviceNode {
|
||||
@ -41,38 +43,20 @@ impl DeviceNode {
|
||||
|
||||
Arc::new_cyclic(|weak_self| DeviceNode {
|
||||
fields,
|
||||
self_ref: weak_self.clone(),
|
||||
weak_self: weak_self.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SysObj for DeviceNode {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn arc_as_node(&self) -> Option<Arc<dyn SysNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysNode>)
|
||||
}
|
||||
|
||||
fn arc_as_branch(&self) -> Option<Arc<dyn SysBranchNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysBranchNode>)
|
||||
}
|
||||
impl_cast_methods_for_branch!();
|
||||
|
||||
fn id(&self) -> &SysNodeId {
|
||||
self.fields.id()
|
||||
}
|
||||
|
||||
fn type_(&self) -> SysNodeType {
|
||||
SysNodeType::Branch
|
||||
}
|
||||
|
||||
fn name(&self) -> SysStr {
|
||||
self.fields.name().to_string().into()
|
||||
fn name(&self) -> &SysStr {
|
||||
self.fields.name()
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,45 +113,13 @@ impl SysNode for DeviceNode {
|
||||
}
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.fields")]
|
||||
impl SysBranchNode for DeviceNode {
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&dyn SysNode>)) {
|
||||
let children = self.fields.children.read();
|
||||
children
|
||||
.get(name)
|
||||
.map(|child| {
|
||||
child
|
||||
.arc_as_node()
|
||||
.map(|node| f(Some(node.as_ref())))
|
||||
.unwrap_or_else(|| f(None))
|
||||
})
|
||||
.unwrap_or_else(|| f(None));
|
||||
}
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&Arc<dyn SysObj>>));
|
||||
|
||||
fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc<dyn SysObj>) -> Option<()>) {
|
||||
let children = self.fields.children.read();
|
||||
for child in children
|
||||
.values()
|
||||
.filter(|child| child.id().as_u64() >= min_id)
|
||||
{
|
||||
if f(child).is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc<dyn SysObj>) -> Option<()>);
|
||||
|
||||
fn child(&self, name: &str) -> Option<Arc<dyn SysObj>> {
|
||||
let children = self.fields.children.read();
|
||||
children.get(name).cloned()
|
||||
}
|
||||
|
||||
fn children(&self) -> Vec<Arc<dyn SysObj>> {
|
||||
let children = self.fields.children.read();
|
||||
children.values().cloned().collect()
|
||||
}
|
||||
|
||||
fn count_children(&self) -> usize {
|
||||
self.fields.children.read().len()
|
||||
}
|
||||
fn child(&self, name: &str) -> Option<Arc<dyn SysObj>>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -175,7 +127,7 @@ struct SymlinkNode {
|
||||
id: SysNodeId,
|
||||
name: SysStr,
|
||||
target: String,
|
||||
self_ref: Weak<Self>,
|
||||
weak_self: Weak<Self>,
|
||||
}
|
||||
|
||||
impl SymlinkNode {
|
||||
@ -184,32 +136,20 @@ impl SymlinkNode {
|
||||
id: SysNodeId::new(),
|
||||
name: name.to_string().into(),
|
||||
target: target.to_string(),
|
||||
self_ref: weak_self.clone(),
|
||||
weak_self: weak_self.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SysObj for SymlinkNode {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn arc_as_symlink(&self) -> Option<Arc<dyn SysSymlink>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysSymlink>)
|
||||
}
|
||||
impl_cast_methods_for_symlink!();
|
||||
|
||||
fn id(&self) -> &SysNodeId {
|
||||
&self.id
|
||||
}
|
||||
|
||||
fn type_(&self) -> SysNodeType {
|
||||
SysNodeType::Symlink
|
||||
}
|
||||
|
||||
fn name(&self) -> SysStr {
|
||||
self.name.clone()
|
||||
fn name(&self) -> &SysStr {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +170,7 @@ fn systree_singleton() {
|
||||
// Check if root node exists
|
||||
assert!(root.is_root());
|
||||
assert_eq!(root.name(), "");
|
||||
assert_eq!(root.type_(), SysNodeType::Leaf);
|
||||
assert_eq!(root.type_(), SysNodeType::Branch);
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
@ -309,7 +249,7 @@ fn symlinks() {
|
||||
|
||||
// Verify symlink was added correctly
|
||||
let symlink_obj = device.child("device_link").unwrap();
|
||||
let symlink_node = symlink_obj.arc_as_symlink().unwrap();
|
||||
let symlink_node = symlink_obj.cast_to_symlink().unwrap();
|
||||
assert_eq!(symlink_node.target_path(), "/sys/devices/device");
|
||||
}
|
||||
|
||||
|
@ -4,22 +4,18 @@
|
||||
|
||||
use alloc::{
|
||||
borrow::Cow,
|
||||
collections::BTreeMap,
|
||||
sync::{Arc, Weak},
|
||||
vec::Vec,
|
||||
};
|
||||
use core::any::Any;
|
||||
|
||||
use ostd::{
|
||||
mm::{VmReader, VmWriter},
|
||||
sync::RwLock,
|
||||
};
|
||||
use inherit_methods_macro::inherit_methods;
|
||||
use ostd::mm::{VmReader, VmWriter};
|
||||
|
||||
use super::{
|
||||
attr::SysAttrSet,
|
||||
node::{SysBranchNode, SysNode, SysNodeId, SysNodeType, SysObj, SysSymlink},
|
||||
node::{SysBranchNode, SysNode, SysNodeId, SysNodeType, SysObj},
|
||||
Error, Result, SysStr,
|
||||
};
|
||||
use crate::{impl_cast_methods_for_branch, SysBranchNodeFields};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SysTree {
|
||||
@ -32,12 +28,13 @@ impl SysTree {
|
||||
/// and standard subdirectories like "devices", "block", "kernel".
|
||||
/// This is intended to be called once for the singleton.
|
||||
pub(crate) fn new() -> Self {
|
||||
let name = ""; // Only the root has an empty name
|
||||
let attr_set = SysAttrSet::new_empty(); // The root has no attributes
|
||||
let fields = SysBranchNodeFields::new(SysStr::from(name), attr_set);
|
||||
|
||||
let root_node = Arc::new_cyclic(|weak_self| RootNode {
|
||||
id: SysNodeId::new(),
|
||||
name: "".into(),
|
||||
attrs: SysAttrSet::new_empty(),
|
||||
children: RwLock::new(BTreeMap::new()),
|
||||
self_ref: weak_self.clone(),
|
||||
fields,
|
||||
weak_self: weak_self.clone(),
|
||||
});
|
||||
|
||||
Self { root: root_node }
|
||||
@ -49,22 +46,22 @@ impl SysTree {
|
||||
}
|
||||
}
|
||||
|
||||
/// The root node in the `SysTree`.
|
||||
///
|
||||
/// A `RootNode` can work like a branching node, allowing to add additional nodes
|
||||
/// as its children.
|
||||
#[derive(Debug)]
|
||||
pub struct RootNode {
|
||||
id: SysNodeId,
|
||||
name: SysStr,
|
||||
attrs: SysAttrSet,
|
||||
children: RwLock<BTreeMap<SysStr, Arc<dyn SysObj>>>,
|
||||
self_ref: Weak<Self>,
|
||||
fields: SysBranchNodeFields<dyn SysObj>,
|
||||
weak_self: Weak<Self>,
|
||||
}
|
||||
|
||||
impl RootNode {
|
||||
/// Adds a child node. This was part of the concrete RootNode impl in lib.rs.
|
||||
/// It's not part of the SysBranchNode trait definition.
|
||||
/// Adds a child node to this `RootNode`.
|
||||
pub fn add_child(&self, new_child: Arc<dyn SysObj>) -> Result<()> {
|
||||
let name = new_child.name();
|
||||
let mut children_guard = self.children.write();
|
||||
if children_guard.contains_key(&name) {
|
||||
let mut children_guard = self.fields.children.write();
|
||||
if children_guard.contains_key(name) {
|
||||
return Err(Error::PermissionDenied);
|
||||
}
|
||||
children_guard.insert(name.clone(), new_child);
|
||||
@ -72,41 +69,13 @@ impl RootNode {
|
||||
}
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.fields")]
|
||||
impl SysObj for RootNode {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
impl_cast_methods_for_branch!();
|
||||
|
||||
fn arc_as_symlink(&self) -> Option<Arc<dyn SysSymlink>> {
|
||||
None
|
||||
}
|
||||
fn id(&self) -> &SysNodeId;
|
||||
|
||||
fn arc_as_node(&self) -> Option<Arc<dyn SysNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysNode>)
|
||||
}
|
||||
|
||||
fn arc_as_branch(&self) -> Option<Arc<dyn SysBranchNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysBranchNode>)
|
||||
}
|
||||
|
||||
fn id(&self) -> &SysNodeId {
|
||||
&self.id
|
||||
}
|
||||
|
||||
fn type_(&self) -> SysNodeType {
|
||||
if self.children.read().is_empty() {
|
||||
return SysNodeType::Leaf;
|
||||
}
|
||||
SysNodeType::Branch
|
||||
}
|
||||
|
||||
fn name(&self) -> SysStr {
|
||||
self.name.clone()
|
||||
}
|
||||
fn name(&self) -> &SysStr;
|
||||
|
||||
fn is_root(&self) -> bool {
|
||||
true
|
||||
@ -119,7 +88,7 @@ impl SysObj for RootNode {
|
||||
|
||||
impl SysNode for RootNode {
|
||||
fn node_attrs(&self) -> &SysAttrSet {
|
||||
&self.attrs
|
||||
self.fields.attr_set()
|
||||
}
|
||||
|
||||
fn read_attr(&self, _name: &str, _writer: &mut VmWriter) -> Result<usize> {
|
||||
@ -131,35 +100,11 @@ impl SysNode for RootNode {
|
||||
}
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.fields")]
|
||||
impl SysBranchNode for RootNode {
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&dyn SysNode>)) {
|
||||
let children_guard = self.children.read();
|
||||
children_guard
|
||||
.get(name)
|
||||
.map(|child| {
|
||||
if let Some(node_ref) = child.arc_as_node().as_deref() {
|
||||
f(Some(node_ref));
|
||||
} else {
|
||||
f(None);
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| f(None));
|
||||
}
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&Arc<dyn SysObj>>));
|
||||
|
||||
fn visit_children_with(&self, _min_id: u64, f: &mut dyn FnMut(&Arc<dyn SysObj>) -> Option<()>) {
|
||||
let children_guard = self.children.read();
|
||||
for child_arc in children_guard.values() {
|
||||
if f(child_arc).is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn visit_children_with(&self, _min_id: u64, f: &mut dyn FnMut(&Arc<dyn SysObj>) -> Option<()>);
|
||||
|
||||
fn child(&self, name: &str) -> Option<Arc<dyn SysObj>> {
|
||||
self.children.read().get(name).cloned()
|
||||
}
|
||||
|
||||
fn children(&self) -> Vec<Arc<dyn SysObj>> {
|
||||
self.children.read().values().cloned().collect()
|
||||
}
|
||||
fn child(&self, name: &str) -> Option<Arc<dyn SysObj>>;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
//! Utility definitions and helper structs for implementing `SysTree` nodes.
|
||||
|
||||
use alloc::{collections::BTreeMap, string::String, sync::Arc};
|
||||
use core::ops::Deref;
|
||||
|
||||
use ostd::sync::RwLock;
|
||||
|
||||
@ -31,8 +30,8 @@ impl SysObjFields {
|
||||
&self.id
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
self.name.deref()
|
||||
pub fn name(&self) -> &SysStr {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +53,7 @@ impl SysNormalNodeFields {
|
||||
self.base.id()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(&self) -> &SysStr {
|
||||
self.base.name()
|
||||
}
|
||||
|
||||
@ -81,7 +80,7 @@ impl<C: SysObj + ?Sized> SysBranchNodeFields<C> {
|
||||
self.base.id()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(&self) -> &SysStr {
|
||||
self.base.name()
|
||||
}
|
||||
|
||||
@ -97,7 +96,7 @@ impl<C: SysObj + ?Sized> SysBranchNodeFields<C> {
|
||||
pub fn add_child(&self, new_child: Arc<C>) -> Result<()> {
|
||||
let mut children = self.children.write();
|
||||
let name = new_child.name();
|
||||
if children.contains_key(name.deref()) {
|
||||
if children.contains_key(name) {
|
||||
return Err(Error::PermissionDenied);
|
||||
}
|
||||
children.insert(name.clone(), new_child);
|
||||
@ -108,6 +107,29 @@ impl<C: SysObj + ?Sized> SysBranchNodeFields<C> {
|
||||
let mut children = self.children.write();
|
||||
children.remove(child_name)
|
||||
}
|
||||
|
||||
pub fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&Arc<C>>)) {
|
||||
let children_guard = self.children.read();
|
||||
f(children_guard.get(name))
|
||||
}
|
||||
|
||||
pub fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc<C>) -> Option<()>) {
|
||||
let children_guard = self.children.read();
|
||||
for child_arc in children_guard.values() {
|
||||
if child_arc.id().as_u64() < min_id {
|
||||
continue;
|
||||
}
|
||||
|
||||
if f(child_arc).is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn child(&self, name: &str) -> Option<Arc<C>> {
|
||||
let children = self.children.read();
|
||||
children.get(name).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -128,7 +150,7 @@ impl SymlinkNodeFields {
|
||||
self.base.id()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(&self) -> &SysStr {
|
||||
self.base.name()
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ impl SysFsInode {
|
||||
match child_type {
|
||||
SysNodeType::Branch => {
|
||||
let child_branch = child_sysnode
|
||||
.arc_as_branch()
|
||||
.cast_to_branch()
|
||||
.ok_or(Error::new(Errno::EIO))?;
|
||||
let inode = Self::new_branch_dir(
|
||||
self.systree,
|
||||
@ -202,7 +202,7 @@ impl SysFsInode {
|
||||
}
|
||||
SysNodeType::Leaf => {
|
||||
let child_leaf_node =
|
||||
child_sysnode.arc_as_node().ok_or(Error::new(Errno::EIO))?;
|
||||
child_sysnode.cast_to_node().ok_or(Error::new(Errno::EIO))?;
|
||||
let inode = Self::new_leaf_dir(
|
||||
self.systree,
|
||||
InnerNode::Leaf(child_leaf_node),
|
||||
@ -212,7 +212,7 @@ impl SysFsInode {
|
||||
}
|
||||
SysNodeType::Symlink => {
|
||||
let child_symlink = child_sysnode
|
||||
.arc_as_symlink()
|
||||
.cast_to_symlink()
|
||||
.ok_or(Error::new(Errno::EIO))?;
|
||||
let inode = Self::new_symlink(
|
||||
self.systree,
|
||||
@ -646,7 +646,7 @@ impl Iterator for NodeDentryIter {
|
||||
};
|
||||
return Some(Dentry {
|
||||
ino: obj_ino,
|
||||
name: obj.name(),
|
||||
name: obj.name().clone(),
|
||||
type_,
|
||||
});
|
||||
}
|
||||
|
@ -9,13 +9,15 @@ use alloc::{
|
||||
vec,
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{any::Any, fmt::Debug};
|
||||
use core::fmt::Debug;
|
||||
|
||||
use aster_systree::{
|
||||
impl_cast_methods_for_branch, impl_cast_methods_for_node, impl_cast_methods_for_symlink,
|
||||
init_for_ktest, singleton as systree_singleton, Error as SysTreeError, Result as SysTreeResult,
|
||||
SysAttrFlags, SysAttrSet, SysAttrSetBuilder, SysBranchNode, SysBranchNodeFields, SysNode,
|
||||
SysNodeId, SysNodeType, SysNormalNodeFields, SysObj, SysStr, SysSymlink, SysTree,
|
||||
};
|
||||
use inherit_methods_macro::inherit_methods;
|
||||
use ostd::{
|
||||
mm::{FallibleVmRead, FallibleVmWrite, VmReader, VmWriter},
|
||||
prelude::ktest,
|
||||
@ -40,7 +42,7 @@ use crate::{
|
||||
struct MockLeafNode {
|
||||
fields: SysNormalNodeFields,
|
||||
data: RwLock<BTreeMap<String, String>>, // Store attribute data
|
||||
self_ref: Weak<Self>,
|
||||
weak_self: Weak<Self>,
|
||||
}
|
||||
|
||||
impl MockLeafNode {
|
||||
@ -67,28 +69,20 @@ impl MockLeafNode {
|
||||
Arc::new_cyclic(|weak_self| MockLeafNode {
|
||||
fields,
|
||||
data: RwLock::new(data),
|
||||
self_ref: weak_self.clone(),
|
||||
weak_self: weak_self.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SysObj for MockLeafNode {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn arc_as_node(&self) -> Option<Arc<dyn SysNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysNode>)
|
||||
}
|
||||
impl_cast_methods_for_node!();
|
||||
|
||||
fn id(&self) -> &SysNodeId {
|
||||
self.fields.id()
|
||||
}
|
||||
fn type_(&self) -> SysNodeType {
|
||||
SysNodeType::Leaf
|
||||
}
|
||||
fn name(&self) -> SysStr {
|
||||
Cow::Owned(self.fields.name().to_string()) // Convert to Cow::Owned
|
||||
|
||||
fn name(&self) -> &SysStr {
|
||||
self.fields.name()
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +137,7 @@ impl SysNode for MockLeafNode {
|
||||
#[derive(Debug)]
|
||||
struct MockBranchNode {
|
||||
fields: SysBranchNodeFields<dyn SysObj>,
|
||||
self_ref: Weak<Self>,
|
||||
weak_self: Weak<Self>,
|
||||
}
|
||||
|
||||
impl MockBranchNode {
|
||||
@ -160,7 +154,7 @@ impl MockBranchNode {
|
||||
|
||||
Arc::new_cyclic(|weak_self| MockBranchNode {
|
||||
fields,
|
||||
self_ref: weak_self.clone(),
|
||||
weak_self: weak_self.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -170,27 +164,14 @@ impl MockBranchNode {
|
||||
}
|
||||
|
||||
impl SysObj for MockBranchNode {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn arc_as_node(&self) -> Option<Arc<dyn SysNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysNode>)
|
||||
}
|
||||
fn arc_as_branch(&self) -> Option<Arc<dyn SysBranchNode>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysBranchNode>)
|
||||
}
|
||||
impl_cast_methods_for_branch!();
|
||||
|
||||
fn id(&self) -> &SysNodeId {
|
||||
self.fields.id()
|
||||
}
|
||||
fn type_(&self) -> SysNodeType {
|
||||
SysNodeType::Branch
|
||||
}
|
||||
fn name(&self) -> SysStr {
|
||||
Cow::Owned(self.fields.name().to_string()) // Convert to Cow::Owned
|
||||
|
||||
fn name(&self) -> &SysStr {
|
||||
self.fields.name()
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,41 +213,13 @@ impl SysNode for MockBranchNode {
|
||||
}
|
||||
}
|
||||
|
||||
#[inherit_methods(from = "self.fields")]
|
||||
impl SysBranchNode for MockBranchNode {
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&dyn SysNode>)) {
|
||||
self.fields
|
||||
.children
|
||||
.read()
|
||||
.get(name)
|
||||
.map(|child| {
|
||||
child
|
||||
.arc_as_node()
|
||||
.map(|node| f(Some(node.as_ref())))
|
||||
.unwrap_or_else(|| f(None));
|
||||
})
|
||||
.unwrap_or_else(|| f(None));
|
||||
}
|
||||
fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&Arc<dyn SysObj>>));
|
||||
|
||||
fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc<dyn SysObj>) -> Option<()>) {
|
||||
let children = self.fields.children.read();
|
||||
for child in children
|
||||
.values()
|
||||
.filter(|child| child.id().as_u64() >= min_id)
|
||||
{
|
||||
if f(child).is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc<dyn SysObj>) -> Option<()>);
|
||||
|
||||
fn child(&self, name: &str) -> Option<Arc<dyn SysObj>> {
|
||||
let children = self.fields.children.read();
|
||||
children.get(name).cloned()
|
||||
}
|
||||
|
||||
fn children(&self) -> Vec<Arc<dyn SysObj>> {
|
||||
self.fields.children.read().values().cloned().collect()
|
||||
}
|
||||
fn child(&self, name: &str) -> Option<Arc<dyn SysObj>>;
|
||||
}
|
||||
|
||||
// Mock Symlink
|
||||
@ -275,7 +228,7 @@ struct MockSymlinkNode {
|
||||
id: SysNodeId,
|
||||
name: SysStr,
|
||||
target: String,
|
||||
self_ref: Weak<Self>,
|
||||
weak_self: Weak<Self>,
|
||||
}
|
||||
|
||||
impl MockSymlinkNode {
|
||||
@ -284,28 +237,20 @@ impl MockSymlinkNode {
|
||||
id: SysNodeId::new(),
|
||||
name: name.to_string().into(),
|
||||
target: target.to_string(),
|
||||
self_ref: weak_self.clone(),
|
||||
weak_self: weak_self.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SysObj for MockSymlinkNode {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn arc_as_symlink(&self) -> Option<Arc<dyn SysSymlink>> {
|
||||
self.self_ref
|
||||
.upgrade()
|
||||
.map(|arc_self| arc_self as Arc<dyn SysSymlink>)
|
||||
}
|
||||
impl_cast_methods_for_symlink!();
|
||||
|
||||
fn id(&self) -> &SysNodeId {
|
||||
&self.id
|
||||
}
|
||||
fn type_(&self) -> SysNodeType {
|
||||
SysNodeType::Symlink
|
||||
}
|
||||
fn name(&self) -> SysStr {
|
||||
self.name.clone()
|
||||
|
||||
fn name(&self) -> &SysStr {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user