Support looking up block devices
This commit is contained in:
parent
e4a09f5503
commit
d8a4b3076f
|
|
@ -9,12 +9,12 @@ mod registry;
|
|||
mod shm;
|
||||
pub mod tty;
|
||||
|
||||
use device_id::DeviceId;
|
||||
pub use mem::{getrandom, geturandom};
|
||||
pub use pty::{new_pty_pair, PtyMaster, PtySlave};
|
||||
pub use registry::lookup;
|
||||
|
||||
use crate::{
|
||||
fs::{device::Device, fs_resolver::FsPath, path::PerMountFlags, ramfs::RamFs},
|
||||
fs::{fs_resolver::FsPath, path::PerMountFlags, ramfs::RamFs},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
|
|
@ -42,11 +42,3 @@ pub fn init_in_first_process(ctx: &Context) -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Looks up a device according to the device ID.
|
||||
pub fn get_device(devid: DeviceId) -> Result<Arc<dyn Device>> {
|
||||
// TODO: Add support for looking up block devices.
|
||||
registry::char::lookup(devid).ok_or_else(|| {
|
||||
Error::with_message(Errno::EINVAL, "the device ID is invalid or unsupported")
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,3 +127,18 @@ impl FileIo for OpenBlockFile {
|
|||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn lookup(id: DeviceId) -> Option<Arc<dyn Device>> {
|
||||
let block_device = aster_block::lookup(id)?;
|
||||
|
||||
let mut registry = DEVICE_REGISTRY.lock();
|
||||
let block_device_file = registry
|
||||
.entry(id.to_raw())
|
||||
.or_insert_with(move || Arc::new(BlockFile::new(block_device)))
|
||||
.clone();
|
||||
Some(block_device_file)
|
||||
}
|
||||
|
||||
// TODO: Merge the two mapping tables, one is here and the other is in the block component.
|
||||
// Maintaining two mapping tables is undesirable due to duplication and (potential) inconsistency.
|
||||
static DEVICE_REGISTRY: Mutex<BTreeMap<u32, Arc<dyn Device>>> = Mutex::new(BTreeMap::new());
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ pub fn collect_all() -> Vec<Arc<dyn Device>> {
|
|||
}
|
||||
|
||||
/// Looks up a char device of a given device ID.
|
||||
pub fn lookup(id: DeviceId) -> Option<Arc<dyn Device>> {
|
||||
pub(super) fn lookup(id: DeviceId) -> Option<Arc<dyn Device>> {
|
||||
DEVICE_REGISTRY.lock().get(&id.to_raw()).cloned()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use crate::{fs::fs_resolver::FsResolver, prelude::*};
|
||||
use device_id::DeviceId;
|
||||
|
||||
use crate::{
|
||||
fs::{
|
||||
device::{Device, DeviceType},
|
||||
fs_resolver::FsResolver,
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
mod block;
|
||||
pub(super) mod char;
|
||||
|
|
@ -15,3 +23,10 @@ pub(super) fn init_in_first_process(fs_resolver: &FsResolver) -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn lookup(device_type: DeviceType, device_id: DeviceId) -> Option<Arc<dyn Device>> {
|
||||
match device_type {
|
||||
DeviceType::Char => char::lookup(device_id),
|
||||
DeviceType::Block => block::lookup(device_id),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use core::time::Duration;
|
|||
use device_id::DeviceId;
|
||||
|
||||
use crate::{
|
||||
device::get_device,
|
||||
device,
|
||||
fs::{
|
||||
ext2::{FilePerm, Inode as Ext2Inode},
|
||||
inode_handle::FileIo,
|
||||
|
|
@ -131,12 +131,24 @@ impl Inode for Ext2Inode {
|
|||
status_flags: StatusFlags,
|
||||
) -> Option<Result<Box<dyn FileIo>>> {
|
||||
match self.inode_type() {
|
||||
InodeType::BlockDevice | InodeType::CharDevice => {
|
||||
inode_type @ (InodeType::BlockDevice | InodeType::CharDevice) => {
|
||||
let device_id = self.device_id();
|
||||
let device = match get_device(DeviceId::from_encoded_u64(device_id)) {
|
||||
Ok(device) => device,
|
||||
Err(e) => return Some(Err(e)),
|
||||
if device_id == 0 {
|
||||
return Some(Err(Error::with_message(
|
||||
Errno::ENODEV,
|
||||
"the device of ID 0 does not exist",
|
||||
)));
|
||||
}
|
||||
let device_type = inode_type.as_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())
|
||||
}
|
||||
InodeType::NamedPipe => Some(self.open_named_pipe(access_mode, status_flags)),
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@ impl InodeType {
|
|||
Self::try_from(mode & TYPE_MASK)
|
||||
.map_err(|_| Error::with_message(Errno::EINVAL, "invalid file type"))
|
||||
}
|
||||
|
||||
pub fn as_device_type(&self) -> Option<DeviceType> {
|
||||
match self {
|
||||
InodeType::BlockDevice => Some(DeviceType::Block),
|
||||
InodeType::CharDevice => Some(DeviceType::Char),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DeviceType> for InodeType {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use device_id::DeviceId;
|
|||
|
||||
use super::SyscallReturn;
|
||||
use crate::{
|
||||
device::get_device,
|
||||
fs,
|
||||
device,
|
||||
fs::{
|
||||
self,
|
||||
file_table::FileDesc,
|
||||
fs_resolver::{FsPath, AT_FDCWD},
|
||||
utils::{InodeMode, InodeType, MknodType},
|
||||
|
|
@ -49,7 +49,9 @@ pub fn sys_mknodat(
|
|||
let _ = dir_path.new_fs_child(&name, InodeType::File, inode_mode)?;
|
||||
}
|
||||
InodeType::CharDevice | InodeType::BlockDevice => {
|
||||
let device_inode = get_device(DeviceId::from_encoded_u64(dev as u64))?;
|
||||
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::NamedPipe => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue