1 use alloc::{ 2 borrow::ToOwned, 3 string::{String, ToString}, 4 sync::Arc, 5 }; 6 use system_error::SystemError; 7 8 use crate::{driver::base::kobject::KObject, filesystem::kernfs::KernFSInode}; 9 10 use super::SysFS; 11 12 impl SysFS { 13 /// 在sysfs中创建一个符号链接 14 /// 15 /// ## 参数 16 /// 17 /// - `kobj`: object whose directory we're creating the link in. (符号链接所在目录) 18 /// 如果为None,则创建在sysfs的根目录下 19 /// - `target`: object we're pointing to. 20 /// - `name`: 符号链接的名称 21 /// 22 /// 参考:https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#89 23 pub fn create_link( 24 &self, 25 kobj: Option<&Arc<dyn KObject>>, 26 target: &Arc<dyn KObject>, 27 name: String, 28 ) -> Result<(), SystemError> { 29 return self.do_create_link(kobj, target, name, true); 30 } 31 32 /// 在sysfs中删除一个符号链接 33 /// 34 /// ## 参数 35 /// 36 /// - `kobj`: 要删除符号链接的kobject(符号链接所在目录) 37 /// - `name`: 符号链接的名称 38 /// 39 /// 40 /// 参考:https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#143 41 pub fn remove_link(&self, _kobj: &Arc<dyn KObject>, _name: String) { 42 todo!("sysfs remove link") 43 } 44 45 fn do_create_link( 46 &self, 47 kobj: Option<&Arc<dyn KObject>>, 48 target: &Arc<dyn KObject>, 49 name: String, 50 warn: bool, 51 ) -> Result<(), SystemError> { 52 let parent = if let Some(kobj) = kobj { 53 kobj.inode() 54 } else { 55 Some(self.root_inode().clone()) 56 }; 57 58 // 没有parent,返回错误 59 let parent = parent.ok_or(SystemError::EFAULT)?; 60 return self.do_create_link_sd(&parent, target, name, warn); 61 } 62 63 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#20 64 fn do_create_link_sd( 65 &self, 66 inode: &Arc<KernFSInode>, 67 target: &Arc<dyn KObject>, 68 name: String, 69 warn: bool, 70 ) -> Result<(), SystemError> { 71 let target_inode = target.inode().ok_or(SystemError::ENOENT)?; 72 73 let target_abs_path = "/sys".to_string() + &self.kernfs_path(&target_inode).to_owned(); 74 // let current_path = self.kernfs_path(inode); 75 // debug!("sysfs: create link {} to {}", current_path, target_abs_path); 76 77 let kn = inode.add_link(name.clone(), &target_inode, target_abs_path); 78 if kn.is_ok() { 79 return Ok(()); 80 } 81 let err = kn.unwrap_err(); 82 if warn && err == SystemError::EEXIST { 83 self.warn_duplicate(inode, &name); 84 } 85 return Err(err); 86 } 87 88 /// sysfs_create_link_sd - create symlink to a given object. 89 /// 90 /// ## 参数 91 /// 92 /// - `inode`: 目录inode,在这个目录下创建符号链接 93 /// - `target`: object we're pointing to. 94 /// - `name`: 符号链接的名称 95 #[allow(dead_code)] 96 pub(super) fn create_link_sd( 97 &self, 98 inode: &Arc<KernFSInode>, 99 target: &Arc<dyn KObject>, 100 name: String, 101 ) -> Result<(), SystemError> { 102 return self.do_create_link_sd(inode, target, name, true); 103 } 104 } 105