Skip to content

Commit

Permalink
refactor(mountpoint): making the implementation sound
Browse files Browse the repository at this point in the history
  • Loading branch information
llenotre committed Aug 27, 2024
1 parent ec5c9d6 commit 08ea5b6
Show file tree
Hide file tree
Showing 17 changed files with 229 additions and 295 deletions.
23 changes: 9 additions & 14 deletions kernel/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl fmt::Display for DeviceType {
}

/// A device type, major and minor, who act as a unique ID for a device.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct DeviceID {
/// The type of the device.
pub dev_type: DeviceType,
Expand Down Expand Up @@ -335,15 +335,11 @@ static DEVICES: Mutex<HashMap<DeviceID, Arc<Device>>> = Mutex::new(HashMap::new(
///
/// If files management is initialized, the function creates the associated device file.
pub fn register(device: Device) -> EResult<()> {
let id = device.id.clone();
let id = device.id;
let path = device.get_path().to_path_buf()?;
let mode = device.get_mode();
// Insert
{
let dev = Arc::new(device)?;
let mut devs = DEVICES.lock();
devs.insert(id.clone(), dev)?;
}
DEVICES.lock().insert(id, Arc::new(device)?)?;
// Create file if files management has been initialized
if file::is_init() {
Device::create_file(&id, &path, mode)?;
Expand Down Expand Up @@ -406,13 +402,12 @@ pub(crate) fn stage2() -> EResult<()> {
default::create().unwrap_or_else(|e| panic!("Failed to create default devices! ({e})"));
// Collecting all data to create device files is necessary to avoid a deadlock, because disk
// accesses require locking the filesystem's device
let devs_info = {
let devs = DEVICES.lock();
devs.iter()
.map(|(id, dev)| Ok((id.clone(), dev.path.try_clone()?, dev.mode)))
.collect::<AllocResult<CollectResult<Vec<_>>>>()?
.0?
};
let devs_info = DEVICES
.lock()
.iter()
.map(|(id, dev)| Ok((*id, dev.path.try_clone()?, dev.mode)))
.collect::<AllocResult<CollectResult<Vec<_>>>>()?
.0?;
for (id, path, mode) in devs_info {
Device::create_file(&id, &path, mode)?;
}
Expand Down
16 changes: 6 additions & 10 deletions kernel/src/file/fs/ext2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ impl NodeOps for Ext2NodeOps {
fn write_content(&self, loc: &FileLocation, off: u64, buf: &[u8]) -> EResult<usize> {
let fs = loc.get_filesystem().unwrap();
let fs = downcast_fs::<Ext2Fs>(&*fs);
if unlikely(fs.is_readonly()) {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
if loc.inode < 1 {
Expand All @@ -330,7 +330,7 @@ impl NodeOps for Ext2NodeOps {
fn truncate_content(&self, loc: &FileLocation, size: u64) -> EResult<()> {
let fs = loc.get_filesystem().unwrap();
let fs = downcast_fs::<Ext2Fs>(&*fs);
if unlikely(fs.is_readonly()) {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
if loc.inode < 1 {
Expand Down Expand Up @@ -394,7 +394,7 @@ impl NodeOps for Ext2NodeOps {
) -> EResult<(INode, Box<dyn NodeOps>)> {
let fs = parent.get_filesystem().unwrap();
let fs = downcast_fs::<Ext2Fs>(&*fs);
if unlikely(fs.is_readonly()) {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
if parent.inode < 1 {
Expand Down Expand Up @@ -480,7 +480,7 @@ impl NodeOps for Ext2NodeOps {
fn link(&self, parent: &FileLocation, name: &[u8], target: INode) -> EResult<()> {
let fs = parent.get_filesystem().unwrap();
let fs = downcast_fs::<Ext2Fs>(&*fs);
if unlikely(fs.is_readonly()) {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
if parent.inode < 1 {
Expand Down Expand Up @@ -525,7 +525,7 @@ impl NodeOps for Ext2NodeOps {
fn unlink(&self, parent: &FileLocation, name: &[u8]) -> EResult<()> {
let fs = parent.get_filesystem().unwrap();
let fs = downcast_fs::<Ext2Fs>(&*fs);
if unlikely(fs.is_readonly()) {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
if parent.inode < 1 {
Expand Down Expand Up @@ -565,7 +565,7 @@ impl NodeOps for Ext2NodeOps {
fn remove_file(&self, loc: &FileLocation) -> EResult<()> {
let fs = loc.get_filesystem().unwrap();
let fs = downcast_fs::<Ext2Fs>(&*fs);
if unlikely(fs.is_readonly()) {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
if loc.inode < 1 {
Expand Down Expand Up @@ -1074,10 +1074,6 @@ impl Filesystem for Ext2Fs {
b"ext2"
}

fn is_readonly(&self) -> bool {
self.readonly
}

fn use_cache(&self) -> bool {
true
}
Expand Down
2 changes: 0 additions & 2 deletions kernel/src/file/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,6 @@ pub trait NodeOps: Debug {
pub trait Filesystem: Any + Debug {
/// Returns the name of the filesystem.
fn get_name(&self) -> &[u8];
/// Tells whether the filesystem is mounted in read-only.
fn is_readonly(&self) -> bool;
/// Tells the kernel can cache the filesystem's files in memory.
fn use_cache(&self) -> bool;
/// Returns the root inode of the filesystem.
Expand Down
4 changes: 0 additions & 4 deletions kernel/src/file/fs/proc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,6 @@ impl Filesystem for ProcFS {
b"proc"
}

fn is_readonly(&self) -> bool {
true
}

fn use_cache(&self) -> bool {
false
}
Expand Down
12 changes: 6 additions & 6 deletions kernel/src/file/fs/proc/proc_dir/cwd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ impl NodeOps for Cwd {
}

fn read_content(&self, _loc: &FileLocation, off: u64, buf: &mut [u8]) -> EResult<usize> {
let cwd = Process::get_by_pid(self.0)
.ok_or_else(|| errno!(ENOENT))?
.lock()
.cwd
.clone();
let cwd = vfs::Entry::get_path(cwd)?;
let cwd = vfs::Entry::get_path(
&Process::get_by_pid(self.0)
.ok_or_else(|| errno!(ENOENT))?
.lock()
.cwd,
)?;
format_content!(off, buf, "{}", DisplayableStr(cwd.as_bytes()))
}
}
10 changes: 7 additions & 3 deletions kernel/src/file/fs/proc/proc_dir/mounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use crate::{
file::{
fs::{proc::get_proc_owner, NodeOps},
vfs,
vfs::mountpoint,
FileLocation, FileType, Stat,
},
Expand Down Expand Up @@ -58,15 +59,18 @@ impl NodeOps for Mounts {

impl fmt::Display for Mounts {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mountpoints = mountpoint::MOUNT_POINTS.lock();
for (_, mp) in mountpoints.iter() {
let mps = mountpoint::MOUNT_POINTS.lock();
for (_, mp) in mps.iter() {
let Ok(target) = vfs::Entry::get_path(&mp.root_entry) else {
continue;
};
let fs_type = mp.fs.get_name();
let flags = "TODO"; // TODO
writeln!(
f,
"{source} {target} {fs_type} {flags} 0 0",
source = mp.source,
target = mp.target_path,
target = target,
fs_type = DisplayableStr(fs_type)
)?;
}
Expand Down
13 changes: 5 additions & 8 deletions kernel/src/file/fs/tmp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use crate::{
};
use core::{
cmp::{max, min},
intrinsics::unlikely,
mem::size_of,
};
use utils::{
Expand Down Expand Up @@ -327,7 +328,7 @@ impl NodeOps for Node {
) -> EResult<(INode, Box<dyn NodeOps>)> {
let fs = parent.get_filesystem().unwrap();
let fs = downcast_fs::<TmpFS>(&*fs);
if fs.is_readonly() {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
let entry_type = stat.get_type().ok_or_else(|| errno!(EINVAL))?;
Expand Down Expand Up @@ -365,7 +366,7 @@ impl NodeOps for Node {
fn link(&self, parent: &FileLocation, name: &[u8], inode: INode) -> EResult<()> {
let fs = parent.get_filesystem().unwrap();
let fs = downcast_fs::<TmpFS>(&*fs);
if fs.is_readonly() {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
// Get node
Expand Down Expand Up @@ -396,7 +397,7 @@ impl NodeOps for Node {
fn unlink(&self, parent: &FileLocation, name: &[u8]) -> EResult<()> {
let fs = parent.get_filesystem().unwrap();
let fs = downcast_fs::<TmpFS>(&*fs);
if fs.is_readonly() {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
let mut parent_inner = self.0.lock();
Expand Down Expand Up @@ -438,7 +439,7 @@ impl NodeOps for Node {
fn remove_file(&self, loc: &FileLocation) -> EResult<()> {
let fs = loc.get_filesystem().unwrap();
let fs = downcast_fs::<TmpFS>(&*fs);
if fs.is_readonly() {
if unlikely(fs.readonly) {
return Err(errno!(EROFS));
}
let mut nodes = fs.nodes.lock();
Expand Down Expand Up @@ -502,10 +503,6 @@ impl Filesystem for TmpFS {
b"tmpfs"
}

fn is_readonly(&self) -> bool {
self.readonly
}

fn use_cache(&self) -> bool {
false
}
Expand Down
19 changes: 3 additions & 16 deletions kernel/src/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ use crate::{
file::{
buffer::{Buffer, BufferOps},
fs::{Filesystem, NodeOps},
path::PathBuf,
perm::{Gid, Uid},
},
syscall::ioctl,
Expand Down Expand Up @@ -767,30 +766,18 @@ impl<'f> Iterator for DirEntryIterator<'f> {
pub(crate) fn init(root: Option<(u32, u32)>) -> EResult<()> {
fs::register_defaults()?;
// Create the root mountpoint
let mount_source = match root {
let source = match root {
Some((major, minor)) => MountSource::Device(DeviceID {
dev_type: DeviceType::Block,
major,
minor,
}),
None => MountSource::NoDev(String::try_from(b"tmpfs")?),
};
let mp = mountpoint::create(
mount_source,
None,
0,
PathBuf::root()?,
FileLocation::nowhere(),
)?;
let root = mountpoint::create_root(source)?;
// Init the VFS's root entry.
let root_location = mp.get_root_location();
let ops = mp.fs.node_from_inode(root_location.inode)?;
let ent = Arc::new(vfs::Entry::from_node(Arc::new(Node {
location: root_location,
ops,
})?))?;
unsafe {
vfs::ROOT.init(ent);
vfs::ROOT.init(root);
}
Ok(())
}
Expand Down
Loading

0 comments on commit 08ea5b6

Please sign in to comment.