xref: /DragonOS/kernel/src/filesystem/sysfs/file.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
106d5e247SLoGin use core::{intrinsics::unlikely, ops::BitAnd};
206d5e247SLoGin 
306d5e247SLoGin use alloc::{
406d5e247SLoGin     string::ToString,
506d5e247SLoGin     sync::{Arc, Weak},
606d5e247SLoGin };
7*2eab6dd7S曾俊 use log::warn;
891e9d4abSLoGin use system_error::SystemError;
906d5e247SLoGin 
1006d5e247SLoGin use crate::{
1106d5e247SLoGin     driver::base::kobject::KObject,
1206d5e247SLoGin     filesystem::{
1306d5e247SLoGin         kernfs::{
1406d5e247SLoGin             callback::{KernCallbackData, KernFSCallback, KernInodePrivateData},
1506d5e247SLoGin             KernFSInode,
1606d5e247SLoGin         },
1706d5e247SLoGin         sysfs::{SysFSOps, SysFSOpsSupport},
1806d5e247SLoGin         vfs::{syscall::ModeType, PollStatus},
1906d5e247SLoGin     },
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 {
new( kobj: &Arc<dyn KObject>, attribute: Option<&'static dyn Attribute>, bin_attribute: Option<Arc<dyn BinAttribute>>, ) -> Self347eda31b2SLoGin     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]
attribute(&self) -> Option<&'static dyn Attribute>566b4e7a29SLoGin     pub fn attribute(&self) -> Option<&'static dyn Attribute> {
576b4e7a29SLoGin         self.attribute
586b4e7a29SLoGin     }
5906d5e247SLoGin 
callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError>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 
callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError>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` 属性
create_file( &self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Result<(), SystemError>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
add_file_with_mode( &self, parent: &Arc<KernFSInode>, attr: &'static dyn Attribute, mode: ModeType, ) -> Result<(), SystemError>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(|| {
133*2eab6dd7S曾俊             warn!("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;
142196b75dcSLoGin         if sys_support.contains(SysFSOpsSupport::ATTR_SHOW)
143196b75dcSLoGin             && sys_support.contains(SysFSOpsSupport::ATTR_STORE)
14406d5e247SLoGin         {
14506d5e247SLoGin             kern_callback = &PreallocKFOpsRW;
146196b75dcSLoGin         } else if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) {
14706d5e247SLoGin             kern_callback = &PreallocKFOpsReadOnly;
148196b75dcSLoGin         } 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` 属性
remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute)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()) {
187*2eab6dd7S曾俊                 warn!(
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
create_bin_file( &self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>, ) -> Result<(), SystemError>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)]
remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>)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()) {
223*2eab6dd7S曾俊                 warn!(
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
add_bin_file_with_mode( &self, parent: &Arc<KernFSInode>, attr: &Arc<dyn BinAttribute>, mode: ModeType, ) -> Result<(), SystemError>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 
253196b75dcSLoGin         if bin_support.contains(SysFSOpsSupport::BATTR_READ)
254196b75dcSLoGin             && bin_support.contains(SysFSOpsSupport::BATTR_WRITE)
2557eda31b2SLoGin         {
2567eda31b2SLoGin             kern_callback = &PreallocKFOpsRW;
257196b75dcSLoGin         } else if bin_support.contains(SysFSOpsSupport::BATTR_READ) {
2587eda31b2SLoGin             kern_callback = &PreallocKFOpsReadOnly;
259196b75dcSLoGin         } 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 {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>29006d5e247SLoGin     fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
29106d5e247SLoGin         return Ok(());
29206d5e247SLoGin     }
29306d5e247SLoGin 
read( &self, data: KernCallbackData, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>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 
write( &self, data: KernCallbackData, buf: &[u8], offset: usize, ) -> Result<usize, SystemError>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]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>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 {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>32206d5e247SLoGin     fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
32306d5e247SLoGin         return Ok(());
32406d5e247SLoGin     }
32506d5e247SLoGin 
read( &self, data: KernCallbackData, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>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 
write( &self, _data: KernCallbackData, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>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]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>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 {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>35406d5e247SLoGin     fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
35506d5e247SLoGin         return Ok(());
35606d5e247SLoGin     }
35706d5e247SLoGin 
read( &self, _data: KernCallbackData, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>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 
write( &self, data: KernCallbackData, buf: &[u8], offset: usize, ) -> Result<usize, SystemError>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]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>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 {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>38606d5e247SLoGin     fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
38706d5e247SLoGin         return Ok(());
38806d5e247SLoGin     }
38906d5e247SLoGin 
read( &self, _data: KernCallbackData, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>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 
write( &self, _data: KernCallbackData, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>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]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>40906d5e247SLoGin     fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
41006d5e247SLoGin         return Ok(PollStatus::empty());
41106d5e247SLoGin     }
41206d5e247SLoGin }
41306d5e247SLoGin 
sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError>41406d5e247SLoGin pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError> {
415b5b571e0SLoGin     let len = if buf.len() > s.len() {
416b5b571e0SLoGin         s.len()
41706d5e247SLoGin     } else {
418b5b571e0SLoGin         buf.len() - 1
419b5b571e0SLoGin     };
42006d5e247SLoGin     buf[..len].copy_from_slice(&s.as_bytes()[..len]);
42106d5e247SLoGin     buf[len] = b'\0';
42206d5e247SLoGin     return Ok(len);
4236b4e7a29SLoGin }
424