mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
parent
ae5ede03be
commit
6b4e7a2972
@ -12,4 +12,5 @@ todo: 由于文件系统模块重构,文档暂时不可用,预计在2023年4
|
|||||||
overview
|
overview
|
||||||
vfs/index
|
vfs/index
|
||||||
sysfs
|
sysfs
|
||||||
|
kernfs
|
||||||
|
|
||||||
|
22
docs/kernel/filesystem/kernfs.md
Normal file
22
docs/kernel/filesystem/kernfs.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# KernFS
|
||||||
|
|
||||||
|
:::{note}
|
||||||
|
|
||||||
|
Maintainer:
|
||||||
|
- 龙进 <longjin@dragonos.org>
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 1. 简介
|
||||||
|
  KernFS是一个伪文件系统,它充当其它内核文件系统的容器,面向用户提供文件接口。其核心功能就是,当kernfs的文件被读/写或者触发回调点的时候,将会对预设的回调函数进行调用,触发其它内核文件系统的操作。
|
||||||
|
|
||||||
|
  这种设计使得SysFS和文件系统的基本操作解耦,KernFS作为SysFS的承载物,使得SysFS能更专注于KObject的管理,让代码更加优雅。
|
||||||
|
|
||||||
|
  在未来,DragonOS的内核子系统,或者其它的内核文件系统,可以使用KernFS作为文件系统操作的承载物,让系统管理的逻辑与具体的文件系统操作解除耦合。
|
||||||
|
|
||||||
|
## 2. 使用方法
|
||||||
|
|
||||||
|
  以SysFS为例,新创建一个KernFS实例,作为SysFS的文件系统接口,然后挂载到`/sys`目录下。接着sysfs实现上层逻辑,管理KObject,每个上层的Kobject里面都需要包含KernFSInode。并且通过设置KernFSInode的PrivateData,使得KernFS能够根据Inode获取到其指向的KObject或者sysfs的attribute。并且在创建KernFSInode的时候,为具体的Inode传入不同的callback,以此实现“不同的Inode在读写时能够触发不同的回调行为”。
|
||||||
|
|
||||||
|
  当发生回调时,KernFS会把回调信息、私有信息传入到回调函数中,让回调函数能够根据传入的信息,获取到对应的KObject或者sysfs的attribute,从而实现sysfs提供的高层功能。
|
||||||
|
|
||||||
|
  从上述描述我们能够看出:KernFS就是通过存储上层文件系统的回调函数、回调信息,来实现“把具体文件操作与高层管理逻辑进行解耦”的目的。
|
@ -1,6 +1,7 @@
|
|||||||
use crate::driver::base::block::block_device::BlockDevice;
|
use crate::driver::base::block::block_device::BlockDevice;
|
||||||
use crate::filesystem::devfs::{DevFS, DeviceINode};
|
use crate::filesystem::devfs::{DevFS, DeviceINode};
|
||||||
use crate::filesystem::vfs::file::FileMode;
|
use crate::filesystem::vfs::file::FileMode;
|
||||||
|
use crate::filesystem::vfs::syscall::ModeType;
|
||||||
use crate::filesystem::vfs::{
|
use crate::filesystem::vfs::{
|
||||||
core::generate_inode_id, make_rawdev, FilePrivateData, FileSystem, FileType, IndexNode,
|
core::generate_inode_id, make_rawdev, FilePrivateData, FileSystem, FileType, IndexNode,
|
||||||
Metadata, PollStatus,
|
Metadata, PollStatus,
|
||||||
@ -49,7 +50,7 @@ impl LockedAhciInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::BlockDevice, // 文件夹,block设备,char设备
|
file_type: FileType::BlockDevice, // 文件夹,block设备,char设备
|
||||||
mode: 0o666,
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
|
@ -6,7 +6,10 @@ use crate::{
|
|||||||
driver::tty::tty_device::TTY_DEVICES,
|
driver::tty::tty_device::TTY_DEVICES,
|
||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
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},
|
include::bindings::bindings::{vfs_file_operations_t, vfs_file_t, vfs_index_node_t},
|
||||||
libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
|
libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
|
||||||
@ -59,7 +62,7 @@ impl LockedPS2KeyBoardInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: 0o666,
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
|
@ -7,7 +7,10 @@ use alloc::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
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,
|
kerror,
|
||||||
libs::{
|
libs::{
|
||||||
@ -271,7 +274,7 @@ impl IndexNode for TtyDevice {
|
|||||||
|
|
||||||
impl TtyDevicePrivateData {
|
impl TtyDevicePrivateData {
|
||||||
pub fn new(name: &str) -> RwLock<Self> {
|
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;
|
metadata.size = TtyCore::STDIN_BUF_SIZE as i64;
|
||||||
return RwLock::new(TtyDevicePrivateData {
|
return RwLock::new(TtyDevicePrivateData {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
@ -15,7 +15,10 @@ use crate::{
|
|||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
devfs::{devfs_register, DevFS, DeviceINode},
|
||||||
sysfs::bus::{bus_device_register, bus_driver_register},
|
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},
|
include::bindings::bindings::{io_in8, io_out8},
|
||||||
kinfo,
|
kinfo,
|
||||||
@ -314,7 +317,7 @@ impl IndexNode for LockedUart {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
|
// 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
|
||||||
return self.create_with_data(name, file_type, mode, 0);
|
return self.create_with_data(name, file_type, mode, 0);
|
||||||
@ -324,7 +327,7 @@ impl IndexNode for LockedUart {
|
|||||||
&self,
|
&self,
|
||||||
_name: &str,
|
_name: &str,
|
||||||
_file_type: FileType,
|
_file_type: FileType,
|
||||||
_mode: u32,
|
_mode: ModeType,
|
||||||
_data: usize,
|
_data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 若文件系统没有实现此方法,则返回“不支持”
|
// 若文件系统没有实现此方法,则返回“不支持”
|
||||||
|
@ -5,6 +5,7 @@ pub mod zero_dev;
|
|||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
core::{generate_inode_id, ROOT_INODE},
|
core::{generate_inode_id, ROOT_INODE},
|
||||||
file::FileMode,
|
file::FileMode,
|
||||||
|
syscall::ModeType,
|
||||||
FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus,
|
FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -55,7 +56,7 @@ impl DevFS {
|
|||||||
let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(
|
let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(
|
||||||
// /dev 的权限设置为 读+执行,root 可以读写
|
// /dev 的权限设置为 读+执行,root 可以读写
|
||||||
// root 的 parent 是空指针
|
// 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 });
|
let devfs: Arc<DevFS> = Arc::new(DevFS { root_inode: root });
|
||||||
@ -109,7 +110,11 @@ impl DevFS {
|
|||||||
// 字节设备挂载在 /dev/char
|
// 字节设备挂载在 /dev/char
|
||||||
FileType::CharDevice => {
|
FileType::CharDevice => {
|
||||||
if let Err(_) = dev_root_inode.find("char") {
|
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")?;
|
let any_char_inode = dev_root_inode.find("char")?;
|
||||||
@ -128,7 +133,11 @@ impl DevFS {
|
|||||||
}
|
}
|
||||||
FileType::BlockDevice => {
|
FileType::BlockDevice => {
|
||||||
if let Err(_) = dev_root_inode.find("block") {
|
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")?;
|
let any_block_inode = dev_root_inode.find("block")?;
|
||||||
@ -212,14 +221,14 @@ pub struct DevFSInode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DevFSInode {
|
impl DevFSInode {
|
||||||
pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
|
pub fn new(dev_type_: FileType, mode: ModeType, data_: usize) -> Self {
|
||||||
return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
|
return Self::new_with_parent(Weak::default(), dev_type_, mode, data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_parent(
|
pub fn new_with_parent(
|
||||||
parent: Weak<LockedDevFSInode>,
|
parent: Weak<LockedDevFSInode>,
|
||||||
dev_type_: FileType,
|
dev_type_: FileType,
|
||||||
mode_: u32,
|
mode: ModeType,
|
||||||
data_: usize,
|
data_: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
return DevFSInode {
|
return DevFSInode {
|
||||||
@ -236,7 +245,7 @@ impl DevFSInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: dev_type_, // 文件夹
|
file_type: dev_type_, // 文件夹
|
||||||
mode: mode_,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -255,7 +264,13 @@ impl LockedDevFSInode {
|
|||||||
return Err(SystemError::EEXIST);
|
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,
|
Ok(inode) => inode,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
@ -291,17 +306,17 @@ impl LockedDevFSInode {
|
|||||||
fn do_create_with_data(
|
fn do_create_with_data(
|
||||||
&self,
|
&self,
|
||||||
mut guard: SpinLockGuard<DevFSInode>,
|
mut guard: SpinLockGuard<DevFSInode>,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_file_type: FileType,
|
file_type: FileType,
|
||||||
_mode: u32,
|
mode: ModeType,
|
||||||
_data: usize,
|
data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
if guard.metadata.file_type != FileType::Dir {
|
if guard.metadata.file_type != FileType::Dir {
|
||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果有重名的,则返回
|
// 如果有重名的,则返回
|
||||||
if guard.children.contains_key(_name) {
|
if guard.children.contains_key(name) {
|
||||||
return Err(SystemError::EEXIST);
|
return Err(SystemError::EEXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,12 +334,12 @@ impl LockedDevFSInode {
|
|||||||
atime: TimeSpec::default(),
|
atime: TimeSpec::default(),
|
||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: _file_type,
|
file_type,
|
||||||
mode: _mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
raw_dev: _data,
|
raw_dev: data,
|
||||||
},
|
},
|
||||||
fs: guard.fs.clone(),
|
fs: guard.fs.clone(),
|
||||||
})));
|
})));
|
||||||
@ -333,7 +348,7 @@ impl LockedDevFSInode {
|
|||||||
result.0.lock().self_ref = Arc::downgrade(&result);
|
result.0.lock().self_ref = Arc::downgrade(&result);
|
||||||
|
|
||||||
// 将子inode插入父inode的B树中
|
// 将子inode插入父inode的B树中
|
||||||
guard.children.insert(String::from(_name), result.clone());
|
guard.children.insert(String::from(name), result.clone());
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,7 +374,7 @@ impl IndexNode for LockedDevFSInode {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
data: usize,
|
data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 获取当前inode
|
// 获取当前inode
|
||||||
@ -399,7 +414,7 @@ impl IndexNode for LockedDevFSInode {
|
|||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
match ino {
|
match ino.into() {
|
||||||
0 => {
|
0 => {
|
||||||
return Ok(String::from("."));
|
return Ok(String::from("."));
|
||||||
}
|
}
|
||||||
@ -412,14 +427,24 @@ impl IndexNode for LockedDevFSInode {
|
|||||||
let mut key: Vec<String> = inode
|
let mut key: Vec<String> = inode
|
||||||
.children
|
.children
|
||||||
.keys()
|
.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()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match key.len() {
|
match key.len() {
|
||||||
0=>{return Err(SystemError::ENOENT);}
|
0=>{return Err(SystemError::ENOENT);}
|
||||||
1=>{return Ok(key.remove(0));}
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::filesystem::vfs::file::FileMode;
|
use crate::filesystem::vfs::file::FileMode;
|
||||||
use crate::filesystem::vfs::make_rawdev;
|
use crate::filesystem::vfs::make_rawdev;
|
||||||
|
use crate::filesystem::vfs::syscall::ModeType;
|
||||||
use crate::filesystem::vfs::{
|
use crate::filesystem::vfs::{
|
||||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
@ -43,7 +44,7 @@ impl LockedNullInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: 0o666,
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::filesystem::vfs::file::FileMode;
|
use crate::filesystem::vfs::file::FileMode;
|
||||||
use crate::filesystem::vfs::make_rawdev;
|
use crate::filesystem::vfs::make_rawdev;
|
||||||
|
use crate::filesystem::vfs::syscall::ModeType;
|
||||||
use crate::filesystem::vfs::{
|
use crate::filesystem::vfs::{
|
||||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
@ -43,7 +44,7 @@ impl LockedZeroInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||||
mode: 0o666,
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
|
@ -13,6 +13,7 @@ use crate::{
|
|||||||
filesystem::vfs::{
|
filesystem::vfs::{
|
||||||
core::generate_inode_id,
|
core::generate_inode_id,
|
||||||
file::{FileMode, FilePrivateData},
|
file::{FileMode, FilePrivateData},
|
||||||
|
syscall::ModeType,
|
||||||
FileSystem, FileType, IndexNode, InodeId, Metadata, PollStatus,
|
FileSystem, FileType, IndexNode, InodeId, Metadata, PollStatus,
|
||||||
},
|
},
|
||||||
kerror,
|
kerror,
|
||||||
@ -189,7 +190,7 @@ impl LockedFATInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: file_type,
|
file_type: file_type,
|
||||||
mode: 0o777,
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -308,7 +309,7 @@ impl FATFileSystem {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: 0o777,
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -1421,7 +1422,7 @@ impl IndexNode for LockedFATInode {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
_mode: u32,
|
_mode: ModeType,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 由于FAT32不支持文件权限的功能,因此忽略mode参数
|
// 由于FAT32不支持文件权限的功能,因此忽略mode参数
|
||||||
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
|
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
|
||||||
@ -1627,7 +1628,7 @@ impl IndexNode for LockedFATInode {
|
|||||||
if guard.metadata.file_type != FileType::Dir {
|
if guard.metadata.file_type != FileType::Dir {
|
||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
match ino {
|
match ino.into() {
|
||||||
0 => {
|
0 => {
|
||||||
return Ok(String::from("."));
|
return Ok(String::from("."));
|
||||||
}
|
}
|
||||||
@ -1640,14 +1641,24 @@ impl IndexNode for LockedFATInode {
|
|||||||
let mut key: Vec<String> = guard
|
let mut key: Vec<String> = guard
|
||||||
.children
|
.children
|
||||||
.keys()
|
.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()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match key.len() {
|
match key.len() {
|
||||||
0=>{return Err(SystemError::ENOENT);}
|
0=>{return Err(SystemError::ENOENT);}
|
||||||
1=>{return Ok(key.remove(0));}
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
73
kernel/src/filesystem/kernfs/callback.rs
Normal file
73
kernel/src/filesystem/kernfs/callback.rs
Normal 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),
|
||||||
|
}
|
486
kernel/src/filesystem/kernfs/mod.rs
Normal file
486
kernel/src/filesystem/kernfs/mod.rs
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
pub mod devfs;
|
pub mod devfs;
|
||||||
pub mod fat;
|
pub mod fat;
|
||||||
|
pub mod kernfs;
|
||||||
pub mod mbr;
|
pub mod mbr;
|
||||||
pub mod procfs;
|
pub mod procfs;
|
||||||
pub mod ramfs;
|
pub mod ramfs;
|
||||||
|
@ -26,6 +26,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
file::{FileMode, FilePrivateData},
|
file::{FileMode, FilePrivateData},
|
||||||
|
syscall::ModeType,
|
||||||
FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
|
FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -262,7 +263,7 @@ impl ProcFS {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: 0o777,
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -294,10 +295,18 @@ impl ProcFS {
|
|||||||
// 获取当前inode
|
// 获取当前inode
|
||||||
let proc: Arc<dyn IndexNode> = self.root_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文件
|
// 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
|
let _sf: &LockedProcFSInode = binding
|
||||||
.as_any_ref()
|
.as_any_ref()
|
||||||
.downcast_ref::<LockedProcFSInode>()
|
.downcast_ref::<LockedProcFSInode>()
|
||||||
@ -482,7 +491,7 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
data: usize,
|
data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 获取当前inode
|
// 获取当前inode
|
||||||
@ -623,7 +632,7 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
match ino {
|
match ino.into() {
|
||||||
0 => {
|
0 => {
|
||||||
return Ok(String::from("."));
|
return Ok(String::from("."));
|
||||||
}
|
}
|
||||||
@ -636,14 +645,25 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
let mut key: Vec<String> = inode
|
let mut key: Vec<String> = inode
|
||||||
.children
|
.children
|
||||||
.keys()
|
.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()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match key.len() {
|
match key.len() {
|
||||||
0=>{return Err(SystemError::ENOENT);}
|
0=>{return Err(SystemError::ENOENT);}
|
||||||
1=>{return Ok(key.remove(0));}
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
file::FilePrivateData, FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
|
file::FilePrivateData, syscall::ModeType, FileSystem, FsInfo, IndexNode, InodeId, Metadata,
|
||||||
|
PollStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// RamFS的inode名称的最大长度
|
/// RamFS的inode名称的最大长度
|
||||||
@ -90,7 +91,7 @@ impl RamFS {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::Dir,
|
file_type: FileType::Dir,
|
||||||
mode: 0o777,
|
mode: ModeType::from_bits_truncate(0o777),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -258,7 +259,7 @@ impl IndexNode for LockedRamFSInode {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
data: usize,
|
data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 获取当前inode
|
// 获取当前inode
|
||||||
@ -425,7 +426,7 @@ impl IndexNode for LockedRamFSInode {
|
|||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
match ino {
|
match ino.into() {
|
||||||
0 => {
|
0 => {
|
||||||
return Ok(String::from("."));
|
return Ok(String::from("."));
|
||||||
}
|
}
|
||||||
@ -438,14 +439,25 @@ impl IndexNode for LockedRamFSInode {
|
|||||||
let mut key: Vec<String> = inode
|
let mut key: Vec<String> = inode
|
||||||
.children
|
.children
|
||||||
.keys()
|
.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()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match key.len() {
|
match key.len() {
|
||||||
0=>{return Err(SystemError::ENOENT);}
|
0=>{return Err(SystemError::ENOENT);}
|
||||||
1=>{return Ok(key.remove(0));}
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
kernel/src/filesystem/sysfs/dir.rs
Normal file
32
kernel/src/filesystem/sysfs/dir.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
21
kernel/src/filesystem/sysfs/file.rs
Normal file
21
kernel/src/filesystem/sysfs/file.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,13 @@
|
|||||||
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
use self::{dir::SysKernDirPriv, file::SysKernFilePriv};
|
||||||
|
|
||||||
use super::vfs::{
|
use super::vfs::{
|
||||||
core::generate_inode_id, file::FileMode, FileSystem, FileType, FsInfo, IndexNode, Metadata,
|
core::generate_inode_id, file::FileMode, syscall::ModeType, FileSystem, FileType, FsInfo,
|
||||||
PollStatus,
|
IndexNode, Metadata, PollStatus,
|
||||||
};
|
};
|
||||||
use crate::{
|
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},
|
filesystem::{sysfs::bus::sys_bus_init, vfs::ROOT_INODE},
|
||||||
kdebug, kinfo,
|
kdebug, kinfo,
|
||||||
libs::{
|
libs::{
|
||||||
@ -23,6 +27,8 @@ use alloc::{
|
|||||||
pub mod bus;
|
pub mod bus;
|
||||||
pub mod class;
|
pub mod class;
|
||||||
pub mod devices;
|
pub mod devices;
|
||||||
|
mod dir;
|
||||||
|
mod file;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
|
||||||
const SYSFS_MAX_NAMELEN: usize = 64;
|
const SYSFS_MAX_NAMELEN: usize = 64;
|
||||||
@ -98,7 +104,7 @@ impl SysFS {
|
|||||||
let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
|
let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
|
||||||
// /sys 的权限设置为 读+执行,root 可以读写
|
// /sys 的权限设置为 读+执行,root 可以读写
|
||||||
// root 的 parent 是空指针
|
// 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 });
|
let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root });
|
||||||
@ -220,7 +226,7 @@ impl IndexNode for LockedSysFSInode {
|
|||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
match ino {
|
match ino.into() {
|
||||||
0 => {
|
0 => {
|
||||||
return Ok(String::from("."));
|
return Ok(String::from("."));
|
||||||
}
|
}
|
||||||
@ -233,14 +239,24 @@ impl IndexNode for LockedSysFSInode {
|
|||||||
let mut key: Vec<String> = inode
|
let mut key: Vec<String> = inode
|
||||||
.children
|
.children
|
||||||
.keys()
|
.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()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match key.len() {
|
match key.len() {
|
||||||
0=>{return Err(SystemError::ENOENT);}
|
0=>{return Err(SystemError::ENOENT);}
|
||||||
1=>{return Ok(key.remove(0));}
|
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(
|
fn do_create_with_data(
|
||||||
&self,
|
&self,
|
||||||
mut guard: SpinLockGuard<SysFSInode>,
|
mut guard: SpinLockGuard<SysFSInode>,
|
||||||
_name: &str,
|
name: &str,
|
||||||
_file_type: FileType,
|
file_type: FileType,
|
||||||
_mode: u32,
|
mode: ModeType,
|
||||||
_data: usize,
|
data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
if guard.metadata.file_type != FileType::Dir {
|
if guard.metadata.file_type != FileType::Dir {
|
||||||
return Err(SystemError::ENOTDIR);
|
return Err(SystemError::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果有重名的,则返回
|
// 如果有重名的,则返回
|
||||||
if guard.children.contains_key(_name) {
|
if guard.children.contains_key(name) {
|
||||||
return Err(SystemError::EEXIST);
|
return Err(SystemError::EEXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,12 +338,12 @@ impl LockedSysFSInode {
|
|||||||
atime: TimeSpec::default(),
|
atime: TimeSpec::default(),
|
||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: _file_type,
|
file_type,
|
||||||
mode: _mode,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
raw_dev: _data,
|
raw_dev: data,
|
||||||
},
|
},
|
||||||
fs: guard.fs.clone(),
|
fs: guard.fs.clone(),
|
||||||
})));
|
})));
|
||||||
@ -336,7 +352,7 @@ impl LockedSysFSInode {
|
|||||||
result.0.lock().self_ref = Arc::downgrade(&result);
|
result.0.lock().self_ref = Arc::downgrade(&result);
|
||||||
|
|
||||||
// 将子inode插入父inode的B树中
|
// 将子inode插入父inode的B树中
|
||||||
guard.children.insert(String::from(_name), result.clone());
|
guard.children.insert(String::from(name), result.clone());
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +368,13 @@ impl LockedSysFSInode {
|
|||||||
return Err(SystemError::EEXIST);
|
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),
|
Ok(inode) => return Ok(inode),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
@ -421,14 +443,14 @@ pub struct SysFSInode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SysFSInode {
|
impl SysFSInode {
|
||||||
pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
|
pub fn new(file_type: FileType, mode: ModeType, data_: usize) -> Self {
|
||||||
return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
|
return Self::new_with_parent(Weak::default(), file_type, mode, data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_parent(
|
pub fn new_with_parent(
|
||||||
parent: Weak<LockedSysFSInode>,
|
parent: Weak<LockedSysFSInode>,
|
||||||
dev_type_: FileType,
|
file_type: FileType,
|
||||||
mode_: u32,
|
mode: ModeType,
|
||||||
data_: usize,
|
data_: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
return SysFSInode {
|
return SysFSInode {
|
||||||
@ -444,8 +466,8 @@ impl SysFSInode {
|
|||||||
atime: TimeSpec::default(),
|
atime: TimeSpec::default(),
|
||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: dev_type_, // 文件夹
|
file_type,
|
||||||
mode: mode_,
|
mode,
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -485,3 +507,24 @@ pub fn sysfs_init() -> Result<(), SystemError> {
|
|||||||
|
|
||||||
return result.unwrap();
|
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;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use core::{
|
use core::{hint::spin_loop, sync::atomic::Ordering};
|
||||||
hint::spin_loop,
|
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloc::{format, string::ToString, sync::Arc};
|
use alloc::{format, string::ToString, sync::Arc};
|
||||||
|
|
||||||
@ -16,7 +13,7 @@ use crate::{
|
|||||||
procfs::procfs_init,
|
procfs::procfs_init,
|
||||||
ramfs::RamFS,
|
ramfs::RamFS,
|
||||||
sysfs::sysfs_init,
|
sysfs::sysfs_init,
|
||||||
vfs::{mount::MountFS, FileSystem, FileType},
|
vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType},
|
||||||
},
|
},
|
||||||
include::bindings::bindings::PAGE_4K_SIZE,
|
include::bindings::bindings::PAGE_4K_SIZE,
|
||||||
kdebug, kerror, kinfo,
|
kdebug, kerror, kinfo,
|
||||||
@ -31,8 +28,8 @@ use super::{file::FileMode, utils::rsplit_path, IndexNode, InodeId};
|
|||||||
/// [0]: 对应'.'目录项
|
/// [0]: 对应'.'目录项
|
||||||
/// [1]: 对应'..'目录项
|
/// [1]: 对应'..'目录项
|
||||||
pub fn generate_inode_id() -> InodeId {
|
pub fn generate_inode_id() -> InodeId {
|
||||||
static INO: AtomicUsize = AtomicUsize::new(1);
|
static INO: AtomicInodeId = AtomicInodeId::new(InodeId::new(1));
|
||||||
return INO.fetch_add(1, Ordering::SeqCst);
|
return INO.fetch_add(InodeId::new(1), Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None;
|
static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None;
|
||||||
@ -59,13 +56,13 @@ pub extern "C" fn vfs_init() -> i32 {
|
|||||||
|
|
||||||
// 创建文件夹
|
// 创建文件夹
|
||||||
root_inode
|
root_inode
|
||||||
.create("proc", FileType::Dir, 0o777)
|
.create("proc", FileType::Dir, ModeType::from_bits_truncate(0o755))
|
||||||
.expect("Failed to create /proc");
|
.expect("Failed to create /proc");
|
||||||
root_inode
|
root_inode
|
||||||
.create("dev", FileType::Dir, 0o777)
|
.create("dev", FileType::Dir, ModeType::from_bits_truncate(0o755))
|
||||||
.expect("Failed to create /dev");
|
.expect("Failed to create /dev");
|
||||||
root_inode
|
root_inode
|
||||||
.create("sys", FileType::Dir, 0o777)
|
.create("sys", FileType::Dir, ModeType::from_bits_truncate(0o755))
|
||||||
.expect("Failed to create /sys");
|
.expect("Failed to create /sys");
|
||||||
kdebug!("dir in root:{:?}", root_inode.list());
|
kdebug!("dir in root:{:?}", root_inode.list());
|
||||||
|
|
||||||
@ -94,7 +91,11 @@ fn do_migrate(
|
|||||||
let r = new_root_inode.find(mountpoint_name);
|
let r = new_root_inode.find(mountpoint_name);
|
||||||
let mountpoint = if r.is_err() {
|
let mountpoint = if r.is_err() {
|
||||||
new_root_inode
|
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())
|
.expect(format!("Failed to create '/{mountpoint_name}' in migrating").as_str())
|
||||||
} else {
|
} else {
|
||||||
r.unwrap()
|
r.unwrap()
|
||||||
@ -191,8 +192,11 @@ pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> {
|
|||||||
let parent_inode: Arc<dyn IndexNode> =
|
let parent_inode: Arc<dyn IndexNode> =
|
||||||
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
||||||
// 创建文件夹
|
// 创建文件夹
|
||||||
let _create_inode: Arc<dyn IndexNode> =
|
let _create_inode: Arc<dyn IndexNode> = parent_inode.create(
|
||||||
parent_inode.create(filename, FileType::Dir, 0o777)?;
|
filename,
|
||||||
|
FileType::Dir,
|
||||||
|
ModeType::from_bits_truncate(0o755),
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
// 不需要创建文件,因此返回错误码
|
// 不需要创建文件,因此返回错误码
|
||||||
return Err(errno);
|
return Err(errno);
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
syscall::SystemError,
|
syscall::SystemError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{Dirent, FileType, IndexNode, Metadata};
|
use super::{Dirent, FileType, IndexNode, InodeId, Metadata};
|
||||||
|
|
||||||
/// 文件私有信息的枚举类型
|
/// 文件私有信息的枚举类型
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -185,7 +185,7 @@ impl File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 根据inode号获取子目录项的名字
|
/// @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);
|
return self.inode.get_entry_name(ino);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ impl File {
|
|||||||
let name_bytes: &[u8] = name.as_bytes();
|
let name_bytes: &[u8] = name.as_bytes();
|
||||||
|
|
||||||
self.offset += 1;
|
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_off = 0;
|
||||||
dirent.d_reclen = 0;
|
dirent.d_reclen = 0;
|
||||||
dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;
|
dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;
|
||||||
|
@ -7,20 +7,20 @@ pub mod mount;
|
|||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
mod utils;
|
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 alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
|
|
||||||
use crate::{libs::casting::DowncastArc, syscall::SystemError, time::TimeSpec};
|
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};
|
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
||||||
|
|
||||||
/// vfs容许的最大的路径名称长度
|
/// vfs容许的最大的路径名称长度
|
||||||
pub const MAX_PATHLEN: usize = 1024;
|
pub const MAX_PATHLEN: usize = 1024;
|
||||||
|
|
||||||
/// 定义inode号的类型为usize
|
// 定义inode号
|
||||||
pub type InodeId = usize;
|
int_like!(InodeId, AtomicInodeId, usize, AtomicUsize);
|
||||||
|
|
||||||
/// 文件的类型
|
/// 文件的类型
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@ -185,7 +185,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
|
// 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
|
||||||
return self.create_with_data(name, file_type, mode, 0);
|
return self.create_with_data(name, file_type, mode, 0);
|
||||||
@ -204,7 +204,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
|
|||||||
&self,
|
&self,
|
||||||
_name: &str,
|
_name: &str,
|
||||||
_file_type: FileType,
|
_file_type: FileType,
|
||||||
_mode: u32,
|
_mode: ModeType,
|
||||||
_data: usize,
|
_data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
// 若文件系统没有实现此方法,则返回“不支持”
|
// 若文件系统没有实现此方法,则返回“不支持”
|
||||||
@ -477,7 +477,7 @@ pub struct Metadata {
|
|||||||
pub file_type: FileType,
|
pub file_type: FileType,
|
||||||
|
|
||||||
/// 权限
|
/// 权限
|
||||||
pub mode: u32,
|
pub mode: ModeType,
|
||||||
|
|
||||||
/// 硬链接的数量
|
/// 硬链接的数量
|
||||||
pub nlinks: usize,
|
pub nlinks: usize,
|
||||||
@ -496,7 +496,7 @@ impl Default for Metadata {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
return Self {
|
return Self {
|
||||||
dev_id: 0,
|
dev_id: 0,
|
||||||
inode_id: 0,
|
inode_id: InodeId::new(0),
|
||||||
size: 0,
|
size: 0,
|
||||||
blk_size: 0,
|
blk_size: 0,
|
||||||
blocks: 0,
|
blocks: 0,
|
||||||
@ -504,7 +504,7 @@ impl Default for Metadata {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::File,
|
file_type: FileType::File,
|
||||||
mode: 0,
|
mode: ModeType::empty(),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
@ -551,7 +551,7 @@ pub struct Dirent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Metadata {
|
impl Metadata {
|
||||||
pub fn new(file_type: FileType, mode: u32) -> Self {
|
pub fn new(file_type: FileType, mode: ModeType) -> Self {
|
||||||
Metadata {
|
Metadata {
|
||||||
dev_id: 0,
|
dev_id: 0,
|
||||||
inode_id: generate_inode_id(),
|
inode_id: generate_inode_id(),
|
||||||
|
@ -10,7 +10,9 @@ use alloc::{
|
|||||||
|
|
||||||
use crate::{libs::spinlock::SpinLock, syscall::SystemError};
|
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 挂载文件系统
|
/// @brief 挂载文件系统
|
||||||
/// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
|
/// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
|
||||||
@ -141,7 +143,7 @@ impl IndexNode for MountFSInode {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
data: usize,
|
data: usize,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
return Ok(MountFSInode {
|
return Ok(MountFSInode {
|
||||||
@ -213,7 +215,7 @@ impl IndexNode for MountFSInode {
|
|||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
file_type: FileType,
|
file_type: FileType,
|
||||||
mode: u32,
|
mode: ModeType,
|
||||||
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
return Ok(MountFSInode {
|
return Ok(MountFSInode {
|
||||||
inner_inode: self.inner_inode.create(name, file_type, mode)?,
|
inner_inode: self.inner_inode.create(name, file_type, mode)?,
|
||||||
|
@ -31,6 +31,7 @@ pub const SEEK_MAX: u32 = 3;
|
|||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// 文件类型和权限
|
/// 文件类型和权限
|
||||||
|
#[repr(C)]
|
||||||
pub struct ModeType: u32 {
|
pub struct ModeType: u32 {
|
||||||
/// 掩码
|
/// 掩码
|
||||||
const S_IFMT = 0o0_170_000;
|
const S_IFMT = 0o0_170_000;
|
||||||
@ -154,8 +155,11 @@ impl Syscall {
|
|||||||
let parent_inode: Arc<dyn IndexNode> =
|
let parent_inode: Arc<dyn IndexNode> =
|
||||||
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
||||||
// 创建文件
|
// 创建文件
|
||||||
let inode: Arc<dyn IndexNode> =
|
let inode: Arc<dyn IndexNode> = parent_inode.create(
|
||||||
parent_inode.create(filename, FileType::File, 0o777)?;
|
filename,
|
||||||
|
FileType::File,
|
||||||
|
ModeType::from_bits_truncate(0o755),
|
||||||
|
)?;
|
||||||
inode
|
inode
|
||||||
} else {
|
} else {
|
||||||
// 不需要创建文件,因此返回错误码
|
// 不需要创建文件,因此返回错误码
|
||||||
@ -649,7 +653,7 @@ impl Syscall {
|
|||||||
let metadata = file.lock().metadata()?;
|
let metadata = file.lock().metadata()?;
|
||||||
kstat.size = metadata.size as i64;
|
kstat.size = metadata.size as i64;
|
||||||
kstat.dev_id = metadata.dev_id as u64;
|
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.blcok_size = metadata.blk_size as i64;
|
||||||
kstat.blocks = metadata.blocks as u64;
|
kstat.blocks = metadata.blocks as u64;
|
||||||
|
|
||||||
@ -664,7 +668,7 @@ impl Syscall {
|
|||||||
kstat.uid = metadata.uid as i32;
|
kstat.uid = metadata.uid as i32;
|
||||||
kstat.gid = metadata.gid as i32;
|
kstat.gid = metadata.gid as i32;
|
||||||
kstat.rdev = metadata.raw_dev as i64;
|
kstat.rdev = metadata.raw_dev as i64;
|
||||||
kstat.mode.bits = metadata.mode;
|
kstat.mode = metadata.mode;
|
||||||
match file.lock().file_type() {
|
match file.lock().file_type() {
|
||||||
FileType::File => kstat.mode.insert(ModeType::S_IFMT),
|
FileType::File => kstat.mode.insert(ModeType::S_IFMT),
|
||||||
FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
|
FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
|
||||||
|
@ -2,8 +2,8 @@ use crate::{
|
|||||||
arch::{sched::sched, CurrentIrqArch},
|
arch::{sched::sched, CurrentIrqArch},
|
||||||
exception::InterruptArch,
|
exception::InterruptArch,
|
||||||
filesystem::vfs::{
|
filesystem::vfs::{
|
||||||
core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode,
|
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
|
||||||
Metadata, PollStatus,
|
FileType, IndexNode, Metadata, PollStatus,
|
||||||
},
|
},
|
||||||
libs::{spinlock::SpinLock, wait_queue::WaitQueue},
|
libs::{spinlock::SpinLock, wait_queue::WaitQueue},
|
||||||
process::ProcessState,
|
process::ProcessState,
|
||||||
@ -56,7 +56,7 @@ impl LockedPipeInode {
|
|||||||
mtime: TimeSpec::default(),
|
mtime: TimeSpec::default(),
|
||||||
ctime: TimeSpec::default(),
|
ctime: TimeSpec::default(),
|
||||||
file_type: FileType::Pipe,
|
file_type: FileType::Pipe,
|
||||||
mode: 0o666,
|
mode: ModeType::from_bits_truncate(0o666),
|
||||||
nlinks: 1,
|
nlinks: 1,
|
||||||
uid: 0,
|
uid: 0,
|
||||||
gid: 0,
|
gid: 0,
|
||||||
|
@ -10,7 +10,7 @@ use smoltcp::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::rand::rand,
|
arch::rand::rand,
|
||||||
driver::net::NetDriver,
|
driver::net::NetDriver,
|
||||||
filesystem::vfs::{FileType, IndexNode, Metadata, PollStatus},
|
filesystem::vfs::{syscall::ModeType, FileType, IndexNode, Metadata, PollStatus},
|
||||||
kerror, kwarn,
|
kerror, kwarn,
|
||||||
libs::{
|
libs::{
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
@ -1215,7 +1215,7 @@ impl IndexNode for SocketInode {
|
|||||||
|
|
||||||
fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
|
fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
|
||||||
let meta = Metadata {
|
let meta = Metadata {
|
||||||
mode: 0o777,
|
mode: ModeType::from_bits_truncate(0o755),
|
||||||
file_type: FileType::Socket,
|
file_type: FileType::Socket,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user