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