Skip to main content

starnix_modules_procfs/
fs.rs

1// Copyright 2021 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::proc_directory::ProcDirectory;
6use starnix_core::task::CurrentTask;
7use starnix_core::vfs::{
8    CacheMode, FileSystem, FileSystemHandle, FileSystemOps, FileSystemOptions, FsStr,
9};
10use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Unlocked};
11use starnix_types::vfs::default_statfs;
12use starnix_uapi::errors::Errno;
13use starnix_uapi::{PROC_SUPER_MAGIC, statfs};
14
15struct ProcFsHandle(FileSystemHandle);
16
17/// Returns `kernel`'s procfs instance, initializing it if needed.
18pub fn proc_fs(
19    locked: &mut Locked<Unlocked>,
20    current_task: &CurrentTask,
21    options: FileSystemOptions,
22) -> Result<FileSystemHandle, Errno> {
23    Ok(current_task
24        .kernel()
25        .expando
26        .get_or_init(|| ProcFsHandle(ProcFs::new_fs(locked, current_task, options)))
27        .0
28        .clone())
29}
30
31/// `ProcFs` is a filesystem that exposes runtime information about a `Kernel` instance.
32#[derive(Debug, Clone)]
33struct ProcFs;
34
35impl FileSystemOps for ProcFs {
36    fn statfs(
37        &self,
38        _locked: &mut Locked<FileOpsCore>,
39        _fs: &FileSystem,
40        _current_task: &CurrentTask,
41    ) -> Result<statfs, Errno> {
42        Ok(default_statfs(PROC_SUPER_MAGIC))
43    }
44    fn name(&self) -> &'static FsStr {
45        "proc".into()
46    }
47}
48
49impl ProcFs {
50    /// Creates a new instance of `ProcFs` for the given `kernel`.
51    pub fn new_fs<L>(
52        locked: &mut Locked<L>,
53        current_task: &CurrentTask,
54        options: FileSystemOptions,
55    ) -> FileSystemHandle
56    where
57        L: LockEqualOrBefore<FileOpsCore>,
58    {
59        let kernel = current_task.kernel();
60        let fs = FileSystem::new(locked, kernel, CacheMode::Uncached, ProcFs, options)
61            .expect("procfs constructed with valid options");
62        let root_ino = fs.allocate_ino();
63        fs.create_root(root_ino, ProcDirectory::new(kernel, &fs));
64        fs
65    }
66}