xref: /DragonOS/kernel/src/filesystem/sysfs/dir.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
16b4e7a29SLoGin #![allow(dead_code)]
206d5e247SLoGin use alloc::{
306d5e247SLoGin     string::{String, ToString},
406d5e247SLoGin     sync::{Arc, Weak},
506d5e247SLoGin     vec::Vec,
606d5e247SLoGin };
7*91e9d4abSLoGin use system_error::SystemError;
86b4e7a29SLoGin 
906d5e247SLoGin use crate::{
1006d5e247SLoGin     driver::base::kobject::KObject,
1106d5e247SLoGin     filesystem::{
1206d5e247SLoGin         kernfs::{callback::KernInodePrivateData, KernFSInode},
1306d5e247SLoGin         vfs::syscall::ModeType,
1406d5e247SLoGin     },
1506d5e247SLoGin };
166b4e7a29SLoGin 
1706d5e247SLoGin use super::{SysFS, SysFSKernPrivateData};
186b4e7a29SLoGin 
196b4e7a29SLoGin #[derive(Debug)]
206b4e7a29SLoGin pub struct SysKernDirPriv {
2106d5e247SLoGin     /// 该目录对应的kobject
2206d5e247SLoGin     /// use weak reference to avoid cyclic reference
2306d5e247SLoGin     kobj: Weak<dyn KObject>,
2406d5e247SLoGin     // attribute_group: Option<&'static dyn AttributeGroup>,
256b4e7a29SLoGin }
266b4e7a29SLoGin 
276b4e7a29SLoGin impl SysKernDirPriv {
new(kobj: Arc<dyn KObject>) -> Self2806d5e247SLoGin     pub fn new(kobj: Arc<dyn KObject>) -> Self {
2906d5e247SLoGin         // let attribute_group = kobj.kobj_type().map(|kobj_type| kobj_type.attribute_groups()).flatten();
306b4e7a29SLoGin         Self {
3106d5e247SLoGin             kobj: Arc::downgrade(&kobj),
3206d5e247SLoGin             // attribute_group,
336b4e7a29SLoGin         }
346b4e7a29SLoGin     }
356b4e7a29SLoGin 
kobj(&self) -> Option<Arc<dyn KObject>>3606d5e247SLoGin     pub fn kobj(&self) -> Option<Arc<dyn KObject>> {
3706d5e247SLoGin         self.kobj.upgrade()
386b4e7a29SLoGin     }
396b4e7a29SLoGin 
4006d5e247SLoGin     // pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> {
4106d5e247SLoGin     //     self.attribute_group
4206d5e247SLoGin     // }
4306d5e247SLoGin }
4406d5e247SLoGin 
4506d5e247SLoGin impl SysFS {
4606d5e247SLoGin     /// 在sysfs中创建一个目录
4706d5e247SLoGin     ///
4806d5e247SLoGin     /// 如果kobj的parent为None,则会在根目录下创建一个目录。
4906d5e247SLoGin     ///
5006d5e247SLoGin     /// ## 参数
5106d5e247SLoGin     ///
5206d5e247SLoGin     /// - `kobj`: 要创建的目录对应的kobject
5306d5e247SLoGin     ///
5406d5e247SLoGin     /// ## 返回
5506d5e247SLoGin     ///
5606d5e247SLoGin     /// 返回创建的目录对应的inode
create_dir(&self, kobj: Arc<dyn KObject>) -> Result<Arc<KernFSInode>, SystemError>5706d5e247SLoGin     pub fn create_dir(&self, kobj: Arc<dyn KObject>) -> Result<Arc<KernFSInode>, SystemError> {
5806d5e247SLoGin         // 如果kobj的parent为None,则会在/sys目录下创建一个目录。
5906d5e247SLoGin         let parent = kobj
6006d5e247SLoGin             .parent()
6106d5e247SLoGin             .map(|p| p.upgrade().unwrap().inode())
6206d5e247SLoGin             .unwrap_or_else(|| Some(self.root_inode.clone()))
6306d5e247SLoGin             .ok_or(SystemError::ENOENT)?;
6406d5e247SLoGin 
6506d5e247SLoGin         let sysfs_dir_priv = SysFSKernPrivateData::Dir(SysKernDirPriv::new(kobj.clone()));
6606d5e247SLoGin         // 在kernfs里面创建一个目录
6706d5e247SLoGin         let dir: Arc<KernFSInode> = parent.add_dir(
6806d5e247SLoGin             kobj.name(),
6906d5e247SLoGin             ModeType::from_bits_truncate(0o755),
7006d5e247SLoGin             Some(KernInodePrivateData::SysFS(sysfs_dir_priv)),
7106d5e247SLoGin             None,
7206d5e247SLoGin         )?;
7306d5e247SLoGin 
7406d5e247SLoGin         kobj.set_inode(Some(dir.clone()));
7506d5e247SLoGin 
7606d5e247SLoGin         return Ok(dir);
7706d5e247SLoGin     }
7806d5e247SLoGin 
7906d5e247SLoGin     /// 获取指定的kernfs inode在sysfs中的路径(不包含`/sys`)
8006d5e247SLoGin     ///
8106d5e247SLoGin     /// ## 参数
8206d5e247SLoGin     ///
8306d5e247SLoGin     /// - `parent`: inode的父目录
8406d5e247SLoGin     /// - `name`: inode的名称
8506d5e247SLoGin     ///
8606d5e247SLoGin     /// ## 返回
8706d5e247SLoGin     ///
8806d5e247SLoGin     /// 返回inode在sysfs中的路径
kernfs_path(&self, parent: &Arc<KernFSInode>) -> String8906d5e247SLoGin     pub(super) fn kernfs_path(&self, parent: &Arc<KernFSInode>) -> String {
9006d5e247SLoGin         let mut p = parent.clone();
9106d5e247SLoGin         let mut parts = Vec::new();
9206d5e247SLoGin         let sys_root_inode = self.root_inode();
9306d5e247SLoGin         let mut not_reach_sys_root = false;
9406d5e247SLoGin         while !Arc::ptr_eq(&p, sys_root_inode) {
9506d5e247SLoGin             parts.push(p.name().to_string());
9606d5e247SLoGin             if let Some(parent) = p.parent() {
9706d5e247SLoGin                 p = parent;
9806d5e247SLoGin             } else {
9906d5e247SLoGin                 not_reach_sys_root = true;
10006d5e247SLoGin                 break;
10106d5e247SLoGin             }
10206d5e247SLoGin         }
10306d5e247SLoGin 
10406d5e247SLoGin         let mut path = String::new();
10506d5e247SLoGin         if not_reach_sys_root {
10606d5e247SLoGin             path.push_str("(null)");
10706d5e247SLoGin         };
10806d5e247SLoGin 
10906d5e247SLoGin         for part in parts.iter().rev() {
11006d5e247SLoGin             path.push('/');
11106d5e247SLoGin             path.push_str(part);
11206d5e247SLoGin         }
11306d5e247SLoGin 
11406d5e247SLoGin         return path;
11506d5e247SLoGin     }
11606d5e247SLoGin 
11706d5e247SLoGin     /// 从sysfs中删除一个kobject对应的目录(包括目录自身以及目录下的所有文件、文件夹)
remove_dir(&self, kobj: &Arc<dyn KObject>)11806d5e247SLoGin     pub fn remove_dir(&self, kobj: &Arc<dyn KObject>) {
11906d5e247SLoGin         let kobj_inode = kobj.inode();
12006d5e247SLoGin         kobj.set_inode(None);
12106d5e247SLoGin 
12206d5e247SLoGin         if let Some(inode) = kobj_inode {
12306d5e247SLoGin             let parent = inode.parent().unwrap();
12406d5e247SLoGin             parent.remove_recursive()
12506d5e247SLoGin         }
1266b4e7a29SLoGin     }
1276b4e7a29SLoGin }
128