增加kernfs (#386)

* 增加kernfs

* kernfs文档
This commit is contained in:
LoGin 2023-09-19 19:46:59 +08:00 committed by GitHub
parent ae5ede03be
commit 6b4e7a2972
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 880 additions and 111 deletions

View File

@ -12,4 +12,5 @@ todo: 由于文件系统模块重构文档暂时不可用预计在2023年4
overview
vfs/index
sysfs
kernfs

View File

@ -0,0 +1,22 @@
# KernFS
:::{note}
Maintainer:
- 龙进 <longjin@dragonos.org>
:::
## 1. 简介
&emsp;&emsp;KernFS是一个伪文件系统它充当其它内核文件系统的容器面向用户提供文件接口。其核心功能就是当kernfs的文件被读/写或者触发回调点的时候,将会对预设的回调函数进行调用,触发其它内核文件系统的操作。
&emsp;&emsp;这种设计使得SysFS和文件系统的基本操作解耦KernFS作为SysFS的承载物使得SysFS能更专注于KObject的管理让代码更加优雅。
&emsp;&emsp;在未来DragonOS的内核子系统或者其它的内核文件系统可以使用KernFS作为文件系统操作的承载物让系统管理的逻辑与具体的文件系统操作解除耦合。
## 2. 使用方法
&emsp;&emsp;以SysFS为例新创建一个KernFS实例作为SysFS的文件系统接口然后挂载到`/sys`目录下。接着sysfs实现上层逻辑管理KObject每个上层的Kobject里面都需要包含KernFSInode。并且通过设置KernFSInode的PrivateData使得KernFS能够根据Inode获取到其指向的KObject或者sysfs的attribute。并且在创建KernFSInode的时候为具体的Inode传入不同的callback以此实现“不同的Inode在读写时能够触发不同的回调行为”。
&emsp;&emsp;当发生回调时KernFS会把回调信息、私有信息传入到回调函数中让回调函数能够根据传入的信息获取到对应的KObject或者sysfs的attribute从而实现sysfs提供的高层功能。
&emsp;&emsp;从上述描述我们能够看出KernFS就是通过存储上层文件系统的回调函数、回调信息来实现“把具体文件操作与高层管理逻辑进行解耦”的目的。

View File

@ -1,6 +1,7 @@
use crate::driver::base::block::block_device::BlockDevice;
use crate::filesystem::devfs::{DevFS, DeviceINode};
use crate::filesystem::vfs::file::FileMode;
use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{
core::generate_inode_id, make_rawdev, FilePrivateData, FileSystem, FileType, IndexNode,
Metadata, PollStatus,
@ -49,7 +50,7 @@ impl LockedAhciInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::BlockDevice, // 文件夹block设备char设备
mode: 0o666,
mode: ModeType::from_bits_truncate(0o666),
nlinks: 1,
uid: 0,
gid: 0,

View File

@ -6,7 +6,10 @@ use crate::{
driver::tty::tty_device::TTY_DEVICES,
filesystem::{
devfs::{devfs_register, DevFS, DeviceINode},
vfs::{core::generate_inode_id, file::FileMode, FileType, IndexNode, Metadata, PollStatus},
vfs::{
core::generate_inode_id, file::FileMode, syscall::ModeType, FileType, IndexNode,
Metadata, PollStatus,
},
},
include::bindings::bindings::{vfs_file_operations_t, vfs_file_t, vfs_index_node_t},
libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
@ -59,7 +62,7 @@ impl LockedPS2KeyBoardInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::CharDevice, // 文件夹block设备char设备
mode: 0o666,
mode: ModeType::from_bits_truncate(0o666),
nlinks: 1,
uid: 0,
gid: 0,

View File

@ -7,7 +7,10 @@ use alloc::{
use crate::{
filesystem::{
devfs::{devfs_register, DevFS, DeviceINode},
vfs::{file::FileMode, FilePrivateData, FileType, IndexNode, Metadata, ROOT_INODE},
vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata,
ROOT_INODE,
},
},
kerror,
libs::{
@ -271,7 +274,7 @@ impl IndexNode for TtyDevice {
impl TtyDevicePrivateData {
pub fn new(name: &str) -> RwLock<Self> {
let mut metadata = Metadata::new(FileType::CharDevice, 0o755);
let mut metadata = Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755));
metadata.size = TtyCore::STDIN_BUF_SIZE as i64;
return RwLock::new(TtyDevicePrivateData {
name: name.to_string(),

View File

@ -15,7 +15,10 @@ use crate::{
filesystem::{
devfs::{devfs_register, DevFS, DeviceINode},
sysfs::bus::{bus_device_register, bus_driver_register},
vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus},
vfs::{
syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
PollStatus,
},
},
include::bindings::bindings::{io_in8, io_out8},
kinfo,
@ -314,7 +317,7 @@ impl IndexNode for LockedUart {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法则默认调用其create_with_data方法。如果仍未实现则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
return self.create_with_data(name, file_type, mode, 0);
@ -324,7 +327,7 @@ impl IndexNode for LockedUart {
&self,
_name: &str,
_file_type: FileType,
_mode: u32,
_mode: ModeType,
_data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”

View File

@ -5,6 +5,7 @@ pub mod zero_dev;
use super::vfs::{
core::{generate_inode_id, ROOT_INODE},
file::FileMode,
syscall::ModeType,
FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus,
};
use crate::{
@ -55,7 +56,7 @@ impl DevFS {
let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(
// /dev 的权限设置为 读+执行root 可以读写
// root 的 parent 是空指针
DevFSInode::new(FileType::Dir, 0o755 as u32, 0),
DevFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
)));
let devfs: Arc<DevFS> = Arc::new(DevFS { root_inode: root });
@ -109,7 +110,11 @@ impl DevFS {
// 字节设备挂载在 /dev/char
FileType::CharDevice => {
if let Err(_) = dev_root_inode.find("char") {
dev_root_inode.create("char", FileType::Dir, 0o755)?;
dev_root_inode.create(
"char",
FileType::Dir,
ModeType::from_bits_truncate(0o755),
)?;
}
let any_char_inode = dev_root_inode.find("char")?;
@ -128,7 +133,11 @@ impl DevFS {
}
FileType::BlockDevice => {
if let Err(_) = dev_root_inode.find("block") {
dev_root_inode.create("block", FileType::Dir, 0o755)?;
dev_root_inode.create(
"block",
FileType::Dir,
ModeType::from_bits_truncate(0o755),
)?;
}
let any_block_inode = dev_root_inode.find("block")?;
@ -212,14 +221,14 @@ pub struct DevFSInode {
}
impl DevFSInode {
pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
pub fn new(dev_type_: FileType, mode: ModeType, data_: usize) -> Self {
return Self::new_with_parent(Weak::default(), dev_type_, mode, data_);
}
pub fn new_with_parent(
parent: Weak<LockedDevFSInode>,
dev_type_: FileType,
mode_: u32,
mode: ModeType,
data_: usize,
) -> Self {
return DevFSInode {
@ -236,7 +245,7 @@ impl DevFSInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: dev_type_, // 文件夹
mode: mode_,
mode,
nlinks: 1,
uid: 0,
gid: 0,
@ -255,7 +264,13 @@ impl LockedDevFSInode {
return Err(SystemError::EEXIST);
}
match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) {
match self.do_create_with_data(
guard,
name,
FileType::Dir,
ModeType::from_bits_truncate(0o755),
0,
) {
Ok(inode) => inode,
Err(err) => {
return Err(err);
@ -291,17 +306,17 @@ impl LockedDevFSInode {
fn do_create_with_data(
&self,
mut guard: SpinLockGuard<DevFSInode>,
_name: &str,
_file_type: FileType,
_mode: u32,
_data: usize,
name: &str,
file_type: FileType,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
if guard.metadata.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
// 如果有重名的,则返回
if guard.children.contains_key(_name) {
if guard.children.contains_key(name) {
return Err(SystemError::EEXIST);
}
@ -319,12 +334,12 @@ impl LockedDevFSInode {
atime: TimeSpec::default(),
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: _file_type,
mode: _mode,
file_type,
mode,
nlinks: 1,
uid: 0,
gid: 0,
raw_dev: _data,
raw_dev: data,
},
fs: guard.fs.clone(),
})));
@ -333,7 +348,7 @@ impl LockedDevFSInode {
result.0.lock().self_ref = Arc::downgrade(&result);
// 将子inode插入父inode的B树中
guard.children.insert(String::from(_name), result.clone());
guard.children.insert(String::from(name), result.clone());
return Ok(result);
}
}
@ -359,7 +374,7 @@ impl IndexNode for LockedDevFSInode {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 获取当前inode
@ -399,7 +414,7 @@ impl IndexNode for LockedDevFSInode {
return Err(SystemError::ENOTDIR);
}
match ino {
match ino.into() {
0 => {
return Ok(String::from("."));
}
@ -412,14 +427,24 @@ impl IndexNode for LockedDevFSInode {
let mut key: Vec<String> = inode
.children
.keys()
.filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
.filter(|k| {
inode
.children
.get(*k)
.unwrap()
.metadata()
.unwrap()
.inode_id
.into()
== ino
})
.cloned()
.collect();
match key.len() {
0=>{return Err(SystemError::ENOENT);}
1=>{return Ok(key.remove(0));}
_ => panic!("Devfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
_ => panic!("Devfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
}
}
}

View File

@ -1,5 +1,6 @@
use crate::filesystem::vfs::file::FileMode;
use crate::filesystem::vfs::make_rawdev;
use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
};
@ -43,7 +44,7 @@ impl LockedNullInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::CharDevice, // 文件夹block设备char设备
mode: 0o666,
mode: ModeType::from_bits_truncate(0o666),
nlinks: 1,
uid: 0,
gid: 0,

View File

@ -1,5 +1,6 @@
use crate::filesystem::vfs::file::FileMode;
use crate::filesystem::vfs::make_rawdev;
use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
};
@ -43,7 +44,7 @@ impl LockedZeroInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::CharDevice, // 文件夹block设备char设备
mode: 0o666,
mode: ModeType::from_bits_truncate(0o666),
nlinks: 1,
uid: 0,
gid: 0,

View File

@ -13,6 +13,7 @@ use crate::{
filesystem::vfs::{
core::generate_inode_id,
file::{FileMode, FilePrivateData},
syscall::ModeType,
FileSystem, FileType, IndexNode, InodeId, Metadata, PollStatus,
},
kerror,
@ -189,7 +190,7 @@ impl LockedFATInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: file_type,
mode: 0o777,
mode: ModeType::from_bits_truncate(0o777),
nlinks: 1,
uid: 0,
gid: 0,
@ -308,7 +309,7 @@ impl FATFileSystem {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::Dir,
mode: 0o777,
mode: ModeType::from_bits_truncate(0o777),
nlinks: 1,
uid: 0,
gid: 0,
@ -1421,7 +1422,7 @@ impl IndexNode for LockedFATInode {
&self,
name: &str,
file_type: FileType,
_mode: u32,
_mode: ModeType,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 由于FAT32不支持文件权限的功能因此忽略mode参数
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
@ -1627,7 +1628,7 @@ impl IndexNode for LockedFATInode {
if guard.metadata.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
match ino {
match ino.into() {
0 => {
return Ok(String::from("."));
}
@ -1640,14 +1641,24 @@ impl IndexNode for LockedFATInode {
let mut key: Vec<String> = guard
.children
.keys()
.filter(|k| guard.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
.filter(|k| {
guard
.children
.get(*k)
.unwrap()
.metadata()
.unwrap()
.inode_id
.into()
== ino
})
.cloned()
.collect();
match key.len() {
0=>{return Err(SystemError::ENOENT);}
1=>{return Ok(key.remove(0));}
_ => panic!("FatFS get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = guard.metadata.inode_id, to_find=ino)
_ => panic!("FatFS get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = guard.metadata.inode_id, to_find=ino)
}
}
}

View File

@ -0,0 +1,73 @@
use crate::{
filesystem::{sysfs::SysFSKernPrivateData, vfs::PollStatus},
libs::spinlock::SpinLockGuard,
syscall::SystemError,
};
use alloc::sync::Arc;
use core::fmt::Debug;
use super::KernFSInode;
/// KernFS文件的回调接口
///
/// 当用户态程序打开、读取、写入、关闭文件时kernfs会调用相应的回调函数。
pub trait KernFSCallback: Send + Sync + Debug {
fn open(&self, data: KernCallbackData) -> Result<(), SystemError>;
fn read(
&self,
data: KernCallbackData,
buf: &mut [u8],
offset: usize,
) -> Result<usize, SystemError>;
fn write(
&self,
data: KernCallbackData,
buf: &[u8],
offset: usize,
) -> Result<usize, SystemError>;
fn poll(&self, data: KernCallbackData) -> Result<PollStatus, SystemError>;
}
/// KernFS文件的回调数据
#[derive(Debug)]
pub struct KernCallbackData<'a> {
kern_inode: Arc<KernFSInode>,
private_data: SpinLockGuard<'a, Option<KernInodePrivateData>>,
}
#[allow(dead_code)]
impl<'a> KernCallbackData<'a> {
pub fn new(
kern_inode: Arc<KernFSInode>,
private_data: SpinLockGuard<'a, Option<KernInodePrivateData>>,
) -> Self {
Self {
kern_inode,
private_data,
}
}
#[inline(always)]
pub fn kern_inode(&self) -> &Arc<KernFSInode> {
return &self.kern_inode;
}
#[inline(always)]
pub fn private_data(&self) -> &Option<KernInodePrivateData> {
return &self.private_data;
}
#[inline(always)]
pub fn private_data_mut(&mut self) -> &mut Option<KernInodePrivateData> {
return &mut self.private_data;
}
}
#[allow(dead_code)]
#[derive(Debug)]
pub enum KernInodePrivateData {
SysFS(SysFSKernPrivateData),
}

View File

@ -0,0 +1,486 @@
use core::{fmt::Debug, intrinsics::unlikely};
use alloc::{
string::String,
sync::{Arc, Weak},
vec::Vec,
};
use hashbrown::HashMap;
use crate::{
libs::{rwlock::RwLock, spinlock::SpinLock},
syscall::SystemError,
time::TimeSpec,
};
use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
use super::vfs::{
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
FileType, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
};
pub mod callback;
#[derive(Debug)]
pub struct KernFS {
root_inode: Arc<KernFSInode>,
}
impl FileSystem for KernFS {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn info(&self) -> FsInfo {
return FsInfo {
blk_dev_id: 0,
max_name_len: KernFS::MAX_NAMELEN,
};
}
fn root_inode(&self) -> Arc<dyn IndexNode> {
return self.root_inode.clone();
}
}
impl KernFS {
pub const MAX_NAMELEN: usize = 4096;
#[allow(dead_code)]
pub fn new() -> Arc<Self> {
let root_inode = Self::create_root_inode();
let fs = Arc::new(Self {
root_inode: root_inode.clone(),
});
{
let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode;
unsafe {
(*ptr).self_ref = Arc::downgrade(&root_inode);
}
}
root_inode.inner.lock().parent = Arc::downgrade(&root_inode);
*root_inode.fs.write() = Arc::downgrade(&fs);
return fs;
}
fn create_root_inode() -> Arc<KernFSInode> {
let metadata = Metadata {
size: 0,
mode: ModeType::from_bits_truncate(0o755),
uid: 0,
gid: 0,
blk_size: 0,
blocks: 0,
atime: TimeSpec::new(0, 0),
mtime: TimeSpec::new(0, 0),
ctime: TimeSpec::new(0, 0),
dev_id: 0,
inode_id: generate_inode_id(),
file_type: FileType::Dir,
nlinks: 1,
raw_dev: 0,
};
let root_inode = Arc::new(KernFSInode {
inner: SpinLock::new(InnerKernFSInode {
parent: Weak::new(),
metadata,
}),
self_ref: Weak::new(),
fs: RwLock::new(Weak::new()),
private_data: SpinLock::new(None),
callback: None,
children: SpinLock::new(HashMap::new()),
inode_type: KernInodeType::Dir,
});
return root_inode;
}
}
#[derive(Debug)]
pub struct KernFSInode {
inner: SpinLock<InnerKernFSInode>,
/// 指向当前Inode所属的文件系统的弱引用
fs: RwLock<Weak<KernFS>>,
/// 指向自身的弱引用
self_ref: Weak<KernFSInode>,
/// 私有数据
private_data: SpinLock<Option<KernInodePrivateData>>,
/// 回调函数
callback: Option<&'static dyn KernFSCallback>,
/// 子Inode
children: SpinLock<HashMap<String, Arc<KernFSInode>>>,
/// Inode类型
inode_type: KernInodeType,
}
#[derive(Debug)]
pub struct InnerKernFSInode {
parent: Weak<KernFSInode>,
/// 当前inode的元数据
metadata: Metadata,
}
impl IndexNode for KernFSInode {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
if let Some(callback) = self.callback {
let callback_data =
KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
return callback.open(callback_data);
}
return Ok(());
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
return Ok(());
}
fn metadata(&self) -> Result<Metadata, SystemError> {
return Ok(self.inner.lock().metadata.clone());
}
fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn resize(&self, _len: usize) -> Result<(), SystemError> {
return Ok(());
}
fn create_with_data(
&self,
_name: &str,
_file_type: FileType,
_mode: ModeType,
_data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 应当通过kernfs的其它方法来创建文件而不能从用户态直接调用此方法。
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
// 应当通过kernfs的其它方法来操作文件而不能从用户态直接调用此方法。
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn unlink(&self, _name: &str) -> Result<(), SystemError> {
// 应当通过kernfs的其它方法来操作文件而不能从用户态直接调用此方法。
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn rmdir(&self, _name: &str) -> Result<(), SystemError> {
// 应当通过kernfs的其它方法来操作文件而不能从用户态直接调用此方法。
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn move_(
&self,
_old_name: &str,
_target: &Arc<dyn IndexNode>,
_new_name: &str,
) -> Result<(), SystemError> {
// 应当通过kernfs的其它方法来操作文件而不能从用户态直接调用此方法。
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
if unlikely(name.len() > KernFS::MAX_NAMELEN) {
return Err(SystemError::ENAMETOOLONG);
}
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);
}
fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
if self.inode_type != KernInodeType::Dir {
return Err(SystemError::ENOTDIR);
}
let children = self.children.lock();
let r = children
.iter()
.find(|(_, v)| v.metadata().unwrap().inode_id == ino)
.map(|(k, _)| k.clone());
return r.ok_or(SystemError::ENOENT);
}
fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> {
// 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。
let name = self.get_entry_name(ino)?;
let entry = self.find(&name)?;
return Ok((name, entry.metadata()?));
}
fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn truncate(&self, _len: usize) -> Result<(), SystemError> {
// 应当通过kernfs的其它方法来操作文件而不能从用户态直接调用此方法。
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn sync(&self) -> Result<(), SystemError> {
return Ok(());
}
fn fs(&self) -> Arc<dyn FileSystem> {
return self.fs.read().upgrade().unwrap();
}
fn list(&self) -> Result<Vec<String>, SystemError> {
let mut list = Vec::new();
for (name, _) in self.children.lock().iter() {
list.push(name.clone());
}
return Ok(list);
}
fn poll(&self) -> Result<PollStatus, SystemError> {
// todo: 根据inode的具体attribute返回PollStatus
return Ok(PollStatus::READ | PollStatus::WRITE);
}
fn read_at(
&self,
offset: usize,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
if self.inode_type != KernInodeType::File {
return Err(SystemError::EISDIR);
}
if self.callback.is_none() {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
let callback_data =
KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
return self
.callback
.as_ref()
.unwrap()
.read(callback_data, &mut buf[..len], offset);
}
fn write_at(
&self,
offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
if self.inode_type != KernInodeType::File {
return Err(SystemError::EISDIR);
}
if self.callback.is_none() {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
let callback_data =
KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
return self
.callback
.as_ref()
.unwrap()
.write(callback_data, &buf[..len], offset);
}
}
impl KernFSInode {
/// 在当前inode下增加子目录
///
/// ## 参数
///
/// - `name`:子目录名称
/// - `mode`:子目录权限
/// - `private_data`:子目录私有数据
/// - `callback`:子目录回调函数
///
/// ## 返回值
///
/// - 成功子目录inode
/// - 失败:错误码
#[allow(dead_code)]
#[inline]
pub fn add_dir(
&self,
name: String,
mode: ModeType,
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Result<Arc<KernFSInode>, SystemError> {
if unlikely(self.inode_type != KernInodeType::Dir) {
return Err(SystemError::ENOTDIR);
}
return self.inner_create(name, KernInodeType::Dir, mode, private_data, callback);
}
/// 在当前inode下增加文件
///
/// ## 参数
///
/// - `name`:文件名称
/// - `mode`:文件权限
/// - `private_data`:文件私有数据
/// - `callback`:文件回调函数
///
/// ## 返回值
///
/// - 成功文件inode
/// - 失败:错误码
#[allow(dead_code)]
#[inline]
pub fn add_file(
&self,
name: String,
mode: ModeType,
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Result<Arc<KernFSInode>, SystemError> {
if unlikely(self.inode_type != KernInodeType::Dir) {
return Err(SystemError::ENOTDIR);
}
return self.inner_create(name, KernInodeType::File, mode, private_data, callback);
}
fn inner_create(
&self,
name: String,
file_type: KernInodeType,
mode: ModeType,
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Result<Arc<KernFSInode>, SystemError> {
let metadata = Metadata {
size: 0,
mode,
uid: 0,
gid: 0,
blk_size: 0,
blocks: 0,
atime: TimeSpec::new(0, 0),
mtime: TimeSpec::new(0, 0),
ctime: TimeSpec::new(0, 0),
dev_id: 0,
inode_id: generate_inode_id(),
file_type: file_type.into(),
nlinks: 1,
raw_dev: 0,
};
let new_inode: Arc<KernFSInode> = Self::new(
self.self_ref.upgrade().unwrap(),
metadata,
KernInodeType::Dir,
private_data,
callback,
);
self.children.lock().insert(name, new_inode.clone());
return Ok(new_inode);
}
/// 在当前inode下删除子目录或者文件
///
/// 如果要删除的是子目录且子目录不为空则返回ENOTEMPTY
///
/// ## 参数
///
/// - `name`:子目录或者文件名称
///
/// ## 返回值
///
/// - 成功:()
/// - 失败:错误码
#[allow(dead_code)]
pub fn remove(&self, name: &str) -> Result<(), SystemError> {
if unlikely(self.inode_type != KernInodeType::Dir) {
return Err(SystemError::ENOTDIR);
}
let mut children = self.children.lock();
let inode = children.get(name).ok_or(SystemError::ENOENT)?;
if inode.children.lock().is_empty() {
children.remove(name);
return Ok(());
} else {
return Err(SystemError::ENOTEMPTY);
}
}
pub(self) fn new(
parent: Arc<KernFSInode>,
metadata: Metadata,
inode_type: KernInodeType,
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Arc<KernFSInode> {
let inode = Arc::new(KernFSInode {
inner: SpinLock::new(InnerKernFSInode {
parent: Arc::downgrade(&parent),
metadata,
}),
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);
}
}
*inode.fs.write() = Arc::downgrade(
parent
.fs()
.as_any_ref()
.downcast_ref()
.expect("KernFSInode::new: parent is not a KernFS instance"),
);
return inode;
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(self) enum KernInodeType {
Dir,
File,
}
impl Into<FileType> for KernInodeType {
fn into(self) -> FileType {
match self {
KernInodeType::Dir => FileType::Dir,
KernInodeType::File => FileType::File,
}
}
}

View File

@ -1,5 +1,6 @@
pub mod devfs;
pub mod fat;
pub mod kernfs;
pub mod mbr;
pub mod procfs;
pub mod ramfs;

View File

@ -26,6 +26,7 @@ use crate::{
use super::vfs::{
file::{FileMode, FilePrivateData},
syscall::ModeType,
FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
};
@ -262,7 +263,7 @@ impl ProcFS {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::Dir,
mode: 0o777,
mode: ModeType::from_bits_truncate(0o777),
nlinks: 1,
uid: 0,
gid: 0,
@ -294,10 +295,18 @@ impl ProcFS {
// 获取当前inode
let proc: Arc<dyn IndexNode> = self.root_inode();
// 创建对应进程文件夹
let _pf: Arc<dyn IndexNode> = proc.create(&pid.to_string(), FileType::Dir, 0o777)?;
let _pf: Arc<dyn IndexNode> = proc.create(
&pid.to_string(),
FileType::Dir,
ModeType::from_bits_truncate(0o777),
)?;
// 创建相关文件
// status文件
let binding: Arc<dyn IndexNode> = _pf.create("status", FileType::File, 0o777)?;
let binding: Arc<dyn IndexNode> = _pf.create(
"status",
FileType::File,
ModeType::from_bits_truncate(0o777),
)?;
let _sf: &LockedProcFSInode = binding
.as_any_ref()
.downcast_ref::<LockedProcFSInode>()
@ -482,7 +491,7 @@ impl IndexNode for LockedProcFSInode {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 获取当前inode
@ -623,7 +632,7 @@ impl IndexNode for LockedProcFSInode {
return Err(SystemError::ENOTDIR);
}
match ino {
match ino.into() {
0 => {
return Ok(String::from("."));
}
@ -636,14 +645,25 @@ impl IndexNode for LockedProcFSInode {
let mut key: Vec<String> = inode
.children
.keys()
.filter(|k| inode.children.get(*k).unwrap().0.lock().metadata.inode_id == ino)
.filter(|k| {
inode
.children
.get(*k)
.unwrap()
.0
.lock()
.metadata
.inode_id
.into()
== ino
})
.cloned()
.collect();
match key.len() {
0=>{return Err(SystemError::ENOENT);}
1=>{return Ok(key.remove(0));}
_ => panic!("Procfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
_ => panic!("Procfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
}
}
}

View File

@ -15,7 +15,8 @@ use crate::{
};
use super::vfs::{
file::FilePrivateData, FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
file::FilePrivateData, syscall::ModeType, FileSystem, FsInfo, IndexNode, InodeId, Metadata,
PollStatus,
};
/// RamFS的inode名称的最大长度
@ -90,7 +91,7 @@ impl RamFS {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::Dir,
mode: 0o777,
mode: ModeType::from_bits_truncate(0o777),
nlinks: 1,
uid: 0,
gid: 0,
@ -258,7 +259,7 @@ impl IndexNode for LockedRamFSInode {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 获取当前inode
@ -425,7 +426,7 @@ impl IndexNode for LockedRamFSInode {
return Err(SystemError::ENOTDIR);
}
match ino {
match ino.into() {
0 => {
return Ok(String::from("."));
}
@ -438,14 +439,25 @@ impl IndexNode for LockedRamFSInode {
let mut key: Vec<String> = inode
.children
.keys()
.filter(|k| inode.children.get(*k).unwrap().0.lock().metadata.inode_id == ino)
.filter(|k| {
inode
.children
.get(*k)
.unwrap()
.0
.lock()
.metadata
.inode_id
.into()
== ino
})
.cloned()
.collect();
match key.len() {
0=>{return Err(SystemError::ENOENT);}
1=>{return Ok(key.remove(0));}
_ => panic!("Ramfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
_ => panic!("Ramfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
}
}
}

View File

@ -0,0 +1,32 @@
#![allow(dead_code)]
use alloc::sync::Arc;
use crate::driver::base::device::KObject;
use super::AttributeGroup;
#[derive(Debug)]
pub struct SysKernDirPriv {
kobj: Arc<dyn KObject>,
attribute_group: Option<&'static dyn AttributeGroup>,
}
impl SysKernDirPriv {
pub fn new(
kobj: Arc<dyn KObject>,
attribute_group: Option<&'static dyn AttributeGroup>,
) -> Self {
Self {
kobj,
attribute_group,
}
}
pub fn kobj(&self) -> Arc<dyn KObject> {
self.kobj.clone()
}
pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> {
self.attribute_group
}
}

View File

@ -0,0 +1,21 @@
#![allow(dead_code)]
use super::Attribute;
#[derive(Debug)]
pub struct SysKernFilePriv {
attribute: Option<&'static dyn Attribute>,
// todo: 增加bin attribute,它和attribute二选一只能有一个为Some
}
impl SysKernFilePriv {
pub fn new(attribute: Option<&'static dyn Attribute>) -> Self {
if attribute.is_none() {
panic!("attribute can't be None");
}
return Self { attribute };
}
pub fn attribute(&self) -> Option<&'static dyn Attribute> {
self.attribute
}
}

View File

@ -1,9 +1,13 @@
use core::fmt::Debug;
use self::{dir::SysKernDirPriv, file::SysKernFilePriv};
use super::vfs::{
core::generate_inode_id, file::FileMode, FileSystem, FileType, FsInfo, IndexNode, Metadata,
PollStatus,
core::generate_inode_id, file::FileMode, syscall::ModeType, FileSystem, FileType, FsInfo,
IndexNode, Metadata, PollStatus,
};
use crate::{
driver::base::platform::platform_bus_init,
driver::base::{device::KObject, platform::platform_bus_init},
filesystem::{sysfs::bus::sys_bus_init, vfs::ROOT_INODE},
kdebug, kinfo,
libs::{
@ -23,6 +27,8 @@ use alloc::{
pub mod bus;
pub mod class;
pub mod devices;
mod dir;
mod file;
pub mod fs;
const SYSFS_MAX_NAMELEN: usize = 64;
@ -98,7 +104,7 @@ impl SysFS {
let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
// /sys 的权限设置为 读+执行root 可以读写
// root 的 parent 是空指针
SysFSInode::new(FileType::Dir, 0o755 as u32, 0),
SysFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
)));
let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root });
@ -220,7 +226,7 @@ impl IndexNode for LockedSysFSInode {
return Err(SystemError::ENOTDIR);
}
match ino {
match ino.into() {
0 => {
return Ok(String::from("."));
}
@ -233,14 +239,24 @@ impl IndexNode for LockedSysFSInode {
let mut key: Vec<String> = inode
.children
.keys()
.filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
.filter(|k| {
inode
.children
.get(*k)
.unwrap()
.metadata()
.unwrap()
.inode_id
.into()
== ino
})
.cloned()
.collect();
match key.len() {
0=>{return Err(SystemError::ENOENT);}
1=>{return Ok(key.remove(0));}
_ => panic!("Sysfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
_ => panic!("Sysfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
}
}
}
@ -294,17 +310,17 @@ impl LockedSysFSInode {
fn do_create_with_data(
&self,
mut guard: SpinLockGuard<SysFSInode>,
_name: &str,
_file_type: FileType,
_mode: u32,
_data: usize,
name: &str,
file_type: FileType,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
if guard.metadata.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
// 如果有重名的,则返回
if guard.children.contains_key(_name) {
if guard.children.contains_key(name) {
return Err(SystemError::EEXIST);
}
@ -322,12 +338,12 @@ impl LockedSysFSInode {
atime: TimeSpec::default(),
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: _file_type,
mode: _mode,
file_type,
mode,
nlinks: 1,
uid: 0,
gid: 0,
raw_dev: _data,
raw_dev: data,
},
fs: guard.fs.clone(),
})));
@ -336,7 +352,7 @@ impl LockedSysFSInode {
result.0.lock().self_ref = Arc::downgrade(&result);
// 将子inode插入父inode的B树中
guard.children.insert(String::from(_name), result.clone());
guard.children.insert(String::from(name), result.clone());
return Ok(result);
}
@ -352,7 +368,13 @@ impl LockedSysFSInode {
return Err(SystemError::EEXIST);
}
match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) {
match self.do_create_with_data(
guard,
name,
FileType::Dir,
ModeType::from_bits_truncate(0o755),
0,
) {
Ok(inode) => return Ok(inode),
Err(err) => {
return Err(err);
@ -421,14 +443,14 @@ pub struct SysFSInode {
}
impl SysFSInode {
pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
pub fn new(file_type: FileType, mode: ModeType, data_: usize) -> Self {
return Self::new_with_parent(Weak::default(), file_type, mode, data_);
}
pub fn new_with_parent(
parent: Weak<LockedSysFSInode>,
dev_type_: FileType,
mode_: u32,
file_type: FileType,
mode: ModeType,
data_: usize,
) -> Self {
return SysFSInode {
@ -444,8 +466,8 @@ impl SysFSInode {
atime: TimeSpec::default(),
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: dev_type_, // 文件夹
mode: mode_,
file_type,
mode,
nlinks: 1,
uid: 0,
gid: 0,
@ -485,3 +507,24 @@ pub fn sysfs_init() -> Result<(), SystemError> {
return result.unwrap();
}
/// SysFS在KernFS的inode中的私有信息
#[allow(dead_code)]
#[derive(Debug)]
pub enum SysFSKernPrivateData {
Dir(SysKernDirPriv),
File(SysKernFilePriv),
}
/// sysfs文件目录的属性组
pub trait AttributeGroup: Debug + Send + Sync {
fn name(&self) -> &str;
fn attrs(&self) -> &[&'static dyn Attribute];
fn is_visible(&self, kobj: Arc<dyn KObject>, attr: &dyn Attribute) -> bool;
}
/// sysfs文件的属性
pub trait Attribute: Debug + Send + Sync {
fn name(&self) -> &str;
fn mode(&self) -> ModeType;
}

View File

@ -1,7 +1,4 @@
use core::{
hint::spin_loop,
sync::atomic::{AtomicUsize, Ordering},
};
use core::{hint::spin_loop, sync::atomic::Ordering};
use alloc::{format, string::ToString, sync::Arc};
@ -16,7 +13,7 @@ use crate::{
procfs::procfs_init,
ramfs::RamFS,
sysfs::sysfs_init,
vfs::{mount::MountFS, FileSystem, FileType},
vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType},
},
include::bindings::bindings::PAGE_4K_SIZE,
kdebug, kerror, kinfo,
@ -31,8 +28,8 @@ use super::{file::FileMode, utils::rsplit_path, IndexNode, InodeId};
/// [0]: 对应'.'目录项
/// [1]: 对应'..'目录项
pub fn generate_inode_id() -> InodeId {
static INO: AtomicUsize = AtomicUsize::new(1);
return INO.fetch_add(1, Ordering::SeqCst);
static INO: AtomicInodeId = AtomicInodeId::new(InodeId::new(1));
return INO.fetch_add(InodeId::new(1), Ordering::SeqCst);
}
static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None;
@ -59,13 +56,13 @@ pub extern "C" fn vfs_init() -> i32 {
// 创建文件夹
root_inode
.create("proc", FileType::Dir, 0o777)
.create("proc", FileType::Dir, ModeType::from_bits_truncate(0o755))
.expect("Failed to create /proc");
root_inode
.create("dev", FileType::Dir, 0o777)
.create("dev", FileType::Dir, ModeType::from_bits_truncate(0o755))
.expect("Failed to create /dev");
root_inode
.create("sys", FileType::Dir, 0o777)
.create("sys", FileType::Dir, ModeType::from_bits_truncate(0o755))
.expect("Failed to create /sys");
kdebug!("dir in root:{:?}", root_inode.list());
@ -94,7 +91,11 @@ fn do_migrate(
let r = new_root_inode.find(mountpoint_name);
let mountpoint = if r.is_err() {
new_root_inode
.create(mountpoint_name, FileType::Dir, 0o777)
.create(
mountpoint_name,
FileType::Dir,
ModeType::from_bits_truncate(0o755),
)
.expect(format!("Failed to create '/{mountpoint_name}' in migrating").as_str())
} else {
r.unwrap()
@ -191,8 +192,11 @@ pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> {
let parent_inode: Arc<dyn IndexNode> =
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
// 创建文件夹
let _create_inode: Arc<dyn IndexNode> =
parent_inode.create(filename, FileType::Dir, 0o777)?;
let _create_inode: Arc<dyn IndexNode> = parent_inode.create(
filename,
FileType::Dir,
ModeType::from_bits_truncate(0o755),
)?;
} else {
// 不需要创建文件,因此返回错误码
return Err(errno);

View File

@ -14,7 +14,7 @@ use crate::{
syscall::SystemError,
};
use super::{Dirent, FileType, IndexNode, Metadata};
use super::{Dirent, FileType, IndexNode, InodeId, Metadata};
/// 文件私有信息的枚举类型
#[derive(Debug, Clone)]
@ -185,7 +185,7 @@ impl File {
}
/// @brief 根据inode号获取子目录项的名字
pub fn get_entry_name(&self, ino: usize) -> Result<String, SystemError> {
pub fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
return self.inode.get_entry_name(ino);
}
@ -276,7 +276,7 @@ impl File {
let name_bytes: &[u8] = name.as_bytes();
self.offset += 1;
dirent.d_ino = sub_inode.metadata().unwrap().inode_id as u64;
dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64;
dirent.d_off = 0;
dirent.d_reclen = 0;
dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;

View File

@ -7,20 +7,20 @@ pub mod mount;
pub mod syscall;
mod utils;
use ::core::{any::Any, fmt::Debug};
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
use alloc::{string::String, sync::Arc, vec::Vec};
use crate::{libs::casting::DowncastArc, syscall::SystemError, time::TimeSpec};
use self::{core::generate_inode_id, file::FileMode};
use self::{core::generate_inode_id, file::FileMode, syscall::ModeType};
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
/// vfs容许的最大的路径名称长度
pub const MAX_PATHLEN: usize = 1024;
/// 定义inode号的类型为usize
pub type InodeId = usize;
// 定义inode号
int_like!(InodeId, AtomicInodeId, usize, AtomicUsize);
/// 文件的类型
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -185,7 +185,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法则默认调用其create_with_data方法。如果仍未实现则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
return self.create_with_data(name, file_type, mode, 0);
@ -204,7 +204,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
&self,
_name: &str,
_file_type: FileType,
_mode: u32,
_mode: ModeType,
_data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
@ -477,7 +477,7 @@ pub struct Metadata {
pub file_type: FileType,
/// 权限
pub mode: u32,
pub mode: ModeType,
/// 硬链接的数量
pub nlinks: usize,
@ -496,7 +496,7 @@ impl Default for Metadata {
fn default() -> Self {
return Self {
dev_id: 0,
inode_id: 0,
inode_id: InodeId::new(0),
size: 0,
blk_size: 0,
blocks: 0,
@ -504,7 +504,7 @@ impl Default for Metadata {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::File,
mode: 0,
mode: ModeType::empty(),
nlinks: 1,
uid: 0,
gid: 0,
@ -551,7 +551,7 @@ pub struct Dirent {
}
impl Metadata {
pub fn new(file_type: FileType, mode: u32) -> Self {
pub fn new(file_type: FileType, mode: ModeType) -> Self {
Metadata {
dev_id: 0,
inode_id: generate_inode_id(),

View File

@ -10,7 +10,9 @@ use alloc::{
use crate::{libs::spinlock::SpinLock, syscall::SystemError};
use super::{file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, InodeId};
use super::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
};
/// @brief 挂载文件系统
/// 挂载文件系统的时候套了MountFS这一层以实现文件系统的递归挂载
@ -141,7 +143,7 @@ impl IndexNode for MountFSInode {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
return Ok(MountFSInode {
@ -213,7 +215,7 @@ impl IndexNode for MountFSInode {
&self,
name: &str,
file_type: FileType,
mode: u32,
mode: ModeType,
) -> Result<Arc<dyn IndexNode>, SystemError> {
return Ok(MountFSInode {
inner_inode: self.inner_inode.create(name, file_type, mode)?,

View File

@ -31,6 +31,7 @@ pub const SEEK_MAX: u32 = 3;
bitflags! {
/// 文件类型和权限
#[repr(C)]
pub struct ModeType: u32 {
/// 掩码
const S_IFMT = 0o0_170_000;
@ -154,8 +155,11 @@ impl Syscall {
let parent_inode: Arc<dyn IndexNode> =
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
// 创建文件
let inode: Arc<dyn IndexNode> =
parent_inode.create(filename, FileType::File, 0o777)?;
let inode: Arc<dyn IndexNode> = parent_inode.create(
filename,
FileType::File,
ModeType::from_bits_truncate(0o755),
)?;
inode
} else {
// 不需要创建文件,因此返回错误码
@ -649,7 +653,7 @@ impl Syscall {
let metadata = file.lock().metadata()?;
kstat.size = metadata.size as i64;
kstat.dev_id = metadata.dev_id as u64;
kstat.inode = metadata.inode_id as u64;
kstat.inode = metadata.inode_id.into() as u64;
kstat.blcok_size = metadata.blk_size as i64;
kstat.blocks = metadata.blocks as u64;
@ -664,7 +668,7 @@ impl Syscall {
kstat.uid = metadata.uid as i32;
kstat.gid = metadata.gid as i32;
kstat.rdev = metadata.raw_dev as i64;
kstat.mode.bits = metadata.mode;
kstat.mode = metadata.mode;
match file.lock().file_type() {
FileType::File => kstat.mode.insert(ModeType::S_IFMT),
FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),

View File

@ -2,8 +2,8 @@ use crate::{
arch::{sched::sched, CurrentIrqArch},
exception::InterruptArch,
filesystem::vfs::{
core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode,
Metadata, PollStatus,
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
FileType, IndexNode, Metadata, PollStatus,
},
libs::{spinlock::SpinLock, wait_queue::WaitQueue},
process::ProcessState,
@ -56,7 +56,7 @@ impl LockedPipeInode {
mtime: TimeSpec::default(),
ctime: TimeSpec::default(),
file_type: FileType::Pipe,
mode: 0o666,
mode: ModeType::from_bits_truncate(0o666),
nlinks: 1,
uid: 0,
gid: 0,

View File

@ -10,7 +10,7 @@ use smoltcp::{
use crate::{
arch::rand::rand,
driver::net::NetDriver,
filesystem::vfs::{FileType, IndexNode, Metadata, PollStatus},
filesystem::vfs::{syscall::ModeType, FileType, IndexNode, Metadata, PollStatus},
kerror, kwarn,
libs::{
spinlock::{SpinLock, SpinLockGuard},
@ -1215,7 +1215,7 @@ impl IndexNode for SocketInode {
fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
let meta = Metadata {
mode: 0o777,
mode: ModeType::from_bits_truncate(0o755),
file_type: FileType::Socket,
..Default::default()
};