complete VFS, and coalesce memory regions in the allocator
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -567,44 +567,89 @@ enum File {
|
||||
}
|
||||
|
||||
impl VNodeOperations for File {
|
||||
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
fn open(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
|
||||
|
||||
fn bmap(&mut self, _block_number: u32, _bnp: (), _vp: NonNull<VNode>) -> super::vfs::VNode {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
|
||||
|
||||
fn bread(&mut self, _block_number: u32, _vp: NonNull<VNode>) -> Arc<[u8]> {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
|
||||
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
|
||||
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<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,
|
||||
_vp: NonNull<VNode>,
|
||||
) -> Result<super::vfs::VNode, ()> {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
|
||||
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");
|
||||
) {
|
||||
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<VNode>,
|
||||
) {
|
||||
fn getattr(&mut self, _c: super::vfs::UserCred, _vp: NonNull<VNode>) -> super::vfs::VAttr {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
|
||||
fn setattr(&mut self, _va: super::vfs::VAttr, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
|
||||
fn access(&mut self, _m: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {
|
||||
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<VNode>,
|
||||
) -> Result<super::vfs::VNode, ()> {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
|
||||
fn open(
|
||||
fn link(
|
||||
&mut self,
|
||||
_f: 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(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,
|
||||
_target_dir: *mut super::vfs::VNode,
|
||||
_target_name: &str,
|
||||
_c: super::vfs::UserCred,
|
||||
_vp: NonNull<VNode>,
|
||||
) {
|
||||
@@ -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<VNode>,
|
||||
) -> Result<super::vfs::VNode, ()> {
|
||||
todo!("VNODE OPERATIONS");
|
||||
}
|
||||
|
||||
fn readdir(
|
||||
&mut self,
|
||||
_uiop: *const super::vfs::UIO,
|
||||
_c: super::vfs::UserCred,
|
||||
_vp: NonNull<VNode>,
|
||||
) {
|
||||
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(
|
||||
&mut self,
|
||||
_link_name: &str,
|
||||
@@ -807,9 +769,29 @@ impl VNodeOperations for File {
|
||||
_target_name: &str,
|
||||
_c: super::vfs::UserCred,
|
||||
_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");
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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<VNode>) {}
|
||||
|
||||
fn close(&mut self, _f: u32, _c: super::vfs::UserCred, _vp: NonNull<VNode>) {}
|
||||
|
||||
fn read(
|
||||
&mut self,
|
||||
count: usize,
|
||||
offset: usize,
|
||||
_f: u32,
|
||||
_c: super::vfs::UserCred,
|
||||
vp: NonNull<VNode>,
|
||||
@@ -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<u8> = Vec::with_capacity(file.file_size as usize);
|
||||
let mut block_data: Vec<u8> = Vec::with_capacity(count);
|
||||
|
||||
let data_table: Vec<u8>;
|
||||
|
||||
@@ -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<VNode>) {
|
||||
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<VNode>,
|
||||
) -> Result<Arc<[u8]>, ()> {
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -524,15 +525,6 @@ impl VNodeOperations for Inode {
|
||||
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 {
|
||||
todo!()
|
||||
}
|
||||
@@ -553,8 +545,6 @@ impl VNodeOperations for Inode {
|
||||
) -> Result<super::vfs::VNode, ()> {
|
||||
let squashfs = unsafe { (*vp.as_ptr()).parent_vfs.as_mut().data.cast::<Squashfs>() };
|
||||
|
||||
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<VNode>) {
|
||||
todo!()
|
||||
fn len(&self, _vp: NonNull<VNode>) -> usize {
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,70 +11,6 @@ use alloc::{
|
||||
|
||||
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();
|
||||
|
||||
@@ -236,8 +172,145 @@ pub enum VNodeType {
|
||||
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 flags: u16,
|
||||
ref_count: u32,
|
||||
inode: Box<dyn VNodeOperations>,
|
||||
pub node_data: Option<NodeData>,
|
||||
pub vfs_mounted_here: Option<NonNull<Vfs>>,
|
||||
@@ -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<Arc<[u8]>, ()> {
|
||||
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<Arc<[u8]>, ()> {
|
||||
let vp = self.as_ptr();
|
||||
|
||||
self.inode.as_mut().rdwr(uiop, direction, f, c, vp)
|
||||
if offset >= self.len() || count > self.len() || count + offset > self.len() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let vp = self.as_ptr();
|
||||
|
||||
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<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 rdwr(
|
||||
fn read(
|
||||
&mut self,
|
||||
uiop: *const UIO,
|
||||
direction: IODirection,
|
||||
count: usize,
|
||||
offset: usize,
|
||||
f: u32,
|
||||
c: UserCred,
|
||||
vp: NonNull<VNode>,
|
||||
) -> 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 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 setattr(&mut self, va: VAttr, 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 fsync(&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 strategy(&mut self, bp: (), vp: NonNull<VNode>);
|
||||
fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>;
|
||||
// fn inactive(&mut self, c: UserCred, vp: NonNull<VNode>);
|
||||
// fn bmap(&mut self, block_number: u32, bnp: (), vp: NonNull<VNode>) -> VNode;
|
||||
// fn strategy(&mut self, bp: (), vp: NonNull<VNode>);
|
||||
// fn bread(&mut self, block_number: u32, vp: NonNull<VNode>) -> Arc<[u8]>;
|
||||
fn len(&self, vp: NonNull<VNode>) -> usize;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
@@ -549,9 +641,9 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> 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<dyn FsOps>) -> 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);
|
||||
}
|
||||
|
||||
55
src/main.rs
55
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();
|
||||
|
||||
|
||||
@@ -62,11 +62,38 @@ impl LinkedListAllocator {
|
||||
);
|
||||
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);
|
||||
node.next = self.head.next.take();
|
||||
node.next = target_node.next.take();
|
||||
|
||||
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 {
|
||||
@@ -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::<MemNode>())
|
||||
@@ -142,6 +194,7 @@ impl LinkedListAllocator {
|
||||
let layout = Self::size_align(layout);
|
||||
|
||||
self.add_free_region(ptr, layout.size());
|
||||
self.coalesce_memory();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user