完善设备驱动模型,基于kset、kobj来维护对象之间的关系 (#401)

* 使用kobj和kset管理/sys文件夹下的对象

* 修改notifier,把action从u64换为泛型。

* 完善设备驱动模型,基于kset、kobj来维护对象之间的关系
This commit is contained in:
LoGin
2023-10-11 00:53:15 +08:00
committed by GitHub
parent 6abb8bd7c0
commit 06d5e24726
46 changed files with 3492 additions and 1530 deletions

View File

@ -64,6 +64,22 @@ impl<'a> KernCallbackData<'a> {
pub fn private_data_mut(&mut self) -> &mut Option<KernInodePrivateData> {
return &mut self.private_data;
}
pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
let private_data = self.private_data();
if let Some(private_data) = private_data {
return private_data.callback_read(buf, offset);
}
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> {
let private_data = self.private_data();
if let Some(private_data) = private_data {
return private_data.callback_write(buf, offset);
}
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
}
#[allow(dead_code)]
@ -71,3 +87,23 @@ impl<'a> KernCallbackData<'a> {
pub enum KernInodePrivateData {
SysFS(SysFSKernPrivateData),
}
impl KernInodePrivateData {
#[inline(always)]
pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
match self {
KernInodePrivateData::SysFS(private_data) => {
return private_data.callback_read(buf, offset);
}
}
}
#[inline(always)]
pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result<usize, SystemError> {
match self {
KernInodePrivateData::SysFS(private_data) => {
return private_data.callback_write(buf, offset);
}
}
}
}

View File

@ -8,7 +8,11 @@ use alloc::{
use hashbrown::HashMap;
use crate::{
libs::{rwlock::RwLock, spinlock::SpinLock},
libs::{
casting::DowncastArc,
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard},
},
syscall::SystemError,
time::TimeSpec,
};
@ -83,6 +87,7 @@ impl KernFS {
raw_dev: 0,
};
let root_inode = Arc::new(KernFSInode {
name: String::from(""),
inner: SpinLock::new(InnerKernFSInode {
parent: Weak::new(),
metadata,
@ -114,6 +119,8 @@ pub struct KernFSInode {
children: SpinLock<HashMap<String, Arc<KernFSInode>>>,
/// Inode类型
inode_type: KernInodeType,
/// Inode名称
name: String,
}
#[derive(Debug)]
@ -199,13 +206,29 @@ impl IndexNode for KernFSInode {
if unlikely(self.inode_type != KernInodeType::Dir) {
return Err(SystemError::ENOTDIR);
}
let x: Arc<KernFSInode> = self
.children
.lock()
.get(name)
.cloned()
.ok_or(SystemError::ENOENT)?;
return Ok(x);
match name {
"" | "." => {
return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
}
".." => {
return Ok(self
.inner
.lock()
.parent
.upgrade()
.ok_or(SystemError::ENOENT)?);
}
name => {
// 在子目录项中查找
return Ok(self
.children
.lock()
.get(name)
.ok_or(SystemError::ENOENT)?
.clone());
}
}
}
fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
@ -248,11 +271,21 @@ impl IndexNode for KernFSInode {
}
fn list(&self) -> Result<Vec<String>, SystemError> {
let mut list = Vec::new();
for (name, _) in self.children.lock().iter() {
list.push(name.clone());
let info = self.metadata()?;
if info.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
return Ok(list);
let mut keys: Vec<String> = Vec::new();
keys.push(String::from("."));
keys.push(String::from(".."));
self.children
.lock()
.keys()
.into_iter()
.for_each(|x| keys.push(x.clone()));
return Ok(keys);
}
fn poll(&self) -> Result<PollStatus, SystemError> {
@ -272,6 +305,7 @@ impl IndexNode for KernFSInode {
}
if self.callback.is_none() {
kwarn!("kernfs: callback is none");
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
@ -376,8 +410,14 @@ impl KernFSInode {
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Result<Arc<KernFSInode>, SystemError> {
let size = if file_type == KernInodeType::File {
4096
} else {
0
};
let metadata = Metadata {
size: 0,
size,
mode,
uid: 0,
gid: 0,
@ -394,9 +434,10 @@ impl KernFSInode {
};
let new_inode: Arc<KernFSInode> = Self::new(
self.self_ref.upgrade().unwrap(),
Some(self.self_ref.upgrade().unwrap()),
name.clone(),
metadata,
KernInodeType::Dir,
file_type,
private_data,
callback,
);
@ -434,16 +475,21 @@ impl KernFSInode {
}
}
pub(self) fn new(
parent: Arc<KernFSInode>,
metadata: Metadata,
pub fn new(
parent: Option<Arc<KernFSInode>>,
name: String,
mut metadata: Metadata,
inode_type: KernInodeType,
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Arc<KernFSInode> {
metadata.file_type = inode_type.into();
let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default();
let inode = Arc::new(KernFSInode {
name,
inner: SpinLock::new(InnerKernFSInode {
parent: Arc::downgrade(&parent),
parent: parent.clone(),
metadata,
}),
self_ref: Weak::new(),
@ -460,18 +506,50 @@ impl KernFSInode {
(*ptr).self_ref = Arc::downgrade(&inode);
}
}
*inode.fs.write() = Arc::downgrade(
parent
if parent.strong_count() > 0 {
let kernfs = parent
.upgrade()
.unwrap()
.fs()
.as_any_ref()
.downcast_ref()
.expect("KernFSInode::new: parent is not a KernFS instance"),
);
.downcast_arc::<KernFS>()
.expect("KernFSInode::new: parent is not a KernFS instance");
*inode.fs.write() = Arc::downgrade(&kernfs);
}
return inode;
}
pub fn name(&self) -> &str {
return &self.name;
}
pub fn parent(&self) -> Option<Arc<KernFSInode>> {
return self.inner.lock().parent.upgrade();
}
pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> {
return self.private_data.lock();
}
/// remove a kernfs_node recursively
pub fn remove_recursive(&self) {
let mut children = self.children.lock().drain().collect::<Vec<_>>();
while let Some((_, child)) = children.pop() {
children.append(&mut child.children.lock().drain().collect::<Vec<_>>());
}
}
/// 删除当前的inode包括其自身、子目录和子文件
#[allow(dead_code)]
pub fn remove_inode_include_self(&self) {
let parent = self.parent();
if let Some(parent) = parent {
parent.children.lock().remove(self.name());
}
self.remove_recursive();
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(self) enum KernInodeType {
pub enum KernInodeType {
Dir,
File,
}