106d5e247SLoGin use core::{intrinsics::unlikely, ops::BitAnd}; 206d5e247SLoGin 306d5e247SLoGin use alloc::{ 406d5e247SLoGin string::ToString, 506d5e247SLoGin sync::{Arc, Weak}, 606d5e247SLoGin }; 791e9d4abSLoGin use system_error::SystemError; 806d5e247SLoGin 906d5e247SLoGin use crate::{ 1006d5e247SLoGin driver::base::kobject::KObject, 1106d5e247SLoGin filesystem::{ 1206d5e247SLoGin kernfs::{ 1306d5e247SLoGin callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}, 1406d5e247SLoGin KernFSInode, 1506d5e247SLoGin }, 1606d5e247SLoGin sysfs::{SysFSOps, SysFSOpsSupport}, 1706d5e247SLoGin vfs::{syscall::ModeType, PollStatus}, 1806d5e247SLoGin }, 1906d5e247SLoGin kwarn, 2006d5e247SLoGin }; 2106d5e247SLoGin 227eda31b2SLoGin use super::{Attribute, BinAttribute, SysFS, SysFSKernPrivateData}; 236b4e7a29SLoGin 246b4e7a29SLoGin #[derive(Debug)] 256b4e7a29SLoGin pub struct SysKernFilePriv { 266b4e7a29SLoGin attribute: Option<&'static dyn Attribute>, 277eda31b2SLoGin /// bin attribute和attribute二选一,只能有一个为Some 287eda31b2SLoGin bin_attribute: Option<Arc<dyn BinAttribute>>, 2906d5e247SLoGin /// 当前文件对应的kobject 3006d5e247SLoGin kobj: Weak<dyn KObject>, 316b4e7a29SLoGin } 326b4e7a29SLoGin 336b4e7a29SLoGin impl SysKernFilePriv { 347eda31b2SLoGin pub fn new( 357eda31b2SLoGin kobj: &Arc<dyn KObject>, 367eda31b2SLoGin attribute: Option<&'static dyn Attribute>, 377eda31b2SLoGin bin_attribute: Option<Arc<dyn BinAttribute>>, 387eda31b2SLoGin ) -> Self { 397eda31b2SLoGin if attribute.is_none() && bin_attribute.is_none() { 407eda31b2SLoGin panic!("attribute and bin_attribute can't be both None"); 416b4e7a29SLoGin } 427eda31b2SLoGin if attribute.is_some() && bin_attribute.is_some() { 437eda31b2SLoGin panic!("attribute and bin_attribute can't be both Some"); 447eda31b2SLoGin } 457eda31b2SLoGin 4606d5e247SLoGin let kobj = Arc::downgrade(kobj); 477eda31b2SLoGin return Self { 487eda31b2SLoGin kobj, 497eda31b2SLoGin attribute, 507eda31b2SLoGin bin_attribute, 517eda31b2SLoGin }; 526b4e7a29SLoGin } 536b4e7a29SLoGin 5406d5e247SLoGin #[allow(dead_code)] 5506d5e247SLoGin #[inline] 566b4e7a29SLoGin pub fn attribute(&self) -> Option<&'static dyn Attribute> { 576b4e7a29SLoGin self.attribute 586b4e7a29SLoGin } 5906d5e247SLoGin 607eda31b2SLoGin pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> { 617eda31b2SLoGin if let Some(attribute) = self.attribute { 6206d5e247SLoGin // 当前文件所指向的kobject已经被释放 6306d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 647eda31b2SLoGin let len = attribute.show(kobj, buf)?; 657eda31b2SLoGin if offset > 0 { 667eda31b2SLoGin if len <= offset { 677eda31b2SLoGin return Ok(0); 687eda31b2SLoGin } 697eda31b2SLoGin let len = len - offset; 707eda31b2SLoGin buf.copy_within(offset..offset + len, 0); 717eda31b2SLoGin buf[len] = 0; 727eda31b2SLoGin } 737eda31b2SLoGin return Ok(len); 747eda31b2SLoGin } else if let Some(bin_attribute) = self.bin_attribute.as_ref() { 757eda31b2SLoGin // 当前文件所指向的kobject已经被释放 767eda31b2SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 777eda31b2SLoGin return bin_attribute.read(kobj, buf, offset); 787eda31b2SLoGin } else { 797eda31b2SLoGin panic!("attribute and bin_attribute can't be both None"); 807eda31b2SLoGin } 8106d5e247SLoGin } 8206d5e247SLoGin 837eda31b2SLoGin pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> { 847eda31b2SLoGin if let Some(attribute) = self.attribute { 8506d5e247SLoGin // 当前文件所指向的kobject已经被释放 8606d5e247SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 8706d5e247SLoGin return attribute.store(kobj, buf); 887eda31b2SLoGin } else if let Some(bin_attribute) = self.bin_attribute.as_ref() { 897eda31b2SLoGin // 当前文件所指向的kobject已经被释放 907eda31b2SLoGin let kobj = self.kobj.upgrade().expect("kobj is None"); 917eda31b2SLoGin return bin_attribute.write(kobj, buf, offset); 927eda31b2SLoGin } else { 937eda31b2SLoGin panic!("attribute and bin_attribute can't be both None"); 947eda31b2SLoGin } 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 114e7071df6SLoGin // https://code.dragonos.org.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; 142*196b75dcSLoGin if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) 143*196b75dcSLoGin && sys_support.contains(SysFSOpsSupport::ATTR_STORE) 14406d5e247SLoGin { 14506d5e247SLoGin kern_callback = &PreallocKFOpsRW; 146*196b75dcSLoGin } else if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) { 14706d5e247SLoGin kern_callback = &PreallocKFOpsReadOnly; 148*196b75dcSLoGin } else if sys_support.contains(SysFSOpsSupport::ATTR_STORE) { 14906d5e247SLoGin kern_callback = &PreallocKFOpsWriteOnly; 15006d5e247SLoGin } else { 15106d5e247SLoGin kern_callback = &PreallocKFOpsEmpty; 15206d5e247SLoGin } 15306d5e247SLoGin 1547eda31b2SLoGin 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)), 1587eda31b2SLoGin 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 } 1957eda31b2SLoGin 1967eda31b2SLoGin /// 在sysfs中,为指定的kobject创建一个动态申请的bin属性文件 1977eda31b2SLoGin /// 1987eda31b2SLoGin /// ## 参数 1997eda31b2SLoGin /// 2007eda31b2SLoGin /// - `kobj` 要创建属性文件的kobject 2017eda31b2SLoGin /// - `attr` 属性 2027eda31b2SLoGin /// 203e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/file.c#558 2047eda31b2SLoGin pub fn create_bin_file( 2057eda31b2SLoGin &self, 2067eda31b2SLoGin kobj: &Arc<dyn KObject>, 2077eda31b2SLoGin attr: &Arc<dyn BinAttribute>, 2087eda31b2SLoGin ) -> Result<(), SystemError> { 2097eda31b2SLoGin let inode = kobj.inode().ok_or(SystemError::EINVAL)?; 2107eda31b2SLoGin return self.add_bin_file_with_mode(&inode, attr, attr.mode()); 2117eda31b2SLoGin } 2127eda31b2SLoGin 2137eda31b2SLoGin /// 在sysfs中删除某个kobject的bin属性文件 2147eda31b2SLoGin /// 2157eda31b2SLoGin /// 如果属性文件不存在,则发出一个警告 2167eda31b2SLoGin #[allow(dead_code)] 2177eda31b2SLoGin pub fn remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>) { 2187eda31b2SLoGin let parent = kobj.inode(); 2197eda31b2SLoGin 2207eda31b2SLoGin if let Some(parent) = parent { 2217eda31b2SLoGin let r = parent.remove(attr.name()); 2227eda31b2SLoGin if unlikely(r.is_err()) { 2237eda31b2SLoGin kwarn!( 2247eda31b2SLoGin "failed to remove file '{}' from '{}'", 2257eda31b2SLoGin attr.name(), 2267eda31b2SLoGin kobj.name() 2277eda31b2SLoGin ); 2287eda31b2SLoGin } 2297eda31b2SLoGin } 2307eda31b2SLoGin } 2317eda31b2SLoGin 232e7071df6SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/sysfs/file.c#304 2337eda31b2SLoGin pub(super) fn add_bin_file_with_mode( 2347eda31b2SLoGin &self, 2357eda31b2SLoGin parent: &Arc<KernFSInode>, 2367eda31b2SLoGin attr: &Arc<dyn BinAttribute>, 2377eda31b2SLoGin mode: ModeType, 2387eda31b2SLoGin ) -> Result<(), SystemError> { 2397eda31b2SLoGin let x = parent.private_data_mut(); 2407eda31b2SLoGin let kobj: Arc<dyn KObject>; 2417eda31b2SLoGin if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() { 2427eda31b2SLoGin kobj = dt.kobj().unwrap(); 2437eda31b2SLoGin } else { 2447eda31b2SLoGin drop(x); 2457eda31b2SLoGin let path = self.kernfs_path(parent); 2467eda31b2SLoGin panic!("parent '{path}' is not a dir"); 2477eda31b2SLoGin } 2487eda31b2SLoGin drop(x); 2497eda31b2SLoGin 2507eda31b2SLoGin let kern_callback: &'static dyn KernFSCallback; 2517eda31b2SLoGin let bin_support = attr.support_battr(); 2527eda31b2SLoGin 253*196b75dcSLoGin if bin_support.contains(SysFSOpsSupport::BATTR_READ) 254*196b75dcSLoGin && bin_support.contains(SysFSOpsSupport::BATTR_WRITE) 2557eda31b2SLoGin { 2567eda31b2SLoGin kern_callback = &PreallocKFOpsRW; 257*196b75dcSLoGin } else if bin_support.contains(SysFSOpsSupport::BATTR_READ) { 2587eda31b2SLoGin kern_callback = &PreallocKFOpsReadOnly; 259*196b75dcSLoGin } else if bin_support.contains(SysFSOpsSupport::BATTR_WRITE) { 2607eda31b2SLoGin kern_callback = &PreallocKFOpsWriteOnly; 2617eda31b2SLoGin } else { 2627eda31b2SLoGin kern_callback = &PreallocKFOpsEmpty; 2637eda31b2SLoGin } 2647eda31b2SLoGin 2657eda31b2SLoGin let sys_priv = 2667eda31b2SLoGin SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, None, Some(attr.clone()))); 2677eda31b2SLoGin let r = parent.add_file( 2687eda31b2SLoGin attr.name().to_string(), 2697eda31b2SLoGin mode.bitand(ModeType::from_bits_truncate(0o777)), 2707eda31b2SLoGin Some(attr.size()), 2717eda31b2SLoGin Some(KernInodePrivateData::SysFS(sys_priv)), 2727eda31b2SLoGin Some(kern_callback), 2737eda31b2SLoGin ); 2747eda31b2SLoGin 2757eda31b2SLoGin if let Err(e) = r { 2767eda31b2SLoGin if e == SystemError::EEXIST { 2777eda31b2SLoGin self.warn_duplicate(parent, attr.name()); 2787eda31b2SLoGin } 2797eda31b2SLoGin 2807eda31b2SLoGin return Err(e); 2817eda31b2SLoGin } 2827eda31b2SLoGin return Ok(()); 2837eda31b2SLoGin } 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