complete VFS, and coalesce memory regions in the allocator

This commit is contained in:
Zoe
2024-05-24 01:13:31 -05:00
parent b9efc59e49
commit 6ba11e9b25
6 changed files with 438 additions and 320 deletions

View File

@@ -1,6 +1,6 @@
use alloc::{borrow::ToOwned, string::String, vec::Vec}; 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; // 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), ()> { fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
// TODO: dont rely on initramfs being mounted at / // 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 = let symbols_table_bytes = symbols_fd
symbols_fd.open(0, crate::drivers::fs::vfs::UserCred { uid: 0, gid: 0 })?; .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 symbols_table = core::str::from_utf8(&symbols_table_bytes).ok().ok_or(())?;
let mut previous_symbol: Option<(&str, u64)> = None; let mut previous_symbol: Option<(&str, u64)> = None;

View File

@@ -567,44 +567,89 @@ enum File {
} }
impl VNodeOperations for File { impl VNodeOperations for File {
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) { fn open(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
todo!("VNODE OPERATIONS");
}
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode { fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
todo!("VNODE OPERATIONS");
}
fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> { fn read(
todo!("VNODE OPERATIONS");
}
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn create(
&mut self, &mut self,
_nm: &str, count: usize,
_va: super::vfs::VAttr, mut offset: usize,
_e: u32, _f: u32,
_m: u32, _c: super::vfs::UserCred,
vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> {
match self {
File::Archive(archive) => {
let fat_fs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<FatFs>() };
let mut file: Vec<u8> = 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, _c: super::vfs::UserCred,
_vp: NonNull<VNode>, _vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) {
todo!("VNODE OPERATIONS"); todo!()
}
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
todo!("VNODE OPERATIONS");
}
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
} }
fn ioctl( fn ioctl(
@@ -618,13 +663,15 @@ impl VNodeOperations for File {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn link( fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
&mut self, todo!("VNODE OPERATIONS");
_target_dir: *mut super::vfs::VNode, }
_target_name: &str,
_c: super::vfs::UserCred, fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
_vp: NonNull<VNode>, todo!("VNODE OPERATIONS");
) { }
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
@@ -663,109 +710,22 @@ impl VNodeOperations for File {
} }
} }
fn mkdir( fn create(
&mut self, &mut self,
_nm: &str, _nm: &str,
_va: super::vfs::VAttr, _va: super::vfs::VAttr,
_e: u32,
_m: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: NonNull<VNode>, _vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn open( fn link(
&mut self, &mut self,
_f: u32, _target_dir: *mut super::vfs::VNode,
_c: super::vfs::UserCred, _target_name: &str,
vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> {
match self {
File::Archive(archive) => {
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_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<VNode>,
) -> Result<Arc<[u8]>, ()> {
todo!("VNODE OPERATIONS");
}
fn readdir(
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) {
todo!("VNODE OPERATIONS");
}
fn readlink(
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: NonNull<VNode>, _vp: NonNull<VNode>,
) { ) {
@@ -783,23 +743,25 @@ impl VNodeOperations for File {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn select( fn mkdir(
&mut self, &mut self,
_w: super::vfs::IODirection, _nm: &str,
_va: super::vfs::VAttr,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) -> Result<super::vfs::VNode, ()> {
todo!("VNODE OPERATIONS");
}
fn readdir(
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: NonNull<VNode>, _vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn strategy(&mut self, _bp: (), _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn symlink( fn symlink(
&mut self, &mut self,
_link_name: &str, _link_name: &str,
@@ -807,9 +769,29 @@ impl VNodeOperations for File {
_target_name: &str, _target_name: &str,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: NonNull<VNode>, _vp: NonNull<VNode>,
) {
todo!("symlink not supported in FAT");
}
fn readlink(
&mut self,
_uiop: *const super::vfs::UIO,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) { ) {
todo!("VNODE OPERATIONS"); todo!("VNODE OPERATIONS");
} }
fn fsync(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
todo!("VNODE OPERATIONS");
}
fn len(&self, _vp: NonNull<VNode>) -> usize {
match self {
File::Archive(archive) => archive.file_entry.file_size as usize,
_ => panic!("idk"),
}
}
} }
struct FatFile { struct FatFile {

View File

@@ -408,8 +408,14 @@ impl From<&[u8]> for Inode {
} }
impl VNodeOperations for Inode { impl VNodeOperations for Inode {
fn open( fn open(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
fn read(
&mut self, &mut self,
count: usize,
offset: usize,
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
vp: NonNull<VNode>, vp: NonNull<VNode>,
@@ -419,7 +425,7 @@ impl VNodeOperations for Inode {
match self { match self {
Inode::BasicFile(file) => unsafe { Inode::BasicFile(file) => unsafe {
// TODO: is this really how you're supposed to do this? // TODO: is this really how you're supposed to do this?
let mut block_data: Vec<u8> = Vec::with_capacity(file.file_size as usize); let mut block_data: Vec<u8> = Vec::with_capacity(count);
let data_table: Vec<u8>; let data_table: Vec<u8>;
@@ -487,10 +493,9 @@ impl VNodeOperations for Inode {
); );
file.block_offset as usize file.block_offset as usize
}; } + offset;
block_data block_data.extend(&data_table[block_offset..(block_offset + count as usize)]);
.extend(&data_table[block_offset..(block_offset + file.file_size as usize)]);
return Ok(Arc::from(block_data)); 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<VNode>) { fn write(
todo!()
}
fn rdwr(
&mut self, &mut self,
_uiop: *const super::vfs::UIO, _offset: usize,
_direction: super::vfs::IODirection, _buf: &[u8],
_f: u32, _f: u32,
_c: super::vfs::UserCred, _c: super::vfs::UserCred,
_vp: NonNull<VNode>, _vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()> { ) {
todo!() todo!()
} }
@@ -524,15 +525,6 @@ impl VNodeOperations for Inode {
todo!() todo!()
} }
fn select(
&mut self,
_w: super::vfs::IODirection,
_c: super::vfs::UserCred,
_vp: NonNull<VNode>,
) {
todo!()
}
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr { fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
todo!() todo!()
} }
@@ -553,8 +545,6 @@ impl VNodeOperations for Inode {
) -> Result<super::vfs::VNode, ()> { ) -> Result<super::vfs::VNode, ()> {
let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().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 {
let inode = (*squashfs).find_entry_in_directory(*self, nm)?; let inode = (*squashfs).find_entry_in_directory(*self, nm)?;
@@ -647,20 +637,11 @@ impl VNodeOperations for Inode {
todo!() todo!()
} }
fn inactive(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) { fn len(&self, _vp: NonNull<VNode>) -> usize {
todo!() match self {
} Inode::BasicFile(file) => file.file_size as usize,
_ => panic!("idk"),
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode { }
todo!()
}
fn strategy(&mut self, _bp: (), _vp: NonNull<VNode>) {
todo!()
}
fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> {
todo!()
} }
} }

View File

@@ -11,70 +11,6 @@ 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 NODE_TREE: Option<TreeNode> = None;
static mut ROOT_VFS: Vfs = Vfs::null(); static mut ROOT_VFS: Vfs = Vfs::null();
@@ -236,8 +172,145 @@ pub enum VNodeType {
Bad, Bad,
} }
pub struct File {
descriptor: NonNull<TreeNode>,
user_cred: UserCred,
}
impl File {
fn new(tree_node: NonNull<TreeNode>, 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<Arc<[u8]>, ()> {
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<NonNull<Self>>,
children: BTreeMap<String, Self>,
}
impl TreeNode {
fn new(vnode: VNode) -> Self {
return Self {
vnode: vnode,
parent: None,
children: BTreeMap::new(),
};
}
fn as_ptr(&self) -> NonNull<Self> {
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<Arc<[u8]>, ()> {
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 struct VNode {
pub flags: u16, pub flags: u16,
ref_count: u32,
inode: Box<dyn VNodeOperations>, inode: Box<dyn VNodeOperations>,
pub node_data: Option<NodeData>, pub node_data: Option<NodeData>,
pub vfs_mounted_here: Option<NonNull<Vfs>>, pub vfs_mounted_here: Option<NonNull<Vfs>>,
@@ -254,6 +327,7 @@ impl VNode {
) -> Self { ) -> Self {
return Self { return Self {
flags: 0, flags: 0,
ref_count: 0,
inode, inode,
node_data: None, node_data: None,
vfs_mounted_here: None, vfs_mounted_here: None,
@@ -268,7 +342,7 @@ impl VNode {
} }
// 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) {
let vp = self.as_ptr(); let vp = self.as_ptr();
self.inode.as_mut().open(f, c, vp) self.inode.as_mut().open(f, c, vp)
@@ -280,29 +354,38 @@ impl VNode {
self.inode.as_mut().close(f, c, vp) self.inode.as_mut().close(f, c, vp)
} }
pub fn rdwr( pub fn read(
&mut self, &mut self,
uiop: *const UIO, count: usize,
direction: IODirection, offset: usize,
f: u32, f: u32,
c: UserCred, c: UserCred,
) -> Result<Arc<[u8]>, ()> { ) -> Result<Arc<[u8]>, ()> {
if offset >= self.len() || count > self.len() || count + offset > self.len() {
return Err(());
}
let vp = self.as_ptr(); 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) { pub fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred) {
let vp = self.as_ptr(); let vp = self.as_ptr();
self.inode.as_mut().ioctl(com, d, f, c, vp) 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) {
let vp = self.as_ptr(); // 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 { pub fn getattr(&mut self, c: UserCred) -> VAttr {
let vp = self.as_ptr(); let vp = self.as_ptr();
@@ -387,28 +470,34 @@ impl VNode {
self.inode.as_mut().fsync(c, vp) 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(); let vp = self.as_ptr();
self.inode.as_mut().inactive(c, vp) self.inode.as_ref().len(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)
} }
} }
@@ -424,15 +513,16 @@ pub union NodeData {
stream_data: (), // Stream stream_data: (), // Stream
} }
#[derive(Clone, Copy)]
pub struct UserCred { pub struct UserCred {
pub uid: u16, pub uid: u16,
pub gid: u16, pub gid: u16,
} }
pub enum IODirection { // pub enum IODirection {
Read, // Read,
Write, // Write,
} // }
#[allow(unused)] #[allow(unused)]
pub struct IoVec { pub struct IoVec {
@@ -452,18 +542,19 @@ pub struct UIO {
} }
pub trait VNodeOperations { pub trait VNodeOperations {
fn open(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>) -> Result<Arc<[u8]>, ()>; fn open(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>);
fn close(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>); fn close(&mut self, f: u32, c: UserCred, vp: NonNull<VNode>);
fn rdwr( fn read(
&mut self, &mut self,
uiop: *const UIO, count: usize,
direction: IODirection, offset: usize,
f: u32, f: u32,
c: UserCred, c: UserCred,
vp: NonNull<VNode>, vp: NonNull<VNode>,
) -> Result<Arc<[u8]>, ()>; ) -> Result<Arc<[u8]>, ()>;
fn write(&mut self, offset: usize, buf: &[u8], f: u32, c: UserCred, vp: NonNull<VNode>);
fn ioctl(&mut self, com: u32, d: *mut u8, f: u32, c: UserCred, vp: NonNull<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: NonNull<VNode>); // fn select(&mut self, w: IODirection, c: UserCred, vp: NonNull<VNode>);
fn getattr(&mut self, c: UserCred, vp: NonNull<VNode>) -> VAttr; fn getattr(&mut self, c: UserCred, vp: NonNull<VNode>) -> VAttr;
fn setattr(&mut self, va: VAttr, c: UserCred, vp: NonNull<VNode>); fn setattr(&mut self, va: VAttr, c: UserCred, vp: NonNull<VNode>);
fn access(&mut self, m: u32, c: UserCred, vp: NonNull<VNode>); fn access(&mut self, m: u32, c: UserCred, vp: NonNull<VNode>);
@@ -498,10 +589,11 @@ pub trait VNodeOperations {
); );
fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull<VNode>); fn readlink(&mut self, uiop: *const UIO, c: UserCred, vp: NonNull<VNode>);
fn fsync(&mut self, c: UserCred, vp: NonNull<VNode>); fn fsync(&mut self, c: UserCred, vp: NonNull<VNode>);
fn inactive(&mut self, c: UserCred, vp: NonNull<VNode>); // fn inactive(&mut self, c: UserCred, vp: NonNull<VNode>);
fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull<VNode>) -> VNode; // fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull<VNode>) -> VNode;
fn strategy(&mut self, bp: (), vp: NonNull<VNode>); // fn strategy(&mut self, bp: (), vp: NonNull<VNode>);
fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>; // fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>;
fn len(&self, vp: NonNull<VNode>) -> usize;
} }
#[allow(unused)] #[allow(unused)]
@@ -549,9 +641,9 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
return Err(()); 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); vfs.mount(mount_point);
@@ -563,7 +655,7 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
return Ok(()); 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() } { if unsafe { ROOT_VFS.next.is_none() || NODE_TREE.is_none() } {
return Err(()); 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);
} }

View File

@@ -51,37 +51,46 @@ 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 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(); drivers::storage::ide::init();
let limine_dir = vfs_open("/mnt/boot/limine").unwrap(); let limine_dir = vfs_open("/mnt/boot/limine").unwrap();
crate::println!( crate::println!("LIMINE BOOT: {:X?}", {
"LIMINE BOOT: {:X?}", let mut cfg_file = limine_dir
limine_dir .lookup("limine.cfg")
.lookup("limine.cfg", UserCred { uid: 0, gid: 0 })
.unwrap() .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 len = cfg_file.len();
// let root_dir = vfs_open("/").unwrap();
// crate::println!( cfg_file.read(len, 0, 0)
// "LIMINE BOOT THROUGH LOOKUP: {:X?}", });
// root_dir
// .lookup("mnt", UserCred { uid: 0, gid: 0 }) let root_dir = vfs_open("/").unwrap();
// .unwrap()
// .lookup("boot", UserCred { uid: 0, gid: 0 }) crate::println!("LIMINE BOOT THROUGH LOOKUP: {:X?}", {
// .unwrap() let mut cfg_file = root_dir
// .lookup("limine", UserCred { uid: 0, gid: 0 }) .lookup("mnt")
// .unwrap() .unwrap()
// .lookup("limine.cfg", UserCred { uid: 0, gid: 0 }) .lookup("boot")
// .unwrap() .unwrap()
// .open(0, UserCred { uid: 0, gid: 0 }) .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(); // let file = vfs_open("/example.txt").unwrap();

View File

@@ -62,11 +62,38 @@ impl LinkedListAllocator {
); );
assert!(size >= core::mem::size_of::<MemNode>()); assert!(size >= core::mem::size_of::<MemNode>());
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); let mut node = MemNode::new(size);
node.next = self.head.next.take(); node.next = target_node.next.take();
addr.cast::<MemNode>().write(node); addr.cast::<MemNode>().write(node);
self.head.next = Some(NonNull::new_unchecked(addr.cast::<MemNode>())); target_node.next = Some(NonNull::new_unchecked(addr.cast::<MemNode>()));
}
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 { fn alloc_from_node(node: &MemNode, layout: Layout) -> *mut u8 {
@@ -110,6 +137,31 @@ impl LinkedListAllocator {
return None; 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 { fn size_align(layout: Layout) -> Layout {
let layout = layout let layout = layout
.align_to(core::mem::align_of::<MemNode>()) .align_to(core::mem::align_of::<MemNode>())
@@ -142,6 +194,7 @@ impl LinkedListAllocator {
let layout = Self::size_align(layout); let layout = Self::size_align(layout);
self.add_free_region(ptr, layout.size()); self.add_free_region(ptr, layout.size());
self.coalesce_memory();
} }
} }