Apply pseudo `Path` to members of `anon_inodefs`

This commit is contained in:
Wang Siyuan 2025-12-26 11:16:16 +00:00
parent 647b7dfc77
commit 0e291b692e
9 changed files with 64 additions and 38 deletions

View File

@ -15,7 +15,7 @@ use crate::{
fs::{
file_handle::FileLike,
file_table::{FdFlags, FileDesc, get_file_fast},
path::RESERVED_MOUNT_ID,
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode},
},
@ -47,14 +47,19 @@ pub struct EpollFile {
// Keep this in a separate `Arc` to avoid dropping `EpollFile` in the observer callback, which
// may cause deadlocks.
ready: Arc<ReadySet>,
/// The pseudo path associated with this epoll file.
pseudo_path: Path,
}
impl EpollFile {
/// Creates a new epoll file.
pub fn new() -> Arc<Self> {
let pseudo_path = AnonInodeFs::new_path(|_| "anon_inode:[eventpoll]".to_string());
Arc::new(Self {
interest: Mutex::new(BTreeSet::new()),
ready: Arc::new(ReadySet::new()),
pseudo_path,
})
}
@ -270,7 +275,7 @@ impl FileLike for EpollFile {
}
fn inode(&self) -> &Arc<dyn Inode> {
AnonInodeFs::shared_inode()
self.pseudo_path.inode()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
@ -288,9 +293,8 @@ impl FileLike for EpollFile {
writeln!(f, "pos:\t{}", 0)?;
writeln!(f, "flags:\t0{:o}", flags)?;
// TODO: This should be the mount ID of the pseudo filesystem.
writeln!(f, "mnt_id:\t{}", RESERVED_MOUNT_ID)?;
writeln!(f, "ino:\t{}", self.inner.inode().ino())?;
writeln!(f, "mnt_id:\t{}", AnonInodeFs::mount_node().id())?;
writeln!(f, "ino:\t{}", AnonInodeFs::shared_inode().ino())?;
for entry in self.inner.interest.lock().iter() {
writeln!(f, "{}", entry.0)?;
}

View File

@ -21,7 +21,7 @@ use crate::{
file_handle::FileLike,
file_table::FdFlags,
notify::{FsEventSubscriber, FsEvents},
path::{Path, RESERVED_MOUNT_ID},
path::Path,
pseudofs::AnonInodeFs,
utils::{AccessMode, CreationFlags, Inode, InodeExt, StatusFlags},
},
@ -58,6 +58,8 @@ pub struct InotifyFile {
pollee: Pollee,
// A weak reference to this inotify file.
this: Weak<InotifyFile>,
/// The pseudo path associated with this inotify file.
pseudo_path: Path,
}
impl Drop for InotifyFile {
@ -93,6 +95,8 @@ const DEFAULT_MAX_QUEUED_EVENTS: usize = 16384;
impl InotifyFile {
/// Creates a new inotify file.
pub fn new(is_nonblocking: bool) -> Result<Arc<Self>> {
let pseudo_path = AnonInodeFs::new_path(|_| "anon_inode:inotify".to_string());
Ok(Arc::new_cyclic(|weak_self| Self {
// Allocate watch descriptors from 1.
// Reference: <https://elixir.bootlin.com/linux/v6.17/source/fs/notify/inotify/inotify_user.c#L402>
@ -104,6 +108,7 @@ impl InotifyFile {
queue_capacity: DEFAULT_MAX_QUEUED_EVENTS,
pollee: Pollee::new(),
this: weak_self.clone(),
pseudo_path,
}))
}
@ -355,7 +360,7 @@ impl FileLike for InotifyFile {
}
fn inode(&self) -> &Arc<dyn Inode> {
AnonInodeFs::shared_inode()
self.pseudo_path.inode()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
@ -373,9 +378,8 @@ impl FileLike for InotifyFile {
writeln!(f, "pos:\t{}", 0)?;
writeln!(f, "flags:\t0{:o}", flags)?;
// TODO: This should be the mount ID of the pseudo filesystem.
writeln!(f, "mnt_id:\t{}", RESERVED_MOUNT_ID)?;
writeln!(f, "ino:\t{}", self.inner.inode().ino())?;
writeln!(f, "mnt_id:\t{}", AnonInodeFs::mount_node().id())?;
writeln!(f, "ino:\t{}", AnonInodeFs::shared_inode().ino())?;
for (wd, entry) in self.inner.watch_map.lock().iter() {
let Some(inode) = entry.inode.upgrade() else {

View File

@ -5,7 +5,7 @@
use core::time::Duration;
use inherit_methods_macro::inherit_methods;
pub use mount::{Mount, MountPropType, PerMountFlags, RESERVED_MOUNT_ID};
pub use mount::{Mount, MountPropType, PerMountFlags};
pub use mount_namespace::MountNamespace;
use crate::{

View File

@ -36,7 +36,7 @@ pub enum MountPropType {
static ID_ALLOCATOR: Once<SpinLock<IdAlloc>> = Once::new();
/// The reserved mount ID, which represents an invalid mount.
pub static RESERVED_MOUNT_ID: usize = 0;
static RESERVED_MOUNT_ID: usize = 0;
pub(super) fn init() {
// TODO: Make it configurable.

View File

@ -170,6 +170,15 @@ impl AnonInodeFs {
PseudoFs::singleton(&ANON_INODEFS, "anon_inodefs", ANON_INODEFS_MAGIC)
}
/// Creates a pseudo `Path` for the shared inode.
pub fn new_path(name_fn: fn(&dyn Inode) -> String) -> Path {
Path::new_pseudo(
Self::mount_node().clone(),
Self::shared_inode().clone(),
name_fn,
)
}
/// Returns the pseudo mount node of the anonymous inode file system.
pub fn mount_node() -> &'static Arc<Mount> {
static ANON_INODEFS_MOUNT: Once<Arc<Mount>> = Once::new();

View File

@ -10,7 +10,7 @@ use crate::{
fs::{
file_handle::FileLike,
file_table::FdFlags,
path::RESERVED_MOUNT_ID,
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode, StatusFlags},
},
@ -24,6 +24,8 @@ use crate::{
pub struct PidFile {
process: Arc<Process>,
is_nonblocking: AtomicBool,
/// The pseudo path associated with this pid file.
pseudo_path: Path,
}
impl Debug for PidFile {
@ -40,9 +42,12 @@ impl Debug for PidFile {
impl PidFile {
pub fn new(process: Arc<Process>, is_nonblocking: bool) -> Self {
let pseudo_path = AnonInodeFs::new_path(|_| "anon_inode:[pidfd]".to_string());
Self {
process,
is_nonblocking: AtomicBool::new(is_nonblocking),
pseudo_path,
}
}
@ -95,13 +100,12 @@ impl FileLike for PidFile {
}
fn inode(&self) -> &Arc<dyn Inode> {
AnonInodeFs::shared_inode()
self.pseudo_path.inode()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
struct FdInfo {
flags: u32,
ino: u64,
pid: u32,
}
@ -109,9 +113,8 @@ impl FileLike for PidFile {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "pos:\t{}", 0)?;
writeln!(f, "flags:\t0{:o}", self.flags)?;
// TODO: This should be the mount ID of the pseudo filesystem.
writeln!(f, "mnt_id:\t{}", RESERVED_MOUNT_ID)?;
writeln!(f, "ino:\t{}", self.ino)?;
writeln!(f, "mnt_id:\t{}", AnonInodeFs::mount_node().id())?;
writeln!(f, "ino:\t{}", AnonInodeFs::shared_inode().ino())?;
writeln!(f, "Pid:\t{}", self.pid)?;
// TODO: Currently we do not support PID namespaces. Just print the PID once.
writeln!(f, "NSpid:\t{}", self.pid)
@ -125,7 +128,6 @@ impl FileLike for PidFile {
Box::new(FdInfo {
flags,
ino: self.inode().ino(),
pid: self.process.pid(),
})
}

View File

@ -24,7 +24,7 @@ use crate::{
fs::{
file_handle::FileLike,
file_table::{FdFlags, FileDesc},
path::RESERVED_MOUNT_ID,
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode, StatusFlags},
},
@ -76,6 +76,8 @@ struct EventFile {
pollee: Pollee,
flags: Mutex<Flags>,
write_wait_queue: WaitQueue,
/// The pseudo path associated with this eventfd file.
pseudo_path: Path,
}
impl EventFile {
@ -85,11 +87,13 @@ impl EventFile {
let counter = Mutex::new(init_val);
let pollee = Pollee::new();
let write_wait_queue = WaitQueue::new();
let pseudo_path = AnonInodeFs::new_path(|_| "anon_inode:[eventfd]".to_string());
Self {
counter,
pollee,
flags: Mutex::new(flags),
write_wait_queue,
pseudo_path,
}
}
@ -232,7 +236,7 @@ impl FileLike for EventFile {
}
fn inode(&self) -> &Arc<dyn Inode> {
AnonInodeFs::shared_inode()
self.pseudo_path.inode()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
@ -250,9 +254,8 @@ impl FileLike for EventFile {
writeln!(f, "pos:\t{}", 0)?;
writeln!(f, "flags:\t0{:o}", flags)?;
// TODO: This should be the mount ID of the pseudo filesystem.
writeln!(f, "mnt_id:\t{}", RESERVED_MOUNT_ID)?;
writeln!(f, "ino:\t{}", self.inner.inode().ino())?;
writeln!(f, "mnt_id:\t{}", AnonInodeFs::mount_node().id())?;
writeln!(f, "ino:\t{}", AnonInodeFs::shared_inode().ino())?;
writeln!(f, "eventfd-count: {:16x}", *self.inner.counter.lock())
}
}

View File

@ -20,7 +20,7 @@ use crate::{
fs::{
file_handle::FileLike,
file_table::{FdFlags, FileDesc, get_file_fast},
path::RESERVED_MOUNT_ID,
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode, StatusFlags},
},
@ -139,14 +139,19 @@ struct SignalFile {
signals_mask: AtomicSigMask,
/// Non-blocking mode flag
non_blocking: AtomicBool,
/// The pseudo path associated with this signalfd file.
pseudo_path: Path,
}
impl SignalFile {
/// Create a new signalfd instance
fn new(mask: AtomicSigMask, non_blocking: bool) -> Self {
let pseudo_path = AnonInodeFs::new_path(|_| "anon_inode:[signalfd]".to_string());
Self {
signals_mask: mask,
non_blocking: AtomicBool::new(non_blocking),
pseudo_path,
}
}
@ -264,13 +269,12 @@ impl FileLike for SignalFile {
}
fn inode(&self) -> &Arc<dyn Inode> {
AnonInodeFs::shared_inode()
self.pseudo_path.inode()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
struct FdInfo {
flags: u32,
ino: u64,
sigmask: u64,
}
@ -278,9 +282,8 @@ impl FileLike for SignalFile {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "pos:\t{}", 0)?;
writeln!(f, "flags:\t0{:o}", self.flags)?;
// TODO: This should be the mount ID of the pseudo filesystem.
writeln!(f, "mnt_id:\t{}", RESERVED_MOUNT_ID)?;
writeln!(f, "ino:\t{}", self.ino)?;
writeln!(f, "mnt_id:\t{}", AnonInodeFs::mount_node().id())?;
writeln!(f, "ino:\t{}", AnonInodeFs::shared_inode().ino())?;
writeln!(f, "sigmask:\t{:016x}", self.sigmask)
}
}
@ -292,7 +295,6 @@ impl FileLike for SignalFile {
Box::new(FdInfo {
flags,
ino: self.inode().ino(),
sigmask: self.mask().load(Ordering::Relaxed).into(),
})
}

View File

@ -14,7 +14,7 @@ use crate::{
fs::{
file_handle::FileLike,
file_table::FdFlags,
path::RESERVED_MOUNT_ID,
path::Path,
pseudofs::AnonInodeFs,
utils::{CreationFlags, Inode, StatusFlags},
},
@ -35,6 +35,8 @@ pub struct TimerfdFile {
pollee: Pollee,
flags: AtomicTFDFlags,
settime_flags: AtomicTFDSetTimeFlags,
/// The pseudo path associated with this timerfd file.
pseudo_path: Path,
}
bitflags! {
@ -115,6 +117,8 @@ impl TimerfdFile {
create_timer(clockid, expired_fn, ctx)
}?;
let pseudo_path = AnonInodeFs::new_path(|_| "anon_inode:[timerfd]".to_string());
Ok(TimerfdFile {
clockid,
timer,
@ -122,6 +126,7 @@ impl TimerfdFile {
pollee,
flags: AtomicTFDFlags::new(flags),
settime_flags: AtomicTFDSetTimeFlags::default(),
pseudo_path,
})
}
@ -252,13 +257,12 @@ impl FileLike for TimerfdFile {
}
fn inode(&self) -> &Arc<dyn Inode> {
AnonInodeFs::shared_inode()
self.pseudo_path.inode()
}
fn dump_proc_fdinfo(self: Arc<Self>, fd_flags: FdFlags) -> Box<dyn Display> {
struct FdInfo {
flags: u32,
ino: u64,
clockid: i32,
ticks: u64,
settime_flags: u32,
@ -270,9 +274,8 @@ impl FileLike for TimerfdFile {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "pos:\t{}", 0)?;
writeln!(f, "flags:\t0{:o}", self.flags)?;
// TODO: This should be the mount ID of the pseudo filesystem.
writeln!(f, "mnt_id:\t{}", RESERVED_MOUNT_ID)?;
writeln!(f, "ino:\t{}", self.ino)?;
writeln!(f, "mnt_id:\t{}", AnonInodeFs::mount_node().id())?;
writeln!(f, "ino:\t{}", AnonInodeFs::shared_inode().ino())?;
writeln!(f, "clockid: {}", self.clockid)?;
writeln!(f, "ticks: {}", self.ticks)?;
writeln!(f, "settime flags: 0{:o}", self.settime_flags)?;
@ -299,7 +302,6 @@ impl FileLike for TimerfdFile {
let timer_guard = self.timer.lock();
Box::new(FdInfo {
flags,
ino: self.inode().ino(),
clockid: self.clockid,
ticks: self.ticks.load(Ordering::Relaxed),
settime_flags: self.settime_flags.load(Ordering::Relaxed).bits(),