starnix_core/fs/
debugfs.rs

1// Copyright 2025 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::task::{CurrentTask, Kernel};
6use crate::vfs::pseudo::simple_directory::{SimpleDirectory, SimpleDirectoryMutator};
7use crate::vfs::pseudo::stub_empty_file::StubEmptyFile;
8use crate::vfs::{
9    CacheConfig, CacheMode, FileSystem, FileSystemHandle, FileSystemOps, FileSystemOptions, FsStr,
10};
11use starnix_logging::bug_ref;
12use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Unlocked};
13use starnix_types::vfs::default_statfs;
14use starnix_uapi::errors::Errno;
15use starnix_uapi::file_mode::mode;
16use starnix_uapi::{DEBUGFS_MAGIC, statfs};
17
18struct DebugFs;
19
20impl FileSystemOps for DebugFs {
21    fn statfs(
22        &self,
23        _locked: &mut Locked<FileOpsCore>,
24        _fs: &FileSystem,
25        _current_task: &CurrentTask,
26    ) -> Result<statfs, Errno> {
27        Ok(default_statfs(DEBUGFS_MAGIC))
28    }
29    fn name(&self) -> &'static FsStr {
30        "debugfs".into()
31    }
32}
33
34impl DebugFs {
35    fn new_fs<L>(
36        locked: &mut Locked<L>,
37        kernel: &Kernel,
38        options: FileSystemOptions,
39    ) -> FileSystemHandle
40    where
41        L: LockEqualOrBefore<FileOpsCore>,
42    {
43        let fs = FileSystem::new(
44            locked,
45            kernel,
46            CacheMode::Cached(CacheConfig::default()),
47            DebugFs,
48            options,
49        )
50        .expect("debugfs constructed with valid options");
51
52        let root = SimpleDirectory::new();
53        fs.create_root(fs.allocate_ino(), root.clone());
54
55        let dir = SimpleDirectoryMutator::new(fs.clone(), root);
56        let dir_mode = 0o700;
57        dir.subdir("binder", dir_mode, |dir| {
58            dir.entry(
59                "failed_transaction_log",
60                StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/452096300")),
61                mode!(IFREG, 0o444),
62            );
63            dir.entry(
64                "state",
65                StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/452096300")),
66                mode!(IFREG, 0o444),
67            );
68            dir.entry(
69                "stats",
70                StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/452096300")),
71                mode!(IFREG, 0o444),
72            );
73            dir.entry(
74                "transaction_log",
75                StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/452096300")),
76                mode!(IFREG, 0o444),
77            );
78            dir.entry(
79                "transactions",
80                StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/452096300")),
81                mode!(IFREG, 0o444),
82            );
83        });
84        dir.subdir("mmc0", dir_mode, |dir| {
85            dir.subdir("mmc0:0001", dir_mode, |dir| {
86                dir.entry(
87                    "ext_csd",
88                    StubEmptyFile::new_node(bug_ref!("https://fxbug.dev/452096300")),
89                    mode!(IFREG, 0o444),
90                );
91            });
92        });
93        dir.subdir("tracing", 0o644, |_| ());
94
95        fs
96    }
97}
98
99struct DebugFsHandle(FileSystemHandle);
100
101pub fn debug_fs(
102    locked: &mut Locked<Unlocked>,
103    current_task: &CurrentTask,
104    _options: FileSystemOptions,
105) -> Result<FileSystemHandle, Errno> {
106    Ok(get_debugfs(locked, current_task.kernel()))
107}
108
109pub fn get_debugfs<L>(locked: &mut Locked<L>, kernel: &Kernel) -> FileSystemHandle
110where
111    L: LockEqualOrBefore<FileOpsCore>,
112{
113    kernel
114        .expando
115        .get_or_init(|| {
116            DebugFsHandle(DebugFs::new_fs(locked, kernel, FileSystemOptions::default()))
117        })
118        .0
119        .clone()
120}