1*06d5e247SLoGin use core::{intrinsics::unlikely, ops::BitAnd}; 2*06d5e247SLoGin 3*06d5e247SLoGin use alloc::{ 4*06d5e247SLoGin string::ToString, 5*06d5e247SLoGin sync::{Arc, Weak}, 6*06d5e247SLoGin }; 7*06d5e247SLoGin 8*06d5e247SLoGin use crate::{ 9*06d5e247SLoGin driver::base::kobject::KObject, 10*06d5e247SLoGin filesystem::{ 11*06d5e247SLoGin kernfs::{ 12*06d5e247SLoGin callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}, 13*06d5e247SLoGin KernFSInode, 14*06d5e247SLoGin }, 15*06d5e247SLoGin sysfs::{SysFSOps, SysFSOpsSupport}, 16*06d5e247SLoGin vfs::{syscall::ModeType, PollStatus}, 17*06d5e247SLoGin }, 18*06d5e247SLoGin kwarn, 19*06d5e247SLoGin syscall::SystemError, 20*06d5e247SLoGin }; 21*06d5e247SLoGin 22*06d5e247SLoGin use super::{Attribute, SysFS, SysFSKernPrivateData}; 236b4e7a29SLoGin 246b4e7a29SLoGin #[derive(Debug)] 256b4e7a29SLoGin pub struct SysKernFilePriv { 266b4e7a29SLoGin attribute: Option<&'static dyn Attribute>, 27*06d5e247SLoGin /// 当前文件对应的kobject 28*06d5e247SLoGin kobj: Weak<dyn KObject>, 296b4e7a29SLoGin // todo: 增加bin attribute,它和attribute二选一,只能有一个为Some 306b4e7a29SLoGin } 316b4e7a29SLoGin 326b4e7a29SLoGin impl SysKernFilePriv { 33*06d5e247SLoGin pub fn new(kobj: &Arc<dyn KObject>, attribute: Option<&'static dyn Attribute>) -> Self { 346b4e7a29SLoGin if attribute.is_none() { 356b4e7a29SLoGin panic!("attribute can't be None"); 366b4e7a29SLoGin } 37*06d5e247SLoGin let kobj = Arc::downgrade(kobj); 38*06d5e247SLoGin return Self { kobj, attribute }; 396b4e7a29SLoGin } 406b4e7a29SLoGin 41*06d5e247SLoGin #[allow(dead_code)] 42*06d5e247SLoGin #[inline] 436b4e7a29SLoGin pub fn attribute(&self) -> Option<&'static dyn Attribute> { 446b4e7a29SLoGin self.attribute 456b4e7a29SLoGin } 46*06d5e247SLoGin 47*06d5e247SLoGin pub fn callback_read(&self, buf: &mut [u8]) -> Result<usize, SystemError> { 48*06d5e247SLoGin let attribute = self.attribute.ok_or(SystemError::EINVAL)?; 49*06d5e247SLoGin // 当前文件所指向的kobject已经被释放 50*06d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 51*06d5e247SLoGin return attribute.show(kobj, buf); 52*06d5e247SLoGin } 53*06d5e247SLoGin 54*06d5e247SLoGin pub fn callback_write(&self, buf: &[u8]) -> Result<usize, SystemError> { 55*06d5e247SLoGin let attribute = self.attribute.ok_or(SystemError::EINVAL)?; 56*06d5e247SLoGin // 当前文件所指向的kobject已经被释放 57*06d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 58*06d5e247SLoGin return attribute.store(kobj, buf); 59*06d5e247SLoGin } 60*06d5e247SLoGin } 61*06d5e247SLoGin 62*06d5e247SLoGin impl SysFS { 63*06d5e247SLoGin /// 为指定的kobject创建一个属性文件 64*06d5e247SLoGin /// 65*06d5e247SLoGin /// ## 参数 66*06d5e247SLoGin /// 67*06d5e247SLoGin /// - `kobj` 要创建属性文件的kobject 68*06d5e247SLoGin /// - `attr` 属性 69*06d5e247SLoGin pub fn create_file( 70*06d5e247SLoGin &self, 71*06d5e247SLoGin kobj: &Arc<dyn KObject>, 72*06d5e247SLoGin attr: &'static dyn Attribute, 73*06d5e247SLoGin ) -> Result<(), SystemError> { 74*06d5e247SLoGin let inode = kobj.inode().ok_or(SystemError::EINVAL)?; 75*06d5e247SLoGin return self.add_file_with_mode(&inode, attr, attr.mode()); 76*06d5e247SLoGin } 77*06d5e247SLoGin 78*06d5e247SLoGin // https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/file.c?fi=sysfs_add_file_mode_ns#271 79*06d5e247SLoGin pub(super) fn add_file_with_mode( 80*06d5e247SLoGin &self, 81*06d5e247SLoGin parent: &Arc<KernFSInode>, 82*06d5e247SLoGin attr: &'static dyn Attribute, 83*06d5e247SLoGin mode: ModeType, 84*06d5e247SLoGin ) -> Result<(), SystemError> { 85*06d5e247SLoGin let x = parent.private_data_mut(); 86*06d5e247SLoGin let kobj: Arc<dyn KObject>; 87*06d5e247SLoGin if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() { 88*06d5e247SLoGin kobj = dt.kobj().unwrap(); 89*06d5e247SLoGin } else { 90*06d5e247SLoGin drop(x); 91*06d5e247SLoGin let path = self.kernfs_path(parent); 92*06d5e247SLoGin panic!("parent '{path}' is not a dir"); 93*06d5e247SLoGin } 94*06d5e247SLoGin drop(x); 95*06d5e247SLoGin 96*06d5e247SLoGin let sysfs_ops: &dyn SysFSOps = kobj.kobj_type().unwrap().sysfs_ops().ok_or_else(|| { 97*06d5e247SLoGin kwarn!("missing sysfs attribute operations for kobject: {kobj:?}"); 98*06d5e247SLoGin SystemError::EINVAL 99*06d5e247SLoGin })?; 100*06d5e247SLoGin 101*06d5e247SLoGin // assume that all sysfs ops are preallocated. 102*06d5e247SLoGin 103*06d5e247SLoGin let sys_support = sysfs_ops.support(attr); 104*06d5e247SLoGin 105*06d5e247SLoGin let kern_callback: &'static dyn KernFSCallback; 106*06d5e247SLoGin if sys_support.contains(SysFSOpsSupport::SHOW) 107*06d5e247SLoGin && sys_support.contains(SysFSOpsSupport::STORE) 108*06d5e247SLoGin { 109*06d5e247SLoGin kern_callback = &PreallocKFOpsRW; 110*06d5e247SLoGin } else if sys_support.contains(SysFSOpsSupport::SHOW) { 111*06d5e247SLoGin kern_callback = &PreallocKFOpsReadOnly; 112*06d5e247SLoGin } else if sys_support.contains(SysFSOpsSupport::STORE) { 113*06d5e247SLoGin kern_callback = &PreallocKFOpsWriteOnly; 114*06d5e247SLoGin } else { 115*06d5e247SLoGin kern_callback = &PreallocKFOpsEmpty; 116*06d5e247SLoGin } 117*06d5e247SLoGin 118*06d5e247SLoGin let sys_priv = SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, Some(attr))); 119*06d5e247SLoGin let r = parent.add_file( 120*06d5e247SLoGin attr.name().to_string(), 121*06d5e247SLoGin mode.bitand(ModeType::from_bits_truncate(0o777)), 122*06d5e247SLoGin Some(KernInodePrivateData::SysFS(sys_priv)), 123*06d5e247SLoGin Some(kern_callback), 124*06d5e247SLoGin ); 125*06d5e247SLoGin 126*06d5e247SLoGin if let Err(e) = r { 127*06d5e247SLoGin if e == SystemError::EEXIST { 128*06d5e247SLoGin self.warn_duplicate(parent, attr.name()); 129*06d5e247SLoGin } 130*06d5e247SLoGin 131*06d5e247SLoGin return Err(e); 132*06d5e247SLoGin } 133*06d5e247SLoGin return Ok(()); 134*06d5e247SLoGin } 135*06d5e247SLoGin 136*06d5e247SLoGin /// 在sysfs中删除某个kobject的属性文件 137*06d5e247SLoGin /// 138*06d5e247SLoGin /// 如果属性文件不存在,则发出一个警告 139*06d5e247SLoGin /// 140*06d5e247SLoGin /// ## 参数 141*06d5e247SLoGin /// 142*06d5e247SLoGin /// - `kobj` 要删除属性文件的kobject 143*06d5e247SLoGin /// - `attr` 属性 144*06d5e247SLoGin pub fn remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute) { 145*06d5e247SLoGin let parent = kobj.inode(); 146*06d5e247SLoGin 147*06d5e247SLoGin if let Some(parent) = parent { 148*06d5e247SLoGin let r = parent.remove(attr.name()); 149*06d5e247SLoGin if unlikely(r.is_err()) { 150*06d5e247SLoGin kwarn!( 151*06d5e247SLoGin "failed to remove file '{}' from '{}'", 152*06d5e247SLoGin attr.name(), 153*06d5e247SLoGin kobj.name() 154*06d5e247SLoGin ); 155*06d5e247SLoGin } 156*06d5e247SLoGin } 157*06d5e247SLoGin } 158*06d5e247SLoGin } 159*06d5e247SLoGin 160*06d5e247SLoGin #[derive(Debug)] 161*06d5e247SLoGin struct PreallocKFOpsRW; 162*06d5e247SLoGin 163*06d5e247SLoGin impl KernFSCallback for PreallocKFOpsRW { 164*06d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 165*06d5e247SLoGin return Ok(()); 166*06d5e247SLoGin } 167*06d5e247SLoGin 168*06d5e247SLoGin fn read( 169*06d5e247SLoGin &self, 170*06d5e247SLoGin data: KernCallbackData, 171*06d5e247SLoGin buf: &mut [u8], 172*06d5e247SLoGin offset: usize, 173*06d5e247SLoGin ) -> Result<usize, SystemError> { 174*06d5e247SLoGin return data.callback_read(buf, offset); 175*06d5e247SLoGin } 176*06d5e247SLoGin 177*06d5e247SLoGin fn write( 178*06d5e247SLoGin &self, 179*06d5e247SLoGin data: KernCallbackData, 180*06d5e247SLoGin buf: &[u8], 181*06d5e247SLoGin offset: usize, 182*06d5e247SLoGin ) -> Result<usize, SystemError> { 183*06d5e247SLoGin return data.callback_write(buf, offset); 184*06d5e247SLoGin } 185*06d5e247SLoGin 186*06d5e247SLoGin #[inline] 187*06d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 188*06d5e247SLoGin return Ok(PollStatus::READ | PollStatus::WRITE); 189*06d5e247SLoGin } 190*06d5e247SLoGin } 191*06d5e247SLoGin 192*06d5e247SLoGin #[derive(Debug)] 193*06d5e247SLoGin struct PreallocKFOpsReadOnly; 194*06d5e247SLoGin 195*06d5e247SLoGin impl KernFSCallback for PreallocKFOpsReadOnly { 196*06d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 197*06d5e247SLoGin return Ok(()); 198*06d5e247SLoGin } 199*06d5e247SLoGin 200*06d5e247SLoGin fn read( 201*06d5e247SLoGin &self, 202*06d5e247SLoGin data: KernCallbackData, 203*06d5e247SLoGin buf: &mut [u8], 204*06d5e247SLoGin offset: usize, 205*06d5e247SLoGin ) -> Result<usize, SystemError> { 206*06d5e247SLoGin return data.callback_read(buf, offset); 207*06d5e247SLoGin } 208*06d5e247SLoGin 209*06d5e247SLoGin fn write( 210*06d5e247SLoGin &self, 211*06d5e247SLoGin _data: KernCallbackData, 212*06d5e247SLoGin _buf: &[u8], 213*06d5e247SLoGin _offset: usize, 214*06d5e247SLoGin ) -> Result<usize, SystemError> { 215*06d5e247SLoGin return Err(SystemError::EPERM); 216*06d5e247SLoGin } 217*06d5e247SLoGin 218*06d5e247SLoGin #[inline] 219*06d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 220*06d5e247SLoGin return Ok(PollStatus::READ); 221*06d5e247SLoGin } 222*06d5e247SLoGin } 223*06d5e247SLoGin 224*06d5e247SLoGin #[derive(Debug)] 225*06d5e247SLoGin struct PreallocKFOpsWriteOnly; 226*06d5e247SLoGin 227*06d5e247SLoGin impl KernFSCallback for PreallocKFOpsWriteOnly { 228*06d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 229*06d5e247SLoGin return Ok(()); 230*06d5e247SLoGin } 231*06d5e247SLoGin 232*06d5e247SLoGin fn read( 233*06d5e247SLoGin &self, 234*06d5e247SLoGin _data: KernCallbackData, 235*06d5e247SLoGin _buf: &mut [u8], 236*06d5e247SLoGin _offset: usize, 237*06d5e247SLoGin ) -> Result<usize, SystemError> { 238*06d5e247SLoGin return Err(SystemError::EPERM); 239*06d5e247SLoGin } 240*06d5e247SLoGin 241*06d5e247SLoGin fn write( 242*06d5e247SLoGin &self, 243*06d5e247SLoGin data: KernCallbackData, 244*06d5e247SLoGin buf: &[u8], 245*06d5e247SLoGin offset: usize, 246*06d5e247SLoGin ) -> Result<usize, SystemError> { 247*06d5e247SLoGin return data.callback_write(buf, offset); 248*06d5e247SLoGin } 249*06d5e247SLoGin 250*06d5e247SLoGin #[inline] 251*06d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 252*06d5e247SLoGin return Ok(PollStatus::WRITE); 253*06d5e247SLoGin } 254*06d5e247SLoGin } 255*06d5e247SLoGin 256*06d5e247SLoGin #[derive(Debug)] 257*06d5e247SLoGin struct PreallocKFOpsEmpty; 258*06d5e247SLoGin 259*06d5e247SLoGin impl KernFSCallback for PreallocKFOpsEmpty { 260*06d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 261*06d5e247SLoGin return Ok(()); 262*06d5e247SLoGin } 263*06d5e247SLoGin 264*06d5e247SLoGin fn read( 265*06d5e247SLoGin &self, 266*06d5e247SLoGin _data: KernCallbackData, 267*06d5e247SLoGin _buf: &mut [u8], 268*06d5e247SLoGin _offset: usize, 269*06d5e247SLoGin ) -> Result<usize, SystemError> { 270*06d5e247SLoGin return Err(SystemError::EPERM); 271*06d5e247SLoGin } 272*06d5e247SLoGin 273*06d5e247SLoGin fn write( 274*06d5e247SLoGin &self, 275*06d5e247SLoGin _data: KernCallbackData, 276*06d5e247SLoGin _buf: &[u8], 277*06d5e247SLoGin _offset: usize, 278*06d5e247SLoGin ) -> Result<usize, SystemError> { 279*06d5e247SLoGin return Err(SystemError::EPERM); 280*06d5e247SLoGin } 281*06d5e247SLoGin 282*06d5e247SLoGin #[inline] 283*06d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 284*06d5e247SLoGin return Ok(PollStatus::empty()); 285*06d5e247SLoGin } 286*06d5e247SLoGin } 287*06d5e247SLoGin 288*06d5e247SLoGin pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError> { 289*06d5e247SLoGin let len; 290*06d5e247SLoGin if buf.len() > s.len() { 291*06d5e247SLoGin len = s.len(); 292*06d5e247SLoGin } else { 293*06d5e247SLoGin len = buf.len() - 1; 294*06d5e247SLoGin } 295*06d5e247SLoGin buf[..len].copy_from_slice(&s.as_bytes()[..len]); 296*06d5e247SLoGin buf[len] = b'\0'; 297*06d5e247SLoGin return Ok(len); 2986b4e7a29SLoGin } 299