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 pub fn add_kobj( 165 kobj: Arc<dyn KObject>, 166 join_kset: Option<Arc<KSet>>, 167 ) -> Result<(), SystemError> { 168 if join_kset.is_some() { 169 let kset = join_kset.unwrap(); 170 kset.join(&kobj); 171 // 如果kobject没有parent,那么就将这个kset作为parent 172 if kobj.parent().is_none() { 173 kobj.set_parent(Some(Arc::downgrade(&(kset as Arc<dyn KObject>)))); 174 } 175 } 176 177 let r = Self::create_dir(kobj.clone()); 178 179 if let Err(e) = r { 180 // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224 181 if let Some(kset) = kobj.kset() { 182 kset.leave(&kobj); 183 } 184 kobj.set_parent(None); 185 if e == SystemError::EEXIST { 186 kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}"); 187 } 188 189 return Err(e); 190 } 191 192 kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None); 193 return Ok(()); 194 } 195 196 fn create_dir(kobj: Arc<dyn KObject>) -> Result<(), SystemError> { 197 // create dir in sysfs 198 sysfs_instance().create_dir(kobj.clone())?; 199 200 // create default attributes in sysfs 201 if let Some(ktype) = kobj.kobj_type() { 202 let groups = ktype.attribute_groups(); 203 if let Some(groups) = groups { 204 let r = sysfs_instance().create_groups(&kobj, groups); 205 if let Err(e) = r { 206 sysfs_instance().remove_dir(&kobj); 207 return Err(e); 208 } 209 } 210 } 211 212 return Ok(()); 213 } 214 } 215