1 use core::{intrinsics::unlikely, ops::BitAnd};
2
3 use alloc::{
4 string::ToString,
5 sync::{Arc, Weak},
6 };
7 use log::warn;
8 use system_error::SystemError;
9
10 use crate::{
11 driver::base::kobject::KObject,
12 filesystem::{
13 kernfs::{
14 callback::{KernCallbackData, KernFSCallback, KernInodePrivateData},
15 KernFSInode,
16 },
17 sysfs::{SysFSOps, SysFSOpsSupport},
18 vfs::{syscall::ModeType, PollStatus},
19 },
20 };
21
22 use super::{Attribute, BinAttribute, SysFS, SysFSKernPrivateData};
23
24 #[derive(Debug)]
25 pub struct SysKernFilePriv {
26 attribute: Option<&'static dyn Attribute>,
27 /// bin attribute和attribute二选一,只能有一个为Some
28 bin_attribute: Option<Arc<dyn BinAttribute>>,
29 /// 当前文件对应的kobject
30 kobj: Weak<dyn KObject>,
31 }
32
33 impl SysKernFilePriv {
new( kobj: &Arc<dyn KObject>, attribute: Option<&'static dyn Attribute>, bin_attribute: Option<Arc<dyn BinAttribute>>, ) -> Self34 pub fn new(
35 kobj: &Arc<dyn KObject>,
36 attribute: Option<&'static dyn Attribute>,
37 bin_attribute: Option<Arc<dyn BinAttribute>>,
38 ) -> Self {
39 if attribute.is_none() && bin_attribute.is_none() {
40 panic!("attribute and bin_attribute can't be both None");
41 }
42 if attribute.is_some() && bin_attribute.is_some() {
43 panic!("attribute and bin_attribute can't be both Some");
44 }
45
46 let kobj = Arc::downgrade(kobj);
47 return Self {
48 kobj,
49 attribute,
50 bin_attribute,
51 };
52 }
53
54 #[allow(dead_code)]
55 #[inline]
attribute(&self) -> Option<&'static dyn Attribute>56 pub fn attribute(&self) -> Option<&'static dyn Attribute> {
57 self.attribute
58 }
59
callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError>60 pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
61 if let Some(attribute) = self.attribute {
62 // 当前文件所指向的kobject已经被释放
63 let kobj = self.kobj.upgrade().expect("kobj is None");
64 let len = attribute.show(kobj, buf)?;
65 if offset > 0 {
66 if len <= offset {
67 return Ok(0);
68 }
69 let len = len - offset;
70 buf.copy_within(offset..offset + len, 0);
71 buf[len] = 0;
72 }
73 return Ok(len);
74 } else if let Some(bin_attribute) = self.bin_attribute.as_ref() {
75 // 当前文件所指向的kobject已经被释放
76 let kobj = self.kobj.upgrade().expect("kobj is None");
77 return bin_attribute.read(kobj, buf, offset);
78 } else {
79 panic!("attribute and bin_attribute can't be both None");
80 }
81 }
82
callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError>83 pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> {
84 if let Some(attribute) = self.attribute {
85 // 当前文件所指向的kobject已经被释放
86 let kobj = self.kobj.upgrade().expect("kobj is None");
87 return attribute.store(kobj, buf);
88 } else if let Some(bin_attribute) = self.bin_attribute.as_ref() {
89 // 当前文件所指向的kobject已经被释放
90 let kobj = self.kobj.upgrade().expect("kobj is None");
91 return bin_attribute.write(kobj, buf, offset);
92 } else {
93 panic!("attribute and bin_attribute can't be both None");
94 }
95 }
96 }
97
98 impl SysFS {
99 /// 为指定的kobject创建一个属性文件
100 ///
101 /// ## 参数
102 ///
103 /// - `kobj` 要创建属性文件的kobject
104 /// - `attr` 属性
create_file( &self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Result<(), SystemError>105 pub fn create_file(
106 &self,
107 kobj: &Arc<dyn KObject>,
108 attr: &'static dyn Attribute,
109 ) -> Result<(), SystemError> {
110 let inode = kobj.inode().ok_or(SystemError::EINVAL)?;
111 return self.add_file_with_mode(&inode, attr, attr.mode());
112 }
113
114 // 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>115 pub(super) fn add_file_with_mode(
116 &self,
117 parent: &Arc<KernFSInode>,
118 attr: &'static dyn Attribute,
119 mode: ModeType,
120 ) -> Result<(), SystemError> {
121 let x = parent.private_data_mut();
122 let kobj: Arc<dyn KObject>;
123 if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() {
124 kobj = dt.kobj().unwrap();
125 } else {
126 drop(x);
127 let path = self.kernfs_path(parent);
128 panic!("parent '{path}' is not a dir");
129 }
130 drop(x);
131
132 let sysfs_ops: &dyn SysFSOps = kobj.kobj_type().unwrap().sysfs_ops().ok_or_else(|| {
133 warn!("missing sysfs attribute operations for kobject: {kobj:?}");
134 SystemError::EINVAL
135 })?;
136
137 // assume that all sysfs ops are preallocated.
138
139 let sys_support = sysfs_ops.support(attr);
140
141 let kern_callback: &'static dyn KernFSCallback;
142 if sys_support.contains(SysFSOpsSupport::ATTR_SHOW)
143 && sys_support.contains(SysFSOpsSupport::ATTR_STORE)
144 {
145 kern_callback = &PreallocKFOpsRW;
146 } else if sys_support.contains(SysFSOpsSupport::ATTR_SHOW) {
147 kern_callback = &PreallocKFOpsReadOnly;
148 } else if sys_support.contains(SysFSOpsSupport::ATTR_STORE) {
149 kern_callback = &PreallocKFOpsWriteOnly;
150 } else {
151 kern_callback = &PreallocKFOpsEmpty;
152 }
153
154 let sys_priv = SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, Some(attr), None));
155 let r = parent.add_file(
156 attr.name().to_string(),
157 mode.bitand(ModeType::from_bits_truncate(0o777)),
158 Some(4096),
159 Some(KernInodePrivateData::SysFS(sys_priv)),
160 Some(kern_callback),
161 );
162
163 if let Err(e) = r {
164 if e == SystemError::EEXIST {
165 self.warn_duplicate(parent, attr.name());
166 }
167
168 return Err(e);
169 }
170 return Ok(());
171 }
172
173 /// 在sysfs中删除某个kobject的属性文件
174 ///
175 /// 如果属性文件不存在,则发出一个警告
176 ///
177 /// ## 参数
178 ///
179 /// - `kobj` 要删除属性文件的kobject
180 /// - `attr` 属性
remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute)181 pub fn remove_file(&self, kobj: &Arc<dyn KObject>, attr: &'static dyn Attribute) {
182 let parent = kobj.inode();
183
184 if let Some(parent) = parent {
185 let r = parent.remove(attr.name());
186 if unlikely(r.is_err()) {
187 warn!(
188 "failed to remove file '{}' from '{}'",
189 attr.name(),
190 kobj.name()
191 );
192 }
193 }
194 }
195
196 /// 在sysfs中,为指定的kobject创建一个动态申请的bin属性文件
197 ///
198 /// ## 参数
199 ///
200 /// - `kobj` 要创建属性文件的kobject
201 /// - `attr` 属性
202 ///
203 /// 参考 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>204 pub fn create_bin_file(
205 &self,
206 kobj: &Arc<dyn KObject>,
207 attr: &Arc<dyn BinAttribute>,
208 ) -> Result<(), SystemError> {
209 let inode = kobj.inode().ok_or(SystemError::EINVAL)?;
210 return self.add_bin_file_with_mode(&inode, attr, attr.mode());
211 }
212
213 /// 在sysfs中删除某个kobject的bin属性文件
214 ///
215 /// 如果属性文件不存在,则发出一个警告
216 #[allow(dead_code)]
remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>)217 pub fn remove_bin_file(&self, kobj: &Arc<dyn KObject>, attr: &Arc<dyn BinAttribute>) {
218 let parent = kobj.inode();
219
220 if let Some(parent) = parent {
221 let r = parent.remove(attr.name());
222 if unlikely(r.is_err()) {
223 warn!(
224 "failed to remove file '{}' from '{}'",
225 attr.name(),
226 kobj.name()
227 );
228 }
229 }
230 }
231
232 /// 参考 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>233 pub(super) fn add_bin_file_with_mode(
234 &self,
235 parent: &Arc<KernFSInode>,
236 attr: &Arc<dyn BinAttribute>,
237 mode: ModeType,
238 ) -> Result<(), SystemError> {
239 let x = parent.private_data_mut();
240 let kobj: Arc<dyn KObject>;
241 if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() {
242 kobj = dt.kobj().unwrap();
243 } else {
244 drop(x);
245 let path = self.kernfs_path(parent);
246 panic!("parent '{path}' is not a dir");
247 }
248 drop(x);
249
250 let kern_callback: &'static dyn KernFSCallback;
251 let bin_support = attr.support_battr();
252
253 if bin_support.contains(SysFSOpsSupport::BATTR_READ)
254 && bin_support.contains(SysFSOpsSupport::BATTR_WRITE)
255 {
256 kern_callback = &PreallocKFOpsRW;
257 } else if bin_support.contains(SysFSOpsSupport::BATTR_READ) {
258 kern_callback = &PreallocKFOpsReadOnly;
259 } else if bin_support.contains(SysFSOpsSupport::BATTR_WRITE) {
260 kern_callback = &PreallocKFOpsWriteOnly;
261 } else {
262 kern_callback = &PreallocKFOpsEmpty;
263 }
264
265 let sys_priv =
266 SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, None, Some(attr.clone())));
267 let r = parent.add_file(
268 attr.name().to_string(),
269 mode.bitand(ModeType::from_bits_truncate(0o777)),
270 Some(attr.size()),
271 Some(KernInodePrivateData::SysFS(sys_priv)),
272 Some(kern_callback),
273 );
274
275 if let Err(e) = r {
276 if e == SystemError::EEXIST {
277 self.warn_duplicate(parent, attr.name());
278 }
279
280 return Err(e);
281 }
282 return Ok(());
283 }
284 }
285
286 #[derive(Debug)]
287 struct PreallocKFOpsRW;
288
289 impl KernFSCallback for PreallocKFOpsRW {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>290 fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
291 return Ok(());
292 }
293
read( &self, data: KernCallbackData, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>294 fn read(
295 &self,
296 data: KernCallbackData,
297 buf: &mut [u8],
298 offset: usize,
299 ) -> Result<usize, SystemError> {
300 return data.callback_read(buf, offset);
301 }
302
write( &self, data: KernCallbackData, buf: &[u8], offset: usize, ) -> Result<usize, SystemError>303 fn write(
304 &self,
305 data: KernCallbackData,
306 buf: &[u8],
307 offset: usize,
308 ) -> Result<usize, SystemError> {
309 return data.callback_write(buf, offset);
310 }
311
312 #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>313 fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
314 return Ok(PollStatus::READ | PollStatus::WRITE);
315 }
316 }
317
318 #[derive(Debug)]
319 struct PreallocKFOpsReadOnly;
320
321 impl KernFSCallback for PreallocKFOpsReadOnly {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>322 fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
323 return Ok(());
324 }
325
read( &self, data: KernCallbackData, buf: &mut [u8], offset: usize, ) -> Result<usize, SystemError>326 fn read(
327 &self,
328 data: KernCallbackData,
329 buf: &mut [u8],
330 offset: usize,
331 ) -> Result<usize, SystemError> {
332 return data.callback_read(buf, offset);
333 }
334
write( &self, _data: KernCallbackData, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>335 fn write(
336 &self,
337 _data: KernCallbackData,
338 _buf: &[u8],
339 _offset: usize,
340 ) -> Result<usize, SystemError> {
341 return Err(SystemError::EPERM);
342 }
343
344 #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>345 fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
346 return Ok(PollStatus::READ);
347 }
348 }
349
350 #[derive(Debug)]
351 struct PreallocKFOpsWriteOnly;
352
353 impl KernFSCallback for PreallocKFOpsWriteOnly {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>354 fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
355 return Ok(());
356 }
357
read( &self, _data: KernCallbackData, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>358 fn read(
359 &self,
360 _data: KernCallbackData,
361 _buf: &mut [u8],
362 _offset: usize,
363 ) -> Result<usize, SystemError> {
364 return Err(SystemError::EPERM);
365 }
366
write( &self, data: KernCallbackData, buf: &[u8], offset: usize, ) -> Result<usize, SystemError>367 fn write(
368 &self,
369 data: KernCallbackData,
370 buf: &[u8],
371 offset: usize,
372 ) -> Result<usize, SystemError> {
373 return data.callback_write(buf, offset);
374 }
375
376 #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>377 fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
378 return Ok(PollStatus::WRITE);
379 }
380 }
381
382 #[derive(Debug)]
383 struct PreallocKFOpsEmpty;
384
385 impl KernFSCallback for PreallocKFOpsEmpty {
open(&self, _data: KernCallbackData) -> Result<(), SystemError>386 fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> {
387 return Ok(());
388 }
389
read( &self, _data: KernCallbackData, _buf: &mut [u8], _offset: usize, ) -> Result<usize, SystemError>390 fn read(
391 &self,
392 _data: KernCallbackData,
393 _buf: &mut [u8],
394 _offset: usize,
395 ) -> Result<usize, SystemError> {
396 return Err(SystemError::EPERM);
397 }
398
write( &self, _data: KernCallbackData, _buf: &[u8], _offset: usize, ) -> Result<usize, SystemError>399 fn write(
400 &self,
401 _data: KernCallbackData,
402 _buf: &[u8],
403 _offset: usize,
404 ) -> Result<usize, SystemError> {
405 return Err(SystemError::EPERM);
406 }
407
408 #[inline]
poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError>409 fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
410 return Ok(PollStatus::empty());
411 }
412 }
413
sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError>414 pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError> {
415 let len = if buf.len() > s.len() {
416 s.len()
417 } else {
418 buf.len() - 1
419 };
420 buf[..len].copy_from_slice(&s.as_bytes()[..len]);
421 buf[len] = b'\0';
422 return Ok(len);
423 }
424