xref: /DragonOS/kernel/src/filesystem/sysfs/symlink.rs (revision a03c4f9dee5705207325c56629c0ccd219168f10)
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