mirror of
https://github.com/ZeroOSProject/ZeroOS.git
synced 2026-09-13 02:24:42 +08:00
内存缓存和ext4完整支持
This commit is contained in:
+106
-19
@@ -15,7 +15,6 @@ const EINVAL: isize = 22;
|
||||
const ENOENT: isize = 2;
|
||||
const ENOTDIR: isize = 20;
|
||||
const EMFILE: isize = 24;
|
||||
const EIO: isize = 5;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
enum Color {
|
||||
@@ -226,12 +225,25 @@ impl Vfs {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
let offset = self.fds[fd].offset.min(node.len);
|
||||
let available = node.len - offset;
|
||||
if node.data.is_null() {
|
||||
let count =
|
||||
match crate::fs::lwext4::read_path_at(&node.path, self.fds[fd].offset, buffer, len)
|
||||
{
|
||||
Ok(count) => count,
|
||||
Err(error) => return error,
|
||||
};
|
||||
self.fds[fd].offset = self.fds[fd].offset.saturating_add(count);
|
||||
return count as isize;
|
||||
}
|
||||
|
||||
let node_len = self.node_len(node_index);
|
||||
let offset = self.fds[fd].offset.min(node_len);
|
||||
let available = node_len - offset;
|
||||
let count = len.min(available);
|
||||
if count > 0 {
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(node.data.add(offset), buffer, count);
|
||||
let source = node.data.add(offset);
|
||||
core::ptr::copy_nonoverlapping(source, buffer, count);
|
||||
}
|
||||
}
|
||||
self.fds[fd].offset = offset + count;
|
||||
@@ -245,6 +257,9 @@ impl Vfs {
|
||||
let Some(node_index) = self.fds[fd].node else {
|
||||
return -EBADF;
|
||||
};
|
||||
if self.nodes[node_index].kind == NodeKind::Regular {
|
||||
return self.write_regular_fd(fd, node_index, buffer, len);
|
||||
}
|
||||
if self.nodes[node_index].kind != NodeKind::CharDevice {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -253,6 +268,31 @@ impl Vfs {
|
||||
crate::console::write(buffer) as isize
|
||||
}
|
||||
|
||||
fn write_regular_fd(
|
||||
&mut self,
|
||||
fd: usize,
|
||||
node_index: usize,
|
||||
buffer: *const u8,
|
||||
len: usize,
|
||||
) -> isize {
|
||||
let offset = self.fds[fd].offset;
|
||||
let count = match crate::fs::lwext4::write_path_at(
|
||||
&self.nodes[node_index].path,
|
||||
offset,
|
||||
buffer,
|
||||
len,
|
||||
) {
|
||||
Ok(count) => count,
|
||||
Err(error) => return error,
|
||||
};
|
||||
let end = offset.saturating_add(count);
|
||||
self.fds[fd].offset = end;
|
||||
if end > self.nodes[node_index].len {
|
||||
self.nodes[node_index].len = end;
|
||||
}
|
||||
count as isize
|
||||
}
|
||||
|
||||
fn close_fd(&mut self, fd: usize) -> isize {
|
||||
if fd < 3 || fd >= MAX_FDS || self.fds[fd].node.is_none() {
|
||||
return -EBADF;
|
||||
@@ -298,7 +338,7 @@ impl Vfs {
|
||||
let Some(node_index) = self.fds[fd].node else {
|
||||
return -EBADF;
|
||||
};
|
||||
let len = self.nodes[node_index].len as isize;
|
||||
let len = self.node_len(node_index) as isize;
|
||||
let current = self.fds[fd].offset as isize;
|
||||
let next = match whence {
|
||||
0 => offset,
|
||||
@@ -323,6 +363,24 @@ impl Vfs {
|
||||
write_stat(stat, self.nodes[node_index])
|
||||
}
|
||||
|
||||
fn ftruncate_fd(&mut self, fd: usize, size: usize) -> isize {
|
||||
if fd >= MAX_FDS {
|
||||
return -EBADF;
|
||||
}
|
||||
let Some(node_index) = self.fds[fd].node else {
|
||||
return -EBADF;
|
||||
};
|
||||
if self.nodes[node_index].kind != NodeKind::Regular {
|
||||
return -EINVAL;
|
||||
}
|
||||
match crate::fs::lwext4::truncate_path(&self.nodes[node_index].path, size) {
|
||||
Ok(()) => {}
|
||||
Err(error) => return error,
|
||||
}
|
||||
self.nodes[node_index].len = size;
|
||||
0
|
||||
}
|
||||
|
||||
fn is_tty_fd(&self, fd: usize) -> bool {
|
||||
if fd >= MAX_FDS {
|
||||
return false;
|
||||
@@ -387,6 +445,22 @@ impl Vfs {
|
||||
write_stat(stat, self.nodes[node_index])
|
||||
}
|
||||
|
||||
fn truncate_path(&mut self, path: &[u8], size: usize) -> isize {
|
||||
let Some(node_index) = self.find(path) else {
|
||||
return -ENOENT;
|
||||
};
|
||||
if self.nodes[node_index].kind != NodeKind::Regular {
|
||||
return -EINVAL;
|
||||
}
|
||||
match crate::fs::lwext4::truncate_path(&self.nodes[node_index].path, size) {
|
||||
Ok(()) => {
|
||||
self.nodes[node_index].len = size;
|
||||
0
|
||||
}
|
||||
Err(error) => error,
|
||||
}
|
||||
}
|
||||
|
||||
fn chdir_path(&mut self, path: &[u8]) -> isize {
|
||||
let Some(node_index) = self.find(path) else {
|
||||
return -ENOENT;
|
||||
@@ -414,6 +488,15 @@ impl Vfs {
|
||||
}
|
||||
}
|
||||
|
||||
fn node_len(&self, node_index: usize) -> usize {
|
||||
let node = self.nodes[node_index];
|
||||
if node.kind == NodeKind::Regular && node.data.is_null() {
|
||||
crate::fs::lwext4::size_path(&node.path).unwrap_or(node.len)
|
||||
} else {
|
||||
node.len
|
||||
}
|
||||
}
|
||||
|
||||
fn getcwd(&self, buffer: *mut u8, len: usize) -> isize {
|
||||
if buffer.is_null() {
|
||||
return -EFAULT;
|
||||
@@ -576,10 +659,7 @@ pub unsafe fn init() {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn mount_static_file(path: &'static [u8], data: *const u8, len: usize) -> Option<()> {
|
||||
unsafe { vfs_mut().insert(path, NodeKind::Regular, data, len) }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn mount_ext4_node(path: &[u8], kind: NodeKind) -> Option<()> {
|
||||
unsafe { vfs_mut().insert(path, kind, core::ptr::null(), 0) }
|
||||
}
|
||||
@@ -655,6 +735,10 @@ pub fn fstat(fd: usize, stat: *mut u8) -> isize {
|
||||
unsafe { vfs_ref().stat_fd(fd, stat) }
|
||||
}
|
||||
|
||||
pub fn ftruncate(fd: usize, size: usize) -> isize {
|
||||
unsafe { vfs_mut().ftruncate_fd(fd, size) }
|
||||
}
|
||||
|
||||
pub fn is_tty(fd: usize) -> bool {
|
||||
unsafe { vfs_ref().is_tty_fd(fd) }
|
||||
}
|
||||
@@ -684,6 +768,13 @@ pub fn stat_user_path(path: *const u8, stat: *mut u8) -> isize {
|
||||
unsafe { vfs_ref().stat_path(&path, stat) }
|
||||
}
|
||||
|
||||
pub fn truncate_user_path(path: *const u8, size: usize) -> isize {
|
||||
let Some(path) = (unsafe { read_user_path(path) }) else {
|
||||
return -EFAULT;
|
||||
};
|
||||
unsafe { vfs_mut().truncate_path(&path, size) }
|
||||
}
|
||||
|
||||
pub fn statat_user_path(dirfd: isize, path: *const u8, stat: *mut u8) -> isize {
|
||||
if unsafe { path_starts_with_slash(path) } || dirfd == AT_FDCWD {
|
||||
return stat_user_path(path, stat);
|
||||
@@ -761,9 +852,9 @@ fn create_directory_path(path: &[u8]) -> isize {
|
||||
if unsafe { vfs_ref().find(path).is_some() } {
|
||||
return 0;
|
||||
}
|
||||
match crate::fs::ext4::create_dir(path) {
|
||||
match crate::fs::lwext4::create_dir(path) {
|
||||
Ok(()) => unsafe { vfs_mut().create_path(path, NodeKind::Directory) },
|
||||
Err(_) => -EIO,
|
||||
Err(error) => error,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,9 +862,9 @@ fn create_regular_path(path: &[u8]) -> isize {
|
||||
if unsafe { vfs_ref().find(path).is_some() } {
|
||||
return 0;
|
||||
}
|
||||
match crate::fs::ext4::create_file(path) {
|
||||
match crate::fs::lwext4::create_file(path) {
|
||||
Ok(()) => unsafe { vfs_mut().create_path(path, NodeKind::Regular) },
|
||||
Err(_) => -EIO,
|
||||
Err(error) => error,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,15 +872,11 @@ pub fn getcwd(buffer: *mut u8, len: usize) -> isize {
|
||||
unsafe { vfs_ref().getcwd(buffer, len) }
|
||||
}
|
||||
|
||||
pub fn file_data_user_path(path: *const u8) -> Option<(*const u8, usize)> {
|
||||
pub fn exec_path_user(path: *const u8) -> Option<[u8; MAX_PATH]> {
|
||||
let path = unsafe { read_user_path(path) }?;
|
||||
unsafe {
|
||||
let index = vfs_ref().resolve_executable_path(&path)?;
|
||||
let node = &vfs_ref().nodes[index];
|
||||
if node.kind != NodeKind::Regular {
|
||||
return None;
|
||||
}
|
||||
Some((node.data, node.len))
|
||||
Some(vfs_ref().nodes[index].path)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user