diff --git a/crates/libxernel/src/sync/mod.rs b/crates/libxernel/src/sync/mod.rs index 46ae7dc..05a31f4 100644 --- a/crates/libxernel/src/sync/mod.rs +++ b/crates/libxernel/src/sync/mod.rs @@ -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; diff --git a/crates/libxernel/src/sync/spin.rs b/crates/libxernel/src/sync/spin.rs index d1b359c..4e176c7 100644 --- a/crates/libxernel/src/sync/spin.rs +++ b/crates/libxernel/src/sync/spin.rs @@ -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. /// diff --git a/crates/libxernel/src/sync/spinirq.rs b/crates/libxernel/src/sync/spinirq.rs index e25587f..57bdc72 100644 --- a/crates/libxernel/src/sync/spinirq.rs +++ b/crates/libxernel/src/sync/spinirq.rs @@ -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; diff --git a/kernel/src/fs/direntry.rs b/kernel/src/fs/direntry.rs new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/fs/initramfs.rs b/kernel/src/fs/initramfs.rs index 2c5bf15..e26502f 100644 --- a/kernel/src/fs/initramfs.rs +++ b/kernel/src/fs/initramfs.rs @@ -42,3 +42,4 @@ pub fn load_initramfs() { pub fn initramfs_read(path: &str) -> Option> { 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 diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 4ef1d57..4f6398f 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -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, @@ -12,7 +14,15 @@ pub enum Error { FileSystemNotFound, } -pub type Result = core::result::Result; +impl Display for VfsError { + fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + todo!() + } +} + +impl Error for VfsError {} + +pub type Result = core::result::Result; pub mod file; pub mod initramfs; @@ -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() {} diff --git a/kernel/src/fs/mount.rs b/kernel/src/fs/mount.rs index b67c528..b2e079b 100644 --- a/kernel/src/fs/mount.rs +++ b/kernel/src/fs/mount.rs @@ -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() } @@ -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() } @@ -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() } @@ -100,14 +84,9 @@ pub trait VfsOps { /// Gets the file system root vnode. fn vfs_root(&self) -> Result>>; - /// 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. @@ -118,22 +97,12 @@ pub trait VfsOps { fn vfs_lookup(&self, path: &PathBuf) -> Result>>; - /// 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. @@ -141,14 +110,7 @@ pub trait VfsOps { /// 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 diff --git a/kernel/src/fs/tmpfs.rs b/kernel/src/fs/tmpfs.rs index f5cce31..cd23356 100644 --- a/kernel/src/fs/tmpfs.rs +++ b/kernel/src/fs/tmpfs.rs @@ -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}, @@ -91,8 +91,8 @@ impl VfsOps for Tmpfs { } enum TmpfsNodeData { - Children(Vec<(PathBuf, Arc>)>), - Data(Vec), + Directory(Vec<(PathBuf, Arc>)>), + File(Vec), } pub struct TmpfsNode { @@ -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()), } } } @@ -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) @@ -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 @@ -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) } } @@ -195,19 +195,19 @@ impl VNodeOperations for TmpfsNode { } fn read(&self, buf: &mut [u8]) -> Result { - 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 { - 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() }; @@ -218,7 +218,7 @@ impl VNodeOperations for TmpfsNode { Ok(max_write) } else { - Err(Error::IsADirectory) + Err(VfsError::IsADirectory) } } diff --git a/kernel/src/fs/vfs.rs b/kernel/src/fs/vfs.rs index c78ee51..7229e64 100644 --- a/kernel/src/fs/vfs.rs +++ b/kernel/src/fs/vfs.rs @@ -12,11 +12,12 @@ use super::{ pathbuf::PathBuf, tmpfs::Tmpfs, vnode::VNode, - {Error, Result}, + {Result, VfsError}, }; pub static VFS: Spinlock = 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>)>, drivers: Vec<(String, Arc>)>, @@ -45,7 +46,7 @@ impl Vfs { .iter() .find(|(pt, _)| pt == mounted_on) .map(|(_, mnt)| mnt) - .ok_or(Error::MountPointNotFound) + .ok_or(VfsError::MountPointNotFound) .cloned() } @@ -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 @@ -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); } }; @@ -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)) } @@ -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) } diff --git a/kernel/src/fs/vfs_syscalls.rs b/kernel/src/fs/vfs_syscalls.rs index 046b9e2..bd5e33f 100644 --- a/kernel/src/fs/vfs_syscalls.rs +++ b/kernel/src/fs/vfs_syscalls.rs @@ -7,6 +7,9 @@ use super::{file::File, vfs::VFS}; pub fn sys_open(path: String, mode: u64) -> Result { 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); diff --git a/kernel/src/fs/vnode.rs b/kernel/src/fs/vnode.rs index 498aaef..ee5ae63 100644 --- a/kernel/src/fs/vnode.rs +++ b/kernel/src/fs/vnode.rs @@ -53,16 +53,12 @@ impl VNode { } impl VNode { - pub fn close(&self) { - self.v_data_op.lock().close(); - } - pub fn access(&self) { self.v_data_op.lock().access() } - pub fn bmap(&self) { - self.v_data_op.lock().bmap() + pub fn close(&self) { + self.v_data_op.lock().close(); } pub fn create(&mut self, path: String, v_type: VType) -> Result>> { @@ -101,10 +97,6 @@ impl VNode { self.v_data_op.lock().open() } - pub fn pathconf(&self) { - self.v_data_op.lock().pathconf() - } - pub fn read(&self, buf: &mut [u8]) -> Result { self.v_data_op.lock().read(buf) } @@ -148,10 +140,6 @@ impl VNode { pub fn write(&self, buf: &mut [u8]) -> Result { self.v_data_op.lock().write(buf) } - - pub fn kqfilter(&self) { - self.v_data_op.lock().kqfilter() - } } /// This trait maps logical operations to real functions. It is file system specific as the actions taken by each operation depend heavily on the file system where the file resides. @@ -166,20 +154,6 @@ pub trait VNodeOperations { unimplemented!() } - fn advlock(&self) { - unimplemented!() - } - - /// Maps a logical block number to a physical block number. - fn bmap(&self) { - unimplemented!() - } - - /// Writes a system buffer. - fn bwrite(&self) { - unimplemented!() - } - /// Closes a file. fn close(&self); @@ -213,98 +187,66 @@ pub trait VNodeOperations { fn lookup(&self, path: &PathBuf) -> Result>>; /// Creates a new special file (a device or a named pipe). - fn mknod(&self); + fn mknod(&self) { + unimplemented!(); + } + + /// Map file into user address space + fn mmap(&self) { + unimplemented!(); + } /// Opens a file. fn open(&self); - /// Returns pathconf information. - fn pathconf(&self) { - unimplemented!() - } - /// Reads a chunk of data from a file. fn read(&self, buf: &mut [u8]) -> Result; /// Reads directory entries from a directory. - fn readdir(&self); + fn readdir(&self) { + unimplemented!(); + } /// Reads the contents of a symbolic link. - fn readlink(&self); + fn readlink(&self) { + unimplemented!(); + } /// Reclaims the vnode. - fn reclaim(&self); + fn reclaim(&self) { + unimplemented!(); + } /// Removes a file. - fn remove(&self); + fn remove(&self) { + unimplemented!(); + } /// Renames a file. - fn rename(&self); + fn rename(&self) { + unimplemented!(); + } /// Creates a new directory. - fn mkdir(&self); + fn mkdir(&self) { + unimplemented!(); + } /// Removes a directory. - fn rmdir(&self); + fn rmdir(&self) { + unimplemented!(); + } /// Sets a file's attributes. fn setattr(&self) { unimplemented!() } - /// Performs a file transfer between the file system's backing store and memory. - fn strategy(&self) { - unimplemented!() - } - /// Creates a new symbolic link for a file. - fn symlink(&self); + fn symlink(&self) { + unimplemented!(); + } /// Writes a chunk of data to a file. fn write(&mut self, buf: &mut [u8]) -> Result; - - fn kqfilter(&self) { - unimplemented!() - } - - fn print(&self) { - unimplemented!() - } // OpenBSD has it, NetBSD not?! - - /// Performs a fcntl on a file. - fn fcntl(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Performs a poll on a file. - fn poll(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Revoke access to a vnode and all aliases. - fn revoke(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Maps a file on a memory region. - fn mmap(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Test and inform file system of seek - fn seek(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Truncates a file. - fn truncate(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Updates a file's times. - fn update(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Reads memory pages from the file. - fn getpages(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! - /// Writes memory pages to the file. - fn putpages(&self) { - unimplemented!() - } // NetBSD has it, OpenBSD not?! } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index dc6c65e..fe5dda7 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -18,17 +18,17 @@ use crate::{ mem::mmap::mmap, }; -impl From for SyscallError { - fn from(err: fs::Error) -> SyscallError { +impl From for SyscallError { + fn from(err: fs::VfsError) -> SyscallError { match err { - fs::Error::VNodeNotFound => SyscallError::VNodeNotFound, - fs::Error::NotADirectory => SyscallError::NotADirectory, - fs::Error::IsADirectory => SyscallError::IsADirectory, - fs::Error::NoSpace => SyscallError::NoSpace, - fs::Error::NotEmpty => SyscallError::NotEmpty, - fs::Error::EntryNotFound => SyscallError::EntryNotFound, - fs::Error::MountPointNotFound => SyscallError::MountPointNotFound, - fs::Error::FileSystemNotFound => SyscallError::FileSystemNotFound, + fs::VfsError::VNodeNotFound => SyscallError::VNodeNotFound, + fs::VfsError::NotADirectory => SyscallError::NotADirectory, + fs::VfsError::IsADirectory => SyscallError::IsADirectory, + fs::VfsError::NoSpace => SyscallError::NoSpace, + fs::VfsError::NotEmpty => SyscallError::NotEmpty, + fs::VfsError::EntryNotFound => SyscallError::EntryNotFound, + fs::VfsError::MountPointNotFound => SyscallError::MountPointNotFound, + fs::VfsError::FileSystemNotFound => SyscallError::FileSystemNotFound, } } }