diff --git a/src/arch/x86_64/stack_trace.rs b/src/arch/x86_64/stack_trace.rs index 459f7ba..c21a2a1 100644 --- a/src/arch/x86_64/stack_trace.rs +++ b/src/arch/x86_64/stack_trace.rs @@ -1,6 +1,6 @@ use alloc::{borrow::ToOwned, string::String, vec::Vec}; -use crate::drivers::fs::vfs::vfs_open; +use crate::drivers::fs::vfs::{vfs_open, UserCred}; // use crate::drivers::fs::vfs::VfsFileSystem; @@ -47,10 +47,11 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) { fn get_function_name(function_address: u64) -> Result<(String, u64), ()> { // TODO: dont rely on initramfs being mounted at / - let mut symbols_fd = vfs_open("/symbols.table")?; + let symbols_fd = vfs_open("/symbols.table")?; - let symbols_table_bytes = - symbols_fd.open(0, crate::drivers::fs::vfs::UserCred { uid: 0, gid: 0 })?; + let symbols_table_bytes = symbols_fd + .open(0, UserCred { uid: 0, gid: 0 }) + .read(0, 0, 0)?; let symbols_table = core::str::from_utf8(&symbols_table_bytes).ok().ok_or(())?; let mut previous_symbol: Option<(&str, u64)> = None; diff --git a/src/drivers/fs/fat.rs b/src/drivers/fs/fat.rs index ff8a7a4..cb99967 100755 --- a/src/drivers/fs/fat.rs +++ b/src/drivers/fs/fat.rs @@ -567,44 +567,89 @@ enum File { } impl VNodeOperations for File { - fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull) { - todo!("VNODE OPERATIONS"); - } + fn open(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull) {} - fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull) -> super::vfs::VNode { - todo!("VNODE OPERATIONS"); - } + fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull) {} - fn bread(&mut self, _block_number: u32, _vp: NonNull) -> Arc<[u8]> { - todo!("VNODE OPERATIONS"); - } - - fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull) { - todo!("VNODE OPERATIONS"); - } - - fn create( + fn read( &mut self, - _nm: &str, - _va: super::vfs::VAttr, - _e: u32, - _m: u32, + count: usize, + mut offset: usize, + _f: u32, + _c: super::vfs::UserCred, + vp: NonNull, + ) -> Result, ()> { + match self { + File::Archive(archive) => { + let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::() }; + + let mut file: Vec = Vec::with_capacity(count); + + let mut cluster = ((archive.file_entry.high_first_cluster_number as u32) << 16) + | archive.file_entry.low_first_cluster_number as u32; + + let cluster_size = unsafe { (*fat_fs).cluster_size }; + + let mut cluster_offset = offset / cluster_size; + while cluster_offset > 0 { + cluster = unsafe { (*fat_fs).get_next_cluster(cluster as usize) }; + cluster_offset -= 1; + } + + let mut copied_bytes = 0; + + loop { + let cluster_data = unsafe { (*fat_fs).read_cluster(cluster as usize)? }; + + let remaining = count as usize - copied_bytes; + let to_copy = if remaining > cluster_size { + cluster_size - offset + } else { + remaining + }; + + file.extend(cluster_data[offset..offset + to_copy].iter()); + + offset = 0; + + copied_bytes += to_copy; + + cluster = unsafe { (*fat_fs).get_next_cluster(cluster as usize) }; + + match unsafe { (*fat_fs).fat_type } { + FatType::Fat12(_) => { + if cluster >= EOC_12 { + break; + } + } + FatType::Fat16(_) => { + if cluster >= EOC_16 { + break; + } + } + FatType::Fat32(_) => { + if cluster >= EOC_32 { + break; + } + } + } + } + + return Ok(Arc::from(file)); + } + _ => panic!("Cannot open non archives"), + } + } + + fn write( + &mut self, + _offset: usize, + _buf: &[u8], + _f: u32, _c: super::vfs::UserCred, _vp: NonNull, - ) -> Result { - todo!("VNODE OPERATIONS"); - } - - fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull) { - todo!("VNODE OPERATIONS"); - } - - fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull) -> super::vfs::VAttr { - todo!("VNODE OPERATIONS"); - } - - fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull) { - todo!("VNODE OPERATIONS"); + ) { + todo!() } fn ioctl( @@ -618,13 +663,15 @@ impl VNodeOperations for File { todo!("VNODE OPERATIONS"); } - fn link( - &mut self, - _target_dir: *mut super::vfs::VNode, - _target_name: &str, - _c: super::vfs::UserCred, - _vp: NonNull, - ) { + fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull) -> super::vfs::VAttr { + todo!("VNODE OPERATIONS"); + } + + fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull) { + todo!("VNODE OPERATIONS"); + } + + fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull) { todo!("VNODE OPERATIONS"); } @@ -663,109 +710,22 @@ impl VNodeOperations for File { } } - fn mkdir( + fn create( &mut self, _nm: &str, _va: super::vfs::VAttr, + _e: u32, + _m: u32, _c: super::vfs::UserCred, _vp: NonNull, ) -> Result { todo!("VNODE OPERATIONS"); } - fn open( + fn link( &mut self, - _f: u32, - _c: super::vfs::UserCred, - vp: NonNull, - ) -> Result, ()> { - match self { - File::Archive(archive) => { - let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::() }; - - let mut file: Vec = Vec::with_capacity(archive.file_entry.file_size as usize); - let mut file_ptr_index = 0; - - let mut cluster = ((archive.file_entry.high_first_cluster_number as u32) << 16) - | archive.file_entry.low_first_cluster_number as u32; - let cluster_size = unsafe { (*fat_fs).cluster_size }; - - let mut copied_bytes = 0; - - loop { - let cluster_data = unsafe { (*fat_fs).read_cluster(cluster as usize)? }; - - let remaining = archive.file_entry.file_size as usize - copied_bytes; - let to_copy = if remaining > cluster_size { - cluster_size - } else { - remaining - }; - - unsafe { - core::ptr::copy_nonoverlapping( - cluster_data.as_ptr(), - file.as_mut_ptr().add(file_ptr_index), - to_copy, - ); - - file.set_len(file.len() + to_copy); - } - - file_ptr_index += cluster_size; - - copied_bytes += to_copy; - - cluster = unsafe { (*fat_fs).get_next_cluster(cluster as usize) }; - - match unsafe { (*fat_fs).fat_type } { - FatType::Fat12(_) => { - if cluster >= EOC_12 { - break; - } - } - FatType::Fat16(_) => { - if cluster >= EOC_16 { - break; - } - } - FatType::Fat32(_) => { - if cluster >= EOC_32 { - break; - } - } - } - } - - return Ok(Arc::from(file)); - } - _ => panic!("Cannot open non archives"), - } - } - - fn rdwr( - &mut self, - _uiop: *const super::vfs::UIO, - _direction: super::vfs::IODirection, - _f: u32, - _c: super::vfs::UserCred, - _vp: NonNull, - ) -> Result, ()> { - todo!("VNODE OPERATIONS"); - } - - fn readdir( - &mut self, - _uiop: *const super::vfs::UIO, - _c: super::vfs::UserCred, - _vp: NonNull, - ) { - todo!("VNODE OPERATIONS"); - } - - fn readlink( - &mut self, - _uiop: *const super::vfs::UIO, + _target_dir: *mut super::vfs::VNode, + _target_name: &str, _c: super::vfs::UserCred, _vp: NonNull, ) { @@ -783,23 +743,25 @@ impl VNodeOperations for File { todo!("VNODE OPERATIONS"); } - fn select( + fn mkdir( &mut self, - _w: super::vfs::IODirection, + _nm: &str, + _va: super::vfs::VAttr, + _c: super::vfs::UserCred, + _vp: NonNull, + ) -> Result { + todo!("VNODE OPERATIONS"); + } + + fn readdir( + &mut self, + _uiop: *const super::vfs::UIO, _c: super::vfs::UserCred, _vp: NonNull, ) { todo!("VNODE OPERATIONS"); } - fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull) { - todo!("VNODE OPERATIONS"); - } - - fn strategy(&mut self, _bp: (), _vp: NonNull) { - todo!("VNODE OPERATIONS"); - } - fn symlink( &mut self, _link_name: &str, @@ -807,9 +769,29 @@ impl VNodeOperations for File { _target_name: &str, _c: super::vfs::UserCred, _vp: NonNull, + ) { + todo!("symlink not supported in FAT"); + } + + fn readlink( + &mut self, + _uiop: *const super::vfs::UIO, + _c: super::vfs::UserCred, + _vp: NonNull, ) { todo!("VNODE OPERATIONS"); } + + fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull) { + todo!("VNODE OPERATIONS"); + } + + fn len(&self, _vp: NonNull) -> usize { + match self { + File::Archive(archive) => archive.file_entry.file_size as usize, + _ => panic!("idk"), + } + } } struct FatFile { diff --git a/src/drivers/fs/initramfs/mod.rs b/src/drivers/fs/initramfs/mod.rs index bfc3680..db18f85 100755 --- a/src/drivers/fs/initramfs/mod.rs +++ b/src/drivers/fs/initramfs/mod.rs @@ -408,8 +408,14 @@ impl From<&[u8]> for Inode { } impl VNodeOperations for Inode { - fn open( + fn open(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull) {} + + fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull) {} + + fn read( &mut self, + count: usize, + offset: usize, _f: u32, _c: super::vfs::UserCred, vp: NonNull, @@ -419,7 +425,7 @@ impl VNodeOperations for Inode { match self { Inode::BasicFile(file) => unsafe { // TODO: is this really how you're supposed to do this? - let mut block_data: Vec = Vec::with_capacity(file.file_size as usize); + let mut block_data: Vec = Vec::with_capacity(count); let data_table: Vec; @@ -487,10 +493,9 @@ impl VNodeOperations for Inode { ); file.block_offset as usize - }; + } + offset; - block_data - .extend(&data_table[block_offset..(block_offset + file.file_size as usize)]); + block_data.extend(&data_table[block_offset..(block_offset + count as usize)]); return Ok(Arc::from(block_data)); }, @@ -498,18 +503,14 @@ impl VNodeOperations for Inode { } } - fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull) { - todo!() - } - - fn rdwr( + fn write( &mut self, - _uiop: *const super::vfs::UIO, - _direction: super::vfs::IODirection, + _offset: usize, + _buf: &[u8], _f: u32, _c: super::vfs::UserCred, _vp: NonNull, - ) -> Result, ()> { + ) { todo!() } @@ -524,15 +525,6 @@ impl VNodeOperations for Inode { todo!() } - fn select( - &mut self, - _w: super::vfs::IODirection, - _c: super::vfs::UserCred, - _vp: NonNull, - ) { - todo!() - } - fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull) -> super::vfs::VAttr { todo!() } @@ -553,8 +545,6 @@ impl VNodeOperations for Inode { ) -> Result { let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::() }; - crate::println!("wawawaw"); - match self { Inode::BasicDirectory(_) | Inode::ExtendedDirectory(_) => unsafe { let inode = (*squashfs).find_entry_in_directory(*self, nm)?; @@ -647,20 +637,11 @@ impl VNodeOperations for Inode { todo!() } - fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull) { - todo!() - } - - fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull) -> super::vfs::VNode { - todo!() - } - - fn strategy(&mut self, _bp: (), _vp: NonNull) { - todo!() - } - - fn bread(&mut self, _block_number: u32, _vp: NonNull) -> Arc<[u8]> { - todo!() + fn len(&self, _vp: NonNull) -> usize { + match self { + Inode::BasicFile(file) => file.file_size as usize, + _ => panic!("idk"), + } } } diff --git a/src/drivers/fs/vfs.rs b/src/drivers/fs/vfs.rs index ff7136a..777bec5 100755 --- a/src/drivers/fs/vfs.rs +++ b/src/drivers/fs/vfs.rs @@ -11,70 +11,6 @@ use alloc::{ use crate::{log_info, log_ok}; -// TODO: probably keeps excess memory but whatever -struct TreeNode { - vnode: Rc, - parent: Option>, - children: BTreeMap, -} - -impl TreeNode { - fn new(vnode: VNode) -> Self { - return Self { - vnode: Rc::new(vnode), - parent: None, - children: BTreeMap::new(), - }; - } - - fn as_ptr(&self) -> NonNull { - 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 = None; static mut ROOT_VFS: Vfs = Vfs::null(); @@ -236,8 +172,145 @@ pub enum VNodeType { Bad, } +pub struct File { + descriptor: NonNull, + user_cred: UserCred, +} + +impl File { + fn new(tree_node: NonNull, user_cred: UserCred) -> Self { + return Self { + descriptor: tree_node, + user_cred, + }; + } + + fn get_node(&mut self) -> &mut TreeNode { + unsafe { self.descriptor.as_mut() } + } + + pub fn read(&mut self, count: usize, offset: usize, f: u32) -> Result, ()> { + return self.get_node().read(count, offset, f); + } + + pub fn write(&mut self, offset: usize, buf: &[u8], f: u32) { + self.get_node().write(offset, buf, f); + } + + pub fn len(&mut self) -> usize { + self.get_node().len() + } +} + +impl Drop for File { + fn drop(&mut self) { + let cred = self.user_cred; + + self.get_node().close(0, cred); + } +} + +// TODO: probably keeps excess memory but whatever +pub struct TreeNode { + vnode: VNode, + parent: Option>, + children: BTreeMap, +} + +impl TreeNode { + fn new(vnode: VNode) -> Self { + return Self { + vnode: vnode, + parent: None, + children: BTreeMap::new(), + }; + } + + fn as_ptr(&self) -> NonNull { + return NonNull::from(self); + } + + fn get_vnode_mut(&mut self) -> &mut VNode { + &mut self.vnode + } + + fn get_vnode(&self) -> &VNode { + &self.vnode + } + + pub fn lookup(&mut self, name: &str) -> Result<&mut Self, ()> { + let parent = Some(self.as_ptr()); + + if !self.children.contains_key(name) { + let vnode: VNode; + + if let Some(mut vfs) = self.vnode.vfs_mounted_here { + unsafe { + vnode = vfs + .as_mut() + .root() + .lookup(name, UserCred { uid: 0, gid: 0 })? + }; + } else { + vnode = self + .get_vnode_mut() + .lookup(name, UserCred { uid: 0, gid: 0 })?; + } + + let child_node = TreeNode { + vnode: 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()); + } + + fn read(&mut self, count: usize, offset: usize, f: u32) -> Result, ()> { + self.get_vnode_mut() + .read(count, offset, f, UserCred { uid: 0, gid: 0 }) + } + + fn write(&mut self, offset: usize, buf: &[u8], f: u32) { + self.get_vnode_mut() + .write(offset, buf, f, UserCred { uid: 0, gid: 0 }) + } + + pub fn open(&mut self, f: u32, c: UserCred) -> File { + let vnode = self.get_vnode_mut(); + + if vnode.ref_count == 0 { + vnode.open(f, c); + } + + vnode.ref_count += 1; + + return File::new(self.as_ptr(), c); + } + + fn close(&mut self, f: u32, c: UserCred) { + let vnode = self.get_vnode_mut(); + + vnode.ref_count -= 1; + + if vnode.ref_count == 0 { + vnode.close(f, c) + } + } + + fn len(&self) -> usize { + self.get_vnode().len() + } +} + pub struct VNode { pub flags: u16, + ref_count: u32, inode: Box, pub node_data: Option, pub vfs_mounted_here: Option>, @@ -254,6 +327,7 @@ impl VNode { ) -> Self { return Self { flags: 0, + ref_count: 0, inode, node_data: None, vfs_mounted_here: None, @@ -268,7 +342,7 @@ impl VNode { } // Trait functions - pub fn open(&mut self, f: u32, c: UserCred) -> Result, ()> { + pub fn open(&mut self, f: u32, c: UserCred) { let vp = self.as_ptr(); self.inode.as_mut().open(f, c, vp) @@ -280,29 +354,38 @@ impl VNode { self.inode.as_mut().close(f, c, vp) } - pub fn rdwr( + pub fn read( &mut self, - uiop: *const UIO, - direction: IODirection, + count: usize, + offset: usize, f: u32, c: UserCred, ) -> Result, ()> { + if offset >= self.len() || count > self.len() || count + offset > self.len() { + return Err(()); + } + let vp = self.as_ptr(); - self.inode.as_mut().rdwr(uiop, direction, f, c, vp) + self.inode.as_mut().read(count, offset, f, c, vp) } + pub fn write(&mut self, offset: usize, buf: &[u8], f: u32, c: UserCred) { + let vp = self.as_ptr(); + + self.inode.as_mut().write(offset, buf, f, c, vp) + } pub fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred) { let vp = self.as_ptr(); self.inode.as_mut().ioctl(com, d, f, c, vp) } - pub fn select(&mut self, w: IODirection, c: UserCred) { - let vp = self.as_ptr(); + // pub fn select(&mut self, w: IODirection, c: UserCred) { + // let vp = self.as_ptr(); - self.inode.as_mut().select(w, c, vp) - } + // self.inode.as_mut().select(w, c, vp) + // } pub fn getattr(&mut self, c: UserCred) -> VAttr { let vp = self.as_ptr(); @@ -387,28 +470,34 @@ impl VNode { self.inode.as_mut().fsync(c, vp) } - pub fn inactive(&mut self, c: UserCred) { + // pub fn inactive(&mut self, c: UserCred) { + // let vp = self.as_ptr(); + + // self.inode.as_mut().inactive(c, vp) + // } + + // pub fn bmap(&mut self, block_number: u32, bnp: ()) -> VNode { + // let vp = self.as_ptr(); + + // self.inode.as_mut().bmap(block_number, bnp, vp) + // } + + // pub fn strategy(&mut self, bp: ()) { + // let vp = self.as_ptr(); + + // self.inode.as_mut().strategy(bp, vp) + // } + + // pub fn bread(&mut self, block_number: u32) -> Arc<[u8]> { + // let vp = self.as_ptr(); + + // self.inode.as_mut().bread(block_number, vp) + // } + + pub fn len(&self) -> usize { let vp = self.as_ptr(); - self.inode.as_mut().inactive(c, vp) - } - - pub fn bmap(&mut self, block_number: u32, bnp: ()) -> VNode { - let vp = self.as_ptr(); - - self.inode.as_mut().bmap(block_number, bnp, vp) - } - - pub fn strategy(&mut self, bp: ()) { - let vp = self.as_ptr(); - - self.inode.as_mut().strategy(bp, vp) - } - - pub fn bread(&mut self, block_number: u32) -> Arc<[u8]> { - let vp = self.as_ptr(); - - self.inode.as_mut().bread(block_number, vp) + self.inode.as_ref().len(vp) } } @@ -424,15 +513,16 @@ pub union NodeData { stream_data: (), // Stream } +#[derive(Clone, Copy)] pub struct UserCred { pub uid: u16, pub gid: u16, } -pub enum IODirection { - Read, - Write, -} +// pub enum IODirection { +// Read, +// Write, +// } #[allow(unused)] pub struct IoVec { @@ -452,18 +542,19 @@ pub struct UIO { } pub trait VNodeOperations { - fn open(&mut self, f: u32, c: UserCred, vp: NonNull) -> Result, ()>; + fn open(&mut self, f: u32, c: UserCred, vp: NonNull); fn close(&mut self, f: u32, c: UserCred, vp: NonNull); - fn rdwr( + fn read( &mut self, - uiop: *const UIO, - direction: IODirection, + count: usize, + offset: usize, f: u32, c: UserCred, vp: NonNull, ) -> Result, ()>; + fn write(&mut self, offset: usize, buf: &[u8], f: u32, c: UserCred, vp: NonNull); fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred, vp: NonNull); - fn select(&mut self, w: IODirection, c: UserCred, vp: NonNull); + // fn select(&mut self, w: IODirection, c: UserCred, vp: NonNull); fn getattr(&mut self, c: UserCred, vp: NonNull) -> VAttr; fn setattr(&mut self, va: VAttr, c: UserCred, vp: NonNull); fn access(&mut self, m: u32, c: UserCred, vp: NonNull); @@ -498,10 +589,11 @@ pub trait VNodeOperations { ); fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull); fn fsync(&mut self, c: UserCred, vp: NonNull); - fn inactive(&mut self, c: UserCred, vp: NonNull); - fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull) -> VNode; - fn strategy(&mut self, bp: (), vp: NonNull); - fn bread(&mut self, block_number: u32, vp: NonNull) -> Arc<[u8]>; + // fn inactive(&mut self, c: UserCred, vp: NonNull); + // fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull) -> VNode; + // fn strategy(&mut self, bp: (), vp: NonNull); + // fn bread(&mut self, block_number: u32, vp: NonNull) -> Arc<[u8]>; + fn len(&self, vp: NonNull) -> usize; } #[allow(unused)] @@ -549,9 +641,9 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box) -> Result<(), ()> { return Err(()); } - let vnode = vfs_open(mount_point)?; + let file = vfs_open(mount_point)?; - vnode.vfs_mounted_here = Some(vfsp); + file.get_vnode_mut().vfs_mounted_here = Some(vfsp); } vfs.mount(mount_point); @@ -563,7 +655,7 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box) -> Result<(), ()> { return Ok(()); } -pub fn vfs_open(path: &str) -> Result<&mut VNode, ()> { +pub fn vfs_open(path: &str) -> Result<&mut TreeNode, ()> { if unsafe { ROOT_VFS.next.is_none() || NODE_TREE.is_none() } { return Err(()); } @@ -584,5 +676,5 @@ pub fn vfs_open(path: &str) -> Result<&mut VNode, ()> { } } - return Ok(cur_node.get_vnode()); + return Ok(cur_node); } diff --git a/src/main.rs b/src/main.rs index 05b0c69..da8734b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,37 +51,46 @@ pub fn kmain() -> ! { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] drivers::pci::enumerate_pci_bus(); - let file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt").unwrap(); + let mut file = vfs_open("/firstdir/seconddirbutlonger/yeah.txt") + .unwrap() + .open(0, UserCred { uid: 0, gid: 0 }); - crate::println!("YEAH.TXT: {:X?}", file.open(0, UserCred { uid: 0, gid: 0 })); + let file_len = file.len(); + + crate::println!("YEAH.TXT: {:X?}", file.read(file_len, 0, 0)); drivers::storage::ide::init(); let limine_dir = vfs_open("/mnt/boot/limine").unwrap(); - crate::println!( - "LIMINE BOOT: {:X?}", - limine_dir - .lookup("limine.cfg", UserCred { uid: 0, gid: 0 }) + crate::println!("LIMINE BOOT: {:X?}", { + let mut cfg_file = limine_dir + .lookup("limine.cfg") .unwrap() - .open(0, UserCred { uid: 0, gid: 0 }) - ); + .open(0, UserCred { uid: 0, gid: 0 }); - // TODO: figure out whether this should or shouldnt work in the first place - // let root_dir = vfs_open("/").unwrap(); + let len = cfg_file.len(); - // crate::println!( - // "LIMINE BOOT THROUGH LOOKUP: {:X?}", - // root_dir - // .lookup("mnt", UserCred { uid: 0, gid: 0 }) - // .unwrap() - // .lookup("boot", UserCred { uid: 0, gid: 0 }) - // .unwrap() - // .lookup("limine", UserCred { uid: 0, gid: 0 }) - // .unwrap() - // .lookup("limine.cfg", UserCred { uid: 0, gid: 0 }) - // .unwrap() - // .open(0, UserCred { uid: 0, gid: 0 }) - // ); + cfg_file.read(len, 0, 0) + }); + + let root_dir = vfs_open("/").unwrap(); + + crate::println!("LIMINE BOOT THROUGH LOOKUP: {:X?}", { + let mut cfg_file = root_dir + .lookup("mnt") + .unwrap() + .lookup("boot") + .unwrap() + .lookup("limine") + .unwrap() + .lookup("limine.cfg") + .unwrap() + .open(0, UserCred { uid: 0, gid: 0 }); + + let len = cfg_file.len(); + + cfg_file.read(len, 0, 0) + }); // let file = vfs_open("/example.txt").unwrap(); diff --git a/src/mem/allocator.rs b/src/mem/allocator.rs index c321ad3..dbabb20 100644 --- a/src/mem/allocator.rs +++ b/src/mem/allocator.rs @@ -62,11 +62,38 @@ impl LinkedListAllocator { ); assert!(size >= core::mem::size_of::()); + let mut target_node = &mut self.head; + + while let Some(mut next_node) = target_node.next { + if next_node.as_ref().addr() > addr as usize { + break; + } + + target_node = next_node.as_mut() + } + let mut node = MemNode::new(size); - node.next = self.head.next.take(); + node.next = target_node.next.take(); addr.cast::().write(node); - self.head.next = Some(NonNull::new_unchecked(addr.cast::())); + target_node.next = Some(NonNull::new_unchecked(addr.cast::())); + } + + unsafe fn coalesce_memory(&mut self) { + let mut current_node = &mut self.head; + + while let Some(mut next) = current_node.next { + let next = next.as_mut(); + + if current_node.end_addr() == next.addr() { + let new_size = current_node.size + next.size; + + current_node.size = new_size; + current_node.next = next.next.take(); + } else { + current_node = next; + } + } } fn alloc_from_node(node: &MemNode, layout: Layout) -> *mut u8 { @@ -110,6 +137,31 @@ impl LinkedListAllocator { return None; } + pub fn count_reginos(&self) -> usize { + let mut region_count = 0; + let mut cur_region = &self.head; + + while let Some(next) = cur_region.next { + cur_region = unsafe { next.as_ref() }; + region_count += 1; + } + + region_count + } + + pub fn debug_regions(&self, buf: &mut [(usize, usize)]) { + let mut i = 0; + let mut cur_region = &self.head; + buf[i] = (cur_region.addr(), cur_region.end_addr()); + i += 1; + + while let Some(next) = cur_region.next { + cur_region = unsafe { next.as_ref() }; + buf[i] = (cur_region.addr(), cur_region.end_addr()); + i += 1; + } + } + fn size_align(layout: Layout) -> Layout { let layout = layout .align_to(core::mem::align_of::()) @@ -142,6 +194,7 @@ impl LinkedListAllocator { let layout = Self::size_align(layout); self.add_free_region(ptr, layout.size()); + self.coalesce_memory(); } }