1 #![allow(dead_code)] 2 use alloc::{ 3 string::{String, ToString}, 4 sync::{Arc, Weak}, 5 vec::Vec, 6 }; 7 8 use crate::{ 9 driver::base::kobject::KObject, 10 filesystem::{ 11 kernfs::{callback::KernInodePrivateData, KernFSInode}, 12 vfs::syscall::ModeType, 13 }, 14 syscall::SystemError, 15 }; 16 17 use super::{SysFS, SysFSKernPrivateData}; 18 19 #[derive(Debug)] 20 pub struct SysKernDirPriv { 21 /// 该目录对应的kobject 22 /// use weak reference to avoid cyclic reference 23 kobj: Weak<dyn KObject>, 24 // attribute_group: Option<&'static dyn AttributeGroup>, 25 } 26 27 impl SysKernDirPriv { 28 pub fn new(kobj: Arc<dyn KObject>) -> Self { 29 // let attribute_group = kobj.kobj_type().map(|kobj_type| kobj_type.attribute_groups()).flatten(); 30 Self { 31 kobj: Arc::downgrade(&kobj), 32 // attribute_group, 33 } 34 } 35 36 pub fn kobj(&self) -> Option<Arc<dyn KObject>> { 37 self.kobj.upgrade() 38 } 39 40 // pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> { 41 // self.attribute_group 42 // } 43 } 44 45 impl SysFS { 46 /// 在sysfs中创建一个目录 47 /// 48 /// 如果kobj的parent为None,则会在根目录下创建一个目录。 49 /// 50 /// ## 参数 51 /// 52 /// - `kobj`: 要创建的目录对应的kobject 53 /// 54 /// ## 返回 55 /// 56 /// 返回创建的目录对应的inode 57 pub fn create_dir(&self, kobj: Arc<dyn KObject>) -> Result<Arc<KernFSInode>, SystemError> { 58 // 如果kobj的parent为None,则会在/sys目录下创建一个目录。 59 let parent = kobj 60 .parent() 61 .map(|p| p.upgrade().unwrap().inode()) 62 .unwrap_or_else(|| Some(self.root_inode.clone())) 63 .ok_or(SystemError::ENOENT)?; 64 65 let sysfs_dir_priv = SysFSKernPrivateData::Dir(SysKernDirPriv::new(kobj.clone())); 66 // 在kernfs里面创建一个目录 67 let dir: Arc<KernFSInode> = parent.add_dir( 68 kobj.name(), 69 ModeType::from_bits_truncate(0o755), 70 Some(KernInodePrivateData::SysFS(sysfs_dir_priv)), 71 None, 72 )?; 73 74 kobj.set_inode(Some(dir.clone())); 75 76 return Ok(dir); 77 } 78 79 /// 获取指定的kernfs inode在sysfs中的路径(不包含`/sys`) 80 /// 81 /// ## 参数 82 /// 83 /// - `parent`: inode的父目录 84 /// - `name`: inode的名称 85 /// 86 /// ## 返回 87 /// 88 /// 返回inode在sysfs中的路径 89 pub(super) fn kernfs_path(&self, parent: &Arc<KernFSInode>) -> String { 90 let mut p = parent.clone(); 91 let mut parts = Vec::new(); 92 let sys_root_inode = self.root_inode(); 93 let mut not_reach_sys_root = false; 94 while !Arc::ptr_eq(&p, sys_root_inode) { 95 parts.push(p.name().to_string()); 96 if let Some(parent) = p.parent() { 97 p = parent; 98 } else { 99 not_reach_sys_root = true; 100 break; 101 } 102 } 103 104 let mut path = String::new(); 105 if not_reach_sys_root { 106 path.push_str("(null)"); 107 }; 108 109 for part in parts.iter().rev() { 110 path.push('/'); 111 path.push_str(part); 112 } 113 114 return path; 115 } 116 117 /// 从sysfs中删除一个kobject对应的目录(包括目录自身以及目录下的所有文件、文件夹) 118 pub fn remove_dir(&self, kobj: &Arc<dyn KObject>) { 119 let kobj_inode = kobj.inode(); 120 kobj.set_inode(None); 121 122 if let Some(inode) = kobj_inode { 123 let parent = inode.parent().unwrap(); 124 parent.remove_recursive() 125 } 126 } 127 } 128