xref: /DragonOS/kernel/src/driver/base/kobject.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
1 use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref};
2 
3 use alloc::{
4     string::String,
5     sync::{Arc, Weak},
6 };
7 use intertrait::CastFromSync;
8 
9 use crate::{
10     filesystem::{
11         kernfs::KernFSInode,
12         sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
13     },
14     kerror,
15     libs::{
16         casting::DowncastArc,
17         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
18     },
19 };
20 
21 use system_error::SystemError;
22 
23 use super::kset::KSet;
24 
25 pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
26     fn as_any_ref(&self) -> &dyn core::any::Any;
27 
28     /// 设置当前kobject对应的sysfs inode(类型为KernFSInode)
29     fn set_inode(&self, inode: Option<Arc<KernFSInode>>);
30 
31     /// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
32     fn inode(&self) -> Option<Arc<KernFSInode>>;
33 
34     fn parent(&self) -> Option<Weak<dyn KObject>>;
35 
36     /// 设置当前kobject的parent kobject(不一定与kset相同)
37     fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
38 
39     /// 当前kobject属于哪个kset
40     fn kset(&self) -> Option<Arc<KSet>>;
41 
42     /// 设置当前kobject所属的kset
43     fn set_kset(&self, kset: Option<Arc<KSet>>);
44 
45     fn kobj_type(&self) -> Option<&'static dyn KObjType>;
46 
47     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>);
48 
49     fn name(&self) -> String;
50 
51     fn set_name(&self, name: String);
52 
53     fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
54 
55     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
56 
57     fn set_kobj_state(&self, state: KObjectState);
58 }
59 
60 impl dyn KObject {
61     /// 更新kobject的状态
62     pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) {
63         let insert = insert.unwrap_or(KObjectState::empty());
64         let remove = remove.unwrap_or(KObjectState::empty());
65         let mut state = self.kobj_state_mut();
66         *state = (*state | insert) & !remove;
67     }
68 }
69 
70 impl DowncastArc for dyn KObject {
71     fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> {
72         self
73     }
74 }
75 
76 pub trait KObjType: Debug + Send + Sync {
77     /// 当指定的kobject被释放时,设备驱动模型会调用此方法
78     fn release(&self, _kobj: Arc<dyn KObject>) {}
79     fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;
80 
81     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>;
82 }
83 
84 bitflags! {
85     pub struct KObjectState: u32 {
86         const IN_SYSFS = 1 << 0;
87         const ADD_UEVENT_SENT = 1 << 1;
88         const REMOVE_UEVENT_SENT = 1 << 2;
89         const INITIALIZED = 1 << 3;
90     }
91 
92 }
93 
94 #[derive(Debug)]
95 pub struct LockedKObjectState(RwLock<KObjectState>);
96 
97 impl LockedKObjectState {
98     pub fn new(state: Option<KObjectState>) -> LockedKObjectState {
99         let state = state.unwrap_or(KObjectState::empty());
100         LockedKObjectState(RwLock::new(state))
101     }
102 }
103 
104 impl Deref for LockedKObjectState {
105     type Target = RwLock<KObjectState>;
106 
107     fn deref(&self) -> &Self::Target {
108         &self.0
109     }
110 }
111 
112 pub trait KObjectAttribute: Attribute {
113     fn support(&self) -> SysFSOpsSupport;
114 
115     fn show(&self, kobj: &dyn KObject, buf: &mut [u8]) -> Result<usize, SystemError>;
116     fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result<usize, SystemError>;
117 }
118 
119 #[derive(Debug)]
120 pub struct KObjectSysFSOps;
121 
122 impl SysFSOps for KObjectSysFSOps {
123     fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
124         return attr.support();
125     }
126 
127     fn show(
128         &self,
129         kobj: Arc<dyn KObject>,
130         attr: &dyn Attribute,
131         buf: &mut [u8],
132     ) -> Result<usize, SystemError> {
133         let r = attr.show(kobj, buf).map_err(|e| {
134             if e == SystemError::EOPNOTSUPP_OR_ENOTSUP {
135                 SystemError::EIO
136             } else {
137                 e
138             }
139         });
140 
141         return r;
142     }
143 
144     fn store(
145         &self,
146         kobj: Arc<dyn KObject>,
147         attr: &dyn Attribute,
148         buf: &[u8],
149     ) -> Result<usize, SystemError> {
150         let r = attr.store(kobj, buf).map_err(|e| {
151             if e == SystemError::EOPNOTSUPP_OR_ENOTSUP {
152                 SystemError::EIO
153             } else {
154                 e
155             }
156         });
157 
158         return r;
159     }
160 }
161 
162 #[derive(Debug)]
163 pub struct KObjectManager;
164 
165 impl KObjectManager {
166     #[allow(dead_code)]
167     pub fn init_and_add_kobj(
168         kobj: Arc<dyn KObject>,
169         join_kset: Option<Arc<KSet>>,
170     ) -> Result<(), SystemError> {
171         Self::kobj_init(&kobj);
172         Self::add_kobj(kobj, join_kset)
173     }
174 
175     #[allow(dead_code)]
176     pub fn kobj_init(kobj: &Arc<dyn KObject>) {
177         kobj.set_kobj_type(Some(&DynamicKObjKType));
178     }
179 
180     pub fn add_kobj(
181         kobj: Arc<dyn KObject>,
182         join_kset: Option<Arc<KSet>>,
183     ) -> Result<(), SystemError> {
184         if join_kset.is_some() {
185             let kset = join_kset.unwrap();
186             kset.join(&kobj);
187             // 如果kobject没有parent,那么就将这个kset作为parent
188             if kobj.parent().is_none() {
189                 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>))));
190             }
191         }
192 
193         let r = Self::create_dir(kobj.clone());
194 
195         if let Err(e) = r {
196             // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224
197             if let Some(kset) = kobj.kset() {
198                 kset.leave(&kobj);
199             }
200             kobj.set_parent(None);
201             if e == SystemError::EEXIST {
202                 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}");
203             }
204 
205             return Err(e);
206         }
207 
208         kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None);
209         return Ok(());
210     }
211 
212     fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> {
213         // create dir in sysfs
214         sysfs_instance().create_dir(kobj.clone())?;
215 
216         // create default attributes in sysfs
217         if let Some(ktype) = kobj.kobj_type() {
218             let groups = ktype.attribute_groups();
219             if let Some(groups) = groups {
220                 let r = sysfs_instance().create_groups(&kobj, groups);
221                 if let Err(e) = r {
222                     sysfs_instance().remove_dir(&kobj);
223                     return Err(e);
224                 }
225             }
226         }
227 
228         return Ok(());
229     }
230 
231     /// 从sysfs中移除kobject
232     pub fn remove_kobj(kobj: Arc<dyn KObject>) {
233         let ktype = kobj.kobj_type();
234         if let Some(ktype) = ktype {
235             if let Some(groups) = ktype.attribute_groups() {
236                 sysfs_instance().remove_groups(&kobj, groups);
237             }
238         }
239 
240         // todo: 发送uevent: KOBJ_REMOVE
241 
242         sysfs_instance().remove_dir(&kobj);
243         kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
244         let kset = kobj.kset();
245         if let Some(kset) = kset {
246             kset.leave(&kobj);
247         }
248         kobj.set_parent(None);
249     }
250 }
251 
252 /// 动态创建的kobject对象的ktype
253 #[derive(Debug)]
254 pub struct DynamicKObjKType;
255 
256 impl KObjType for DynamicKObjKType {
257     fn release(&self, kobj: Arc<dyn KObject>) {
258         kdebug!("DynamicKObjKType::release() kobj:{:?}", kobj.name());
259     }
260 
261     fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
262         Some(&KObjectSysFSOps)
263     }
264 
265     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
266         None
267     }
268 }
269