dir.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #![allow(dead_code)]
  2. use alloc::{
  3. string::{String, ToString},
  4. sync::{Arc, Weak},
  5. vec::Vec,
  6. };
  7. use system_error::SystemError;
  8. use crate::{
  9. driver::base::kobject::KObject,
  10. filesystem::{
  11. kernfs::{callback::KernInodePrivateData, KernFSInode},
  12. vfs::syscall::ModeType,
  13. },
  14. };
  15. use super::{SysFS, SysFSKernPrivateData};
  16. #[derive(Debug)]
  17. pub struct SysKernDirPriv {
  18. /// 该目录对应的kobject
  19. /// use weak reference to avoid cyclic reference
  20. kobj: Weak<dyn KObject>,
  21. // attribute_group: Option<&'static dyn AttributeGroup>,
  22. }
  23. impl SysKernDirPriv {
  24. pub fn new(kobj: Arc<dyn KObject>) -> Self {
  25. // let attribute_group = kobj.kobj_type().map(|kobj_type| kobj_type.attribute_groups()).flatten();
  26. Self {
  27. kobj: Arc::downgrade(&kobj),
  28. // attribute_group,
  29. }
  30. }
  31. pub fn kobj(&self) -> Option<Arc<dyn KObject>> {
  32. self.kobj.upgrade()
  33. }
  34. // pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> {
  35. // self.attribute_group
  36. // }
  37. }
  38. impl SysFS {
  39. /// 在sysfs中创建一个目录
  40. ///
  41. /// 如果kobj的parent为None,则会在根目录下创建一个目录。
  42. ///
  43. /// ## 参数
  44. ///
  45. /// - `kobj`: 要创建的目录对应的kobject
  46. ///
  47. /// ## 返回
  48. ///
  49. /// 返回创建的目录对应的inode
  50. pub fn create_dir(&self, kobj: Arc<dyn KObject>) -> Result<Arc<KernFSInode>, SystemError> {
  51. // 如果kobj的parent为None,则会在/sys目录下创建一个目录。
  52. let parent = kobj
  53. .parent()
  54. .map(|p| p.upgrade().unwrap().inode())
  55. .unwrap_or_else(|| Some(self.root_inode.clone()))
  56. .ok_or(SystemError::ENOENT)?;
  57. let sysfs_dir_priv = SysFSKernPrivateData::Dir(SysKernDirPriv::new(kobj.clone()));
  58. // 在kernfs里面创建一个目录
  59. let dir: Arc<KernFSInode> = parent.add_dir(
  60. kobj.name(),
  61. ModeType::from_bits_truncate(0o755),
  62. Some(KernInodePrivateData::SysFS(sysfs_dir_priv)),
  63. None,
  64. )?;
  65. kobj.set_inode(Some(dir.clone()));
  66. return Ok(dir);
  67. }
  68. /// 获取指定的kernfs inode在sysfs中的路径(不包含`/sys`)
  69. ///
  70. /// ## 参数
  71. ///
  72. /// - `parent`: inode的父目录
  73. /// - `name`: inode的名称
  74. ///
  75. /// ## 返回
  76. ///
  77. /// 返回inode在sysfs中的路径
  78. pub(super) fn kernfs_path(&self, parent: &Arc<KernFSInode>) -> String {
  79. let mut p = parent.clone();
  80. let mut parts = Vec::new();
  81. let sys_root_inode = self.root_inode();
  82. let mut not_reach_sys_root = false;
  83. while !Arc::ptr_eq(&p, sys_root_inode) {
  84. parts.push(p.name().to_string());
  85. if let Some(parent) = p.parent() {
  86. p = parent;
  87. } else {
  88. not_reach_sys_root = true;
  89. break;
  90. }
  91. }
  92. let mut path = String::new();
  93. if not_reach_sys_root {
  94. path.push_str("(null)");
  95. };
  96. for part in parts.iter().rev() {
  97. path.push('/');
  98. path.push_str(part);
  99. }
  100. return path;
  101. }
  102. /// 从sysfs中删除一个kobject对应的目录(包括目录自身以及目录下的所有文件、文件夹)
  103. pub fn remove_dir(&self, kobj: &Arc<dyn KObject>) {
  104. let kobj_inode = kobj.inode();
  105. kobj.set_inode(None);
  106. if let Some(inode) = kobj_inode {
  107. let parent = inode.parent().unwrap();
  108. parent.remove_recursive()
  109. }
  110. }
  111. }