设备驱动模型:完善platform bus相关内容。并注册串口到sysfs (#403)

* 完成初始化platform bus
* 删除旧的sysfs
* 把uart驱动移动到tty/serial文件夹下
* 完成将串口挂载到sysfs
* 修复vfs系统调用未能follow symlink的问题
* 修复shell未能正确获取pwd的问题
This commit is contained in:
LoGin
2023-10-20 22:11:33 +08:00
committed by GitHub
parent 06d5e24726
commit a03c4f9dee
61 changed files with 2904 additions and 1325 deletions

View File

@ -1,4 +1,4 @@
use core::{fmt::Debug, intrinsics::unlikely};
use core::{cmp::min, fmt::Debug, intrinsics::unlikely};
use alloc::{
string::String,
@ -64,7 +64,7 @@ impl KernFS {
(*ptr).self_ref = Arc::downgrade(&root_inode);
}
}
root_inode.inner.lock().parent = Arc::downgrade(&root_inode);
root_inode.inner.write().parent = Arc::downgrade(&root_inode);
*root_inode.fs.write() = Arc::downgrade(&fs);
return fs;
}
@ -88,9 +88,11 @@ impl KernFS {
};
let root_inode = Arc::new(KernFSInode {
name: String::from(""),
inner: SpinLock::new(InnerKernFSInode {
inner: RwLock::new(InnerKernFSInode {
parent: Weak::new(),
metadata,
symlink_target: None,
symlink_target_absolute_path: None,
}),
self_ref: Weak::new(),
fs: RwLock::new(Weak::new()),
@ -106,7 +108,7 @@ impl KernFS {
#[derive(Debug)]
pub struct KernFSInode {
inner: SpinLock<InnerKernFSInode>,
inner: RwLock<InnerKernFSInode>,
/// 指向当前Inode所属的文件系统的弱引用
fs: RwLock<Weak<KernFS>>,
/// 指向自身的弱引用
@ -129,6 +131,9 @@ pub struct InnerKernFSInode {
/// 当前inode的元数据
metadata: Metadata,
/// 符号链接指向的inode仅当inode_type为SymLink时有效
symlink_target: Option<Weak<KernFSInode>>,
symlink_target_absolute_path: Option<String>,
}
impl IndexNode for KernFSInode {
@ -151,7 +156,7 @@ impl IndexNode for KernFSInode {
}
fn metadata(&self) -> Result<Metadata, SystemError> {
return Ok(self.inner.lock().metadata.clone());
return Ok(self.inner.read().metadata.clone());
}
fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> {
@ -214,7 +219,7 @@ impl IndexNode for KernFSInode {
".." => {
return Ok(self
.inner
.lock()
.read()
.parent
.upgrade()
.ok_or(SystemError::ENOENT)?);
@ -300,6 +305,25 @@ impl IndexNode for KernFSInode {
buf: &mut [u8],
_data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
if self.inode_type == KernInodeType::SymLink {
let inner = self.inner.read();
if offset >= inner.symlink_target_absolute_path.as_ref().unwrap().len() {
return Ok(0);
}
let len = min(len, buf.len());
let len = min(
len,
inner.symlink_target_absolute_path.as_ref().unwrap().len() - offset,
);
buf[0..len].copy_from_slice(
&inner
.symlink_target_absolute_path
.as_ref()
.unwrap()
.as_bytes()[offset..offset + len],
);
return Ok(len);
}
if self.inode_type != KernInodeType::File {
return Err(SystemError::EISDIR);
}
@ -344,6 +368,51 @@ impl IndexNode for KernFSInode {
}
impl KernFSInode {
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: RwLock::new(InnerKernFSInode {
parent: parent.clone(),
metadata,
symlink_target: None,
symlink_target_absolute_path: None,
}),
self_ref: Weak::new(),
fs: RwLock::new(Weak::new()),
private_data: SpinLock::new(private_data),
callback,
children: SpinLock::new(HashMap::new()),
inode_type,
});
{
let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode;
unsafe {
(*ptr).self_ref = Arc::downgrade(&inode);
}
}
if parent.strong_count() > 0 {
let kernfs = parent
.upgrade()
.unwrap()
.fs()
.downcast_arc::<KernFS>()
.expect("KernFSInode::new: parent is not a KernFS instance");
*inode.fs.write() = Arc::downgrade(&kernfs);
}
return inode;
}
/// 在当前inode下增加子目录
///
/// ## 参数
@ -410,11 +479,15 @@ 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 size;
match file_type {
KernInodeType::Dir | KernInodeType::SymLink => {
size = 0;
}
KernInodeType::File => {
size = 4096;
}
}
let metadata = Metadata {
size,
@ -475,47 +548,35 @@ impl KernFSInode {
}
}
pub fn new(
parent: Option<Arc<KernFSInode>>,
/// add_link - create a symlink in kernfs
///
/// ## 参数
///
/// - `parent`: directory to create the symlink in
/// - `name`: name of the symlink
/// - `target`: target node for the symlink to point to
///
/// Returns the created node on success
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25
pub fn add_link(
&self,
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 {
target: &Arc<KernFSInode>,
target_absolute_path: String,
) -> Result<Arc<KernFSInode>, SystemError> {
// kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}");
let inode = self.inner_create(
name,
inner: SpinLock::new(InnerKernFSInode {
parent: parent.clone(),
metadata,
}),
self_ref: Weak::new(),
fs: RwLock::new(Weak::new()),
private_data: SpinLock::new(private_data),
callback,
children: SpinLock::new(HashMap::new()),
inode_type,
});
KernInodeType::SymLink,
ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777),
None,
None,
)?;
{
let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode;
unsafe {
(*ptr).self_ref = Arc::downgrade(&inode);
}
}
if parent.strong_count() > 0 {
let kernfs = parent
.upgrade()
.unwrap()
.fs()
.downcast_arc::<KernFS>()
.expect("KernFSInode::new: parent is not a KernFS instance");
*inode.fs.write() = Arc::downgrade(&kernfs);
}
return inode;
inode.inner.write().symlink_target = Some(Arc::downgrade(target));
inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path);
return Ok(inode);
}
pub fn name(&self) -> &str {
@ -523,13 +584,18 @@ impl KernFSInode {
}
pub fn parent(&self) -> Option<Arc<KernFSInode>> {
return self.inner.lock().parent.upgrade();
return self.inner.read().parent.upgrade();
}
pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> {
return self.private_data.lock();
}
#[allow(dead_code)]
pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> {
return self.inner.read().symlink_target.as_ref()?.upgrade();
}
/// remove a kernfs_node recursively
pub fn remove_recursive(&self) {
let mut children = self.children.lock().drain().collect::<Vec<_>>();
@ -552,6 +618,7 @@ impl KernFSInode {
pub enum KernInodeType {
Dir,
File,
SymLink,
}
impl Into<FileType> for KernInodeType {
@ -559,6 +626,7 @@ impl Into<FileType> for KernInodeType {
match self {
KernInodeType::Dir => FileType::Dir,
KernInodeType::File => FileType::File,
KernInodeType::SymLink => FileType::SymLink,
}
}
}