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