starnix_core/fs/sysfs/
device_directory.rs1use crate::device::kobject::{Device, UEventFsNode};
6use crate::task::CurrentTask;
7use crate::vfs::pseudo::simple_directory::SimpleDirectoryMutator;
8use crate::vfs::pseudo::simple_file::{BytesFile, BytesFileOps};
9use crate::vfs::pseudo::stub_empty_file::StubEmptyFile;
10use crate::vfs::{DEFAULT_BYTES_PER_BLOCK, FsNodeOps};
11use starnix_logging::{bug_ref, track_stub};
12use starnix_uapi::errno;
13use starnix_uapi::errors::Errno;
14use starnix_uapi::file_mode::mode;
15use std::borrow::Cow;
16use std::sync::Weak;
17
18pub fn build_device_directory(device: &Device, dir: &SimpleDirectoryMutator) {
19 if let Some(metadata) = &device.metadata {
20 dir.entry(
21 "dev",
22 BytesFile::new_node(format!("{}\n", metadata.device_type).into_bytes()),
23 mode!(IFREG, 0o444),
24 );
25 }
26 dir.entry("uevent", UEventFsNode::new(device.clone()), mode!(IFREG, 0o644));
27}
28
29pub fn build_block_device_directory(
30 device: &Device,
31 block_info: Weak<dyn BlockDeviceInfo>,
32 dir: &SimpleDirectoryMutator,
33) {
34 build_device_directory(device, dir);
35 dir.subdir("queue", 0o755, |dir| {
36 dir.entry("nr_requests", BytesFile::new_node(NrRequestsFile::new()), mode!(IFREG, 0o644));
37 dir.entry("read_ahead_kb", BytesFile::new_node(ReadAheadKbFile), mode!(IFREG, 0o644));
38 dir.entry(
39 "scheduler",
40 StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/322907749")),
41 mode!(IFREG, 0o644),
42 );
43 });
44 dir.subdir("holders", 0o755, |_dir| {});
45 dir.entry("size", BlockDeviceSizeFile::new_node(block_info), mode!(IFREG, 0o444));
46}
47
48pub trait BlockDeviceInfo: Send + Sync {
49 fn size(&self) -> Result<usize, Errno>;
50}
51
52struct BlockDeviceSizeFile {
53 block_info: Weak<dyn BlockDeviceInfo>,
54}
55
56impl BlockDeviceSizeFile {
57 pub fn new_node(block_info: Weak<dyn BlockDeviceInfo>) -> impl FsNodeOps {
58 BytesFile::new_node(Self { block_info })
59 }
60}
61
62impl BytesFileOps for BlockDeviceSizeFile {
63 fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
64 let size = self.block_info.upgrade().ok_or_else(|| errno!(EINVAL))?.size()?;
65 let size_blocks = size / DEFAULT_BYTES_PER_BLOCK;
66 Ok(format!("{size_blocks}").into_bytes().into())
67 }
68}
69
70struct NrRequestsFile;
71
72impl NrRequestsFile {
73 fn new() -> Self {
74 Self
75 }
76}
77
78impl BytesFileOps for NrRequestsFile {
79 fn write(&self, _current_task: &CurrentTask, _data: Vec<u8>) -> Result<(), Errno> {
80 track_stub!(TODO("https://fxbug.dev/322906857"), "updating nr_requests");
83 Ok(())
84 }
85
86 fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
87 track_stub!(TODO("https://fxbug.dev/322906857"), "reading nr_requests");
91 Ok(b"128\n".into())
92 }
93}
94
95struct ReadAheadKbFile;
96
97impl BytesFileOps for ReadAheadKbFile {
98 fn write(&self, _current_task: &CurrentTask, _data: Vec<u8>) -> Result<(), Errno> {
99 track_stub!(TODO("https://fxbug.dev/297295673"), "updating read_ahead_kb");
100 Ok(())
101 }
102
103 fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
104 Ok(b"0".into())
105 }
106}