mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-26 10:53:25 +00:00
Add Extension implementation on inode for lock storing
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0c9b7c03bb
commit
4a2da992a6
@ -31,7 +31,7 @@ use crate::{
|
|||||||
device::Device,
|
device::Device,
|
||||||
exfat::{dentry::ExfatDentryIterator, fat::ExfatChain, fs::ExfatFS},
|
exfat::{dentry::ExfatDentryIterator, fat::ExfatChain, fs::ExfatFS},
|
||||||
utils::{
|
utils::{
|
||||||
DirentVisitor, Inode, InodeMode, InodeType, IoctlCmd, Metadata, PageCache,
|
DirentVisitor, Extension, Inode, InodeMode, InodeType, IoctlCmd, Metadata, PageCache,
|
||||||
PageCacheBackend,
|
PageCacheBackend,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -79,6 +79,7 @@ impl FatAttr {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExfatInode {
|
pub struct ExfatInode {
|
||||||
inner: RwMutex<ExfatInodeInner>,
|
inner: RwMutex<ExfatInodeInner>,
|
||||||
|
extension: Extension,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -667,6 +668,7 @@ impl ExfatInode {
|
|||||||
fs: fs_weak,
|
fs: fs_weak,
|
||||||
page_cache: PageCache::with_capacity(size, weak_self.clone() as _).unwrap(),
|
page_cache: PageCache::with_capacity(size, weak_self.clone() as _).unwrap(),
|
||||||
}),
|
}),
|
||||||
|
extension: Extension::new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let inner = inode.inner.upread();
|
let inner = inode.inner.upread();
|
||||||
@ -776,6 +778,7 @@ impl ExfatInode {
|
|||||||
fs: fs_weak,
|
fs: fs_weak,
|
||||||
page_cache: PageCache::with_capacity(size, weak_self.clone() as _).unwrap(),
|
page_cache: PageCache::with_capacity(size, weak_self.clone() as _).unwrap(),
|
||||||
}),
|
}),
|
||||||
|
extension: Extension::new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if matches!(inode_type, InodeType::Dir) {
|
if matches!(inode_type, InodeType::Dir) {
|
||||||
@ -1703,4 +1706,8 @@ impl Inode for ExfatInode {
|
|||||||
fn is_dentry_cacheable(&self) -> bool {
|
fn is_dentry_cacheable(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extension(&self) -> Option<&Extension> {
|
||||||
|
Some(&self.extension)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ use crate::{
|
|||||||
device::Device,
|
device::Device,
|
||||||
ext2::{FilePerm, FileType, Inode as Ext2Inode},
|
ext2::{FilePerm, FileType, Inode as Ext2Inode},
|
||||||
utils::{
|
utils::{
|
||||||
DirentVisitor, FallocMode, FileSystem, Inode, InodeMode, InodeType, IoctlCmd, Metadata,
|
DirentVisitor, Extension, FallocMode, FileSystem, Inode, InodeMode, InodeType,
|
||||||
|
IoctlCmd, Metadata,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -193,6 +194,10 @@ impl Inode for Ext2Inode {
|
|||||||
fn fs(&self) -> Arc<dyn FileSystem> {
|
fn fs(&self) -> Arc<dyn FileSystem> {
|
||||||
self.fs()
|
self.fs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extension(&self) -> Option<&Extension> {
|
||||||
|
Some(self.extension())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FilePerm> for InodeMode {
|
impl From<FilePerm> for InodeMode {
|
||||||
|
@ -16,7 +16,7 @@ use super::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
utils::now,
|
utils::now,
|
||||||
};
|
};
|
||||||
use crate::fs::utils::FallocMode;
|
use crate::fs::utils::{Extension, FallocMode};
|
||||||
|
|
||||||
/// Max length of file name.
|
/// Max length of file name.
|
||||||
pub const MAX_FNAME_LEN: usize = 255;
|
pub const MAX_FNAME_LEN: usize = 255;
|
||||||
@ -30,6 +30,7 @@ pub struct Inode {
|
|||||||
block_group_idx: usize,
|
block_group_idx: usize,
|
||||||
inner: RwMutex<Inner>,
|
inner: RwMutex<Inner>,
|
||||||
fs: Weak<Ext2>,
|
fs: Weak<Ext2>,
|
||||||
|
extension: Extension,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inode {
|
impl Inode {
|
||||||
@ -44,6 +45,7 @@ impl Inode {
|
|||||||
block_group_idx,
|
block_group_idx,
|
||||||
inner: RwMutex::new(Inner::new(desc, weak_self.clone(), fs.clone())),
|
inner: RwMutex::new(Inner::new(desc, weak_self.clone(), fs.clone())),
|
||||||
fs,
|
fs,
|
||||||
|
extension: Extension::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,6 +738,10 @@ impl Inode {
|
|||||||
inner.set_ctime(now());
|
inner.set_ctime(now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn extension(&self) -> &Extension {
|
||||||
|
&self.extension
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> {
|
pub fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> {
|
||||||
if self.file_type() != FileType::File {
|
if self.file_type() != FileType::File {
|
||||||
return_errno_with_message!(Errno::EISDIR, "not regular file");
|
return_errno_with_message!(Errno::EISDIR, "not regular file");
|
||||||
|
@ -19,8 +19,8 @@ use crate::{
|
|||||||
fs::{
|
fs::{
|
||||||
device::Device,
|
device::Device,
|
||||||
utils::{
|
utils::{
|
||||||
CStr256, DirentVisitor, FallocMode, FileSystem, FsFlags, Inode, InodeMode, InodeType,
|
CStr256, DirentVisitor, Extension, FallocMode, FileSystem, FsFlags, Inode, InodeMode,
|
||||||
IoctlCmd, Metadata, PageCache, PageCacheBackend, SuperBlock,
|
InodeType, IoctlCmd, Metadata, PageCache, PageCacheBackend, SuperBlock,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -55,6 +55,7 @@ impl RamFS {
|
|||||||
typ: InodeType::Dir,
|
typ: InodeType::Dir,
|
||||||
this: weak_root.clone(),
|
this: weak_root.clone(),
|
||||||
fs: weak_fs.clone(),
|
fs: weak_fs.clone(),
|
||||||
|
extension: Extension::new(),
|
||||||
}),
|
}),
|
||||||
inode_allocator: AtomicU64::new(ROOT_INO + 1),
|
inode_allocator: AtomicU64::new(ROOT_INO + 1),
|
||||||
})
|
})
|
||||||
@ -99,6 +100,8 @@ struct RamInode {
|
|||||||
this: Weak<RamInode>,
|
this: Weak<RamInode>,
|
||||||
/// Reference to fs
|
/// Reference to fs
|
||||||
fs: Weak<RamFS>,
|
fs: Weak<RamFS>,
|
||||||
|
/// Extensions
|
||||||
|
extension: Extension,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Node {
|
struct Node {
|
||||||
@ -415,6 +418,7 @@ impl RamInode {
|
|||||||
typ: InodeType::Dir,
|
typ: InodeType::Dir,
|
||||||
this: weak_self.clone(),
|
this: weak_self.clone(),
|
||||||
fs: Arc::downgrade(fs),
|
fs: Arc::downgrade(fs),
|
||||||
|
extension: Extension::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +429,7 @@ impl RamInode {
|
|||||||
typ: InodeType::File,
|
typ: InodeType::File,
|
||||||
this: weak_self.clone(),
|
this: weak_self.clone(),
|
||||||
fs: Arc::downgrade(fs),
|
fs: Arc::downgrade(fs),
|
||||||
|
extension: Extension::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,6 +440,7 @@ impl RamInode {
|
|||||||
typ: InodeType::SymLink,
|
typ: InodeType::SymLink,
|
||||||
this: weak_self.clone(),
|
this: weak_self.clone(),
|
||||||
fs: Arc::downgrade(fs),
|
fs: Arc::downgrade(fs),
|
||||||
|
extension: Extension::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,6 +451,7 @@ impl RamInode {
|
|||||||
typ: InodeType::Socket,
|
typ: InodeType::Socket,
|
||||||
this: weak_self.clone(),
|
this: weak_self.clone(),
|
||||||
fs: Arc::downgrade(fs),
|
fs: Arc::downgrade(fs),
|
||||||
|
extension: Extension::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,6 +468,7 @@ impl RamInode {
|
|||||||
typ: InodeType::from(device.type_()),
|
typ: InodeType::from(device.type_()),
|
||||||
this: weak_self.clone(),
|
this: weak_self.clone(),
|
||||||
fs: Arc::downgrade(fs),
|
fs: Arc::downgrade(fs),
|
||||||
|
extension: Extension::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,6 +1162,10 @@ impl Inode for RamInode {
|
|||||||
}
|
}
|
||||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extension(&self) -> Option<&Extension> {
|
||||||
|
Some(&self.extension)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_lock_two_inodes<'a>(
|
fn write_lock_two_inodes<'a>(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
use core::time::Duration;
|
use core::{any::TypeId, time::Duration};
|
||||||
|
|
||||||
use aster_rights::Full;
|
use aster_rights::Full;
|
||||||
use core2::io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult, Write};
|
use core2::io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult, Write};
|
||||||
@ -385,6 +385,11 @@ pub trait Inode: Any + Sync + Send {
|
|||||||
fn is_dentry_cacheable(&self) -> bool {
|
fn is_dentry_cacheable(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the extension of this inode
|
||||||
|
fn extension(&self) -> Option<&Extension> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dyn Inode {
|
impl dyn Inode {
|
||||||
@ -454,3 +459,74 @@ impl Debug for dyn Inode {
|
|||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An extension is a set of objects 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.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Extension {
|
||||||
|
data: RwLock<BTreeMap<TypeId, Arc<dyn Any + Send + Sync>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extension {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
data: RwLock::new(BTreeMap::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())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
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.
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user