Redesign inode extensions
This commit is contained in:
parent
57399a223c
commit
e362520d49
|
|
@ -8,10 +8,9 @@ use super::fs::CgroupFs;
|
|||
use crate::{
|
||||
fs::{
|
||||
cgroupfs::CgroupNode,
|
||||
notify::FsEventPublisher,
|
||||
path::{is_dot, is_dotdot},
|
||||
utils::{
|
||||
FileSystem, Inode, InodeMode, Metadata,
|
||||
Extension, FileSystem, Inode, InodeMode, Metadata,
|
||||
systree_inode::{SysTreeInodeTy, SysTreeNodeKind},
|
||||
},
|
||||
},
|
||||
|
|
@ -24,8 +23,8 @@ pub(super) struct CgroupInode {
|
|||
node_kind: SysTreeNodeKind,
|
||||
/// The metadata of this inode.
|
||||
metadata: Metadata,
|
||||
/// FS event publisher.
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
/// The extension of this inode.
|
||||
extension: Extension,
|
||||
/// The file mode (permissions) of this inode, protected by a lock.
|
||||
mode: RwLock<InodeMode>,
|
||||
/// Weak reference to the parent inode.
|
||||
|
|
@ -47,7 +46,7 @@ impl SysTreeInodeTy for CgroupInode {
|
|||
Arc::new_cyclic(|this| Self {
|
||||
node_kind,
|
||||
metadata,
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
mode: RwLock::new(mode),
|
||||
parent,
|
||||
this: this.clone(),
|
||||
|
|
@ -62,8 +61,8 @@ impl SysTreeInodeTy for CgroupInode {
|
|||
&self.metadata
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
fn mode(&self) -> Result<InodeMode> {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@ use ostd::sync::RwLock;
|
|||
use crate::{
|
||||
fs::{
|
||||
configfs::fs::ConfigFs,
|
||||
notify::FsEventPublisher,
|
||||
utils::{
|
||||
FileSystem, Inode, InodeMode, Metadata,
|
||||
Extension, FileSystem, Inode, InodeMode, Metadata,
|
||||
systree_inode::{SysTreeInodeTy, SysTreeNodeKind},
|
||||
},
|
||||
},
|
||||
|
|
@ -22,8 +21,8 @@ pub struct ConfigInode {
|
|||
node_kind: SysTreeNodeKind,
|
||||
/// The metadata of this inode.
|
||||
metadata: Metadata,
|
||||
/// FS event publisher.
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
/// The extension of this inode.
|
||||
extension: Extension,
|
||||
/// The file mode (permissions) of this inode, protected by a lock.
|
||||
mode: RwLock<InodeMode>,
|
||||
/// Weak reference to the parent inode.
|
||||
|
|
@ -45,7 +44,7 @@ impl SysTreeInodeTy for ConfigInode {
|
|||
Arc::new_cyclic(|this| Self {
|
||||
node_kind,
|
||||
metadata,
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
mode: RwLock::new(mode),
|
||||
parent,
|
||||
this: this.clone(),
|
||||
|
|
@ -73,13 +72,13 @@ impl SysTreeInodeTy for ConfigInode {
|
|||
&self.parent
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
}
|
||||
|
||||
fn this(&self) -> Arc<Self> {
|
||||
self.this.upgrade().expect("Weak ref invalid")
|
||||
}
|
||||
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
}
|
||||
|
||||
impl Inode for ConfigInode {
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@ use id_alloc::IdAlloc;
|
|||
|
||||
pub use self::ptmx::Ptmx;
|
||||
use self::slave::PtySlaveInode;
|
||||
use super::utils::{MknodType, StatusFlags};
|
||||
use super::utils::{Extension, MknodType, StatusFlags};
|
||||
use crate::{
|
||||
device::PtyMaster,
|
||||
fs::{
|
||||
device::{Device, DeviceType},
|
||||
notify::FsEventPublisher,
|
||||
registry::{FsProperties, FsType},
|
||||
utils::{
|
||||
DirEntryVecExt, DirentVisitor, FileSystem, FsEventSubscriberStats, FsFlags, Inode,
|
||||
|
|
@ -151,7 +150,7 @@ struct RootInode {
|
|||
ptmx: Arc<Ptmx>,
|
||||
slaves: RwLock<SlotVec<(String, Arc<dyn Inode>)>>,
|
||||
metadata: RwLock<Metadata>,
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
extension: Extension,
|
||||
fs: Weak<DevPts>,
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +160,7 @@ impl RootInode {
|
|||
ptmx: Ptmx::new(fs.clone()),
|
||||
slaves: RwLock::new(SlotVec::new()),
|
||||
metadata: RwLock::new(Metadata::new_dir(ROOT_INO, mkmod!(a+rx, u+w), BLOCK_SIZE)),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
fs,
|
||||
})
|
||||
}
|
||||
|
|
@ -200,8 +199,8 @@ impl Inode for RootInode {
|
|||
*self.metadata.read()
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
fn ino(&self) -> u64 {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ use device_id::{DeviceId, MajorId, MinorId};
|
|||
use super::*;
|
||||
use crate::fs::{
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
utils::{AccessMode, InodeIo, StatusFlags},
|
||||
utils::{AccessMode, Extension, InodeIo, StatusFlags},
|
||||
};
|
||||
|
||||
/// Same major number with Linux.
|
||||
|
|
@ -21,7 +20,7 @@ const PTMX_MINOR_NUM: u32 = 2;
|
|||
pub struct Ptmx {
|
||||
inner: Inner,
|
||||
metadata: RwLock<Metadata>,
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
extension: Extension,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -38,7 +37,7 @@ impl Ptmx {
|
|||
&inner,
|
||||
)),
|
||||
inner,
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -82,8 +81,8 @@ impl Inode for Ptmx {
|
|||
*self.metadata.read()
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
fn ino(&self) -> u64 {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use crate::{
|
|||
device::PtySlave,
|
||||
fs::{
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
utils::{AccessMode, InodeIo, StatusFlags},
|
||||
},
|
||||
};
|
||||
|
|
@ -20,7 +19,7 @@ const SLAVE_MAJOR_NUM: u32 = 3;
|
|||
pub struct PtySlaveInode {
|
||||
device: Arc<PtySlave>,
|
||||
metadata: RwLock<Metadata>,
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
extension: Extension,
|
||||
fs: Weak<DevPts>,
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +33,7 @@ impl PtySlaveInode {
|
|||
device.as_ref(),
|
||||
)),
|
||||
device,
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
fs,
|
||||
})
|
||||
}
|
||||
|
|
@ -81,8 +80,8 @@ impl Inode for PtySlaveInode {
|
|||
*self.metadata.read()
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
fn ino(&self) -> u64 {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ use super::{
|
|||
use crate::{
|
||||
fs::{
|
||||
exfat::{dentry::ExfatDentryIterator, fat::ExfatChain, fs::ExfatFs},
|
||||
notify::FsEventPublisher,
|
||||
path::{is_dot, is_dot_or_dotdot, is_dotdot},
|
||||
utils::{
|
||||
CachePage, DirentVisitor, Extension, Inode, InodeIo, InodeMode, InodeType, Metadata,
|
||||
|
|
@ -79,7 +78,6 @@ impl FatAttr {
|
|||
pub struct ExfatInode {
|
||||
inner: RwMutex<ExfatInodeInner>,
|
||||
extension: Extension,
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -862,7 +860,6 @@ impl ExfatInode {
|
|||
page_cache: PageCache::with_capacity(size, weak_self.clone() as _).unwrap(),
|
||||
}),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
});
|
||||
|
||||
let inner = inode.inner.upread();
|
||||
|
|
@ -973,7 +970,6 @@ impl ExfatInode {
|
|||
page_cache: PageCache::with_capacity(size, weak_self.clone() as _).unwrap(),
|
||||
}),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
});
|
||||
|
||||
if matches!(inode_type, InodeType::Dir) {
|
||||
|
|
@ -1734,11 +1730,7 @@ impl Inode for ExfatInode {
|
|||
true
|
||||
}
|
||||
|
||||
fn extension(&self) -> Option<&Extension> {
|
||||
Some(&self.extension)
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
fs::{
|
||||
ext2::{FilePerm, Inode as Ext2Inode},
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
utils::{
|
||||
AccessMode, DirentVisitor, Extension, FallocMode, FileSystem, Inode, InodeIo,
|
||||
InodeMode, InodeType, Metadata, MknodType, StatusFlags, SymbolicLink, XattrName,
|
||||
|
|
@ -234,12 +233,8 @@ impl Inode for Ext2Inode {
|
|||
self.fs()
|
||||
}
|
||||
|
||||
fn extension(&self) -> Option<&Extension> {
|
||||
Some(self.extension())
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
self.fs_event_publisher()
|
||||
fn extension(&self) -> &Extension {
|
||||
self.extension()
|
||||
}
|
||||
|
||||
fn set_xattr(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ use super::{
|
|||
use crate::{
|
||||
fs::{
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
path::{is_dot, is_dot_or_dotdot, is_dotdot},
|
||||
pipe::Pipe,
|
||||
utils::{
|
||||
|
|
@ -46,7 +45,6 @@ pub struct Inode {
|
|||
inner: RwMutex<InodeInner>,
|
||||
fs: Weak<Ext2>,
|
||||
extension: Extension,
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
xattr: Option<Xattr>,
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +65,6 @@ impl Inode {
|
|||
inner: RwMutex::new(InodeInner::new(desc, weak_self.clone(), fs.clone())),
|
||||
fs,
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -112,10 +109,6 @@ impl Inode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
}
|
||||
|
||||
pub fn resize(&self, new_size: usize) -> Result<()> {
|
||||
if self.type_ == InodeType::Dir {
|
||||
return_errno!(Errno::EISDIR);
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ use core::sync::atomic::{AtomicU32, Ordering};
|
|||
|
||||
pub use dyn_cap::InodeHandle;
|
||||
|
||||
use super::utils::InodeIo;
|
||||
use super::utils::{InodeExt, InodeIo};
|
||||
use crate::{
|
||||
events::IoEvents,
|
||||
fs::{
|
||||
file_handle::Mappable,
|
||||
path::Path,
|
||||
utils::{
|
||||
DirentVisitor, FallocMode, FileRange, FlockItem, FlockList, Inode, InodeType,
|
||||
OFFSET_MAX, RangeLockItem, RangeLockList, RangeLockType, SeekFrom, StatusFlags,
|
||||
DirentVisitor, FallocMode, FileRange, FlockItem, Inode, InodeType, OFFSET_MAX,
|
||||
RangeLockItem, RangeLockType, SeekFrom, StatusFlags,
|
||||
},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -211,13 +211,12 @@ impl HandleInner {
|
|||
}
|
||||
|
||||
pub(self) fn test_range_lock(&self, mut lock: RangeLockItem) -> Result<RangeLockItem> {
|
||||
let Some(extension) = self.path.inode().extension() else {
|
||||
// Range locks are not supported. So nothing is locked.
|
||||
lock.set_type(RangeLockType::Unlock);
|
||||
return Ok(lock);
|
||||
};
|
||||
|
||||
let Some(range_lock_list) = extension.get::<RangeLockList>() else {
|
||||
let Some(range_lock_list) = self
|
||||
.path
|
||||
.inode()
|
||||
.fs_lock_context()
|
||||
.map(|c| c.range_lock_list())
|
||||
else {
|
||||
// The lock list is not present. So nothing is locked.
|
||||
lock.set_type(RangeLockType::Unlock);
|
||||
return Ok(lock);
|
||||
|
|
@ -233,24 +232,15 @@ impl HandleInner {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let Some(extension) = self.path.inode().extension() else {
|
||||
// TODO: Figure out whether range locks are supported on all inodes.
|
||||
warn!("the inode does not have support for range locks; this operation will fail");
|
||||
return_errno_with_message!(Errno::ENOLCK, "range locks are not supported");
|
||||
};
|
||||
|
||||
let range_lock_list = match extension.get::<RangeLockList>() {
|
||||
Some(list) => list,
|
||||
None => extension.get_or_put_default::<RangeLockList>(),
|
||||
};
|
||||
let range_lock_list = self
|
||||
.path
|
||||
.inode()
|
||||
.fs_lock_context_or_init()
|
||||
.range_lock_list();
|
||||
range_lock_list.set_lock(lock, is_nonblocking)
|
||||
}
|
||||
|
||||
pub(self) fn release_range_locks(&self) {
|
||||
if self.path.inode().extension().is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let range_lock = RangeLockItem::new(
|
||||
RangeLockType::Unlock,
|
||||
FileRange::new(0, OFFSET_MAX).unwrap(),
|
||||
|
|
@ -259,31 +249,23 @@ impl HandleInner {
|
|||
}
|
||||
|
||||
pub(self) fn unlock_range_lock(&self, lock: &RangeLockItem) {
|
||||
if let Some(extension) = self.path.inode().extension()
|
||||
&& let Some(range_lock_list) = extension.get::<RangeLockList>()
|
||||
if let Some(range_lock_list) = self
|
||||
.path
|
||||
.inode()
|
||||
.fs_lock_context()
|
||||
.map(|c| c.range_lock_list())
|
||||
{
|
||||
range_lock_list.unlock(lock);
|
||||
}
|
||||
}
|
||||
|
||||
pub(self) fn set_flock(&self, lock: FlockItem, is_nonblocking: bool) -> Result<()> {
|
||||
let Some(extension) = self.path.inode().extension() else {
|
||||
// TODO: Figure out whether flocks are supported on all inodes.
|
||||
warn!("the inode does not have support for flocks; this operation will fail");
|
||||
return_errno_with_message!(Errno::ENOLCK, "flocks are not supported");
|
||||
};
|
||||
|
||||
let flock_list = match extension.get::<FlockList>() {
|
||||
Some(list) => list,
|
||||
None => extension.get_or_put_default::<FlockList>(),
|
||||
};
|
||||
let flock_list = self.path.inode().fs_lock_context_or_init().flock_list();
|
||||
flock_list.set_lock(lock, is_nonblocking)
|
||||
}
|
||||
|
||||
pub(self) fn unlock_flock(&self, req_owner: &InodeHandle) {
|
||||
if let Some(extension) = self.path.inode().extension()
|
||||
&& let Some(flock_list) = extension.get::<FlockList>()
|
||||
{
|
||||
if let Some(flock_list) = self.path.inode().fs_lock_context().map(|c| c.flock_list()) {
|
||||
flock_list.unlock(req_owner);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use crate::{
|
|||
notify::{FsEventSubscriber, FsEvents},
|
||||
path::{Path, RESERVED_MOUNT_ID},
|
||||
pseudofs::anon_inodefs_shared_inode,
|
||||
utils::{AccessMode, CreationFlags, Inode, StatusFlags},
|
||||
utils::{AccessMode, CreationFlags, Inode, InodeExt, StatusFlags},
|
||||
},
|
||||
prelude::*,
|
||||
process::signal::{PollHandle, Pollable, Pollee},
|
||||
|
|
@ -75,7 +75,11 @@ impl Drop for InotifyFile {
|
|||
continue;
|
||||
};
|
||||
|
||||
if inode.fs_event_publisher().remove_subscriber(&subscriber) {
|
||||
if inode
|
||||
.fs_event_publisher()
|
||||
.unwrap()
|
||||
.remove_subscriber(&subscriber)
|
||||
{
|
||||
inode.fs().fs_event_subscriber_stats().remove_subscriber();
|
||||
}
|
||||
}
|
||||
|
|
@ -163,7 +167,11 @@ impl InotifyFile {
|
|||
_ => return_errno_with_message!(Errno::EINVAL, "watch not found"),
|
||||
};
|
||||
|
||||
if inode.fs_event_publisher().remove_subscriber(&subscriber) {
|
||||
if inode
|
||||
.fs_event_publisher()
|
||||
.unwrap()
|
||||
.remove_subscriber(&subscriber)
|
||||
{
|
||||
inode.fs().fs_event_subscriber_stats().remove_subscriber();
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -176,7 +184,9 @@ impl InotifyFile {
|
|||
interesting: InotifyEvents,
|
||||
options: InotifyControls,
|
||||
) -> Result<u32> {
|
||||
let publisher = path.inode().fs_event_publisher();
|
||||
let Some(publisher) = path.inode().fs_event_publisher() else {
|
||||
return_errno_with_message!(Errno::ENOENT, "watch not found");
|
||||
};
|
||||
let inotify_file = self.this();
|
||||
|
||||
let result = publisher.find_subscriber_and_process(|subscriber| {
|
||||
|
|
@ -214,7 +224,7 @@ impl InotifyFile {
|
|||
|
||||
if path
|
||||
.inode()
|
||||
.fs_event_publisher()
|
||||
.fs_event_publisher_or_init()
|
||||
.add_subscriber(subscriber.clone())
|
||||
{
|
||||
path.inode()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::{
|
|||
|
||||
pub mod inotify;
|
||||
|
||||
use super::utils::{Inode, InodeType};
|
||||
use super::utils::{Inode, InodeExt, InodeType};
|
||||
|
||||
/// Publishes filesystem events to subscribers.
|
||||
///
|
||||
|
|
@ -432,5 +432,7 @@ fn notify_parent(path: &Path, mut events: FsEvents, name: String) {
|
|||
/// functions in `fs/notify/`, which then call this function to broadcast events
|
||||
/// to all registered subscribers through the inode's publisher.
|
||||
fn notify_inode(inode: &Arc<dyn Inode>, events: FsEvents, name: Option<String>) {
|
||||
inode.fs_event_publisher().publish_event(events, name);
|
||||
if let Some(publisher) = inode.fs_event_publisher() {
|
||||
publisher.publish_event(events, name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@ use crate::{
|
|||
fs::{
|
||||
fs_resolver::FsPath,
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
path::Path,
|
||||
registry::{FsProperties, FsType},
|
||||
utils::{
|
||||
AccessMode, DirentCounter, DirentVisitor, FallocMode, FileSystem,
|
||||
AccessMode, DirentCounter, DirentVisitor, Extension, FallocMode, FileSystem,
|
||||
FsEventSubscriberStats, FsFlags, Inode, InodeIo, InodeMode, InodeType, Metadata,
|
||||
MknodType, NAME_MAX, StatusFlags, SuperBlock, SymbolicLink, XATTR_VALUE_MAX_LEN,
|
||||
XattrName, XattrNamespace, XattrSetFlags, mkmod,
|
||||
|
|
@ -91,8 +90,8 @@ struct OverlayInode {
|
|||
/// This field is used to build hierarchical upper inodes.
|
||||
/// The lock is intended to implement `rename`.
|
||||
name_upon_creation: SpinLock<String>,
|
||||
/// FS event publisher.
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
/// The extension of this inode.
|
||||
extension: Extension,
|
||||
/// The parent inode. `None` for root inode.
|
||||
parent: Option<Arc<OverlayInode>>,
|
||||
/// The mutable upper regular inode.
|
||||
|
|
@ -173,7 +172,7 @@ impl FileSystem for OverlayFs {
|
|||
ino,
|
||||
type_: InodeType::Dir,
|
||||
name_upon_creation: SpinLock::new(String::from("")),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
parent: None,
|
||||
upper: Mutex::new(Some(upper_inode)),
|
||||
upper_is_opaque: false,
|
||||
|
|
@ -279,7 +278,7 @@ impl OverlayInode {
|
|||
ino: new_upper.ino(),
|
||||
type_,
|
||||
name_upon_creation: SpinLock::new(String::from(name)),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
parent: Some(self.self_.upgrade().unwrap()),
|
||||
upper: Mutex::new(Some(new_upper)),
|
||||
upper_is_opaque,
|
||||
|
|
@ -452,8 +451,8 @@ impl OverlayInode {
|
|||
self.type_
|
||||
}
|
||||
|
||||
pub fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
pub fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
pub fn page_cache(&self) -> Option<Arc<Vmo>> {
|
||||
|
|
@ -693,7 +692,7 @@ impl OverlayInode {
|
|||
ino,
|
||||
type_: type_.unwrap(),
|
||||
name_upon_creation: SpinLock::new(String::from(name)),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
parent: Some(self.self_.upgrade().unwrap()),
|
||||
upper: Mutex::new(upper_child),
|
||||
upper_is_opaque,
|
||||
|
|
@ -934,7 +933,7 @@ impl Inode for OverlayInode {
|
|||
fn size(&self) -> usize;
|
||||
fn resize(&self, new_size: usize) -> Result<()>;
|
||||
fn metadata(&self) -> Metadata;
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
fn ino(&self) -> u64;
|
||||
fn type_(&self) -> InodeType;
|
||||
fn mode(&self) -> Result<InodeMode>;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ use ostd::sync::RwMutexWriteGuard;
|
|||
|
||||
use super::{is_dot, is_dot_or_dotdot, is_dotdot};
|
||||
use crate::{
|
||||
fs,
|
||||
fs::utils::{Inode, InodeMode, InodeType, MknodType},
|
||||
fs::{
|
||||
self,
|
||||
utils::{Inode, InodeExt, InodeMode, InodeType, MknodType},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
|
|
@ -273,7 +275,10 @@ impl Dentry {
|
|||
}
|
||||
fs::notify::on_delete(self.inode(), &child_inode, || name.to_string());
|
||||
if nlinks == 0 {
|
||||
let publisher = child_inode.fs_event_publisher();
|
||||
// Ideally, we would use `fs_event_publisher()` here to avoid creating a
|
||||
// `FsEventPublisher` instance on a dying inode. However, it isn't possible because we
|
||||
// need to disable new subscribers.
|
||||
let publisher = child_inode.fs_event_publisher_or_init();
|
||||
publisher.disable_new_subscribers();
|
||||
let removed_nr_subscribers = publisher.remove_all_subscribers();
|
||||
child_inode
|
||||
|
|
@ -323,7 +328,10 @@ impl Dentry {
|
|||
}
|
||||
fs::notify::on_delete(self.inode(), &child_inode, || name.to_string());
|
||||
if nlinks == 0 {
|
||||
let publisher = child_inode.fs_event_publisher();
|
||||
// Ideally, we would use `fs_event_publisher()` here to avoid creating a
|
||||
// `FsEventPublisher` on a dying inode. However, it isn't possible because we need to
|
||||
// disable new subscribers.
|
||||
let publisher = child_inode.fs_event_publisher_or_init();
|
||||
publisher.disable_new_subscribers();
|
||||
let removed_nr_subscribers = publisher.remove_all_subscribers();
|
||||
child_inode
|
||||
|
|
|
|||
|
|
@ -13,13 +13,12 @@ use crate::{
|
|||
fs::{
|
||||
file_handle::FileLike,
|
||||
file_table::FdFlags,
|
||||
notify::FsEventPublisher,
|
||||
path::RESERVED_MOUNT_ID,
|
||||
pipe::{Pipe, common::PipeHandle},
|
||||
pseudofs::{PseudoInode, pipefs_singleton},
|
||||
utils::{
|
||||
AccessMode, CreationFlags, FileSystem, Inode, InodeIo, InodeMode, InodeType, Metadata,
|
||||
StatusFlags, mkmod,
|
||||
AccessMode, CreationFlags, Extension, FileSystem, Inode, InodeIo, InodeMode, InodeType,
|
||||
Metadata, StatusFlags, mkmod,
|
||||
},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -221,7 +220,7 @@ impl Inode for AnonPipeInode {
|
|||
fn size(&self) -> usize;
|
||||
fn resize(&self, _new_size: usize) -> Result<()>;
|
||||
fn metadata(&self) -> Metadata;
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
fn ino(&self) -> u64;
|
||||
fn type_(&self) -> InodeType;
|
||||
fn mode(&self) -> Result<InodeMode>;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@ use ostd::sync::RwMutexUpgradeableGuard;
|
|||
use super::{Common, ProcFs};
|
||||
use crate::{
|
||||
fs::{
|
||||
notify::FsEventPublisher,
|
||||
path::{is_dot, is_dotdot},
|
||||
utils::{
|
||||
DirEntryVecExt, DirentVisitor, FileSystem, Inode, InodeIo, InodeMode, InodeType,
|
||||
Metadata, MknodType, StatusFlags,
|
||||
DirEntryVecExt, DirentVisitor, Extension, FileSystem, Inode, InodeIo, InodeMode,
|
||||
InodeType, Metadata, MknodType, StatusFlags,
|
||||
},
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -96,7 +95,7 @@ impl<D: DirOps + 'static> InodeIo for ProcDir<D> {
|
|||
impl<D: DirOps + 'static> Inode for ProcDir<D> {
|
||||
fn size(&self) -> usize;
|
||||
fn metadata(&self) -> Metadata;
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
fn ino(&self) -> u64;
|
||||
fn mode(&self) -> Result<InodeMode>;
|
||||
fn set_mode(&self, mode: InodeMode) -> Result<()>;
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ use inherit_methods_macro::inherit_methods;
|
|||
|
||||
use super::{Common, ProcFs};
|
||||
use crate::{
|
||||
fs::{
|
||||
notify::FsEventPublisher,
|
||||
utils::{
|
||||
FileSystem, Inode, InodeIo, InodeMode, InodeType, Metadata, StatusFlags, SymbolicLink,
|
||||
},
|
||||
fs::utils::{
|
||||
Extension, FileSystem, Inode, InodeIo, InodeMode, InodeType, Metadata, StatusFlags,
|
||||
SymbolicLink,
|
||||
},
|
||||
prelude::*,
|
||||
process::{Gid, Uid},
|
||||
|
|
@ -69,7 +67,7 @@ impl<F: FileOps + 'static> InodeIo for ProcFile<F> {
|
|||
impl<F: FileOps + 'static> Inode for ProcFile<F> {
|
||||
fn size(&self) -> usize;
|
||||
fn metadata(&self) -> Metadata;
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
fn ino(&self) -> u64;
|
||||
fn mode(&self) -> Result<InodeMode>;
|
||||
fn set_mode(&self, mode: InodeMode) -> Result<()>;
|
||||
|
|
|
|||
|
|
@ -10,10 +10,7 @@ pub(super) use self::{
|
|||
};
|
||||
use super::{BLOCK_SIZE, ProcFs};
|
||||
use crate::{
|
||||
fs::{
|
||||
notify::FsEventPublisher,
|
||||
utils::{FileSystem, InodeMode, InodeType, Metadata},
|
||||
},
|
||||
fs::utils::{Extension, FileSystem, InodeMode, InodeType, Metadata},
|
||||
prelude::*,
|
||||
process::{Gid, Uid},
|
||||
};
|
||||
|
|
@ -25,7 +22,7 @@ mod sym;
|
|||
|
||||
struct Common {
|
||||
metadata: RwLock<Metadata>,
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
extension: Extension,
|
||||
fs: Weak<dyn FileSystem>,
|
||||
is_volatile: bool,
|
||||
}
|
||||
|
|
@ -34,7 +31,7 @@ impl Common {
|
|||
pub fn new(metadata: Metadata, fs: Weak<dyn FileSystem>, is_volatile: bool) -> Self {
|
||||
Self {
|
||||
metadata: RwLock::new(metadata),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
fs,
|
||||
is_volatile,
|
||||
}
|
||||
|
|
@ -115,7 +112,7 @@ impl Common {
|
|||
self.is_volatile
|
||||
}
|
||||
|
||||
pub fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
pub fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ use inherit_methods_macro::inherit_methods;
|
|||
|
||||
use super::{Common, ProcFs};
|
||||
use crate::{
|
||||
fs::{
|
||||
notify::FsEventPublisher,
|
||||
utils::{
|
||||
FileSystem, Inode, InodeIo, InodeMode, InodeType, Metadata, StatusFlags, SymbolicLink,
|
||||
},
|
||||
fs::utils::{
|
||||
Extension, FileSystem, Inode, InodeIo, InodeMode, InodeType, Metadata, StatusFlags,
|
||||
SymbolicLink,
|
||||
},
|
||||
prelude::*,
|
||||
process::{Gid, Uid},
|
||||
|
|
@ -66,7 +64,7 @@ impl<S: SymOps + 'static> InodeIo for ProcSym<S> {
|
|||
impl<S: SymOps + 'static> Inode for ProcSym<S> {
|
||||
fn size(&self) -> usize;
|
||||
fn metadata(&self) -> Metadata;
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
fn ino(&self) -> u64;
|
||||
fn mode(&self) -> Result<InodeMode>;
|
||||
fn set_mode(&self, mode: InodeMode) -> Result<()>;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,9 @@ use core::time::Duration;
|
|||
|
||||
use spin::Once;
|
||||
|
||||
use super::utils::{InodeIo, StatusFlags};
|
||||
use super::utils::{Extension, InodeIo, StatusFlags};
|
||||
use crate::{
|
||||
fs::{
|
||||
notify::FsEventPublisher,
|
||||
registry::{FsProperties, FsType},
|
||||
utils::{
|
||||
FileSystem, FsEventSubscriberStats, FsFlags, Inode, InodeMode, InodeType, Metadata,
|
||||
|
|
@ -182,7 +181,7 @@ const ANON_INODEFS_MAGIC: u64 = 0x09041934;
|
|||
/// A pseudo inode that does not correspond to any real path in the file system.
|
||||
pub struct PseudoInode {
|
||||
metadata: SpinLock<Metadata>,
|
||||
fs_events_publisher: FsEventPublisher,
|
||||
extension: Extension,
|
||||
fs: Weak<PseudoFs>,
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +214,7 @@ impl PseudoInode {
|
|||
};
|
||||
PseudoInode {
|
||||
metadata: SpinLock::new(metadata),
|
||||
fs_events_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
fs,
|
||||
}
|
||||
}
|
||||
|
|
@ -260,8 +259,8 @@ impl Inode for PseudoInode {
|
|||
*self.metadata.lock()
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_events_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
fn ino(&self) -> u64 {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ use crate::{
|
|||
fs::{
|
||||
device::DeviceType,
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
path::{is_dot, is_dot_or_dotdot, is_dotdot},
|
||||
pipe::Pipe,
|
||||
registry::{FsProperties, FsType},
|
||||
|
|
@ -67,7 +66,6 @@ impl RamFs {
|
|||
fs: weak_fs.clone(),
|
||||
extension: Extension::new(),
|
||||
xattr: RamXattr::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
}),
|
||||
inode_allocator: AtomicU64::new(ROOT_INO + 1),
|
||||
fs_event_subscriber_stats: FsEventSubscriberStats::new(),
|
||||
|
|
@ -118,8 +116,6 @@ pub(super) struct RamInode {
|
|||
fs: Weak<RamFs>,
|
||||
/// Extensions
|
||||
extension: Extension,
|
||||
/// FS event publisher
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
/// Extended attributes
|
||||
xattr: RamXattr,
|
||||
}
|
||||
|
|
@ -454,7 +450,6 @@ impl RamInode {
|
|||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -468,7 +463,6 @@ impl RamInode {
|
|||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -488,7 +482,6 @@ impl RamInode {
|
|||
this: Weak::new(),
|
||||
fs: Weak::new(),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
}
|
||||
}
|
||||
|
|
@ -502,7 +495,6 @@ impl RamInode {
|
|||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -528,7 +520,6 @@ impl RamInode {
|
|||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -542,7 +533,6 @@ impl RamInode {
|
|||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -556,7 +546,6 @@ impl RamInode {
|
|||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
xattr: RamXattr::new(),
|
||||
})
|
||||
}
|
||||
|
|
@ -1234,12 +1223,8 @@ impl Inode for RamInode {
|
|||
}
|
||||
}
|
||||
|
||||
fn extension(&self) -> Option<&Extension> {
|
||||
Some(&self.extension)
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
|
||||
fn set_xattr(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ use crate::{
|
|||
file_handle::{FileLike, Mappable},
|
||||
file_table::FdFlags,
|
||||
inode_handle::{do_fallocate_util, do_resize_util, do_seek_util},
|
||||
notify::FsEventPublisher,
|
||||
path::{RESERVED_MOUNT_ID, check_open_util},
|
||||
tmpfs::TmpFs,
|
||||
utils::{
|
||||
|
|
@ -179,8 +178,7 @@ impl Inode for MemfdInode {
|
|||
fn group(&self) -> Result<Gid>;
|
||||
fn set_group(&self, gid: Gid) -> Result<()>;
|
||||
fn page_cache(&self) -> Option<Arc<Vmo>>;
|
||||
fn extension(&self) -> Option<&Extension>;
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
fn set_xattr(
|
||||
&self,
|
||||
name: XattrName,
|
||||
|
|
|
|||
|
|
@ -6,12 +6,9 @@ use ostd::sync::RwLock;
|
|||
|
||||
use super::fs::SysFs;
|
||||
use crate::{
|
||||
fs::{
|
||||
notify::FsEventPublisher,
|
||||
utils::{
|
||||
FileSystem, Inode, InodeMode, InodeType, Metadata,
|
||||
systree_inode::{SysTreeInodeTy, SysTreeNodeKind},
|
||||
},
|
||||
fs::utils::{
|
||||
Extension, FileSystem, Inode, InodeMode, InodeType, Metadata,
|
||||
systree_inode::{SysTreeInodeTy, SysTreeNodeKind},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
|
@ -28,8 +25,8 @@ pub(super) struct SysFsInode {
|
|||
/// Currently, the only mutable metadata is `mode`,
|
||||
/// which allows user space to `chmod` an inode on sysfs.
|
||||
metadata: Metadata,
|
||||
/// FS event publisher.
|
||||
fs_event_publisher: FsEventPublisher,
|
||||
/// The extension of this inode.
|
||||
extension: Extension,
|
||||
/// The file mode (permissions) of this inode, protected by a lock.
|
||||
mode: RwLock<InodeMode>,
|
||||
/// Weak reference to the parent inode.
|
||||
|
|
@ -51,7 +48,7 @@ impl SysTreeInodeTy for SysFsInode {
|
|||
Arc::new_cyclic(|this| Self {
|
||||
node_kind,
|
||||
metadata,
|
||||
fs_event_publisher: FsEventPublisher::new(),
|
||||
extension: Extension::new(),
|
||||
mode: RwLock::new(mode),
|
||||
parent,
|
||||
this: this.clone(),
|
||||
|
|
@ -85,8 +82,8 @@ impl SysTreeInodeTy for SysFsInode {
|
|||
.expect("invalid weak reference to `self`")
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
&self.fs_event_publisher
|
||||
fn extension(&self) -> &Extension {
|
||||
&self.extension
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
#![expect(unused_variables)]
|
||||
|
||||
use core::{any::TypeId, time::Duration};
|
||||
use alloc::boxed::ThinBox;
|
||||
use core::time::Duration;
|
||||
|
||||
use core2::io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult, Write};
|
||||
use ostd::task::Task;
|
||||
use spin::Once;
|
||||
|
||||
use super::{
|
||||
AccessMode, DirentVisitor, FallocMode, FileSystem, InodeMode, XattrName, XattrNamespace,
|
||||
|
|
@ -16,7 +18,6 @@ use crate::{
|
|||
device::{Device, DeviceType},
|
||||
fs_resolver::PathOrInode,
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
path::Path,
|
||||
utils::StatusFlags,
|
||||
},
|
||||
|
|
@ -402,19 +403,7 @@ pub trait Inode: Any + InodeIo + Send + Sync {
|
|||
}
|
||||
|
||||
/// Gets the extension of this inode.
|
||||
fn extension(&self) -> Option<&Extension> {
|
||||
None
|
||||
}
|
||||
|
||||
// TODO: Add `FsEventPublisher` as an extension.
|
||||
//
|
||||
// Conceptually, an `FsEventPublisher` attached to an inode is also a kind of extension
|
||||
// as this object is required by the VFS layer, not by FS implementations.
|
||||
// But we do not add it to `Extension` because `FsEventPublisher` is used in the most time-critical path
|
||||
// and looking up an extension object in an `Extension` incurs some extra overheads.
|
||||
// If we could make `Extension` a zero-cost abstraction,
|
||||
// then `FsEventPublisher` can be moved into `Extension`.
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
|
||||
fn set_xattr(
|
||||
&self,
|
||||
|
|
@ -569,76 +558,34 @@ impl Debug for dyn Inode {
|
|||
}
|
||||
}
|
||||
|
||||
/// An extension is a set of objects that is attached to
|
||||
/// an inode.
|
||||
/// An extension is a set of object groups that is attached to an inode.
|
||||
///
|
||||
/// Each objects of an extension is of different types.
|
||||
/// In other words, types are used as the keys to get and
|
||||
/// set the objects in an extension.
|
||||
/// In this structure, we do not specify the exact type, but instead use [`Any`], which makes the
|
||||
/// FS types (e.g., [`Inode`]) independent of the kernel types. This allows the file system
|
||||
/// implementation to exist outside the kernel.
|
||||
#[derive(Debug)]
|
||||
pub struct Extension {
|
||||
data: RwLock<BTreeMap<TypeId, Arc<dyn Any + Send + Sync>>>,
|
||||
group1: Once<ThinBox<dyn Any + Send + Sync>>,
|
||||
group2: Once<ThinBox<dyn Any + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl Extension {
|
||||
/// Creates a new, empty extension.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
data: RwLock::new(BTreeMap::new()),
|
||||
group1: Once::new(),
|
||||
group2: Once::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get an object of `Arc<T>`.
|
||||
pub fn get<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
|
||||
let read_guard = self.data.read();
|
||||
read_guard
|
||||
.get(&TypeId::of::<T>())
|
||||
.and_then(|arc_any| Arc::downcast::<T>(arc_any.clone()).ok())
|
||||
/// Gets the first extension group.
|
||||
pub fn group1(&self) -> &Once<ThinBox<dyn Any + Send + Sync>> {
|
||||
&self.group1
|
||||
}
|
||||
|
||||
/// Try to get an object of `Arc<T>`. If no object of the type exists,
|
||||
/// put the default value for the type, then return it.
|
||||
pub fn get_or_put_default<T: Any + Send + Sync + Default>(&self) -> Arc<T> {
|
||||
let mut write_guard = self.data.write();
|
||||
let type_id = TypeId::of::<T>();
|
||||
let arc_any = write_guard.entry(type_id).or_insert_with(|| {
|
||||
let obj = T::default();
|
||||
Arc::new(obj) as Arc<dyn Any + Send + Sync>
|
||||
});
|
||||
Arc::downcast::<T>(arc_any.clone()).unwrap()
|
||||
}
|
||||
|
||||
/// Put an object of `Arc<T>`. If there exists one object of the type,
|
||||
/// then the old one is returned.
|
||||
#[expect(dead_code)]
|
||||
pub fn put<T: Any + Send + Sync>(&self, obj: Arc<T>) -> Option<Arc<T>> {
|
||||
let mut write_guard = self.data.write();
|
||||
write_guard
|
||||
.insert(TypeId::of::<T>(), obj as Arc<dyn Any + Send + Sync>)
|
||||
.and_then(|arc_any| Arc::downcast::<T>(arc_any).ok())
|
||||
}
|
||||
|
||||
/// Delete an object of `Arc<T>`. If there exists one object of the type,
|
||||
/// then the old one is returned.
|
||||
#[expect(dead_code)]
|
||||
pub fn del<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
|
||||
let mut write_guard = self.data.write();
|
||||
write_guard
|
||||
.remove(&TypeId::of::<T>())
|
||||
.and_then(|arc_any| Arc::downcast::<T>(arc_any).ok())
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Extension {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
data: RwLock::new(self.data.read().clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Extension {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
/// Gets the second extension group.
|
||||
pub fn group2(&self) -> &Once<ThinBox<dyn Any + Send + Sync>> {
|
||||
&self.group2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::boxed::ThinBox;
|
||||
|
||||
use super::{FlockList, Inode, RangeLockList};
|
||||
use crate::fs::notify::FsEventPublisher;
|
||||
|
||||
/// Context for FS locks.
|
||||
pub struct FsLockContext {
|
||||
range_lock_list: RangeLockList,
|
||||
flock_list: FlockList,
|
||||
}
|
||||
|
||||
impl FsLockContext {
|
||||
pub(self) fn new() -> Self {
|
||||
Self {
|
||||
range_lock_list: RangeLockList::new(),
|
||||
flock_list: FlockList::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the range lock list.
|
||||
pub fn range_lock_list(&self) -> &RangeLockList {
|
||||
&self.range_lock_list
|
||||
}
|
||||
|
||||
/// Returns a reference to the flock list.
|
||||
pub fn flock_list(&self) -> &FlockList {
|
||||
&self.flock_list
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that instantiates kernel types for the inode [`Extension`].
|
||||
///
|
||||
/// [`Extension`]: super::Extension
|
||||
pub trait InodeExt {
|
||||
/// Gets or initializes the FS event publisher.
|
||||
///
|
||||
/// If the publisher does not exist for this inode, it will be created.
|
||||
fn fs_event_publisher_or_init(&self) -> &FsEventPublisher;
|
||||
|
||||
/// Returns a reference to the FS event publisher.
|
||||
///
|
||||
/// If the publisher does not exist for this inode, a [`None`] will be returned.
|
||||
fn fs_event_publisher(&self) -> Option<&FsEventPublisher>;
|
||||
|
||||
/// Gets or initializes the FS lock context.
|
||||
///
|
||||
/// If the context does not exist for this inode, it will be created.
|
||||
fn fs_lock_context_or_init(&self) -> &FsLockContext;
|
||||
|
||||
/// Returns a reference to the FS lock context.
|
||||
///
|
||||
/// If the context does not exist for this inode, a [`None`] will be returned.
|
||||
fn fs_lock_context(&self) -> Option<&FsLockContext>;
|
||||
}
|
||||
|
||||
impl InodeExt for dyn Inode {
|
||||
fn fs_event_publisher_or_init(&self) -> &FsEventPublisher {
|
||||
self.extension()
|
||||
.group1()
|
||||
.call_once(|| ThinBox::new_unsize(FsEventPublisher::new()))
|
||||
.downcast_ref()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn fs_event_publisher(&self) -> Option<&FsEventPublisher> {
|
||||
Some(self.extension().group1().get()?.downcast_ref().unwrap())
|
||||
}
|
||||
|
||||
fn fs_lock_context_or_init(&self) -> &FsLockContext {
|
||||
self.extension()
|
||||
.group2()
|
||||
.call_once(|| ThinBox::new_unsize(FsLockContext::new()))
|
||||
.downcast_ref()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn fs_lock_context(&self) -> Option<&FsLockContext> {
|
||||
Some(self.extension().group2().get()?.downcast_ref().unwrap())
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ pub use id_bitmap::IdBitmap;
|
|||
pub use inode::{
|
||||
Extension, Inode, InodeIo, InodeType, Metadata, MknodType, Permission, SymbolicLink,
|
||||
};
|
||||
pub use inode_ext::InodeExt;
|
||||
pub use inode_mode::InodeMode;
|
||||
pub(crate) use inode_mode::{chmod, mkmod, perms_to_mask, who_and_perms_to_mask, who_to_mask};
|
||||
pub use open_args::OpenArgs;
|
||||
|
|
@ -38,6 +39,7 @@ mod flock;
|
|||
mod fs;
|
||||
mod id_bitmap;
|
||||
mod inode;
|
||||
mod inode_ext;
|
||||
mod inode_mode;
|
||||
pub mod ioctl_defs;
|
||||
mod open_args;
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ use aster_systree::{
|
|||
SysAttr, SysBranchNode, SysNode, SysNodeId, SysNodeType, SysObj, SysStr, SysSymlink,
|
||||
};
|
||||
|
||||
use super::Extension;
|
||||
use crate::{
|
||||
fs::{
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
utils::{
|
||||
AccessMode, DirentVisitor, FallocMode, FileSystem, Inode, InodeIo, InodeMode,
|
||||
InodeType, Metadata, MknodType, StatusFlags, SymbolicLink, mkmod,
|
||||
|
|
@ -54,7 +54,7 @@ pub(in crate::fs) trait SysTreeInodeTy: Send + Sync + 'static {
|
|||
|
||||
fn set_mode(&self, mode: InodeMode) -> Result<()>;
|
||||
|
||||
fn fs_event_publisher(&self) -> &FsEventPublisher;
|
||||
fn extension(&self) -> &Extension;
|
||||
|
||||
fn parent(&self) -> &Weak<Self>;
|
||||
|
||||
|
|
@ -593,8 +593,8 @@ impl<KInode: SysTreeInodeTy + Send + Sync + 'static> Inode for KInode {
|
|||
true
|
||||
}
|
||||
|
||||
default fn fs_event_publisher(&self) -> &FsEventPublisher {
|
||||
self.fs_event_publisher()
|
||||
default fn extension(&self) -> &Extension {
|
||||
self.extension()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#![feature(panic_can_unwind)]
|
||||
#![feature(register_tool)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(thin_box)]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(try_with_capacity)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue