starnix_core/fs/sysfs/
device_directory.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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(
37            "nr_requests",
38            StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/322906857")),
39            mode!(IFREG, 0o644),
40        );
41        dir.entry("read_ahead_kb", BytesFile::new_node(ReadAheadKbFile), mode!(IFREG, 0o644));
42        dir.entry(
43            "scheduler",
44            StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/322907749")),
45            mode!(IFREG, 0o644),
46        );
47    });
48    dir.entry("size", BlockDeviceSizeFile::new_node(block_info), mode!(IFREG, 0o444));
49}
50
51pub trait BlockDeviceInfo: Send + Sync {
52    fn size(&self) -> Result<usize, Errno>;
53}
54
55struct BlockDeviceSizeFile {
56    block_info: Weak<dyn BlockDeviceInfo>,
57}
58
59impl BlockDeviceSizeFile {
60    pub fn new_node(block_info: Weak<dyn BlockDeviceInfo>) -> impl FsNodeOps {
61        BytesFile::new_node(Self { block_info })
62    }
63}
64
65impl BytesFileOps for BlockDeviceSizeFile {
66    fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
67        let size = self.block_info.upgrade().ok_or_else(|| errno!(EINVAL))?.size()?;
68        let size_blocks = size / DEFAULT_BYTES_PER_BLOCK;
69        Ok(format!("{size_blocks}").into_bytes().into())
70    }
71}
72
73struct ReadAheadKbFile;
74
75impl BytesFileOps for ReadAheadKbFile {
76    fn write(&self, _current_task: &CurrentTask, _data: Vec<u8>) -> Result<(), Errno> {
77        track_stub!(TODO("https://fxbug.dev/297295673"), "updating read_ahead_kb");
78        Ok(())
79    }
80
81    fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
82        Ok(b"0".into())
83    }
84}