the correctest way (mostly) to do vfs

This commit is contained in:
Zoe
2024-05-22 00:23:27 -05:00
parent fdacc74091
commit b9efc59e49
11 changed files with 424 additions and 358 deletions

View File

@@ -106,6 +106,8 @@ copy-iso-files:
mkdir -p ${ISO_PATH}/boot/limine mkdir -p ${ISO_PATH}/boot/limine
mkdir -p ${ISO_PATH}/EFI/BOOT mkdir -p ${ISO_PATH}/EFI/BOOT
mkdir -p ${ISO_PATH}/mnt
cp -v limine.cfg limine/limine-bios.sys ${ISO_PATH}/boot/limine cp -v limine.cfg limine/limine-bios.sys ${ISO_PATH}/boot/limine
cp -v limine/BOOT${LIMINE_BOOT_VARIATION}.EFI ${ISO_PATH}/EFI/BOOT/ cp -v limine/BOOT${LIMINE_BOOT_VARIATION}.EFI ${ISO_PATH}/EFI/BOOT/
@@ -158,8 +160,6 @@ compile-bootloader:
@if [ ! -d "limine" ]; then \ @if [ ! -d "limine" ]; then \
echo "Cloning Limine into limine/..."; \ echo "Cloning Limine into limine/..."; \
git clone https://github.com/limine-bootloader/limine.git --branch=${LIMINE_BRANCH} --depth=1; \ git clone https://github.com/limine-bootloader/limine.git --branch=${LIMINE_BRANCH} --depth=1; \
else \
echo "Folder limine already exists. Skipping clone."; \
fi fi
make -C limine make -C limine

View File

@@ -103,7 +103,6 @@ exception_function!(0x00, div_error);
exception_function!(0x06, invalid_opcode); exception_function!(0x06, invalid_opcode);
exception_function!(0x08, double_fault); exception_function!(0x08, double_fault);
exception_function!(0x0D, general_protection_fault); exception_function!(0x0D, general_protection_fault);
// TODO: fix the page fault then gracefully return.
exception_function!(0x0E, page_fault); exception_function!(0x0E, page_fault);
exception_function!(0xFF, generic_handler); exception_function!(0xFF, generic_handler);

View File

@@ -95,7 +95,11 @@ pub fn idt_init() {
let mut idt_lock = IDT.lock(); let mut idt_lock = IDT.lock();
IDT_PTR.base = idt_lock.as_ptr() as u64; IDT_PTR.base = idt_lock.as_ptr() as u64;
core::ptr::write_bytes(idt_lock.as_mut_ptr() as *mut core::ffi::c_void, 0, idt_size); core::ptr::write_bytes(
idt_lock.as_mut_ptr().cast::<core::ffi::c_void>(),
0,
idt_size,
);
} }
// Set every interrupt to the "null" interrupt handler (it does nothing) // Set every interrupt to the "null" interrupt handler (it does nothing)

View File

@@ -1,3 +1,5 @@
use core::ptr::NonNull;
use alloc::{ use alloc::{
boxed::Box, boxed::Box,
string::{String, ToString}, string::{String, ToString},
@@ -265,45 +267,6 @@ impl FatFs {
_ => bpb.sectors_per_fat as usize, _ => bpb.sectors_per_fat as usize,
}; };
let bytes_per_fat = 512 * sectors_per_fat;
let mut fat: Option<Arc<[u32]>> = None;
if crate::KERNEL_FEATURES.fat_in_mem {
let cluster_bytes = match fat_type {
FatType::Fat32(_) => 4,
_ => 2,
};
let mut fat_vec: Vec<u32> = Vec::with_capacity(bytes_per_fat / cluster_bytes);
for i in 0..sectors_per_fat {
let sector = partition
.read(fat_start + i as u64, 1)
.expect("Failed to read FAT");
for j in 0..(512 / cluster_bytes) {
match fat_type {
FatType::Fat32(_) => fat_vec.push(u32::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
)),
_ => fat_vec.push(u16::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
) as u32),
}
}
}
fat = Some(Arc::from(fat_vec));
} else {
crate::log_info!(
"\x1B[33mWARNING\x1B[0m: FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower."
)
}
crate::println!("Found {fat_type:?} FS"); crate::println!("Found {fat_type:?} FS");
let cluster_size = bpb.sectors_per_cluster as usize * 512; let cluster_size = bpb.sectors_per_cluster as usize * 512;
@@ -311,7 +274,7 @@ impl FatFs {
return Ok(Self { return Ok(Self {
partition, partition,
fs_info, fs_info,
fat, fat: None,
bpb, bpb,
fat_start, fat_start,
fat_type, fat_type,
@@ -511,17 +474,57 @@ impl FatFs {
} }
impl FsOps for FatFs { impl FsOps for FatFs {
fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfsp: *const super::vfs::Vfs) { fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfsp: NonNull<super::vfs::Vfs>) {
// TODO: load the FAT into memory here let bytes_per_fat = 512 * self.sectors_per_fat;
let mut fat: Option<Arc<[u32]>> = None;
if crate::KERNEL_FEATURES.fat_in_mem {
let cluster_bytes = match self.fat_type {
FatType::Fat32(_) => 4,
_ => 2,
};
let mut fat_vec: Vec<u32> = Vec::with_capacity(bytes_per_fat / cluster_bytes);
for i in 0..self.sectors_per_fat {
let sector = self
.partition
.read(self.fat_start + i as u64, 1)
.expect("Failed to read FAT");
for j in 0..(512 / cluster_bytes) {
match self.fat_type {
FatType::Fat32(_) => fat_vec.push(u32::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
)),
_ => fat_vec.push(u16::from_le_bytes(
sector[j * cluster_bytes..(j * cluster_bytes + cluster_bytes)]
.try_into()
.unwrap(),
) as u32),
}
}
}
fat = Some(Arc::from(fat_vec));
} else {
crate::log_info!(
"\x1B[33mWARNING\x1B[0m: FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower."
)
}
self.fat = fat;
*data = core::ptr::addr_of!(*self) as *mut u8; *data = core::ptr::addr_of!(*self) as *mut u8;
} }
fn unmount(&mut self, _vfsp: *const super::vfs::Vfs) { fn unmount(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
// TODO: unload the FAT form memory self.fat = None;
} }
fn root(&mut self, vfsp: *const super::vfs::Vfs) -> super::vfs::VNode { fn root(&mut self, vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::VNode {
let root_cluster = match self.fat_type { let root_cluster = match self.fat_type {
FatType::Fat32(ebpb) => ebpb.root_dir_cluster as usize, FatType::Fat32(ebpb) => ebpb.root_dir_cluster as usize,
_ => self.sector_to_cluster( _ => self.sector_to_cluster(
@@ -537,22 +540,22 @@ impl FsOps for FatFs {
return VNode::new(Box::new(file), super::vfs::VNodeType::Directory, vfsp); return VNode::new(Box::new(file), super::vfs::VNodeType::Directory, vfsp);
} }
fn fid(&mut self, _path: &str, _vfsp: *const super::vfs::Vfs) -> Option<super::vfs::FileId> { fn fid(&mut self, _path: &str, _vfsp: NonNull<super::vfs::Vfs>) -> Option<super::vfs::FileId> {
todo!("FAT FID"); todo!("FAT FID");
} }
fn statfs(&mut self, _vfsp: *const super::vfs::Vfs) -> super::vfs::StatFs { fn statfs(&mut self, _vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::StatFs {
todo!("FAT STATFS"); todo!("FAT STATFS");
} }
fn sync(&mut self, _vfsp: *const super::vfs::Vfs) { fn sync(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
todo!("FAT SYNC"); todo!("FAT SYNC");
} }
fn vget( fn vget(
&mut self, &mut self,
_fid: super::vfs::FileId, _fid: super::vfs::FileId,
_vfsp: *const super::vfs::Vfs, _vfsp: NonNull<super::vfs::Vfs>,
) -> super::vfs::VNode { ) -> super::vfs::VNode {
todo!("FAT VGET"); todo!("FAT VGET");
} }
@@ -564,19 +567,19 @@ enum File {
} }
impl VNodeOperations for File { impl VNodeOperations for File {
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: *const VNode) { fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: *const VNode) -> super::vfs::VNode { fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn bread(&mut self, _block_number: u32, _vp: *const VNode) -> Arc<[u8]> { fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: *const VNode) { fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -587,20 +590,20 @@ impl VNodeOperations for File {
_e: u32, _e: u32,
_m: u32, _m: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) { fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) -> super::vfs::VAttr { fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) { fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -610,7 +613,7 @@ impl VNodeOperations for File {
_d: *mut u8, _d: *mut u8,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -620,7 +623,7 @@ impl VNodeOperations for File {
_target_dir: *mut super::vfs::VNode, _target_dir: *mut super::vfs::VNode,
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -629,9 +632,9 @@ impl VNodeOperations for File {
&mut self, &mut self,
nm: &str, nm: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
vp: *const VNode, vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
let fat_fs = unsafe { (*(*vp).parent_vfs).data.cast::<FatFs>() }; let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<FatFs>() };
match self { match self {
File::Dir(directory) => unsafe { File::Dir(directory) => unsafe {
@@ -652,7 +655,7 @@ impl VNodeOperations for File {
File::Archive(FatFile { file_entry }) File::Archive(FatFile { file_entry })
}; };
let vnode = VNode::new(Box::new(file), file_typ, (*vp).parent_vfs); let vnode = VNode::new(Box::new(file), file_typ, (*vp.as_ptr()).parent_vfs);
Ok(vnode) Ok(vnode)
}, },
@@ -665,7 +668,7 @@ impl VNodeOperations for File {
_nm: &str, _nm: &str,
_va: super::vfs::VAttr, _va: super::vfs::VAttr,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -674,11 +677,11 @@ impl VNodeOperations for File {
&mut self, &mut self,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
vp: *const VNode, vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> { ) -> Result<Arc<[u8]>, ()> {
match self { match self {
File::Archive(archive) => { File::Archive(archive) => {
let fat_fs = unsafe { (*(*vp).parent_vfs).data.cast::<FatFs>() }; let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<FatFs>() };
let mut file: Vec<u8> = Vec::with_capacity(archive.file_entry.file_size as usize); let mut file: Vec<u8> = Vec::with_capacity(archive.file_entry.file_size as usize);
let mut file_ptr_index = 0; let mut file_ptr_index = 0;
@@ -746,8 +749,8 @@ impl VNodeOperations for File {
_direction: super::vfs::IODirection, _direction: super::vfs::IODirection,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) -> Result<Arc<[u8]>, ()> {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -755,7 +758,7 @@ impl VNodeOperations for File {
&mut self, &mut self,
_uiop: *const super::vfs::UIO, _uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -764,7 +767,7 @@ impl VNodeOperations for File {
&mut self, &mut self,
_uiop: *const super::vfs::UIO, _uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -775,20 +778,25 @@ impl VNodeOperations for File {
_target_dir: *mut super::vfs::VNode, _target_dir: *mut super::vfs::VNode,
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn select(&mut self, _w: super::vfs::IODirection, _c: super::vfs::UserCred, _vp: *const VNode) { fn select(
&mut self,
_w: super::vfs::IODirection,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: *const VNode) { fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn strategy(&mut self, _bp: (), _vp: *const VNode) { fn strategy(&mut self, _bp: (), _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -798,7 +806,7 @@ impl VNodeOperations for File {
_va: super::vfs::VAttr, _va: super::vfs::VAttr,
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }

View File

@@ -1,7 +1,7 @@
mod chunk_reader; mod chunk_reader;
mod superblock; mod superblock;
use core::{fmt::Debug, mem::MaybeUninit}; use core::{fmt::Debug, mem::MaybeUninit, ptr::NonNull};
use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
use limine::ModuleRequest; use limine::ModuleRequest;
@@ -82,7 +82,7 @@ impl Squashfs<'_> {
// crate::log_info!("Parsing initramfs at {:p}", ptr); // crate::log_info!("Parsing initramfs at {:p}", ptr);
// 40 is the offset for bytes used by the archive in the superblock // 40 is the offset for bytes used by the archive in the superblock
let length = unsafe { u64::from_le(*(ptr.add(40) as *const u64)) as usize }; let length = unsafe { u64::from_le(*(ptr.add(40).cast::<u64>())) as usize };
let squashfs_data: &[u8] = unsafe { core::slice::from_raw_parts(ptr, length) }; let squashfs_data: &[u8] = unsafe { core::slice::from_raw_parts(ptr, length) };
@@ -345,39 +345,39 @@ impl Squashfs<'_> {
} }
impl<'a> FsOps for Squashfs<'a> { impl<'a> FsOps for Squashfs<'a> {
fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfspp: *const super::vfs::Vfs) { fn mount(&mut self, _path: &str, data: &mut *mut u8, _vfsp: NonNull<super::vfs::Vfs>) {
// STUB // STUB
// not recommended:tm: // not recommended:tm:
*data = core::ptr::addr_of!(*self) as *mut u8; *data = core::ptr::addr_of!(*self) as *mut u8;
} }
fn unmount(&mut self, _vfsp: *const super::vfs::Vfs) { fn unmount(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
// STUB // STUB
} }
fn root(&mut self, vfsp: *const super::vfs::Vfs) -> super::vfs::VNode { fn root(&mut self, vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::VNode {
let root_dir = self.read_root_dir(); let root_dir = self.read_root_dir();
return VNode::new(Box::new(root_dir), VNodeType::Directory, vfsp); return VNode::new(Box::new(root_dir), VNodeType::Directory, vfsp);
} }
fn fid(&mut self, _path: &str, _vfspp: *const super::vfs::Vfs) -> Option<super::vfs::FileId> { fn fid(&mut self, _path: &str, _vfsp: NonNull<super::vfs::Vfs>) -> Option<super::vfs::FileId> {
todo!(); todo!();
} }
fn statfs(&mut self, _vfsp: *const super::vfs::Vfs) -> super::vfs::StatFs { fn statfs(&mut self, _vfsp: NonNull<super::vfs::Vfs>) -> super::vfs::StatFs {
todo!(); todo!();
} }
fn sync(&mut self, _vfsp: *const super::vfs::Vfs) { fn sync(&mut self, _vfsp: NonNull<super::vfs::Vfs>) {
todo!(); todo!();
} }
fn vget( fn vget(
&mut self, &mut self,
_fid: super::vfs::FileId, _fid: super::vfs::FileId,
_vfsp: *const super::vfs::Vfs, _vfsp: NonNull<super::vfs::Vfs>,
) -> super::vfs::VNode { ) -> super::vfs::VNode {
todo!(); todo!();
} }
@@ -412,9 +412,9 @@ impl VNodeOperations for Inode {
&mut self, &mut self,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
vp: *const VNode, vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> { ) -> Result<Arc<[u8]>, ()> {
let squashfs = unsafe { (*(*vp).parent_vfs).data.cast::<Squashfs>() }; let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<Squashfs>() };
match self { match self {
Inode::BasicFile(file) => unsafe { Inode::BasicFile(file) => unsafe {
@@ -456,7 +456,7 @@ impl VNodeOperations for Inode {
// And since we are building the array due to unaligned pointer shenanigans we need to // And since we are building the array due to unaligned pointer shenanigans we need to
// include the header bytes otherwise we are short by two bytes // include the header bytes otherwise we are short by two bytes
let fragment_block_size = let fragment_block_size =
(u16::from_le(core::ptr::read_unaligned(fragment_pointer as *mut u16)) (u16::from_le(core::ptr::read_unaligned(fragment_pointer.cast::<u16>()))
& 0x7FFF) & 0x7FFF)
+ 2; + 2;
@@ -498,7 +498,7 @@ impl VNodeOperations for Inode {
} }
} }
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: *const VNode) { fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!() todo!()
} }
@@ -508,8 +508,8 @@ impl VNodeOperations for Inode {
_direction: super::vfs::IODirection, _direction: super::vfs::IODirection,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) -> Result<Arc<[u8]>, ()> {
todo!() todo!()
} }
@@ -519,24 +519,29 @@ impl VNodeOperations for Inode {
_d: *mut u8, _d: *mut u8,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!() todo!()
} }
fn select(&mut self, _w: super::vfs::IODirection, _c: super::vfs::UserCred, _vp: *const VNode) { fn select(
&mut self,
_w: super::vfs::IODirection,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) {
todo!() todo!()
} }
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) -> super::vfs::VAttr { fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
todo!() todo!()
} }
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: *const VNode) { fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!() todo!()
} }
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: *const VNode) { fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!() todo!()
} }
@@ -544,9 +549,11 @@ impl VNodeOperations for Inode {
&mut self, &mut self,
nm: &str, nm: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
vp: *const VNode, vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
let squashfs = unsafe { (*(*vp).parent_vfs).data.cast::<Squashfs>() }; let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<Squashfs>() };
crate::println!("wawawaw");
match self { match self {
Inode::BasicDirectory(_) | Inode::ExtendedDirectory(_) => unsafe { Inode::BasicDirectory(_) | Inode::ExtendedDirectory(_) => unsafe {
@@ -556,7 +563,7 @@ impl VNodeOperations for Inode {
Inode::BasicFile(_) => VNodeType::Regular, Inode::BasicFile(_) => VNodeType::Regular,
}; };
let vnode = VNode::new(Box::new(inode), vnode_type, (*vp).parent_vfs); let vnode = VNode::new(Box::new(inode), vnode_type, (*vp.as_ptr()).parent_vfs);
return Ok(vnode); return Ok(vnode);
}, },
@@ -571,7 +578,7 @@ impl VNodeOperations for Inode {
_e: u32, _e: u32,
_m: u32, _m: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
todo!() todo!()
} }
@@ -581,7 +588,7 @@ impl VNodeOperations for Inode {
_target_dir: *mut super::vfs::VNode, _target_dir: *mut super::vfs::VNode,
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!() todo!()
} }
@@ -592,7 +599,7 @@ impl VNodeOperations for Inode {
_target_dir: *mut super::vfs::VNode, _target_dir: *mut super::vfs::VNode,
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!() todo!()
} }
@@ -602,7 +609,7 @@ impl VNodeOperations for Inode {
_nm: &str, _nm: &str,
_va: super::vfs::VAttr, _va: super::vfs::VAttr,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
todo!() todo!()
} }
@@ -611,7 +618,7 @@ impl VNodeOperations for Inode {
&mut self, &mut self,
_uiop: *const super::vfs::UIO, _uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!() todo!()
} }
@@ -622,7 +629,7 @@ impl VNodeOperations for Inode {
_va: super::vfs::VAttr, _va: super::vfs::VAttr,
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!() todo!()
} }
@@ -631,28 +638,28 @@ impl VNodeOperations for Inode {
&mut self, &mut self,
_uiop: *const super::vfs::UIO, _uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: *const VNode, _vp: NonNull<VNode>,
) { ) {
todo!() todo!()
} }
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) { fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!() todo!()
} }
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: *const VNode) { fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!() todo!()
} }
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: *const VNode) -> super::vfs::VNode { fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode {
todo!() todo!()
} }
fn strategy(&mut self, _bp: (), _vp: *const VNode) { fn strategy(&mut self, _bp: (), _vp: NonNull<VNode>) {
todo!() todo!()
} }
fn bread(&mut self, _block_number: u32, _vp: *const VNode) -> Arc<[u8]> { fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> {
todo!() todo!()
} }
} }

View File

@@ -1,10 +1,9 @@
// is this terrible? God yes, but it works
use core::{fmt::Debug, ptr::NonNull}; use core::{fmt::Debug, ptr::NonNull};
use alloc::{ use alloc::{
alloc::{alloc, dealloc, handle_alloc_error},
boxed::Box, boxed::Box,
collections::BTreeMap,
rc::Rc,
string::{String, ToString}, string::{String, ToString},
sync::Arc, sync::Arc,
vec::Vec, vec::Vec,
@@ -12,108 +11,196 @@ use alloc::{
use crate::{log_info, log_ok}; use crate::{log_info, log_ok};
// TODO: probably keeps excess memory but whatever
struct TreeNode {
vnode: Rc<VNode>,
parent: Option<NonNull<Self>>,
children: BTreeMap<String, Self>,
}
impl TreeNode {
fn new(vnode: VNode) -> Self {
return Self {
vnode: Rc::new(vnode),
parent: None,
children: BTreeMap::new(),
};
}
fn as_ptr(&self) -> NonNull<Self> {
return NonNull::from(self);
}
fn get_vnode(&mut self) -> &mut VNode {
Rc::get_mut(&mut self.vnode).unwrap()
}
fn lookup(&mut self, name: &str) -> Result<&mut Self, ()> {
let parent = Some(self.as_ptr());
crate::println!("looking up {name} in node_tree");
if !self.children.contains_key(name) {
crate::println!("not found in node tree");
let vnode: VNode;
if let Some(mut vfs) = self.vnode.vfs_mounted_here {
crate::println!("using VFS root");
unsafe {
vnode = vfs
.as_mut()
.root()
.lookup(name, UserCred { uid: 0, gid: 0 })?
};
} else {
vnode = Rc::get_mut(&mut self.vnode)
.unwrap()
.lookup(name, UserCred { uid: 0, gid: 0 })?;
}
let child_node = TreeNode {
vnode: Rc::new(vnode),
parent,
children: BTreeMap::new(),
};
self.children.insert(name.to_string(), child_node);
let child = self.children.get_mut(name).unwrap();
return Ok(child);
}
return Ok(self.children.get_mut(name).unwrap());
}
}
static mut NODE_TREE: Option<TreeNode> = None;
static mut ROOT_VFS: Vfs = Vfs::null(); static mut ROOT_VFS: Vfs = Vfs::null();
// TODO: everything being Option to accomodate the stupid null root vfs is getting annoying
#[allow(unused)] #[allow(unused)]
pub struct Vfs { pub struct Vfs {
mount_point: Option<String>, next: Option<Box<Vfs>>,
next: Option<NonNull<Vfs>>, pub fs: Option<Box<dyn FsOps>>,
ops: Option<NonNull<dyn FsOps>>, vnode_covered: Option<NonNull<VNode>>,
// vnode_covered: Option<*const VNode>,
flags: u32, flags: u32,
block_size: u32, block_size: u32,
pub data: *mut u8, pub data: *mut u8,
} }
unsafe impl Sync for Vfs {} impl !Sync for Vfs {}
impl Vfs { impl Vfs {
const fn null() -> Self { const fn null() -> Self {
return Vfs { return Vfs {
mount_point: None,
next: None, next: None,
ops: None, fs: None,
// vnode_covered: None, vnode_covered: None,
flags: 0, flags: 0,
block_size: 0, block_size: 0,
data: core::ptr::null_mut(), data: core::ptr::null_mut(),
}; };
} }
fn as_ptr(&self) -> *const Self { fn add_vfs(&mut self, vfs: Box<Self>) {
core::ptr::addr_of!(*self) let mut current = self;
while let Some(ref mut next_vfs) = current.next {
current = next_vfs;
}
current.next = Some(vfs);
}
fn as_ptr(&self) -> NonNull<Self> {
unsafe { NonNull::new_unchecked(core::ptr::addr_of!(*self) as *mut Self) }
} }
pub fn mount(&mut self, path: &str) { pub fn mount(&mut self, path: &str) {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
let vfsp = self.as_ptr(); let vfsp = self.as_ptr();
unsafe { self.ops.unwrap().as_mut().mount(path, &mut self.data, vfsp) }; self.fs
.as_mut()
.unwrap()
.as_mut()
.mount(path, &mut self.data, vfsp);
} }
pub fn unmount(&mut self) { pub fn unmount(&mut self) {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
unsafe { self.ops.unwrap().as_mut().unmount(self.as_ptr()) }; let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().unmount(vfsp);
} }
pub fn root(&mut self) -> VNode { pub fn root(&mut self) -> VNode {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
unsafe { self.ops.unwrap().as_mut().root(self.as_ptr()) } let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().root(vfsp)
} }
pub fn statfs(&mut self) -> StatFs { pub fn statfs(&mut self) -> StatFs {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
unsafe { self.ops.unwrap().as_mut().statfs(self.as_ptr()) } let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().statfs(vfsp)
} }
pub fn sync(&mut self) { pub fn sync(&mut self) {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
unsafe { self.ops.unwrap().as_mut().sync(self.as_ptr()) }; let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().sync(vfsp);
} }
pub fn fid(&mut self, path: &str) -> Option<FileId> { pub fn fid(&mut self, path: &str) -> Option<FileId> {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
unsafe { self.ops.unwrap().as_mut().fid(path, self.as_ptr()) } let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().fid(path, vfsp)
} }
pub fn vget(&mut self, fid: FileId) -> VNode { pub fn vget(&mut self, fid: FileId) -> VNode {
if self.ops.is_none() { if self.fs.is_none() {
panic!("FsOps is null"); panic!("FsOps is null");
} }
unsafe { self.ops.unwrap().as_mut().vget(fid, self.as_ptr()) } let vfsp = self.as_ptr();
self.fs.as_mut().unwrap().as_mut().vget(fid, vfsp)
} }
} }
pub trait FsOps { pub trait FsOps {
// yes, the vfsp was the best solution I could come up with // yes, the vfsp was the best solution I could come up with
fn mount(&mut self, path: &str, data: &mut *mut u8, vfsp: *const Vfs); fn mount(&mut self, path: &str, data: &mut *mut u8, vfsp: NonNull<Vfs>);
fn unmount(&mut self, vfsp: *const Vfs); fn unmount(&mut self, vfsp: NonNull<Vfs>);
fn root(&mut self, vfsp: *const Vfs) -> VNode; fn root(&mut self, vfsp: NonNull<Vfs>) -> VNode;
fn statfs(&mut self, vfsp: *const Vfs) -> StatFs; fn statfs(&mut self, vfsp: NonNull<Vfs>) -> StatFs;
fn sync(&mut self, vfsp: *const Vfs); fn sync(&mut self, vfsp: NonNull<Vfs>);
fn fid(&mut self, path: &str, vfsp: *const Vfs) -> Option<FileId>; fn fid(&mut self, path: &str, vfsp: NonNull<Vfs>) -> Option<FileId>;
// idk how the fuck you're supposed to accomplish this // idk how the fuck you're supposed to accomplish this
// good luck I guess. // good luck I guess.
fn vget(&mut self, fid: FileId, vfsp: *const Vfs) -> VNode; fn vget(&mut self, fid: FileId, vfsp: NonNull<Vfs>) -> VNode;
} }
#[allow(unused)] #[allow(unused)]
@@ -136,6 +223,7 @@ pub struct StatFs {
} }
#[repr(u8)] #[repr(u8)]
#[derive(PartialEq)]
pub enum VNodeType { pub enum VNodeType {
// Jury is out on this one // Jury is out on this one
NON = 0, NON = 0,
@@ -149,87 +237,95 @@ pub enum VNodeType {
} }
pub struct VNode { pub struct VNode {
// for internal use only
relative_path: String,
pub flags: u16, pub flags: u16,
pub ref_count: u16, inode: Box<dyn VNodeOperations>,
pub shared_lock_count: u16,
pub exclusive_lock_count: u16,
ops: NonNull<dyn VNodeOperations>,
pub node_data: Option<NodeData>, pub node_data: Option<NodeData>,
pub parent_vfs: *const Vfs, pub vfs_mounted_here: Option<NonNull<Vfs>>,
pub typ: VNodeType, pub parent_vfs: NonNull<Vfs>,
pub file_typ: VNodeType,
pub data: *mut u8, pub data: *mut u8,
} }
impl VNode { impl VNode {
pub fn new(ops: Box<dyn VNodeOperations>, file_typ: VNodeType, parent_vfs: *const Vfs) -> Self { pub fn new(
inode: Box<dyn VNodeOperations>,
file_typ: VNodeType,
parent_vfs: NonNull<Vfs>,
) -> Self {
return Self { return Self {
relative_path: "".to_string(),
flags: 0, flags: 0,
ref_count: 0, inode,
shared_lock_count: 0,
exclusive_lock_count: 0,
ops: unsafe { NonNull::new_unchecked(Box::into_raw(ops)) },
node_data: None, node_data: None,
vfs_mounted_here: None,
parent_vfs, parent_vfs,
typ: file_typ, file_typ,
data: core::ptr::null_mut(), data: core::ptr::null_mut(),
}; };
} }
pub fn as_ptr(&self) -> *const VNode { pub fn as_ptr(&self) -> NonNull<VNode> {
core::ptr::addr_of!(*self) unsafe { NonNull::new_unchecked(core::ptr::addr_of!(*self) as *mut Self) }
} }
// Trait functions // Trait functions
pub fn open(&mut self, f: u32, c: UserCred) -> Result<Arc<[u8]>, ()> { pub fn open(&mut self, f: u32, c: UserCred) -> Result<Arc<[u8]>, ()> {
unsafe { self.ops.as_mut().open(f, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().open(f, c, vp)
} }
pub fn close(&mut self, f: u32, c: UserCred) { pub fn close(&mut self, f: u32, c: UserCred) {
unsafe { self.ops.as_mut().close(f, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().close(f, c, vp)
} }
pub fn rdwr(&mut self, uiop: *const UIO, direction: IODirection, f: u32, c: UserCred) { pub fn rdwr(
unsafe { self.ops.as_mut().rdwr(uiop, direction, f, c, self.as_ptr()) } &mut self,
uiop: *const UIO,
direction: IODirection,
f: u32,
c: UserCred,
) -> Result<Arc<[u8]>, ()> {
let vp = self.as_ptr();
self.inode.as_mut().rdwr(uiop, direction, f, c, vp)
} }
pub fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred) { pub fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred) {
unsafe { self.ops.as_mut().ioctl(com, d, f, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().ioctl(com, d, f, c, vp)
} }
pub fn select(&mut self, w: IODirection, c: UserCred) { pub fn select(&mut self, w: IODirection, c: UserCred) {
unsafe { self.ops.as_mut().select(w, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().select(w, c, vp)
} }
pub fn getattr(&mut self, c: UserCred) -> VAttr { pub fn getattr(&mut self, c: UserCred) -> VAttr {
unsafe { self.ops.as_mut().getattr(c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().getattr(c, vp)
} }
pub fn setattr(&mut self, va: VAttr, c: UserCred) { pub fn setattr(&mut self, va: VAttr, c: UserCred) {
unsafe { self.ops.as_mut().setattr(va, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().setattr(va, c, vp)
} }
pub fn access(&mut self, m: u32, c: UserCred) { pub fn access(&mut self, m: u32, c: UserCred) {
unsafe { self.ops.as_mut().access(m, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().access(m, c, vp)
} }
pub fn lookup(&mut self, nm: &str, c: UserCred) -> Result<VNode, ()> { pub fn lookup(&mut self, nm: &str, c: UserCred) -> Result<VNode, ()> {
let mut vnode = unsafe { self.ops.as_mut().lookup(nm, c, self.as_ptr()) }?; let vp = self.as_ptr();
// TODO: the memory cost of this is pretty bad self.inode.as_mut().lookup(nm, c, vp)
vnode.relative_path = self.relative_path.clone() + "/" + nm;
unsafe {
if let Some(mut new_vfs) = vfs_has_mount_point(
&((*self.parent_vfs).mount_point.clone().unwrap() + &vnode.relative_path),
) {
return Ok(new_vfs.as_mut().root());
}
}
return Ok(vnode);
} }
pub fn create( pub fn create(
@@ -240,70 +336,79 @@ impl VNode {
m: u32, m: u32,
c: UserCred, c: UserCred,
) -> Result<VNode, ()> { ) -> Result<VNode, ()> {
unsafe { self.ops.as_mut().create(nm, va, e, m, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().create(nm, va, e, m, c, vp)
} }
pub fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred) { pub fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred) {
unsafe { let vp = self.as_ptr();
self.ops
.as_mut() self.inode.as_mut().link(target_dir, target_name, c, vp)
.link(target_dir, target_name, c, self.as_ptr())
}
} }
pub fn rename(&mut self, nm: &str, target_dir: *mut VNode, target_name: &str, c: UserCred) { pub fn rename(&mut self, nm: &str, target_dir: *mut VNode, target_name: &str, c: UserCred) {
unsafe { let vp = self.as_ptr();
self.ops
.as_mut() self.inode
.rename(nm, target_dir, target_name, c, self.as_ptr()) .as_mut()
} .rename(nm, target_dir, target_name, c, vp)
} }
pub fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred) -> Result<VNode, ()> { pub fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred) -> Result<VNode, ()> {
unsafe { self.ops.as_mut().mkdir(nm, va, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().mkdir(nm, va, c, vp)
} }
pub fn readdir(&mut self, uiop: *const UIO, c: UserCred) { pub fn readdir(&mut self, uiop: *const UIO, c: UserCred) {
unsafe { self.ops.as_mut().readdir(uiop, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().readdir(uiop, c, vp)
} }
pub fn symlink(&mut self, link_name: &str, va: VAttr, target_name: &str, c: UserCred) { pub fn symlink(&mut self, link_name: &str, va: VAttr, target_name: &str, c: UserCred) {
unsafe { let vp = self.as_ptr();
self.ops
.as_mut() self.inode
.symlink(link_name, va, target_name, c, self.as_ptr()) .as_mut()
} .symlink(link_name, va, target_name, c, vp)
} }
pub fn readlink(&mut self, uiop: *const UIO, c: UserCred) { pub fn readlink(&mut self, uiop: *const UIO, c: UserCred) {
unsafe { self.ops.as_mut().readlink(uiop, c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().readlink(uiop, c, vp)
} }
pub fn fsync(&mut self, c: UserCred) { pub fn fsync(&mut self, c: UserCred) {
unsafe { self.ops.as_mut().fsync(c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().fsync(c, vp)
} }
pub fn inactive(&mut self, c: UserCred) { pub fn inactive(&mut self, c: UserCred) {
unsafe { self.ops.as_mut().inactive(c, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().inactive(c, vp)
} }
pub fn bmap(&mut self, block_number: u32, bnp: ()) -> VNode { pub fn bmap(&mut self, block_number: u32, bnp: ()) -> VNode {
unsafe { self.ops.as_mut().bmap(block_number, bnp, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().bmap(block_number, bnp, vp)
} }
pub fn strategy(&mut self, bp: ()) { pub fn strategy(&mut self, bp: ()) {
unsafe { self.ops.as_mut().strategy(bp, self.as_ptr()) } let vp = self.as_ptr();
self.inode.as_mut().strategy(bp, vp)
} }
pub fn bread(&mut self, block_number: u32) -> Arc<[u8]> { pub fn bread(&mut self, block_number: u32) -> Arc<[u8]> {
unsafe { self.ops.as_mut().bread(block_number, self.as_ptr()) } let vp = self.as_ptr();
}
}
impl Drop for VNode { self.inode.as_mut().bread(block_number, vp)
fn drop(&mut self) {
let vnode_ops = unsafe { Box::from_raw(self.ops.as_ptr()) };
drop(vnode_ops)
} }
} }
@@ -347,22 +452,22 @@ pub struct UIO {
} }
pub trait VNodeOperations { pub trait VNodeOperations {
fn open(&mut self, f: u32, c: UserCred, vp: *const VNode) -> Result<Arc<[u8]>, ()>; fn open(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>) -> Result<Arc<[u8]>, ()>;
fn close(&mut self, f: u32, c: UserCred, vp: *const VNode); fn close(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>);
fn rdwr( fn rdwr(
&mut self, &mut self,
uiop: *const UIO, uiop: *const UIO,
direction: IODirection, direction: IODirection,
f: u32, f: u32,
c: UserCred, c: UserCred,
vp: *const VNode, vp: NonNull<VNode>,
); ) -> Result<Arc<[u8]>, ()>;
fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred, vp: *const VNode); fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred, vp: NonNull<VNode>);
fn select(&mut self, w: IODirection, c: UserCred, vp: *const VNode); fn select(&mut self, w: IODirection, c: UserCred, vp: NonNull<VNode>);
fn getattr(&mut self, c: UserCred, vp: *const VNode) -> VAttr; fn getattr(&mut self, c: UserCred, vp: NonNull<VNode>) -> VAttr;
fn setattr(&mut self, va: VAttr, c: UserCred, vp: *const VNode); fn setattr(&mut self, va: VAttr, c: UserCred, vp: NonNull<VNode>);
fn access(&mut self, m: u32, c: UserCred, vp: *const VNode); fn access(&mut self, m: u32, c: UserCred, vp: NonNull<VNode>);
fn lookup(&mut self, nm: &str, c: UserCred, vp: *const VNode) -> Result<VNode, ()>; fn lookup(&mut self, nm: &str, c: UserCred, vp: NonNull<VNode>) -> Result<VNode, ()>;
fn create( fn create(
&mut self, &mut self,
nm: &str, nm: &str,
@@ -370,33 +475,33 @@ pub trait VNodeOperations {
e: u32, e: u32,
m: u32, m: u32,
c: UserCred, c: UserCred,
vp: *const VNode, vp: NonNull<VNode>,
) -> Result<VNode, ()>; ) -> Result<VNode, ()>;
fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred, vp: *const VNode); fn link(&mut self, target_dir: *mut VNode, target_name: &str, c: UserCred, vp: NonNull<VNode>);
fn rename( fn rename(
&mut self, &mut self,
nm: &str, nm: &str,
target_dir: *mut VNode, target_dir: *mut VNode,
target_name: &str, target_name: &str,
c: UserCred, c: UserCred,
vp: *const VNode, vp: NonNull<VNode>,
); );
fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred, vp: *const VNode) -> Result<VNode, ()>; fn mkdir(&mut self, nm: &str, va: VAttr, c: UserCred, vp: NonNull<VNode>) -> Result<VNode, ()>;
fn readdir(&mut self, uiop: *const UIO, c: UserCred, vp: *const VNode); fn readdir(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull<VNode>);
fn symlink( fn symlink(
&mut self, &mut self,
link_name: &str, link_name: &str,
va: VAttr, va: VAttr,
target_name: &str, target_name: &str,
c: UserCred, c: UserCred,
vp: *const VNode, vp: NonNull<VNode>,
); );
fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: *const VNode); fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull<VNode>);
fn fsync(&mut self, c: UserCred, vp: *const VNode); fn fsync(&mut self, c: UserCred, vp: NonNull<VNode>);
fn inactive(&mut self, c: UserCred, vp: *const VNode); fn inactive(&mut self, c: UserCred, vp: NonNull<VNode>);
fn bmap(&mut self, block_number: u32, bnp: (), vp: *const VNode) -> VNode; fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull<VNode>) -> VNode;
fn strategy(&mut self, bp: (), vp: *const VNode); fn strategy(&mut self, bp: (), vp: NonNull<VNode>);
fn bread(&mut self, block_number: u32, vp: *const VNode) -> Arc<[u8]>; fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>;
} }
#[allow(unused)] #[allow(unused)]
@@ -419,72 +524,24 @@ pub struct VAttr {
used_blocks: u32, used_blocks: u32,
} }
unsafe fn vfs_has_mount_point(mount_point: &str) -> Option<NonNull<Vfs>> {
let mut current = ROOT_VFS.next;
while let Some(node) = current {
if node.as_ref().mount_point.as_ref().unwrap() == mount_point {
return Some(node);
}
current = unsafe { (*node.as_ptr()).next };
}
None
}
pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> { pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
/// # Safety
/// Consumes vfs
unsafe fn deallocate_vfs(vfs: NonNull<Vfs>) {
let fs_ops_box = Box::from_raw(vfs.as_ref().ops.unwrap().as_ptr());
drop(fs_ops_box);
dealloc(
vfs.as_ptr().cast::<u8>(),
alloc::alloc::Layout::new::<Vfs>(),
);
}
let layout = alloc::alloc::Layout::new::<Vfs>();
let vfs_ptr = unsafe { alloc(layout).cast::<Vfs>() };
if vfs_ptr.is_null() {
handle_alloc_error(layout)
}
// Initialize the data so we can use the nonnull helpers // Initialize the data so we can use the nonnull helpers
unsafe { let mut new_vfs = Vfs::null();
let mut vfs = Vfs::null(); new_vfs.fs = Some(fs_ops);
vfs.ops = Some(NonNull::new_unchecked(Box::into_raw(fs_ops))); let mut vfs = Box::new(new_vfs);
// 'normalize' the path (yes, making "/" == "" is intentional)
vfs.mount_point = Some(mount_point.trim_end_matches('/').to_string());
vfs_ptr.write(vfs);
};
// Safety: We know vfs_ptr is not null let vfsp = vfs.as_ptr();
let mut vfs_ptr = unsafe { NonNull::new_unchecked(vfs_ptr) };
let vfs = unsafe { vfs_ptr.as_mut() };
log_info!("Adding vfs at {mount_point}"); log_info!("Adding vfs at {mount_point}");
if mount_point == "/" { if mount_point == "/" {
if unsafe { ROOT_VFS.next.is_some() } { if unsafe { ROOT_VFS.next.is_some() } {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(()); return Err(());
} }
vfs.mount(mount_point); unsafe { NODE_TREE = Some(TreeNode::new(vfs.fs.as_mut().unwrap().as_mut().root(vfsp))) }
unsafe { ROOT_VFS.next = Some(vfs_ptr) };
} else { } else {
if unsafe { ROOT_VFS.next.is_none() } { if unsafe { ROOT_VFS.next.is_none() } {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(()); return Err(());
} }
@@ -492,46 +549,26 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
return Err(()); return Err(());
} }
let mut next_vfs = unsafe { ROOT_VFS.next }; let vnode = vfs_open(mount_point)?;
while let Some(target_vfs) = next_vfs { vnode.vfs_mounted_here = Some(vfsp);
if unsafe { target_vfs.as_ref().mount_point.as_ref().unwrap() == mount_point } {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(());
}
if unsafe { target_vfs.as_ref().next }.is_none() {
break;
}
next_vfs = unsafe { target_vfs.as_ref().next };
}
if next_vfs.is_none() {
unsafe {
deallocate_vfs(vfs_ptr);
};
return Err(());
}
vfs.mount(mount_point);
unsafe { (next_vfs.unwrap()).as_mut().next = Some(vfs_ptr) };
} }
vfs.mount(mount_point);
unsafe { ROOT_VFS.add_vfs(vfs) };
log_ok!("Added vfs at {mount_point}"); log_ok!("Added vfs at {mount_point}");
return Ok(()); return Ok(());
} }
pub fn vfs_open(path: &str) -> Result<VNode, ()> { pub fn vfs_open(path: &str) -> Result<&mut VNode, ()> {
if unsafe { ROOT_VFS.next.is_none() } { if unsafe { ROOT_VFS.next.is_none() || NODE_TREE.is_none() } {
return Err(()); return Err(());
} }
let mut cur_vnode = unsafe { ROOT_VFS.next.unwrap().as_mut().root() }; let mut cur_node = unsafe { NODE_TREE.as_mut().unwrap() };
let parts = path.split('/').collect::<Vec<&str>>(); let parts = path.split('/').collect::<Vec<&str>>();
@@ -540,12 +577,12 @@ pub fn vfs_open(path: &str) -> Result<VNode, ()> {
continue; continue;
} }
if let Ok(vnode) = cur_vnode.lookup(part, UserCred { uid: 0, gid: 0 }) { if let Ok(new_node) = cur_node.lookup(part) {
cur_vnode = vnode; cur_node = new_node;
} else { } else {
return Err(()); return Err(());
} }
} }
return Ok(cur_vnode); return Ok(cur_node.get_vnode());
} }

View File

@@ -100,7 +100,7 @@ pub fn is_transmit_empty() -> bool {
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
pub fn write_serial(character: u8) { pub fn write_serial(character: u8) {
unsafe { unsafe {
*UART = character; UART.write(character);
}; };
} }

View File

@@ -432,14 +432,14 @@ impl ATABus {
ATADriveDirection::Read => unsafe { ATADriveDirection::Read => unsafe {
insw( insw(
self.io_bar + ATADriveDataRegister::Data as u16, self.io_bar + ATADriveDataRegister::Data as u16,
(buffer.as_mut_ptr() as *mut u16).add(buffer_offset), (buffer.as_mut_ptr().cast::<u16>()).add(buffer_offset),
ATA_SECTOR_SIZE / size_of::<u16>(), ATA_SECTOR_SIZE / size_of::<u16>(),
); );
}, },
ATADriveDirection::Write => unsafe { ATADriveDirection::Write => unsafe {
outsw( outsw(
self.io_bar + ATADriveDataRegister::Data as u16, self.io_bar + ATADriveDataRegister::Data as u16,
(buffer.as_mut_ptr() as *mut u16).add(buffer_offset), (buffer.as_mut_ptr().cast::<u16>()).add(buffer_offset),
ATA_SECTOR_SIZE / size_of::<u16>(), ATA_SECTOR_SIZE / size_of::<u16>(),
) )
}, },
@@ -502,7 +502,7 @@ impl ATADrive {
fn sector_count(&self) -> u64 { fn sector_count(&self) -> u64 {
let sectors = self.identify_data[120..].as_ptr(); let sectors = self.identify_data[120..].as_ptr();
return unsafe { *(sectors as *const u32) } as u64; return unsafe { *(sectors.cast::<u32>()) } as u64;
} }
pub fn as_ptr(&self) -> *const ATADrive { pub fn as_ptr(&self) -> *const ATADrive {
@@ -524,7 +524,7 @@ impl BlockDevice for ATADrive {
fn sector_count(&self) -> u64 { fn sector_count(&self) -> u64 {
let sectors = self.identify_data[120..].as_ptr(); let sectors = self.identify_data[120..].as_ptr();
return unsafe { *(sectors as *const u32) } as u64; return unsafe { *(sectors.cast::<u32>()) } as u64;
} }
fn write(&self, sector: u64, buffer: &[u8]) -> Result<(), ()> { fn write(&self, sector: u64, buffer: &[u8]) -> Result<(), ()> {
@@ -542,7 +542,6 @@ static DRIVES: Mutex<Vec<ATADrive>> = Mutex::new(Vec::new());
// TODO: This code is pretty much just the C from @Moldytzu's mOS // TODO: This code is pretty much just the C from @Moldytzu's mOS
// This code could probably be made better and more device agnostic // This code could probably be made better and more device agnostic
// But that's TODO obviously
fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) { fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) {
let mut drives_lock = DRIVES.lock(); let mut drives_lock = DRIVES.lock();
let io_port_base = bar0 as u16; let io_port_base = bar0 as u16;

View File

@@ -32,7 +32,7 @@ impl Framebuffer {
let pixel_offset = (y * self.pitch as u32 + (x * (self.bpp / 8) as u32)) as isize; let pixel_offset = (y * self.pitch as u32 + (x * (self.bpp / 8) as u32)) as isize;
unsafe { unsafe {
*(self.pointer.offset(pixel_offset) as *mut u32) = color; *(self.pointer.offset(pixel_offset).cast::<u32>()) = color;
} }
} }
@@ -43,21 +43,25 @@ impl Framebuffer {
unsafe { unsafe {
if let Some(mirror_buffer) = mirror_buffer { if let Some(mirror_buffer) = mirror_buffer {
crate::mem::memset32(mirror_buffer.pointer as *mut u32, color, buffer_size); crate::mem::memset32(mirror_buffer.pointer.cast::<u32>(), color, buffer_size);
} }
crate::mem::memset32(self.pointer as *mut u32, color, buffer_size); crate::mem::memset32(self.pointer.cast::<u32>(), color, buffer_size);
} }
} }
pub fn blit_screen(&self, buffer: &mut [u32], mirror_buffer: Option<Self>) { pub fn blit_screen(&self, buffer: &mut [u32], mirror_buffer: Option<Self>) {
unsafe { unsafe {
core::ptr::copy_nonoverlapping(buffer.as_ptr(), self.pointer as *mut u32, buffer.len()); core::ptr::copy_nonoverlapping(
buffer.as_ptr(),
self.pointer.cast::<u32>(),
buffer.len(),
);
if let Some(mirror_buffer) = mirror_buffer { if let Some(mirror_buffer) = mirror_buffer {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
buffer.as_ptr(), buffer.as_ptr(),
mirror_buffer.pointer as *mut u32, mirror_buffer.pointer.cast::<u32>(),
buffer.len(), buffer.len(),
); );
} }

View File

@@ -10,6 +10,8 @@ pub struct Cell<T: ?Sized> {
value: UnsafeCell<T>, value: UnsafeCell<T>,
} }
impl<T: ?Sized> !Sync for Cell<T> {}
impl<T> Cell<T> { impl<T> Cell<T> {
pub const fn new(value: T) -> Cell<T> { pub const fn new(value: T) -> Cell<T> {
return Self { return Self {

View File

@@ -1,4 +1,10 @@
#![feature(allocator_api, abi_x86_interrupt, naked_functions, const_mut_refs)] #![feature(
allocator_api,
abi_x86_interrupt,
naked_functions,
const_mut_refs,
negative_impls
)]
#![allow(clippy::needless_return)] #![allow(clippy::needless_return)]
#![no_std] #![no_std]
#![no_main] #![no_main]
@@ -45,13 +51,12 @@ pub fn kmain() -> ! {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
drivers::pci::enumerate_pci_bus(); drivers::pci::enumerate_pci_bus();
let mut file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt").unwrap(); let file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt").unwrap();
crate::println!("YEAH.TXT: {:X?}", file.open(0, UserCred { uid: 0, gid: 0 })); crate::println!("YEAH.TXT: {:X?}", file.open(0, UserCred { uid: 0, gid: 0 }));
drivers::storage::ide::init(); drivers::storage::ide::init();
let limine_dir = vfs_open("/mnt/boot/limine").unwrap();
let mut limine_dir = vfs_open("/mnt/boot/limine").unwrap();
crate::println!( crate::println!(
"LIMINE BOOT: {:X?}", "LIMINE BOOT: {:X?}",
@@ -61,21 +66,22 @@ pub fn kmain() -> ! {
.open(0, UserCred { uid: 0, gid: 0 }) .open(0, UserCred { uid: 0, gid: 0 })
); );
let mut root_dir = vfs_open("/").unwrap(); // TODO: figure out whether this should or shouldnt work in the first place
// let root_dir = vfs_open("/").unwrap();
crate::println!( // crate::println!(
"LIMINE BOOT THROUGH LOOKUP: {:X?}", // "LIMINE BOOT THROUGH LOOKUP: {:X?}",
root_dir // root_dir
.lookup("mnt", UserCred { uid: 0, gid: 0 }) // .lookup("mnt", UserCred { uid: 0, gid: 0 })
.unwrap() // .unwrap()
.lookup("boot", UserCred { uid: 0, gid: 0 }) // .lookup("boot", UserCred { uid: 0, gid: 0 })
.unwrap() // .unwrap()
.lookup("limine", UserCred { uid: 0, gid: 0 }) // .lookup("limine", UserCred { uid: 0, gid: 0 })
.unwrap() // .unwrap()
.lookup("limine.cfg", UserCred { uid: 0, gid: 0 }) // .lookup("limine.cfg", UserCred { uid: 0, gid: 0 })
.unwrap() // .unwrap()
.open(0, UserCred { uid: 0, gid: 0 }) // .open(0, UserCred { uid: 0, gid: 0 })
); // );
// let file = vfs_open("/example.txt").unwrap(); // let file = vfs_open("/example.txt").unwrap();
@@ -83,20 +89,20 @@ pub fn kmain() -> ! {
draw_gradient(); draw_gradient();
// loop { // loop {
// let ch = read_serial(); // let ch = crate::drivers::serial::read_serial();
// if ch == b'\x00' { // if ch == b'\x00' {
// continue; // continue;
// } // }
// if ch == b'\x08' { // if ch == b'\x08' {
// write_serial(b'\x08'); // crate::drivers::serial::write_serial(b'\x08');
// write_serial(b' '); // crate::drivers::serial::write_serial(b' ');
// write_serial(b'\x08'); // crate::drivers::serial::write_serial(b'\x08');
// } // }
// if ch > 0x20 && ch < 0x7F { // if ch > 0x1F && ch < 0x7F {
// write_serial(ch); // crate::drivers::serial::write_serial(ch);
// } // }
// } // }