mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
设备驱动模型:完善platform bus相关内容。并注册串口到sysfs (#403)
* 完成初始化platform bus * 删除旧的sysfs * 把uart驱动移动到tty/serial文件夹下 * 完成将串口挂载到sysfs * 修复vfs系统调用未能follow symlink的问题 * 修复shell未能正确获取pwd的问题
This commit is contained in:
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user