xref: /DragonOS/kernel/src/driver/base/kset.rs (revision 9fab312ea9921618629924ab15c28c2d255b21c6)
1 use alloc::{
2     string::String,
3     sync::{Arc, Weak},
4     vec::Vec,
5 };
6 
7 use core::hash::Hash;
8 
9 use super::kobject::{
10     DynamicKObjKType, KObjType, KObject, KObjectManager, KObjectState, LockedKObjectState,
11 };
12 use crate::{
13     filesystem::kernfs::KernFSInode,
14     libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
15 };
16 use system_error::SystemError;
17 
18 #[derive(Debug)]
19 pub struct KSet {
20     /// 属于当前kset的kobject
21     kobjects: RwLock<Vec<Weak<dyn KObject>>>,
22     /// 节点的一些信息
23     inner: RwLock<InnerKSet>,
24     /// kobject的状态
25     kobj_state: LockedKObjectState,
26     /// 与父节点有关的一些信息
27     parent_data: RwLock<KSetParentData>,
28     self_ref: Weak<KSet>,
29 }
30 
31 impl Hash for KSet {
32     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
33         self.self_ref.as_ptr().hash(state);
34         self.inner.read().name.hash(state);
35     }
36 }
37 
38 impl core::cmp::Eq for KSet {}
39 
40 impl core::cmp::PartialEq for KSet {
41     fn eq(&self, other: &Self) -> bool {
42         self.self_ref.as_ptr() == other.self_ref.as_ptr()
43     }
44 }
45 
46 impl KSet {
47     pub fn new(name: String) -> Arc<Self> {
48         let r = Self {
49             kobjects: RwLock::new(Vec::new()),
50             inner: RwLock::new(InnerKSet::new(name)),
51             kobj_state: LockedKObjectState::new(None),
52             parent_data: RwLock::new(KSetParentData::new(None, None)),
53             self_ref: Weak::default(),
54         };
55 
56         let r = Arc::new(r);
57 
58         unsafe {
59             let p = r.as_ref() as *const Self as *mut Self;
60             (*p).self_ref = Arc::downgrade(&r);
61         }
62 
63         return r;
64     }
65 
66     /// 创建一个kset,并且设置它的父亲为parent_kobj。然后把这个kset注册到sysfs
67     ///
68     /// ## 参数
69     ///
70     /// - name: kset的名字
71     /// - parent_kobj: 父亲kobject
72     /// - join_kset: 如果不为None,那么这个kset会加入到join_kset中
73     pub fn new_and_add(
74         name: String,
75         parent_kobj: Option<Arc<dyn KObject>>,
76         join_kset: Option<Arc<KSet>>,
77     ) -> Result<Arc<Self>, SystemError> {
78         let kset = KSet::new(name);
79         if let Some(parent_kobj) = parent_kobj {
80             kset.set_parent(Some(Arc::downgrade(&parent_kobj)));
81         }
82         kset.register(join_kset)?;
83         return Ok(kset);
84     }
85 
86     /// 注册一个kset
87     ///
88     /// ## 参数
89     ///
90     /// - join_kset: 如果不为None,那么这个kset会加入到join_kset中
91     pub fn register(&self, join_kset: Option<Arc<KSet>>) -> Result<(), SystemError> {
92         return KObjectManager::add_kobj(self.self_ref.upgrade().unwrap(), join_kset);
93         // todo: 引入uevent之后,发送uevent
94     }
95 
96     /// 注销一个kset
97     #[allow(dead_code)]
98     pub fn unregister(&self) {
99         KObjectManager::remove_kobj(self.self_ref.upgrade().unwrap());
100     }
101 
102     /// 把一个kobject加入到当前kset中。
103     ///
104     /// 该函数不会修改kobj的parent,需要调用者自己视情况修改。
105     ///
106     /// ## Panic
107     ///
108     /// 这个kobject的kset必须是None,否则会panic
109     pub fn join(&self, kobj: &Arc<dyn KObject>) {
110         assert!(kobj.kset().is_none());
111         kobj.set_kset(self.self_ref.upgrade());
112         self.kobjects.write().push(Arc::downgrade(kobj));
113     }
114 
115     /// 把一个kobject从当前kset中移除。
116     pub fn leave(&self, kobj: &Arc<dyn KObject>) {
117         let mut kobjects = self.kobjects.write();
118         kobjects.retain(|x| x.upgrade().is_some());
119         let index = kobjects.iter().position(|x| {
120             if let Some(x) = x.upgrade() {
121                 return Arc::ptr_eq(&x, kobj);
122             }
123             return false;
124         });
125         if let Some(index) = index {
126             let x = kobjects.remove(index);
127             let x = x.upgrade().unwrap();
128             drop(kobjects);
129             x.set_kset(None);
130         }
131     }
132 
133     /// 清除所有已经被释放的kobject
134     #[allow(dead_code)]
135     pub fn cleanup_weak(&self) {
136         let mut kobjects = self.kobjects.write();
137         kobjects.retain(|x| x.upgrade().is_some());
138     }
139 
140     pub fn as_kobject(&self) -> Arc<dyn KObject> {
141         return self.self_ref.upgrade().unwrap();
142     }
143 
144     pub fn kobjects(&self) -> RwLockReadGuard<Vec<Weak<dyn KObject>>> {
145         return self.kobjects.read();
146     }
147 }
148 
149 impl KObject for KSet {
150     fn as_any_ref(&self) -> &dyn core::any::Any {
151         self
152     }
153 
154     fn inode(&self) -> Option<Arc<KernFSInode>> {
155         self.inner.read().kern_inode.clone()
156     }
157 
158     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
159         self.inner.write().kern_inode = inode;
160     }
161 
162     fn parent(&self) -> Option<Weak<dyn KObject>> {
163         self.parent_data.read().parent.clone()
164     }
165 
166     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
167         self.parent_data.write().parent = parent;
168     }
169 
170     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
171         self.kobj_state.read()
172     }
173 
174     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
175         self.kobj_state.write()
176     }
177 
178     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
179         self.inner.read().ktype
180     }
181 
182     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
183         self.inner.write().ktype = ktype;
184     }
185 
186     fn kset(&self) -> Option<Arc<KSet>> {
187         self.parent_data.read().kset.clone()
188     }
189 
190     fn set_kset(&self, kset: Option<Arc<KSet>>) {
191         self.parent_data.write().kset = kset;
192     }
193 
194     fn name(&self) -> String {
195         return self.inner.read().name.clone();
196     }
197 
198     fn set_name(&self, name: String) {
199         self.inner.write().name = name;
200     }
201 
202     fn set_kobj_state(&self, state: KObjectState) {
203         *self.kobj_state.write() = state;
204     }
205 }
206 
207 #[derive(Debug)]
208 struct KSetParentData {
209     parent: Option<Weak<dyn KObject>>,
210     kset: Option<Arc<KSet>>,
211 }
212 
213 impl KSetParentData {
214     fn new(parent: Option<Weak<dyn KObject>>, kset: Option<Arc<KSet>>) -> Self {
215         Self { parent, kset }
216     }
217 }
218 
219 #[derive(Debug)]
220 struct InnerKSet {
221     kern_inode: Option<Arc<KernFSInode>>,
222     name: String,
223     ktype: Option<&'static dyn KObjType>,
224 }
225 
226 impl InnerKSet {
227     fn new(name: String) -> Self {
228         Self {
229             kern_inode: None,
230             name,
231             ktype: Some(&DynamicKObjKType),
232         }
233     }
234 }
235