Make device Inode behave like pointer
This commit is contained in:
parent
d8a4b3076f
commit
83c158e3b5
|
|
@ -39,7 +39,8 @@ pub(super) fn init_in_first_process(fs_resolver: &FsResolver) -> Result<()> {
|
|||
for device in aster_block::collect_all() {
|
||||
let device = Arc::new(BlockFile::new(device));
|
||||
if let Some(devtmpfs_path) = device.devtmpfs_path() {
|
||||
add_node(device, &devtmpfs_path, fs_resolver)?;
|
||||
let dev_id = device.id().as_encoded_u64();
|
||||
add_node(DeviceType::Block, dev_id, &devtmpfs_path, fs_resolver)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use device_id::{DeviceId, MajorId};
|
|||
|
||||
use crate::{
|
||||
fs::{
|
||||
device::{add_node, Device},
|
||||
device::{add_node, Device, DeviceType},
|
||||
fs_resolver::FsResolver,
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -115,7 +115,8 @@ impl Drop for MajorIdOwner {
|
|||
pub(super) fn init_in_first_process(fs_resolver: &FsResolver) -> Result<()> {
|
||||
for device in collect_all() {
|
||||
if let Some(devtmpfs_path) = device.devtmpfs_path() {
|
||||
add_node(device, &devtmpfs_path, fs_resolver)?;
|
||||
let dev_id = device.id().as_encoded_u64();
|
||||
add_node(DeviceType::Char, dev_id, &devtmpfs_path, fs_resolver)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
fs::{
|
||||
fs_resolver::{FsPath, FsResolver},
|
||||
path::Path,
|
||||
utils::{mkmod, InodeType},
|
||||
utils::{mkmod, InodeType, MknodType},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
|
@ -51,7 +51,12 @@ pub enum DeviceType {
|
|||
/// This function should be called when registering a device.
|
||||
//
|
||||
// TODO: Figure out what should happen when unregistering the device.
|
||||
pub fn add_node(device: Arc<dyn Device>, path: &str, fs_resolver: &FsResolver) -> Result<Path> {
|
||||
pub fn add_node(
|
||||
dev_type: DeviceType,
|
||||
dev_id: u64,
|
||||
path: &str,
|
||||
fs_resolver: &FsResolver,
|
||||
) -> Result<Path> {
|
||||
let mut dev_path = fs_resolver.lookup(&FsPath::try_from("/dev").unwrap())?;
|
||||
let mut relative_path = {
|
||||
let relative_path = path.trim_start_matches('/');
|
||||
|
|
@ -79,7 +84,11 @@ pub fn add_node(device: Arc<dyn Device>, path: &str, fs_resolver: &FsResolver) -
|
|||
Err(_) => {
|
||||
if path_remain.is_empty() {
|
||||
// Create the device node
|
||||
dev_path = dev_path.mknod(next_name, mkmod!(a+rw), device.clone().into())?;
|
||||
let mknod_type = match dev_type {
|
||||
DeviceType::Block => MknodType::BlockDevice(dev_id),
|
||||
DeviceType::Char => MknodType::CharDevice(dev_id),
|
||||
};
|
||||
dev_path = dev_path.mknod(next_name, mkmod!(a+rw), mknod_type)?;
|
||||
} else {
|
||||
// Create the parent directory
|
||||
dev_path =
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ impl Inode for Ext2Inode {
|
|||
"the device of ID 0 does not exist",
|
||||
)));
|
||||
}
|
||||
let device_type = inode_type.as_device_type().unwrap();
|
||||
let device_type = inode_type.device_type().unwrap();
|
||||
let Some(device) =
|
||||
device::lookup(device_type, DeviceId::from_encoded_u64(device_id))
|
||||
else {
|
||||
|
|
@ -161,14 +161,18 @@ impl Inode for Ext2Inode {
|
|||
}
|
||||
|
||||
fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result<Arc<dyn Inode>> {
|
||||
let inode_type = type_.inode_type();
|
||||
let inode = match type_ {
|
||||
MknodType::CharDevice(dev) | MknodType::BlockDevice(dev) => {
|
||||
let inode = self.create(name, inode_type, mode.into())?;
|
||||
inode.set_device_id(dev.id().as_encoded_u64()).unwrap();
|
||||
MknodType::CharDevice(dev) => {
|
||||
let inode = self.create(name, InodeType::CharDevice, mode.into())?;
|
||||
inode.set_device_id(dev).unwrap();
|
||||
inode
|
||||
}
|
||||
MknodType::NamedPipe => self.create(name, inode_type, mode.into())?,
|
||||
MknodType::BlockDevice(dev) => {
|
||||
let inode = self.create(name, InodeType::BlockDevice, mode.into())?;
|
||||
inode.set_device_id(dev).unwrap();
|
||||
inode
|
||||
}
|
||||
MknodType::NamedPipe => self.create(name, InodeType::NamedPipe, mode.into())?,
|
||||
};
|
||||
|
||||
Ok(inode)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use core::{
|
|||
use align_ext::AlignExt;
|
||||
use aster_block::bio::BioWaiter;
|
||||
use aster_util::slot_vec::SlotVec;
|
||||
use device_id::DeviceId;
|
||||
use hashbrown::HashMap;
|
||||
use ostd::{
|
||||
mm::{io_util::HasVmReaderWriter, HasSize},
|
||||
|
|
@ -16,8 +17,9 @@ use ostd::{
|
|||
|
||||
use super::{memfd::MemfdInode, xattr::RamXattr, *};
|
||||
use crate::{
|
||||
device,
|
||||
fs::{
|
||||
device::Device,
|
||||
device::DeviceType,
|
||||
inode_handle::FileIo,
|
||||
notify::FsEventPublisher,
|
||||
path::{is_dot, is_dot_or_dotdot, is_dotdot},
|
||||
|
|
@ -127,7 +129,8 @@ enum Inner {
|
|||
Dir(RwLock<DirEntry>),
|
||||
File(PageCache),
|
||||
SymLink(SpinLock<String>),
|
||||
Device(Arc<dyn Device>),
|
||||
BlockDevice(u64),
|
||||
CharDevice(u64),
|
||||
Socket,
|
||||
NamedPipe(NamedPipe),
|
||||
}
|
||||
|
|
@ -145,8 +148,12 @@ impl Inner {
|
|||
Self::SymLink(SpinLock::new(String::from("")))
|
||||
}
|
||||
|
||||
pub(self) fn new_device(device: Arc<dyn Device>) -> Self {
|
||||
Self::Device(device)
|
||||
pub(self) fn new_block_device(dev_id: u64) -> Self {
|
||||
Self::BlockDevice(dev_id)
|
||||
}
|
||||
|
||||
pub(self) fn new_char_device(dev_id: u64) -> Self {
|
||||
Self::CharDevice(dev_id)
|
||||
}
|
||||
|
||||
pub(self) fn new_socket() -> Self {
|
||||
|
|
@ -182,9 +189,17 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
|
||||
fn as_device(&self) -> Option<&Arc<dyn Device>> {
|
||||
fn device_id(&self) -> Option<u64> {
|
||||
match self {
|
||||
Self::Device(device) => Some(device),
|
||||
Self::BlockDevice(dev_id) | Self::CharDevice(dev_id) => Some(*dev_id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn device_type(&self) -> Option<DeviceType> {
|
||||
match self {
|
||||
Self::BlockDevice(_) => Some(DeviceType::Block),
|
||||
Self::CharDevice(_) => Some(DeviceType::Char),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +210,26 @@ impl Inner {
|
|||
status_flags: StatusFlags,
|
||||
) -> Option<Result<Box<dyn FileIo>>> {
|
||||
match self {
|
||||
Self::Device(device) => Some(device.open()),
|
||||
Self::BlockDevice(device_id) | Self::CharDevice(device_id) => {
|
||||
if *device_id == 0 {
|
||||
return Some(Err(Error::with_message(
|
||||
Errno::ENODEV,
|
||||
"the device of ID 0 does not exist",
|
||||
)));
|
||||
}
|
||||
|
||||
let device_type = self.device_type().unwrap();
|
||||
let Some(device) =
|
||||
device::lookup(device_type, DeviceId::from_encoded_u64(*device_id))
|
||||
else {
|
||||
return Some(Err(Error::with_message(
|
||||
Errno::ENODEV,
|
||||
"the required device ID does not exist",
|
||||
)));
|
||||
};
|
||||
|
||||
Some(device.open())
|
||||
}
|
||||
Self::NamedPipe(pipe) => Some(pipe.open(access_mode, status_flags)),
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -480,13 +514,19 @@ impl RamInode {
|
|||
mode: InodeMode,
|
||||
uid: Uid,
|
||||
gid: Gid,
|
||||
device: Arc<dyn Device>,
|
||||
dev_type: DeviceType,
|
||||
dev_id: u64,
|
||||
) -> Arc<Self> {
|
||||
let inner = match dev_type {
|
||||
DeviceType::Block => Inner::new_block_device(dev_id),
|
||||
DeviceType::Char => Inner::new_char_device(dev_id),
|
||||
};
|
||||
|
||||
Arc::new_cyclic(|weak_self| RamInode {
|
||||
inner: Inner::new_device(device.clone()),
|
||||
inner,
|
||||
metadata: SpinLock::new(InodeMeta::new(mode, uid, gid)),
|
||||
ino: fs.alloc_id(),
|
||||
typ: InodeType::from(device.type_()),
|
||||
typ: dev_type.into(),
|
||||
this: weak_self.clone(),
|
||||
fs: Arc::downgrade(fs),
|
||||
extension: Extension::new(),
|
||||
|
|
@ -733,13 +773,17 @@ impl Inode for RamInode {
|
|||
}
|
||||
|
||||
let new_inode = match type_ {
|
||||
MknodType::CharDevice(device) | MknodType::BlockDevice(device) => RamInode::new_device(
|
||||
&self.fs.upgrade().unwrap(),
|
||||
mode,
|
||||
Uid::new_root(),
|
||||
Gid::new_root(),
|
||||
device,
|
||||
),
|
||||
MknodType::CharDevice(dev_id) | MknodType::BlockDevice(dev_id) => {
|
||||
let dev_type = type_.device_type().unwrap();
|
||||
RamInode::new_device(
|
||||
&self.fs.upgrade().unwrap(),
|
||||
mode,
|
||||
Uid::new_root(),
|
||||
Gid::new_root(),
|
||||
dev_type,
|
||||
dev_id,
|
||||
)
|
||||
}
|
||||
MknodType::NamedPipe => RamInode::new_named_pipe(
|
||||
&self.fs.upgrade().unwrap(),
|
||||
mode,
|
||||
|
|
@ -1136,11 +1180,7 @@ impl Inode for RamInode {
|
|||
}
|
||||
|
||||
fn metadata(&self) -> Metadata {
|
||||
let rdev = self
|
||||
.inner
|
||||
.as_device()
|
||||
.map(|device| device.id().as_encoded_u64())
|
||||
.unwrap_or(0);
|
||||
let rdev = self.inner.device_id().unwrap_or(0);
|
||||
let inode_metadata = self.metadata.lock();
|
||||
Metadata {
|
||||
dev: 0,
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ impl InodeType {
|
|||
.map_err(|_| Error::with_message(Errno::EINVAL, "invalid file type"))
|
||||
}
|
||||
|
||||
pub fn as_device_type(&self) -> Option<DeviceType> {
|
||||
pub fn device_type(&self) -> Option<DeviceType> {
|
||||
match self {
|
||||
InodeType::BlockDevice => Some(DeviceType::Block),
|
||||
InodeType::CharDevice => Some(DeviceType::Char),
|
||||
|
|
@ -225,27 +225,16 @@ impl Metadata {
|
|||
|
||||
pub enum MknodType {
|
||||
NamedPipe,
|
||||
CharDevice(Arc<dyn Device>),
|
||||
BlockDevice(Arc<dyn Device>),
|
||||
CharDevice(u64),
|
||||
BlockDevice(u64),
|
||||
}
|
||||
|
||||
impl MknodType {
|
||||
pub fn inode_type(&self) -> InodeType {
|
||||
pub fn device_type(&self) -> Option<DeviceType> {
|
||||
match self {
|
||||
MknodType::NamedPipe => InodeType::NamedPipe,
|
||||
MknodType::CharDevice(_) => InodeType::CharDevice,
|
||||
MknodType::BlockDevice(_) => InodeType::BlockDevice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arc<dyn Device>> for MknodType {
|
||||
fn from(device: Arc<dyn Device>) -> Self {
|
||||
let inode_type: InodeType = device.type_().into();
|
||||
match inode_type {
|
||||
InodeType::CharDevice => Self::CharDevice(device),
|
||||
InodeType::BlockDevice => Self::BlockDevice(device),
|
||||
_ => unreachable!(),
|
||||
MknodType::NamedPipe => None,
|
||||
MknodType::CharDevice(_) => Some(DeviceType::Char),
|
||||
MknodType::BlockDevice(_) => Some(DeviceType::Block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use device_id::DeviceId;
|
||||
|
||||
use super::SyscallReturn;
|
||||
use crate::{
|
||||
device,
|
||||
fs::{
|
||||
self,
|
||||
file_table::FileDesc,
|
||||
|
|
@ -48,11 +45,11 @@ pub fn sys_mknodat(
|
|||
InodeType::File => {
|
||||
let _ = dir_path.new_fs_child(&name, InodeType::File, inode_mode)?;
|
||||
}
|
||||
InodeType::CharDevice | InodeType::BlockDevice => {
|
||||
let device_type = inode_type.as_device_type().unwrap();
|
||||
let device_inode = device::lookup(device_type, DeviceId::from_encoded_u64(dev as u64))
|
||||
.ok_or_else(|| Error::new(Errno::ENODEV))?;
|
||||
let _ = dir_path.mknod(&name, inode_mode, device_inode.into())?;
|
||||
InodeType::CharDevice => {
|
||||
let _ = dir_path.mknod(&name, inode_mode, MknodType::CharDevice(dev as u64))?;
|
||||
}
|
||||
InodeType::BlockDevice => {
|
||||
let _ = dir_path.mknod(&name, inode_mode, MknodType::BlockDevice(dev as u64))?;
|
||||
}
|
||||
InodeType::NamedPipe => {
|
||||
let _ = dir_path.mknod(&name, inode_mode, MknodType::NamedPipe)?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue