106d5e247SLoGin use core::{intrinsics::unlikely, ops::BitAnd}; 206d5e247SLoGin 306d5e247SLoGin use alloc::{ 406d5e247SLoGin string::ToString, 506d5e247SLoGin sync::{Arc, Weak}, 606d5e247SLoGin }; 706d5e247SLoGin 806d5e247SLoGin use crate::{ 906d5e247SLoGin driver::base::kobject::KObject, 1006d5e247SLoGin filesystem::{ 1106d5e247SLoGin kernfs::{ 1206d5e247SLoGin callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}, 1306d5e247SLoGin KernFSInode, 1406d5e247SLoGin }, 1506d5e247SLoGin sysfs::{SysFSOps, SysFSOpsSupport}, 1606d5e247SLoGin vfs::{syscall::ModeType, PollStatus}, 1706d5e247SLoGin }, 1806d5e247SLoGin kwarn, 1906d5e247SLoGin syscall::SystemError, 2006d5e247SLoGin }; 2106d5e247SLoGin 22*7eda31b2SLoGin use super::{Attribute, BinAttribute, SysFS, SysFSKernPrivateData}; 236b4e7a29SLoGin 246b4e7a29SLoGin #[derive(Debug)] 256b4e7a29SLoGin pub struct SysKernFilePriv { 266b4e7a29SLoGin attribute: Option<&'static dyn Attribute>, 27*7eda31b2SLoGin /// bin attribute和attribute二选一,只能有一个为Some 28*7eda31b2SLoGin bin_attribute: Option<Arc<dyn BinAttribute>>, 2906d5e247SLoGin /// 当前文件对应的kobject 3006d5e247SLoGin kobj: Weak<dyn KObject>, 316b4e7a29SLoGin } 326b4e7a29SLoGin 336b4e7a29SLoGin impl SysKernFilePriv { 34*7eda31b2SLoGin pub fn new( 35*7eda31b2SLoGin kobj: &Arc<dyn KObject>, 36*7eda31b2SLoGin attribute: Option<&'static dyn Attribute>, 37*7eda31b2SLoGin bin_attribute: Option<Arc<dyn BinAttribute>>, 38*7eda31b2SLoGin ) -> Self { 39*7eda31b2SLoGin if attribute.is_none() && bin_attribute.is_none() { 40*7eda31b2SLoGin panic!("attribute and bin_attribute can't be both None"); 416b4e7a29SLoGin } 42*7eda31b2SLoGin if attribute.is_some() && bin_attribute.is_some() { 43*7eda31b2SLoGin panic!("attribute and bin_attribute can't be both Some"); 44*7eda31b2SLoGin } 45*7eda31b2SLoGin 4606d5e247SLoGin let kobj = Arc::downgrade(kobj); 47*7eda31b2SLoGin return Self { 48*7eda31b2SLoGin kobj, 49*7eda31b2SLoGin attribute, 50*7eda31b2SLoGin bin_attribute, 51*7eda31b2SLoGin }; 526b4e7a29SLoGin } 536b4e7a29SLoGin 5406d5e247SLoGin #[allow(dead_code)] 5506d5e247SLoGin #[inline] 566b4e7a29SLoGin pub fn attribute(&self) -> Option<&'static dyn Attribute> { 576b4e7a29SLoGin self.attribute 586b4e7a29SLoGin } 5906d5e247SLoGin 60*7eda31b2SLoGin pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> { 61*7eda31b2SLoGin if let Some(attribute) = self.attribute { 6206d5e247SLoGin // 当前文件所指向的kobject已经被释放 6306d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 64*7eda31b2SLoGin let len = attribute.show(kobj, buf)?; 65*7eda31b2SLoGin if offset > 0 { 66*7eda31b2SLoGin if len <= offset { 67*7eda31b2SLoGin return Ok(0); 68*7eda31b2SLoGin } 69*7eda31b2SLoGin let len = len - offset; 70*7eda31b2SLoGin buf.copy_within(offset..offset + len, 0); 71*7eda31b2SLoGin buf[len] = 0; 72*7eda31b2SLoGin } 73*7eda31b2SLoGin return Ok(len); 74*7eda31b2SLoGin } else if let Some(bin_attribute) = self.bin_attribute.as_ref() { 75*7eda31b2SLoGin // 当前文件所指向的kobject已经被释放 76*7eda31b2SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 77*7eda31b2SLoGin return bin_attribute.read(kobj, buf, offset); 78*7eda31b2SLoGin } else { 79*7eda31b2SLoGin panic!("attribute and bin_attribute can't be both None"); 80*7eda31b2SLoGin } 8106d5e247SLoGin } 8206d5e247SLoGin 83*7eda31b2SLoGin pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> { 84*7eda31b2SLoGin if let Some(attribute) = self.attribute { 8506d5e247SLoGin // 当前文件所指向的kobject已经被释放 8606d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 8706d5e247SLoGin return attribute.store(kobj, buf); 88*7eda31b2SLoGin } else if let Some(bin_attribute) = self.bin_attribute.as_ref() { 89*7eda31b2SLoGin // 当前文件所指向的kobject已经被释放 90*7eda31b2SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 91*7eda31b2SLoGin return bin_attribute.write(kobj, buf, offset); 92*7eda31b2SLoGin } else { 93*7eda31b2SLoGin panic!("attribute and bin_attribute can't be both None"); 94*7eda31b2SLoGin } 9506d5e247SLoGin } 9606d5e247SLoGin } 9706d5e247SLoGin 9806d5e247SLoGin impl SysFS { 9906d5e247SLoGin /// 为指定的kobject创建一个属性文件 10006d5e247SLoGin /// 10106d5e247SLoGin /// ## 参数 10206d5e247SLoGin /// 10306d5e247SLoGin /// - `kobj` 要创建属性文件的kobject 10406d5e247SLoGin /// - `attr` 属性 10506d5e247SLoGin pub fn create_file( 10606d5e247SLoGin &self, 10706d5e247SLoGin kobj: &Arc<dyn KObject>, 10806d5e247SLoGin attr: &'static dyn Attribute, 10906d5e247SLoGin ) -> Result<(), SystemError> { 11006d5e247SLoGin let inode = kobj.inode().ok_or(SystemError::EINVAL)?; 11106d5e247SLoGin return self.add_file_with_mode(&inode, attr, attr.mode()); 11206d5e247SLoGin } 11306d5e247SLoGin 11406d5e247SLoGin // https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/file.c?fi=sysfs_add_file_mode_ns#271 11506d5e247SLoGin pub(super) fn add_file_with_mode( 11606d5e247SLoGin &self, 11706d5e247SLoGin parent: &Arc<KernFSInode>, 11806d5e247SLoGin attr: &'static dyn Attribute, 11906d5e247SLoGin mode: ModeType, 12006d5e247SLoGin ) -> Result<(), SystemError> { 12106d5e247SLoGin let x = parent.private_data_mut(); 12206d5e247SLoGin let kobj: Arc<dyn KObject>; 12306d5e247SLoGin if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() { 12406d5e247SLoGin kobj = dt.kobj().unwrap(); 12506d5e247SLoGin } else { 12606d5e247SLoGin drop(x); 12706d5e247SLoGin let path = self.kernfs_path(parent); 12806d5e247SLoGin panic!("parent '{path}' is not a dir"); 12906d5e247SLoGin } 13006d5e247SLoGin drop(x); 13106d5e247SLoGin 13206d5e247SLoGin let sysfs_ops: &dyn SysFSOps = kobj.kobj_type().unwrap().sysfs_ops().ok_or_else(|| { 13306d5e247SLoGin kwarn!("missing sysfs attribute operations for kobject: {kobj:?}"); 13406d5e247SLoGin SystemError::EINVAL 13506d5e247SLoGin })?; 13606d5e247SLoGin 13706d5e247SLoGin // assume that all sysfs ops are preallocated. 13806d5e247SLoGin 13906d5e247SLoGin let sys_support = sysfs_ops.support(attr); 14006d5e247SLoGin 14106d5e247SLoGin let kern_callback: &'static dyn KernFSCallback; 14206d5e247SLoGin if sys_support.contains(SysFSOpsSupport::SHOW) 14306d5e247SLoGin && sys_support.contains(SysFSOpsSupport::STORE) 14406d5e247SLoGin { 14506d5e247SLoGin kern_callback = &PreallocKFOpsRW; 14606d5e247SLoGin } else if sys_support.contains(SysFSOpsSupport::SHOW) { 14706d5e247SLoGin kern_callback = &PreallocKFOpsReadOnly; 14806d5e247SLoGin } else if sys_support.contains(SysFSOpsSupport::STORE) { 14906d5e247SLoGin kern_callback = &PreallocKFOpsWriteOnly; 15006d5e247SLoGin } else { 15106d5e247SLoGin kern_callback = &PreallocKFOpsEmpty; 15206d5e247SLoGin } 15306d5e247SLoGin 154*7eda31b2SLoGin let sys_priv = SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, Some(attr), None)); 15506d5e247SLoGin let r = parent.add_file( 15606d5e247SLoGin attr.name().to_string(), 15706d5e247SLoGin mode.bitand(ModeType::from_bits_truncate(0o777)), 158*7eda31b2SLoGin Some(4096), 15906d5e247SLoGin Some(KernInodePrivateData::SysFS(sys_priv)), 16006d5e247SLoGin Some(kern_callback), 16106d5e247SLoGin ); 16206d5e247SLoGin 16306d5e247SLoGin if let Err(e) = r { 16406d5e247SLoGin if e == SystemError::EEXIST { 16506d5e247SLoGin self.warn_duplicate(parent, attr.name()); 16606d5e247SLoGin } 16706d5e247SLoGin 16806d5e247SLoGin return Err(e); 16906d5e247SLoGin } 17006d5e247SLoGin return Ok(()); 17106d5e247SLoGin } 17206d5e247SLoGin 17306d5e247SLoGin /// 在sysfs中删除某个kobject的属性文件 17406d5e247SLoGin /// 17506d5e247SLoGin /// 如果属性文件不存在,则发出一个警告 17606d5e247SLoGin /// 17706d5e247SLoGin /// ## 参数 17806d5e247SLoGin /// 17906d5e247SLoGin /// - `kobj` 要删除属性文件的kobject 18006d5e247SLoGin /// - `attr` 属性 18106d5e247SLoGin pub fn remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute) { 18206d5e247SLoGin let parent = kobj.inode(); 18306d5e247SLoGin 18406d5e247SLoGin if let Some(parent) = parent { 18506d5e247SLoGin let r = parent.remove(attr.name()); 18606d5e247SLoGin if unlikely(r.is_err()) { 18706d5e247SLoGin kwarn!( 18806d5e247SLoGin "failed to remove file '{}' from '{}'", 18906d5e247SLoGin attr.name(), 19006d5e247SLoGin kobj.name() 19106d5e247SLoGin ); 19206d5e247SLoGin } 19306d5e247SLoGin } 19406d5e247SLoGin } 195*7eda31b2SLoGin 196*7eda31b2SLoGin /// 在sysfs中,为指定的kobject创建一个动态申请的bin属性文件 197*7eda31b2SLoGin /// 198*7eda31b2SLoGin /// ## 参数 199*7eda31b2SLoGin /// 200*7eda31b2SLoGin /// - `kobj` 要创建属性文件的kobject 201*7eda31b2SLoGin /// - `attr` 属性 202*7eda31b2SLoGin /// 203*7eda31b2SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/file.c#558 204*7eda31b2SLoGin pub fn create_bin_file( 205*7eda31b2SLoGin &self, 206*7eda31b2SLoGin kobj: &Arc<dyn KObject>, 207*7eda31b2SLoGin attr: &Arc<dyn BinAttribute>, 208*7eda31b2SLoGin ) -> Result<(), SystemError> { 209*7eda31b2SLoGin let inode = kobj.inode().ok_or(SystemError::EINVAL)?; 210*7eda31b2SLoGin return self.add_bin_file_with_mode(&inode, attr, attr.mode()); 211*7eda31b2SLoGin } 212*7eda31b2SLoGin 213*7eda31b2SLoGin /// 在sysfs中删除某个kobject的bin属性文件 214*7eda31b2SLoGin /// 215*7eda31b2SLoGin /// 如果属性文件不存在,则发出一个警告 216*7eda31b2SLoGin #[allow(dead_code)] 217*7eda31b2SLoGin pub fn remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>) { 218*7eda31b2SLoGin let parent = kobj.inode(); 219*7eda31b2SLoGin 220*7eda31b2SLoGin if let Some(parent) = parent { 221*7eda31b2SLoGin let r = parent.remove(attr.name()); 222*7eda31b2SLoGin if unlikely(r.is_err()) { 223*7eda31b2SLoGin kwarn!( 224*7eda31b2SLoGin "failed to remove file '{}' from '{}'", 225*7eda31b2SLoGin attr.name(), 226*7eda31b2SLoGin kobj.name() 227*7eda31b2SLoGin ); 228*7eda31b2SLoGin } 229*7eda31b2SLoGin } 230*7eda31b2SLoGin } 231*7eda31b2SLoGin 232*7eda31b2SLoGin /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/file.c#304 233*7eda31b2SLoGin pub(super) fn add_bin_file_with_mode( 234*7eda31b2SLoGin &self, 235*7eda31b2SLoGin parent: &Arc<KernFSInode>, 236*7eda31b2SLoGin attr: &Arc<dyn BinAttribute>, 237*7eda31b2SLoGin mode: ModeType, 238*7eda31b2SLoGin ) -> Result<(), SystemError> { 239*7eda31b2SLoGin let x = parent.private_data_mut(); 240*7eda31b2SLoGin let kobj: Arc<dyn KObject>; 241*7eda31b2SLoGin if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() { 242*7eda31b2SLoGin kobj = dt.kobj().unwrap(); 243*7eda31b2SLoGin } else { 244*7eda31b2SLoGin drop(x); 245*7eda31b2SLoGin let path = self.kernfs_path(parent); 246*7eda31b2SLoGin panic!("parent '{path}' is not a dir"); 247*7eda31b2SLoGin } 248*7eda31b2SLoGin drop(x); 249*7eda31b2SLoGin 250*7eda31b2SLoGin let kern_callback: &'static dyn KernFSCallback; 251*7eda31b2SLoGin let bin_support = attr.support_battr(); 252*7eda31b2SLoGin 253*7eda31b2SLoGin if bin_support.contains(SysFSOpsSupport::READ) 254*7eda31b2SLoGin && bin_support.contains(SysFSOpsSupport::WRITE) 255*7eda31b2SLoGin { 256*7eda31b2SLoGin kern_callback = &PreallocKFOpsRW; 257*7eda31b2SLoGin } else if bin_support.contains(SysFSOpsSupport::READ) { 258*7eda31b2SLoGin kern_callback = &PreallocKFOpsReadOnly; 259*7eda31b2SLoGin } else if bin_support.contains(SysFSOpsSupport::WRITE) { 260*7eda31b2SLoGin kern_callback = &PreallocKFOpsWriteOnly; 261*7eda31b2SLoGin } else { 262*7eda31b2SLoGin kern_callback = &PreallocKFOpsEmpty; 263*7eda31b2SLoGin } 264*7eda31b2SLoGin 265*7eda31b2SLoGin let sys_priv = 266*7eda31b2SLoGin SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, None, Some(attr.clone()))); 267*7eda31b2SLoGin let r = parent.add_file( 268*7eda31b2SLoGin attr.name().to_string(), 269*7eda31b2SLoGin mode.bitand(ModeType::from_bits_truncate(0o777)), 270*7eda31b2SLoGin Some(attr.size()), 271*7eda31b2SLoGin Some(KernInodePrivateData::SysFS(sys_priv)), 272*7eda31b2SLoGin Some(kern_callback), 273*7eda31b2SLoGin ); 274*7eda31b2SLoGin 275*7eda31b2SLoGin if let Err(e) = r { 276*7eda31b2SLoGin if e == SystemError::EEXIST { 277*7eda31b2SLoGin self.warn_duplicate(parent, attr.name()); 278*7eda31b2SLoGin } 279*7eda31b2SLoGin 280*7eda31b2SLoGin return Err(e); 281*7eda31b2SLoGin } 282*7eda31b2SLoGin return Ok(()); 283*7eda31b2SLoGin } 28406d5e247SLoGin } 28506d5e247SLoGin 28606d5e247SLoGin #[derive(Debug)] 28706d5e247SLoGin struct PreallocKFOpsRW; 28806d5e247SLoGin 28906d5e247SLoGin impl KernFSCallback for PreallocKFOpsRW { 29006d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 29106d5e247SLoGin return Ok(()); 29206d5e247SLoGin } 29306d5e247SLoGin 29406d5e247SLoGin fn read( 29506d5e247SLoGin &self, 29606d5e247SLoGin data: KernCallbackData, 29706d5e247SLoGin buf: &mut [u8], 29806d5e247SLoGin offset: usize, 29906d5e247SLoGin ) -> Result<usize, SystemError> { 30006d5e247SLoGin return data.callback_read(buf, offset); 30106d5e247SLoGin } 30206d5e247SLoGin 30306d5e247SLoGin fn write( 30406d5e247SLoGin &self, 30506d5e247SLoGin data: KernCallbackData, 30606d5e247SLoGin buf: &[u8], 30706d5e247SLoGin offset: usize, 30806d5e247SLoGin ) -> Result<usize, SystemError> { 30906d5e247SLoGin return data.callback_write(buf, offset); 31006d5e247SLoGin } 31106d5e247SLoGin 31206d5e247SLoGin #[inline] 31306d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 31406d5e247SLoGin return Ok(PollStatus::READ | PollStatus::WRITE); 31506d5e247SLoGin } 31606d5e247SLoGin } 31706d5e247SLoGin 31806d5e247SLoGin #[derive(Debug)] 31906d5e247SLoGin struct PreallocKFOpsReadOnly; 32006d5e247SLoGin 32106d5e247SLoGin impl KernFSCallback for PreallocKFOpsReadOnly { 32206d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 32306d5e247SLoGin return Ok(()); 32406d5e247SLoGin } 32506d5e247SLoGin 32606d5e247SLoGin fn read( 32706d5e247SLoGin &self, 32806d5e247SLoGin data: KernCallbackData, 32906d5e247SLoGin buf: &mut [u8], 33006d5e247SLoGin offset: usize, 33106d5e247SLoGin ) -> Result<usize, SystemError> { 33206d5e247SLoGin return data.callback_read(buf, offset); 33306d5e247SLoGin } 33406d5e247SLoGin 33506d5e247SLoGin fn write( 33606d5e247SLoGin &self, 33706d5e247SLoGin _data: KernCallbackData, 33806d5e247SLoGin _buf: &[u8], 33906d5e247SLoGin _offset: usize, 34006d5e247SLoGin ) -> Result<usize, SystemError> { 34106d5e247SLoGin return Err(SystemError::EPERM); 34206d5e247SLoGin } 34306d5e247SLoGin 34406d5e247SLoGin #[inline] 34506d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 34606d5e247SLoGin return Ok(PollStatus::READ); 34706d5e247SLoGin } 34806d5e247SLoGin } 34906d5e247SLoGin 35006d5e247SLoGin #[derive(Debug)] 35106d5e247SLoGin struct PreallocKFOpsWriteOnly; 35206d5e247SLoGin 35306d5e247SLoGin impl KernFSCallback for PreallocKFOpsWriteOnly { 35406d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 35506d5e247SLoGin return Ok(()); 35606d5e247SLoGin } 35706d5e247SLoGin 35806d5e247SLoGin fn read( 35906d5e247SLoGin &self, 36006d5e247SLoGin _data: KernCallbackData, 36106d5e247SLoGin _buf: &mut [u8], 36206d5e247SLoGin _offset: usize, 36306d5e247SLoGin ) -> Result<usize, SystemError> { 36406d5e247SLoGin return Err(SystemError::EPERM); 36506d5e247SLoGin } 36606d5e247SLoGin 36706d5e247SLoGin fn write( 36806d5e247SLoGin &self, 36906d5e247SLoGin data: KernCallbackData, 37006d5e247SLoGin buf: &[u8], 37106d5e247SLoGin offset: usize, 37206d5e247SLoGin ) -> Result<usize, SystemError> { 37306d5e247SLoGin return data.callback_write(buf, offset); 37406d5e247SLoGin } 37506d5e247SLoGin 37606d5e247SLoGin #[inline] 37706d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 37806d5e247SLoGin return Ok(PollStatus::WRITE); 37906d5e247SLoGin } 38006d5e247SLoGin } 38106d5e247SLoGin 38206d5e247SLoGin #[derive(Debug)] 38306d5e247SLoGin struct PreallocKFOpsEmpty; 38406d5e247SLoGin 38506d5e247SLoGin impl KernFSCallback for PreallocKFOpsEmpty { 38606d5e247SLoGin fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { 38706d5e247SLoGin return Ok(()); 38806d5e247SLoGin } 38906d5e247SLoGin 39006d5e247SLoGin fn read( 39106d5e247SLoGin &self, 39206d5e247SLoGin _data: KernCallbackData, 39306d5e247SLoGin _buf: &mut [u8], 39406d5e247SLoGin _offset: usize, 39506d5e247SLoGin ) -> Result<usize, SystemError> { 39606d5e247SLoGin return Err(SystemError::EPERM); 39706d5e247SLoGin } 39806d5e247SLoGin 39906d5e247SLoGin fn write( 40006d5e247SLoGin &self, 40106d5e247SLoGin _data: KernCallbackData, 40206d5e247SLoGin _buf: &[u8], 40306d5e247SLoGin _offset: usize, 40406d5e247SLoGin ) -> Result<usize, SystemError> { 40506d5e247SLoGin return Err(SystemError::EPERM); 40606d5e247SLoGin } 40706d5e247SLoGin 40806d5e247SLoGin #[inline] 40906d5e247SLoGin fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> { 41006d5e247SLoGin return Ok(PollStatus::empty()); 41106d5e247SLoGin } 41206d5e247SLoGin } 41306d5e247SLoGin 41406d5e247SLoGin pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError> { 41506d5e247SLoGin let len; 41606d5e247SLoGin if buf.len() > s.len() { 41706d5e247SLoGin len = s.len(); 41806d5e247SLoGin } else { 41906d5e247SLoGin len = buf.len() - 1; 42006d5e247SLoGin } 42106d5e247SLoGin buf[..len].copy_from_slice(&s.as_bytes()[..len]); 42206d5e247SLoGin buf[len] = b'\0'; 42306d5e247SLoGin return Ok(len); 4246b4e7a29SLoGin } 425