Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/libxernel/src/sync/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use self::once::Once;
pub use self::rwlock::{ReadGuard, RwLock, WriteGuard};
pub use self::spin::{SpinlockGuard, Spinlock};
pub use self::spin::{Spinlock, SpinlockGuard};

mod once;
mod rwlock;
Expand Down
2 changes: 1 addition & 1 deletion crates/libxernel/src/sync/spin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core::{
use crate::on_drop::OnDrop;

#[cfg(feature = "kernel")]
use crate::ipl::{raise_ipl, splx, IPL};
use crate::ipl::{IPL, raise_ipl, splx};

/// Simple data locking structure using a spin loop.
///
Expand Down
2 changes: 1 addition & 1 deletion crates/libxernel/src/sync/spinirq.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::sync::Spinlock;
use core::arch::asm;
use core::ops::{Deref, DerefMut};
use core::sync::atomic::{compiler_fence, Ordering};
use core::sync::atomic::{Ordering, compiler_fence};

use super::SpinlockGuard;

Expand Down
Empty file added kernel/src/fs/direntry.rs
Empty file.
1 change: 1 addition & 0 deletions kernel/src/fs/initramfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ pub fn load_initramfs() {
pub fn initramfs_read(path: &str) -> Option<Vec<u8>> {
initramfs.lock().get(&path.to_string()).cloned()
}
// TODO: Add initramfs folder to archive and pass it to limine. Parse the archive here and add the folder and files to the tmpfs
18 changes: 16 additions & 2 deletions kernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! The design and implementation of this virtual file system is heavily influenced by BSD.

use core::{error::Error, fmt::Display};

#[derive(Debug)]
pub enum Error {
pub enum VfsError {
VNodeNotFound,
NotADirectory,
IsADirectory,
Expand All @@ -12,7 +14,15 @@ pub enum Error {
FileSystemNotFound,
}

pub type Result<T, E = Error> = core::result::Result<T, E>;
impl Display for VfsError {
fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
todo!()
}
}

impl Error for VfsError {}

pub type Result<T, E = VfsError> = core::result::Result<T, E>;

pub mod file;
pub mod initramfs;
Expand All @@ -22,3 +32,7 @@ pub mod tmpfs;
pub mod vfs;
pub mod vfs_syscalls;
pub mod vnode;

// todo: create fs init function which initializes vfs and initramfs

pub fn init() {}
44 changes: 3 additions & 41 deletions kernel/src/fs/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ impl Mount {
self.mnt_op_data.lock().vfs_root()
}

pub fn vfs_quotactl(&self) {
self.mnt_op_data.lock().vfs_quotactl()
}

pub fn vfs_statvfs(&self) {
self.mnt_op_data.lock().vfs_statvfs()
}
Expand All @@ -60,14 +56,6 @@ impl Mount {
self.mnt_op_data.lock().vfs_lookup(path)
}

pub fn vfs_fhtovp(&self) {
self.mnt_op_data.lock().vfs_fhtovp()
}

pub fn vfs_vptofh(&self) {
self.mnt_op_data.lock().vfs_vptofh()
}

pub fn vfs_init(&mut self) {
self.mnt_op_data.lock().vfs_init()
}
Expand All @@ -76,10 +64,6 @@ impl Mount {
self.mnt_op_data.lock().vfs_done()
}

pub fn vfs_extattrctl(&self) {
self.mnt_op_data.lock().vfs_extattrctl()
}

pub fn vfs_name(&self) -> String {
self.mnt_op_data.lock().vfs_name()
}
Expand All @@ -100,14 +84,9 @@ pub trait VfsOps {
/// Gets the file system root vnode.
fn vfs_root(&self) -> Result<Arc<Spinlock<VNode>>>;

/// Queries or modifies space quotas.
fn vfs_quotactl(&self) {
unimplemented!("{} does not implement vfs_quotactl", self.vfs_name());
}

/// Gets file system statistics.
fn vfs_statvfs(&self) {
unimplemented!("{} does not implement vfs_statvfs", self.vfs_name());
todo!("{} does not implement vfs_statvfs", self.vfs_name());
}

/// Flushes file system buffers.
Expand All @@ -118,37 +97,20 @@ pub trait VfsOps {

fn vfs_lookup(&self, path: &PathBuf) -> Result<Arc<Spinlock<VNode>>>;

/// Converts a NFS file handle to a vnode.
fn vfs_fhtovp(&self) {
unimplemented!("{} does not implement vfs_fhtovp", self.vfs_name());
}

/// Converts a vnode to a NFS file handle.
fn vfs_vptofh(&self) {
unimplemented!("{} does not implement vfs_vptofh", self.vfs_name());
}

/// Initializes the file system driver.
fn vfs_init(&mut self);

/// Reinitializes the file system driver.
fn vfs_reinit(&self) {
unimplemented!("{} does not implement vfs_reinit", self.vfs_name());
todo!("{} does not implement vfs_reinit", self.vfs_name());
}

/// Finalizes the file system driver.
fn vfs_done(&self);

/// Mounts an instance of the file system as the root file system.
fn vfs_mountroot(&self) {
unimplemented!("{} does not implement vfs_mountroot", self.vfs_name());
}

/// Controls extended attributes.
// The generic vfs_stdextattrctl function is provided as a simple hook for file system that do not support this operation
// TODO: create a generic vfs_stdextattrctl function
fn vfs_extattrctl(&self) {
unimplemented!("{} does not implement vfs_extattrctl", self.vfs_name());
todo!("{} does not implement vfs_mountroot", self.vfs_name());
}

/// Returns the name of the file system
Expand Down
30 changes: 15 additions & 15 deletions kernel/src/fs/tmpfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use alloc::{
};
use libxernel::{boot::InitAtBoot, sync::Spinlock};

use crate::{fs::Error, fs::Result};
use crate::{fs::Result, fs::VfsError};

use super::{
mount::{Mount, VfsOps},
Expand Down Expand Up @@ -91,8 +91,8 @@ impl VfsOps for Tmpfs {
}

enum TmpfsNodeData {
Children(Vec<(PathBuf, Arc<Spinlock<VNode>>)>),
Data(Vec<u8>),
Directory(Vec<(PathBuf, Arc<Spinlock<VNode>>)>),
File(Vec<u8>),
}

pub struct TmpfsNode {
Expand All @@ -105,12 +105,12 @@ impl TmpfsNode {
if vtype == VType::Directory {
Self {
parent: None,
data: TmpfsNodeData::Children(Vec::new()),
data: TmpfsNodeData::Directory(Vec::new()),
}
} else {
Self {
parent: None,
data: TmpfsNodeData::Data(Vec::new()),
data: TmpfsNodeData::File(Vec::new()),
}
}
}
Expand All @@ -134,10 +134,10 @@ impl VNodeOperations for TmpfsNode {
None,
)));

if let TmpfsNodeData::Children(children) = &mut self.data {
if let TmpfsNodeData::Directory(children) = &mut self.data {
children.push((PathBuf::from(file_name), new_node.clone()));
} else {
return Err(Error::NotADirectory);
return Err(VfsError::NotADirectory);
}

Ok(new_node)
Expand All @@ -158,14 +158,14 @@ impl VNodeOperations for TmpfsNode {

let components = stripped_path.components();

if let TmpfsNodeData::Children(children) = &self.data {
if let TmpfsNodeData::Directory(children) = &self.data {
match components.len().cmp(&1) {
core::cmp::Ordering::Equal => {
let node = children
.iter()
.find(|(pt, _)| pt == components[0])
.map(|(_, node)| node.clone());
node.ok_or(Error::EntryNotFound)
node.ok_or(VfsError::EntryNotFound)
}
core::cmp::Ordering::Greater => {
let node = children
Expand All @@ -176,13 +176,13 @@ impl VNodeOperations for TmpfsNode {
if let Some(node) = node {
return node.lock().lookup(&stripped_path);
} else {
Err(Error::EntryNotFound)
Err(VfsError::EntryNotFound)
}
}
core::cmp::Ordering::Less => todo!(),
}
} else {
Err(Error::NotADirectory)
Err(VfsError::NotADirectory)
}
}

Expand All @@ -195,19 +195,19 @@ impl VNodeOperations for TmpfsNode {
}

fn read(&self, buf: &mut [u8]) -> Result<usize> {
if let TmpfsNodeData::Data(data) = &self.data {
if let TmpfsNodeData::File(data) = &self.data {
let max_read = if buf.len() > data.len() { data.len() } else { buf.len() };

buf[..max_read].copy_from_slice(&data[..max_read]);

Ok(max_read)
} else {
Err(Error::IsADirectory)
Err(VfsError::IsADirectory)
}
}

fn write(&mut self, buf: &mut [u8]) -> Result<usize> {
if let TmpfsNodeData::Data(data) = &mut self.data {
if let TmpfsNodeData::File(data) = &mut self.data {
data.resize(data.len() + buf.len(), 0);

let max_write = if buf.len() > data.len() { data.len() } else { buf.len() };
Expand All @@ -218,7 +218,7 @@ impl VNodeOperations for TmpfsNode {

Ok(max_write)
} else {
Err(Error::IsADirectory)
Err(VfsError::IsADirectory)
}
}

Expand Down
13 changes: 7 additions & 6 deletions kernel/src/fs/vfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ use super::{
pathbuf::PathBuf,
tmpfs::Tmpfs,
vnode::VNode,
{Error, Result},
{Result, VfsError},
};

pub static VFS: Spinlock<Vfs> = Spinlock::new(Vfs::new());

// FIXME: Move global vfs spinlock to smaller spinlocks in the vfs struct itself
pub struct Vfs {
mount_point_list: Vec<(PathBuf, Arc<Spinlock<Mount>>)>,
drivers: Vec<(String, Arc<Spinlock<dyn VfsOps>>)>,
Expand Down Expand Up @@ -45,7 +46,7 @@ impl Vfs {
.iter()
.find(|(pt, _)| pt == mounted_on)
.map(|(_, mnt)| mnt)
.ok_or(Error::MountPointNotFound)
.ok_or(VfsError::MountPointNotFound)
.cloned()
}

Expand All @@ -59,7 +60,7 @@ impl Vfs {
.iter()
.find(|(name, _)| name == name_of_fs)
.map(|(_, driver)| driver)
.ok_or(Error::FileSystemNotFound)?;
.ok_or(VfsError::FileSystemNotFound)?;

let node_covered = if where_to_mount == "/" {
None
Expand All @@ -68,7 +69,7 @@ impl Vfs {
if let Ok(node) = self.lookuppn(where_to_mount.to_string()) {
Some(node)
} else {
return Err(Error::EntryNotFound);
return Err(VfsError::EntryNotFound);
}
};

Expand Down Expand Up @@ -98,7 +99,7 @@ impl Vfs {
.iter()
.find(|(pt, _)| pt == mnt_point)
.map(|(_, mnt)| mnt)
.ok_or(Error::MountPointNotFound)?;
.ok_or(VfsError::MountPointNotFound)?;

mnt.lock().vfs_lookup(&path.strip_prefix(mnt_point))
}
Expand All @@ -110,7 +111,7 @@ impl Vfs {
.filter(|(pt, _)| path.starts_with(pt))
.max_by_key(|(pt, _)| pt.len())
.map(|(pt, _)| pt)
.ok_or(Error::MountPointNotFound)?;
.ok_or(VfsError::MountPointNotFound)?;

Ok(mnt_point)
}
Expand Down
3 changes: 3 additions & 0 deletions kernel/src/fs/vfs_syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use super::{file::File, vfs::VFS};
pub fn sys_open(path: String, mode: u64) -> Result<isize> {
let vfs = VFS.lock();

// FIXME: If vfs gets locked here whenever a file system syscall is issued, two files could
// never get processed by two differenct processes, which should be possible

let node = vfs.vn_open(path, mode)?;

let file_handle = File::new(node);
Expand Down
Loading