blob: c55a29580a8ba344e7c18a821392971f7320cf88 [file] [log] [blame] [edit]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![recursion_limit = "512"]
use bootreason::get_console_ramoops;
use starnix_core::task::CurrentTask;
use starnix_core::vfs::pseudo::simple_directory::SimpleDirectory;
use starnix_core::vfs::pseudo::simple_file::BytesFile;
use starnix_core::vfs::{
CacheMode, FileSystem, FileSystemHandle, FileSystemOps, FileSystemOptions, FsStr,
};
use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Unlocked};
use starnix_types::vfs::default_statfs;
use starnix_uapi::errors::Errno;
use starnix_uapi::file_mode::mode;
use starnix_uapi::{PSTOREFS_MAGIC, statfs};
struct PstoreFsHandle {
fs_handle: FileSystemHandle,
}
pub fn pstore_fs(
locked: &mut Locked<Unlocked>,
current_task: &CurrentTask,
options: FileSystemOptions,
) -> Result<FileSystemHandle, Errno> {
let handle = current_task.kernel().expando.get_or_try_init(|| {
Ok(PstoreFsHandle { fs_handle: PstoreFs::new_fs(locked, current_task, options)? })
})?;
Ok(handle.fs_handle.clone())
}
pub struct PstoreFs;
impl FileSystemOps for PstoreFs {
fn statfs(
&self,
_locked: &mut Locked<FileOpsCore>,
_fs: &FileSystem,
_current_task: &CurrentTask,
) -> Result<statfs, Errno> {
Ok(default_statfs(PSTOREFS_MAGIC))
}
fn name(&self) -> &'static FsStr {
"pstore".into()
}
}
impl PstoreFs {
pub fn new_fs<L>(
locked: &mut Locked<L>,
current_task: &CurrentTask,
options: FileSystemOptions,
) -> Result<FileSystemHandle, Errno>
where
L: LockEqualOrBefore<FileOpsCore>,
{
let kernel = current_task.kernel();
let fs = FileSystem::new(locked, kernel, CacheMode::Permanent, PstoreFs, options)?;
let dir = SimpleDirectory::new();
dir.edit(&fs, |dir| {
if let Some(ramoops_contents) = get_console_ramoops() {
let ramoops_contents_0 = ramoops_contents.clone();
dir.entry(
"console-ramoops-0",
BytesFile::new_node(ramoops_contents_0),
mode!(IFREG, 0o440),
);
dir.entry(
"console-ramoops",
BytesFile::new_node(ramoops_contents),
mode!(IFREG, 0o440),
);
}
});
let root_ino = fs.allocate_ino();
fs.create_root(root_ino, dir);
Ok(fs)
}
}