Skip to main content

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.subdir("holders", 0o755, |_dir| {});
49    dir.entry("size", BlockDeviceSizeFile::new_node(block_info), mode!(IFREG, 0o444));
50}
51
52pub trait BlockDeviceInfo: Send + Sync {
53    fn size(&self) -> Result<usize, Errno>;
54}
55
56struct BlockDeviceSizeFile {
57    block_info: Weak<dyn BlockDeviceInfo>,
58}
59
60impl BlockDeviceSizeFile {
61    pub fn new_node(block_info: Weak<dyn BlockDeviceInfo>) -> impl FsNodeOps {
62        BytesFile::new_node(Self { block_info })
63    }
64}
65
66impl BytesFileOps for BlockDeviceSizeFile {
67    fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
68        let size = self.block_info.upgrade().ok_or_else(|| errno!(EINVAL))?.size()?;
69        let size_blocks = size / DEFAULT_BYTES_PER_BLOCK;
70        Ok(format!("{size_blocks}").into_bytes().into())
71    }
72}
73
74struct ReadAheadKbFile;
75
76impl BytesFileOps for ReadAheadKbFile {
77    fn write(&self, _current_task: &CurrentTask, _data: Vec<u8>) -> Result<(), Errno> {
78        track_stub!(TODO("https://fxbug.dev/297295673"), "updating read_ahead_kb");
79        Ok(())
80    }
81
82    fn read(&self, _current_task: &CurrentTask) -> Result<Cow<'_, [u8]>, Errno> {
83        Ok(b"0".into())
84    }
85}