Add Extension implementation on inode for lock storing

This commit is contained in:
Fabing Li
2024-08-09 11:18:50 +08:00
committed by Tate, Hongliang Tian
parent 0c9b7c03bb
commit 4a2da992a6
5 changed files with 112 additions and 6 deletions

View File

@ -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)
}
} }

View File

@ -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 {

View File

@ -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");

View 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>(

View File

@ -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()
}
}