Skip to main content

starnix_modules_pstore/
lib.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
5#![recursion_limit = "512"]
6
7use bootreason::get_console_ramoops;
8use starnix_core::task::CurrentTask;
9use starnix_core::vfs::pseudo::simple_directory::SimpleDirectory;
10use starnix_core::vfs::pseudo::simple_file::BytesFile;
11use starnix_core::vfs::{
12    CacheMode, FileSystem, FileSystemHandle, FileSystemOps, FileSystemOptions, FsStr,
13};
14use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Unlocked};
15use starnix_types::vfs::default_statfs;
16use starnix_uapi::errors::Errno;
17use starnix_uapi::file_mode::mode;
18use starnix_uapi::{PSTOREFS_MAGIC, statfs};
19
20struct PstoreFsHandle {
21    fs_handle: FileSystemHandle,
22}
23
24pub fn pstore_fs(
25    locked: &mut Locked<Unlocked>,
26    current_task: &CurrentTask,
27    options: FileSystemOptions,
28) -> Result<FileSystemHandle, Errno> {
29    let handle = current_task.kernel().expando.get_or_try_init(|| {
30        Ok(PstoreFsHandle { fs_handle: PstoreFs::new_fs(locked, current_task, options)? })
31    })?;
32    Ok(handle.fs_handle.clone())
33}
34
35pub struct PstoreFs;
36
37impl FileSystemOps for PstoreFs {
38    fn statfs(
39        &self,
40        _locked: &mut Locked<FileOpsCore>,
41        _fs: &FileSystem,
42        _current_task: &CurrentTask,
43    ) -> Result<statfs, Errno> {
44        Ok(default_statfs(PSTOREFS_MAGIC))
45    }
46
47    fn name(&self) -> &'static FsStr {
48        "pstore".into()
49    }
50}
51
52impl PstoreFs {
53    pub fn new_fs<L>(
54        locked: &mut Locked<L>,
55        current_task: &CurrentTask,
56        options: FileSystemOptions,
57    ) -> Result<FileSystemHandle, Errno>
58    where
59        L: LockEqualOrBefore<FileOpsCore>,
60    {
61        let kernel = current_task.kernel();
62        let fs = FileSystem::new(locked, kernel, CacheMode::Permanent, PstoreFs, options)?;
63
64        let dir = SimpleDirectory::new();
65        dir.edit(&fs, |dir| {
66            if let Some(ramoops_contents) = get_console_ramoops() {
67                let ramoops_contents_0 = ramoops_contents.clone();
68                dir.entry(
69                    "console-ramoops-0",
70                    BytesFile::new_node(ramoops_contents_0),
71                    mode!(IFREG, 0o440),
72                );
73                dir.entry(
74                    "console-ramoops",
75                    BytesFile::new_node(ramoops_contents),
76                    mode!(IFREG, 0o440),
77                );
78            }
79        });
80
81        let root_ino = fs.allocate_ino();
82        fs.create_root(root_ino, dir);
83        Ok(fs)
84    }
85}