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