1*a03c4f9dSLoGin use alloc::{ 2*a03c4f9dSLoGin borrow::ToOwned, 3*a03c4f9dSLoGin string::{String, ToString}, 4*a03c4f9dSLoGin sync::Arc, 5*a03c4f9dSLoGin }; 606d5e247SLoGin 7*a03c4f9dSLoGin use crate::{ 8*a03c4f9dSLoGin driver::base::kobject::KObject, filesystem::kernfs::KernFSInode, syscall::SystemError, 9*a03c4f9dSLoGin }; 1006d5e247SLoGin 1106d5e247SLoGin use super::SysFS; 1206d5e247SLoGin 1306d5e247SLoGin impl SysFS { 1406d5e247SLoGin /// 在sysfs中创建一个符号链接 1506d5e247SLoGin /// 1606d5e247SLoGin /// ## 参数 1706d5e247SLoGin /// 18*a03c4f9dSLoGin /// - `kobj`: object whose directory we're creating the link in. (符号链接所在目录) 19*a03c4f9dSLoGin /// 如果为None,则创建在sysfs的根目录下 20*a03c4f9dSLoGin /// - `target`: object we're pointing to. 2106d5e247SLoGin /// - `name`: 符号链接的名称 2206d5e247SLoGin /// 2306d5e247SLoGin /// 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#89 2406d5e247SLoGin pub fn create_link( 2506d5e247SLoGin &self, 26*a03c4f9dSLoGin kobj: Option<&Arc<dyn KObject>>, 27*a03c4f9dSLoGin target: &Arc<dyn KObject>, 28*a03c4f9dSLoGin name: String, 2906d5e247SLoGin ) -> Result<(), SystemError> { 30*a03c4f9dSLoGin return self.do_create_link(kobj, target, name, true); 3106d5e247SLoGin } 3206d5e247SLoGin 3306d5e247SLoGin /// 在sysfs中删除一个符号链接 3406d5e247SLoGin /// 3506d5e247SLoGin /// ## 参数 3606d5e247SLoGin /// 3706d5e247SLoGin /// - `kobj`: 要删除符号链接的kobject(符号链接所在目录) 3806d5e247SLoGin /// - `name`: 符号链接的名称 3906d5e247SLoGin /// 4006d5e247SLoGin /// 4106d5e247SLoGin /// 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#143 42*a03c4f9dSLoGin pub fn remove_link(&self, _kobj: &Arc<dyn KObject>, _name: String) { 4306d5e247SLoGin todo!("sysfs remove link") 4406d5e247SLoGin } 45*a03c4f9dSLoGin 46*a03c4f9dSLoGin fn do_create_link( 47*a03c4f9dSLoGin &self, 48*a03c4f9dSLoGin kobj: Option<&Arc<dyn KObject>>, 49*a03c4f9dSLoGin target: &Arc<dyn KObject>, 50*a03c4f9dSLoGin name: String, 51*a03c4f9dSLoGin warn: bool, 52*a03c4f9dSLoGin ) -> Result<(), SystemError> { 53*a03c4f9dSLoGin let parent = if let Some(kobj) = kobj { 54*a03c4f9dSLoGin kobj.inode() 55*a03c4f9dSLoGin } else { 56*a03c4f9dSLoGin Some(self.root_inode().clone()) 57*a03c4f9dSLoGin }; 58*a03c4f9dSLoGin 59*a03c4f9dSLoGin // 没有parent,返回错误 60*a03c4f9dSLoGin let parent = parent.ok_or(SystemError::EFAULT)?; 61*a03c4f9dSLoGin return self.do_create_link_sd(&parent, target, name, warn); 62*a03c4f9dSLoGin } 63*a03c4f9dSLoGin 64*a03c4f9dSLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#20 65*a03c4f9dSLoGin fn do_create_link_sd( 66*a03c4f9dSLoGin &self, 67*a03c4f9dSLoGin inode: &Arc<KernFSInode>, 68*a03c4f9dSLoGin target: &Arc<dyn KObject>, 69*a03c4f9dSLoGin name: String, 70*a03c4f9dSLoGin warn: bool, 71*a03c4f9dSLoGin ) -> Result<(), SystemError> { 72*a03c4f9dSLoGin let target_inode = target.inode().ok_or(SystemError::ENOENT)?; 73*a03c4f9dSLoGin 74*a03c4f9dSLoGin let target_abs_path = "/sys".to_string() + &self.kernfs_path(&target_inode).to_owned(); 75*a03c4f9dSLoGin // let current_path = self.kernfs_path(inode); 76*a03c4f9dSLoGin // kdebug!("sysfs: create link {} to {}", current_path, target_abs_path); 77*a03c4f9dSLoGin 78*a03c4f9dSLoGin let kn = inode.add_link(name.clone(), &target_inode, target_abs_path); 79*a03c4f9dSLoGin if kn.is_ok() { 80*a03c4f9dSLoGin return Ok(()); 81*a03c4f9dSLoGin } 82*a03c4f9dSLoGin let err = kn.unwrap_err(); 83*a03c4f9dSLoGin if warn && err == SystemError::EEXIST { 84*a03c4f9dSLoGin self.warn_duplicate(inode, &name); 85*a03c4f9dSLoGin } 86*a03c4f9dSLoGin return Err(err); 87*a03c4f9dSLoGin } 88*a03c4f9dSLoGin 89*a03c4f9dSLoGin /// sysfs_create_link_sd - create symlink to a given object. 90*a03c4f9dSLoGin /// 91*a03c4f9dSLoGin /// ## 参数 92*a03c4f9dSLoGin /// 93*a03c4f9dSLoGin /// - `inode`: 目录inode,在这个目录下创建符号链接 94*a03c4f9dSLoGin /// - `target`: object we're pointing to. 95*a03c4f9dSLoGin /// - `name`: 符号链接的名称 96*a03c4f9dSLoGin #[allow(dead_code)] 97*a03c4f9dSLoGin pub(super) fn create_link_sd( 98*a03c4f9dSLoGin &self, 99*a03c4f9dSLoGin inode: &Arc<KernFSInode>, 100*a03c4f9dSLoGin target: &Arc<dyn KObject>, 101*a03c4f9dSLoGin name: String, 102*a03c4f9dSLoGin ) -> Result<(), SystemError> { 103*a03c4f9dSLoGin return self.do_create_link_sd(inode, target, name, true); 104*a03c4f9dSLoGin } 10506d5e247SLoGin } 106