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