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