xref: /DragonOS/kernel/src/filesystem/sysfs/file.rs (revision 7eda31b2f07c6ef41dc0d2bd13051f0fce5e5976)
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