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