Support allocating inodes from `PseudoFs`
This commit is contained in:
parent
02a04f1365
commit
bb9b979586
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
file_handle::FileLike,
|
||||
file_table::{FdFlags, FileDesc, get_file_fast},
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
pseudofs::AnonInodeFs,
|
||||
utils::{CreationFlags, Inode},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -270,7 +270,7 @@ impl FileLike for EpollFile {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
anon_inodefs_shared_inode()
|
||||
AnonInodeFs::shared_inode()
|
||||
}
|
||||
|
||||
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use crate::{
|
|||
file_table::FdFlags,
|
||||
notify::{FsEventSubscriber, FsEvents},
|
||||
path::{Path, RESERVED_MOUNT_ID},
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
pseudofs::AnonInodeFs,
|
||||
utils::{AccessMode, CreationFlags, Inode, InodeExt, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -355,7 +355,7 @@ impl FileLike for InotifyFile {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
anon_inodefs_shared_inode()
|
||||
AnonInodeFs::shared_inode()
|
||||
}
|
||||
|
||||
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
file_table::FdFlags,
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pipe::{Pipe, common::PipeHandle},
|
||||
pseudofs::{PseudoInode, pipefs_singleton},
|
||||
pseudofs::{PipeFs, PseudoInode},
|
||||
utils::{
|
||||
AccessMode, CreationFlags, Extension, FileSystem, Inode, InodeIo, InodeMode, InodeType,
|
||||
Metadata, StatusFlags, mkmod,
|
||||
|
|
@ -185,14 +185,11 @@ impl AnonPipeInode {
|
|||
fn new() -> Self {
|
||||
let pipe = Pipe::new();
|
||||
|
||||
let pseudo_inode = PseudoInode::new(
|
||||
0,
|
||||
let pseudo_inode = PipeFs::singleton().alloc_inode(
|
||||
InodeType::NamedPipe,
|
||||
mkmod!(u+rw),
|
||||
Uid::new_root(),
|
||||
Gid::new_root(),
|
||||
aster_block::BLOCK_SIZE,
|
||||
Arc::downgrade(pipefs_singleton()),
|
||||
);
|
||||
|
||||
Self { pipe, pseudo_inode }
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ impl ProcFs {
|
|||
}
|
||||
|
||||
pub(self) fn alloc_id(&self) -> u64 {
|
||||
self.inode_allocator.fetch_add(1, Ordering::SeqCst)
|
||||
self.inode_allocator.fetch_add(1, Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use core::time::Duration;
|
||||
use core::{
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use spin::Once;
|
||||
|
||||
|
|
@ -23,6 +26,7 @@ pub struct PseudoFs {
|
|||
name: &'static str,
|
||||
sb: SuperBlock,
|
||||
root: Arc<dyn Inode>,
|
||||
inode_allocator: AtomicU64,
|
||||
fs_event_subscriber_stats: FsEventSubscriberStats,
|
||||
}
|
||||
|
||||
|
|
@ -56,62 +60,106 @@ impl PseudoFs {
|
|||
name: &'static str,
|
||||
magic: u64,
|
||||
) -> &'static Arc<Self> {
|
||||
// Reference: <https://elixir.bootlin.com/linux/v6.16.5/source/fs/libfs.c#L659-L689>
|
||||
fs.call_once(|| {
|
||||
Arc::new_cyclic(|weak_fs: &Weak<Self>| Self {
|
||||
name,
|
||||
sb: SuperBlock::new(magic, aster_block::BLOCK_SIZE, NAME_MAX),
|
||||
root: Arc::new(PseudoInode::new(
|
||||
0,
|
||||
InodeType::Unknown,
|
||||
ROOT_INO,
|
||||
InodeType::Dir,
|
||||
mkmod!(u+rw),
|
||||
Uid::new_root(),
|
||||
Gid::new_root(),
|
||||
aster_block::BLOCK_SIZE,
|
||||
weak_fs.clone(),
|
||||
)),
|
||||
inode_allocator: AtomicU64::new(ROOT_INO + 1),
|
||||
fs_event_subscriber_stats: FsEventSubscriberStats::new(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn alloc_inode(
|
||||
self: &Arc<Self>,
|
||||
type_: InodeType,
|
||||
mode: InodeMode,
|
||||
uid: Uid,
|
||||
gid: Gid,
|
||||
) -> PseudoInode {
|
||||
PseudoInode::new(self.alloc_id(), type_, mode, uid, gid, Arc::downgrade(self))
|
||||
}
|
||||
|
||||
fn alloc_id(&self) -> u64 {
|
||||
self.inode_allocator.fetch_add(1, Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the singleton instance of the anonymous pipe file system.
|
||||
pub fn pipefs_singleton() -> &'static Arc<PseudoFs> {
|
||||
static PIPEFS: Once<Arc<PseudoFs>> = Once::new();
|
||||
|
||||
PseudoFs::singleton(&PIPEFS, "pipefs", PIPEFS_MAGIC)
|
||||
pub(super) struct PipeFs {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
/// Returns the singleton instance of the socket file system.
|
||||
pub fn sockfs_singleton() -> &'static Arc<PseudoFs> {
|
||||
static SOCKFS: Once<Arc<PseudoFs>> = Once::new();
|
||||
impl PipeFs {
|
||||
/// Returns the singleton instance of the anonymous pipe file system.
|
||||
pub(super) fn singleton() -> &'static Arc<PseudoFs> {
|
||||
static PIPEFS: Once<Arc<PseudoFs>> = Once::new();
|
||||
|
||||
PseudoFs::singleton(&SOCKFS, "sockfs", SOCKFS_MAGIC)
|
||||
PseudoFs::singleton(&PIPEFS, "pipefs", PIPEFS_MAGIC)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the singleton instance of the anonymous inode file system.
|
||||
fn anon_inodefs_singleton() -> &'static Arc<PseudoFs> {
|
||||
static ANON_INODEFS: Once<Arc<PseudoFs>> = Once::new();
|
||||
|
||||
PseudoFs::singleton(&ANON_INODEFS, "anon_inodefs", ANON_INODEFS_MAGIC)
|
||||
pub struct SockFs {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
/// Returns the shared inode of the anonymous inode file system singleton.
|
||||
//
|
||||
// Some members of anon_inodefs (such as epollfd, eventfd, timerfd, etc.) share
|
||||
// the same inode. The sharing is not only within the same category (e.g., two
|
||||
// epollfds share the same inode) but also across different categories (e.g.,
|
||||
// an epollfd and a timerfd share the same inode). Even across namespaces, this
|
||||
// inode is still shared. Although this Linux behavior is a bit odd, we keep it
|
||||
// for compatibility.
|
||||
//
|
||||
// A small subset of members in anon_inodefs (i.e., userfaultfd, io_uring, and
|
||||
// kvm_guest_memfd) have their own dedicated inodes. We need to support creating
|
||||
// independent inodes within anon_inodefs for them in the future.
|
||||
//
|
||||
// Reference: <https://elixir.bootlin.com/linux/v6.16.5/source/fs/anon_inodes.c#L153-L164>
|
||||
pub fn anon_inodefs_shared_inode() -> &'static Arc<dyn Inode> {
|
||||
&anon_inodefs_singleton().root
|
||||
impl SockFs {
|
||||
/// Returns the singleton instance of the socket file system.
|
||||
pub fn singleton() -> &'static Arc<PseudoFs> {
|
||||
static SOCKFS: Once<Arc<PseudoFs>> = Once::new();
|
||||
|
||||
PseudoFs::singleton(&SOCKFS, "sockfs", SOCKFS_MAGIC)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnonInodeFs {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl AnonInodeFs {
|
||||
/// Returns the singleton instance of the anonymous inode file system.
|
||||
fn singleton() -> &'static Arc<PseudoFs> {
|
||||
static ANON_INODEFS: Once<Arc<PseudoFs>> = Once::new();
|
||||
|
||||
PseudoFs::singleton(&ANON_INODEFS, "anon_inodefs", ANON_INODEFS_MAGIC)
|
||||
}
|
||||
|
||||
/// Returns the shared inode of the anonymous inode file system singleton.
|
||||
//
|
||||
// Some members of anon_inodefs (such as epollfd, eventfd, timerfd, etc.) share
|
||||
// the same inode. The sharing is not only within the same category (e.g., two
|
||||
// epollfds share the same inode) but also across different categories (e.g.,
|
||||
// an epollfd and a timerfd share the same inode). Even across namespaces, this
|
||||
// inode is still shared. Although this Linux behavior is a bit odd, we keep it
|
||||
// for compatibility.
|
||||
//
|
||||
// A small subset of members in anon_inodefs (i.e., userfaultfd, io_uring, and
|
||||
// kvm_guest_memfd) have their own dedicated inodes. We need to support creating
|
||||
// independent inodes within anon_inodefs for them in the future.
|
||||
//
|
||||
// Reference: <https://elixir.bootlin.com/linux/v6.16.5/source/fs/anon_inodes.c#L153-L164>
|
||||
pub fn shared_inode() -> &'static Arc<dyn Inode> {
|
||||
static SHARED_INODE: Once<Arc<dyn Inode>> = Once::new();
|
||||
|
||||
SHARED_INODE.call_once(|| {
|
||||
let shared_inode = Self::singleton().alloc_inode(
|
||||
InodeType::Unknown,
|
||||
mkmod!(u+rw),
|
||||
Uid::new_root(),
|
||||
Gid::new_root(),
|
||||
);
|
||||
|
||||
Arc::new(shared_inode)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn init() {
|
||||
|
|
@ -171,6 +219,8 @@ impl FsType for SockFsType {
|
|||
}
|
||||
}
|
||||
|
||||
/// Root Inode ID.
|
||||
const ROOT_INO: u64 = 1;
|
||||
// Reference: <https://elixir.bootlin.com/linux/v6.16.5/source/include/uapi/linux/magic.h#L87>
|
||||
const PIPEFS_MAGIC: u64 = 0x50495045;
|
||||
// Reference: <https://elixir.bootlin.com/linux/v6.16.5/source/include/uapi/linux/magic.h#L89>
|
||||
|
|
@ -186,13 +236,12 @@ pub struct PseudoInode {
|
|||
}
|
||||
|
||||
impl PseudoInode {
|
||||
pub fn new(
|
||||
fn new(
|
||||
ino: u64,
|
||||
type_: InodeType,
|
||||
mode: InodeMode,
|
||||
uid: Uid,
|
||||
gid: Gid,
|
||||
blk_size: usize,
|
||||
fs: Weak<PseudoFs>,
|
||||
) -> Self {
|
||||
let now = now();
|
||||
|
|
@ -200,7 +249,7 @@ impl PseudoInode {
|
|||
dev: 0,
|
||||
ino,
|
||||
size: 0,
|
||||
blk_size,
|
||||
blk_size: aster_block::BLOCK_SIZE,
|
||||
blocks: 0,
|
||||
atime: now,
|
||||
mtime: now,
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ impl RamFs {
|
|||
}
|
||||
|
||||
fn alloc_id(&self) -> u64 {
|
||||
self.inode_allocator.fetch_add(1, Ordering::SeqCst)
|
||||
self.inode_allocator.fetch_add(1, Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
file_handle::FileLike,
|
||||
file_table::FdFlags,
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pseudofs::{PseudoInode, sockfs_singleton},
|
||||
pseudofs::SockFs,
|
||||
utils::{CreationFlags, Inode, InodeType, StatusFlags, mkmod},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -210,13 +210,12 @@ impl<T: Socket + 'static> FileLike for T {
|
|||
|
||||
/// Creates a new pseudo inode for a socket.
|
||||
fn new_pseudo_inode() -> Arc<dyn Inode> {
|
||||
Arc::new(PseudoInode::new(
|
||||
0,
|
||||
let pseudo_inode = SockFs::singleton().alloc_inode(
|
||||
InodeType::Socket,
|
||||
mkmod!(a+rwx),
|
||||
Uid::new_root(),
|
||||
Gid::new_root(),
|
||||
aster_block::BLOCK_SIZE,
|
||||
Arc::downgrade(sockfs_singleton()),
|
||||
))
|
||||
);
|
||||
|
||||
Arc::new(pseudo_inode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
file_handle::FileLike,
|
||||
file_table::FdFlags,
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
pseudofs::AnonInodeFs,
|
||||
utils::{CreationFlags, Inode, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -95,7 +95,7 @@ impl FileLike for PidFile {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
anon_inodefs_shared_inode()
|
||||
AnonInodeFs::shared_inode()
|
||||
}
|
||||
|
||||
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use crate::{
|
|||
file_handle::FileLike,
|
||||
file_table::{FdFlags, FileDesc},
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
pseudofs::AnonInodeFs,
|
||||
utils::{CreationFlags, Inode, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -232,7 +232,7 @@ impl FileLike for EventFile {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
anon_inodefs_shared_inode()
|
||||
AnonInodeFs::shared_inode()
|
||||
}
|
||||
|
||||
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use crate::{
|
|||
file_handle::FileLike,
|
||||
file_table::{FdFlags, FileDesc, get_file_fast},
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
pseudofs::AnonInodeFs,
|
||||
utils::{CreationFlags, Inode, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -264,7 +264,7 @@ impl FileLike for SignalFile {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
anon_inodefs_shared_inode()
|
||||
AnonInodeFs::shared_inode()
|
||||
}
|
||||
|
||||
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
file_handle::FileLike,
|
||||
file_table::FdFlags,
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
pseudofs::AnonInodeFs,
|
||||
utils::{CreationFlags, Inode, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -252,7 +252,7 @@ impl FileLike for TimerfdFile {
|
|||
}
|
||||
|
||||
fn inode(&self) -> &Arc<dyn Inode> {
|
||||
anon_inodefs_shared_inode()
|
||||
AnonInodeFs::shared_inode()
|
||||
}
|
||||
|
||||
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue