From c56aee92f4b22f7dfa16643bd96ac3aae04f84d5 Mon Sep 17 00:00:00 2001 From: Chen Chengjun Date: Thu, 5 Jun 2025 03:06:51 +0000 Subject: [PATCH] Re-organize some systree-related code --- Cargo.lock | 1 + kernel/comps/systree/Cargo.toml | 1 + kernel/comps/systree/src/attr.rs | 3 - kernel/comps/systree/src/node.rs | 25 +++---- kernel/comps/systree/src/test.rs | 102 ++++++--------------------- kernel/comps/systree/src/tree.rs | 111 ++++++++---------------------- kernel/comps/systree/src/utils.rs | 36 ++++++++-- kernel/src/fs/sysfs/inode.rs | 8 +-- kernel/src/fs/sysfs/test.rs | 111 ++++++++---------------------- 9 files changed, 125 insertions(+), 273 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08d4db819..a940661b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -268,6 +268,7 @@ version = "0.1.0" dependencies = [ "bitflags 2.9.0", "component", + "inherit-methods-macro", "ostd", "spin", ] diff --git a/kernel/comps/systree/Cargo.toml b/kernel/comps/systree/Cargo.toml index 868259ceb..fd0c5c42d 100644 --- a/kernel/comps/systree/Cargo.toml +++ b/kernel/comps/systree/Cargo.toml @@ -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] diff --git a/kernel/comps/systree/src/attr.rs b/kernel/comps/systree/src/attr.rs index a30d3ea08..e9dd78ef8 100644 --- a/kernel/comps/systree/src/attr.rs +++ b/kernel/comps/systree/src/attr.rs @@ -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, - // write_handler: fn(...) -> Result, } impl SysAttr { diff --git a/kernel/comps/systree/src/node.rs b/kernel/comps/systree/src/node.rs index a3dc515c1..0680caa78 100644 --- a/kernel/comps/systree/src/node.rs +++ b/kernel/comps/systree/src/node.rs @@ -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>)); /// 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> { + /// Casts this object to a trait object of `SysTree` symlink. + fn cast_to_symlink(&self) -> Option> { None } - /// Attempts to get an Arc to this object as a `SysNode`. - fn arc_as_node(&self) -> Option> { + /// Casts this object to a trait object of a `SysTree` node. + fn cast_to_node(&self) -> Option> { None } - /// Attempts to get an Arc to this object as a `SysBranchNode`. - fn arc_as_branch(&self) -> Option> { + /// Casts this object to a trait object of a `SysTree` branch node. + fn cast_to_branch(&self) -> Option> { 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 { diff --git a/kernel/comps/systree/src/test.rs b/kernel/comps/systree/src/test.rs index 5fb5242b0..3c3110314 100644 --- a/kernel/comps/systree/src/test.rs +++ b/kernel/comps/systree/src/test.rs @@ -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, - self_ref: Weak, + weak_self: Weak, } 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> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } - - fn arc_as_branch(&self) -> Option> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } + 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>)); - fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc) -> 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) -> Option<()>); - fn child(&self, name: &str) -> Option> { - let children = self.fields.children.read(); - children.get(name).cloned() - } - - fn children(&self) -> Vec> { - 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>; } #[derive(Debug)] @@ -175,7 +127,7 @@ struct SymlinkNode { id: SysNodeId, name: SysStr, target: String, - self_ref: Weak, + weak_self: Weak, } 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> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } + 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"); } diff --git a/kernel/comps/systree/src/tree.rs b/kernel/comps/systree/src/tree.rs index 76066de84..6cd1a3600 100644 --- a/kernel/comps/systree/src/tree.rs +++ b/kernel/comps/systree/src/tree.rs @@ -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>>, - self_ref: Weak, + fields: SysBranchNodeFields, + weak_self: Weak, } 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) -> 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> { - None - } + fn id(&self) -> &SysNodeId; - fn arc_as_node(&self) -> Option> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } - - fn arc_as_branch(&self) -> Option> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } - - 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 { @@ -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>)); - fn visit_children_with(&self, _min_id: u64, f: &mut dyn FnMut(&Arc) -> 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) -> Option<()>); - fn child(&self, name: &str) -> Option> { - self.children.read().get(name).cloned() - } - - fn children(&self) -> Vec> { - self.children.read().values().cloned().collect() - } + fn child(&self, name: &str) -> Option>; } diff --git a/kernel/comps/systree/src/utils.rs b/kernel/comps/systree/src/utils.rs index 45fa88596..ad4f4b1c5 100644 --- a/kernel/comps/systree/src/utils.rs +++ b/kernel/comps/systree/src/utils.rs @@ -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 SysBranchNodeFields { self.base.id() } - pub fn name(&self) -> &str { + pub fn name(&self) -> &SysStr { self.base.name() } @@ -97,7 +96,7 @@ impl SysBranchNodeFields { pub fn add_child(&self, new_child: Arc) -> 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 SysBranchNodeFields { let mut children = self.children.write(); children.remove(child_name) } + + pub fn visit_child_with(&self, name: &str, f: &mut dyn FnMut(Option<&Arc>)) { + 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) -> 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> { + 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() } diff --git a/kernel/src/fs/sysfs/inode.rs b/kernel/src/fs/sysfs/inode.rs index 21b3d23eb..8d703b515 100644 --- a/kernel/src/fs/sysfs/inode.rs +++ b/kernel/src/fs/sysfs/inode.rs @@ -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_, }); } diff --git a/kernel/src/fs/sysfs/test.rs b/kernel/src/fs/sysfs/test.rs index b0c2e40b3..c0666c52d 100644 --- a/kernel/src/fs/sysfs/test.rs +++ b/kernel/src/fs/sysfs/test.rs @@ -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>, // Store attribute data - self_ref: Weak, + weak_self: Weak, } 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> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } + 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, - self_ref: Weak, + weak_self: Weak, } 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> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } - fn arc_as_branch(&self) -> Option> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } + 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>)); - fn visit_children_with(&self, min_id: u64, f: &mut dyn FnMut(&Arc) -> 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) -> Option<()>); - fn child(&self, name: &str) -> Option> { - let children = self.fields.children.read(); - children.get(name).cloned() - } - - fn children(&self) -> Vec> { - self.fields.children.read().values().cloned().collect() - } + fn child(&self, name: &str) -> Option>; } // Mock Symlink @@ -275,7 +228,7 @@ struct MockSymlinkNode { id: SysNodeId, name: SysStr, target: String, - self_ref: Weak, + weak_self: Weak, } 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> { - self.self_ref - .upgrade() - .map(|arc_self| arc_self as Arc) - } + 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 } }