***: fix incorrect tlbi + add Read/OpenDirectory
This commit is contained in:
parent
64233db3df
commit
867edf7748
@ -2,8 +2,11 @@ use core::marker::PhantomData;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef};
|
||||
use yggdrasil_abi::error::Error;
|
||||
use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef, DIR_POSITION_FROM_CACHE};
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{FileMode, OpenOptions},
|
||||
};
|
||||
|
||||
use crate::{block::BlockAllocator, bvec::BVec, file::FileNode};
|
||||
|
||||
@ -23,6 +26,15 @@ impl<A: BlockAllocator> VnodeImpl for DirectoryNode<A> {
|
||||
}
|
||||
Ok(child)
|
||||
}
|
||||
|
||||
fn open(
|
||||
&mut self,
|
||||
_node: &VnodeRef,
|
||||
_opts: OpenOptions,
|
||||
_mode: FileMode,
|
||||
) -> Result<u64, Error> {
|
||||
Ok(DIR_POSITION_FROM_CACHE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: BlockAllocator> DirectoryNode<A> {
|
||||
|
@ -1,12 +1,15 @@
|
||||
use core::cell::RefCell;
|
||||
use core::{cell::RefCell, mem::MaybeUninit};
|
||||
|
||||
use alloc::rc::Rc;
|
||||
use bitflags::bitflags;
|
||||
use yggdrasil_abi::error::Error;
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{DirectoryEntry, FileType},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
node::{VnodeKind, VnodeRef},
|
||||
Read, Seek, SeekFrom, Write,
|
||||
Read, ReadDirectory, Seek, SeekFrom, Write, DIR_POSITION_FROM_CACHE,
|
||||
};
|
||||
|
||||
bitflags! {
|
||||
@ -18,13 +21,28 @@ bitflags! {
|
||||
|
||||
pub type FileRef = Rc<RefCell<File>>;
|
||||
|
||||
enum DirectoryPosition {
|
||||
DiskPosition(u64),
|
||||
// TODO not the best implementation, but at least somewhat safe?
|
||||
CachePosition(usize),
|
||||
Dot,
|
||||
DotDot,
|
||||
End,
|
||||
}
|
||||
|
||||
pub struct NormalFile {
|
||||
vnode: VnodeRef,
|
||||
pos: u64,
|
||||
}
|
||||
|
||||
pub struct Directory {
|
||||
vnode: VnodeRef,
|
||||
pos: DirectoryPosition,
|
||||
}
|
||||
|
||||
pub enum FileInner {
|
||||
Normal(NormalFile),
|
||||
Directory(Directory),
|
||||
}
|
||||
|
||||
pub struct File {
|
||||
@ -39,6 +57,20 @@ impl File {
|
||||
flags,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn directory(vnode: VnodeRef, pos: u64) -> FileRef {
|
||||
let pos = if pos == DIR_POSITION_FROM_CACHE {
|
||||
// Read from cache
|
||||
DirectoryPosition::Dot
|
||||
} else {
|
||||
// Reading from a "physical" directory
|
||||
todo!()
|
||||
};
|
||||
Rc::new(RefCell::new(Self {
|
||||
inner: FileInner::Directory(Directory { vnode, pos }),
|
||||
flags: FileFlags::READ,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for File {
|
||||
@ -55,6 +87,7 @@ impl Write for File {
|
||||
}
|
||||
Ok(count)
|
||||
}
|
||||
FileInner::Directory(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,6 +106,7 @@ impl Read for File {
|
||||
}
|
||||
Ok(count)
|
||||
}
|
||||
FileInner::Directory(_) => Err(Error::IsADirectory),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,16 +132,78 @@ impl Seek for File {
|
||||
|
||||
Ok(pos)
|
||||
}
|
||||
FileInner::Directory(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReadDirectory for File {
|
||||
fn read_dir_entries(
|
||||
&mut self,
|
||||
entries: &mut [MaybeUninit<DirectoryEntry>],
|
||||
) -> Result<usize, Error> {
|
||||
let FileInner::Directory(inner) = &mut self.inner else {
|
||||
return Err(Error::NotADirectory);
|
||||
};
|
||||
|
||||
let mut nread = 0;
|
||||
let mut rem = entries.len();
|
||||
|
||||
while rem != 0 {
|
||||
let mut entry = DirectoryEntry {
|
||||
name: [0; 256],
|
||||
ty: FileType::File,
|
||||
};
|
||||
|
||||
let next_position = match inner.pos {
|
||||
DirectoryPosition::End => {
|
||||
break;
|
||||
}
|
||||
DirectoryPosition::Dot => {
|
||||
entry.name[0] = b'.';
|
||||
entry.ty = FileType::Directory;
|
||||
DirectoryPosition::DotDot
|
||||
}
|
||||
DirectoryPosition::DotDot => {
|
||||
entry.name[..2].copy_from_slice(b"..");
|
||||
entry.ty = FileType::Directory;
|
||||
DirectoryPosition::CachePosition(0)
|
||||
}
|
||||
DirectoryPosition::CachePosition(index) => {
|
||||
let child = inner.vnode.child_at(index);
|
||||
|
||||
if let Some(child) = child {
|
||||
let child_name = child.name();
|
||||
entry.name[..child_name.len()].copy_from_slice(child_name.as_bytes());
|
||||
entry.ty = FileType::from(child.kind());
|
||||
DirectoryPosition::CachePosition(index + 1)
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DirectoryPosition::DiskPosition(_) => todo!(),
|
||||
};
|
||||
inner.pos = next_position;
|
||||
|
||||
entries[nread].write(entry);
|
||||
|
||||
nread += 1;
|
||||
rem -= 1;
|
||||
}
|
||||
|
||||
Ok(nread)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for File {
|
||||
fn drop(&mut self) {
|
||||
match &mut self.inner {
|
||||
FileInner::Normal(inner) => {
|
||||
inner.vnode.close().ok();
|
||||
}
|
||||
FileInner::Directory(inner) => {
|
||||
inner.vnode.close().ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
#![no_std]
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use yggdrasil_abi::error::Error;
|
||||
use yggdrasil_abi::io::DirectoryEntry;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
@ -24,6 +27,8 @@ pub use fs::Filesystem;
|
||||
pub use ioctx::IoContext;
|
||||
pub use node::{Vnode, VnodeDump, VnodeImpl, VnodeKind, VnodeRef, VnodeWeak};
|
||||
|
||||
pub const DIR_POSITION_FROM_CACHE: u64 = u64::MAX;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SeekFrom {
|
||||
Start(u64),
|
||||
@ -47,6 +52,13 @@ pub trait Seek {
|
||||
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error>;
|
||||
}
|
||||
|
||||
pub trait ReadDirectory {
|
||||
fn read_dir_entries(
|
||||
&mut self,
|
||||
entries: &mut [MaybeUninit<DirectoryEntry>],
|
||||
) -> Result<usize, Error>;
|
||||
}
|
||||
|
||||
fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [u8]) -> Result<(), Error> {
|
||||
while !buf.is_empty() {
|
||||
match this.read(buf) {
|
||||
|
@ -11,12 +11,13 @@ use alloc::{
|
||||
};
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{FileMode, OpenOptions},
|
||||
io::{FileMode, FileType, OpenOptions},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
file::{File, FileFlags, FileRef},
|
||||
fs::Filesystem,
|
||||
DIR_POSITION_FROM_CACHE,
|
||||
};
|
||||
|
||||
pub type VnodeRef = Rc<Vnode>;
|
||||
@ -163,6 +164,11 @@ impl Vnode {
|
||||
parent_borrow.children.push(child);
|
||||
}
|
||||
|
||||
pub fn child_at(self: &VnodeRef, index: usize) -> Option<VnodeRef> {
|
||||
let tree = self.tree.borrow();
|
||||
tree.children.get(index).cloned()
|
||||
}
|
||||
|
||||
pub fn dump(&self, f: &mut fmt::Formatter<'_>, depth: usize, indent: bool) -> fmt::Result {
|
||||
if indent {
|
||||
for _ in 0..depth {
|
||||
@ -244,11 +250,25 @@ impl Vnode {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_directory(self: &VnodeRef) -> Result<FileRef, Error> {
|
||||
if !self.is_directory() {
|
||||
return Err(Error::IsADirectory);
|
||||
}
|
||||
|
||||
if let Some(ref mut data) = *self.data() {
|
||||
let pos = data.open(self, OpenOptions::READ, FileMode::empty())?;
|
||||
Ok(File::directory(self.clone(), pos))
|
||||
} else {
|
||||
// TODO: some options here?
|
||||
Ok(File::directory(self.clone(), DIR_POSITION_FROM_CACHE))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn close(self: &VnodeRef) -> Result<(), Error> {
|
||||
if let Some(ref mut data) = *self.data() {
|
||||
data.close(self)
|
||||
} else {
|
||||
todo!()
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,3 +397,14 @@ impl fmt::Debug for VnodeDump {
|
||||
self.node.dump(f, 0, true)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VnodeKind> for FileType {
|
||||
fn from(value: VnodeKind) -> Self {
|
||||
match value {
|
||||
VnodeKind::Regular => Self::File,
|
||||
VnodeKind::Directory => Self::Directory,
|
||||
VnodeKind::Block => Self::Block,
|
||||
VnodeKind::Char => Self::Char,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,13 +232,13 @@ pub fn kernel_main(dtb_phys: usize) -> ! {
|
||||
devfs::init();
|
||||
PLATFORM.init(true).unwrap();
|
||||
|
||||
let dt = ARCHITECTURE.dt.get();
|
||||
if let Err(e) = smp::start_ap_cores(dt) {
|
||||
errorln!(
|
||||
"Could not initialize AP CPUs: {:?}. Will continue with one CPU.",
|
||||
e
|
||||
);
|
||||
}
|
||||
// let dt = ARCHITECTURE.dt.get();
|
||||
// if let Err(e) = smp::start_ap_cores(dt) {
|
||||
// errorln!(
|
||||
// "Could not initialize AP CPUs: {:?}. Will continue with one CPU.",
|
||||
// e
|
||||
// );
|
||||
// }
|
||||
|
||||
Cpu::init_ipi_queues();
|
||||
|
||||
|
@ -5,8 +5,10 @@ use core::{
|
||||
sync::atomic::{AtomicU8, Ordering},
|
||||
};
|
||||
|
||||
use aarch64_cpu::registers::DAIF;
|
||||
use abi::error::Error;
|
||||
use bitflags::bitflags;
|
||||
use tock_registers::interfaces::Readable;
|
||||
|
||||
use crate::mem::{
|
||||
phys::{self, PageUsage},
|
||||
@ -77,6 +79,8 @@ bitflags! {
|
||||
const AP_BOTH_READWRITE = 1 << 6;
|
||||
/// For page/block mappings, only allows read access for EL0/EL1
|
||||
const AP_BOTH_READONLY = 3 << 6;
|
||||
|
||||
const NON_GLOBAL = 1 << 11;
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,8 +305,6 @@ impl FixedTables {
|
||||
}
|
||||
self.device_l3i += count;
|
||||
|
||||
tlb_flush_vaae1(virt);
|
||||
|
||||
Ok(virt)
|
||||
}
|
||||
}
|
||||
@ -315,6 +317,9 @@ impl VirtualMemoryManager for AddressSpace {
|
||||
len: usize,
|
||||
attrs: PageAttributes,
|
||||
) -> Result<usize, Error> {
|
||||
assert_eq!(DAIF.read(DAIF::I), 1);
|
||||
|
||||
assert_eq!(len, 1);
|
||||
if hint.is_some() {
|
||||
todo!();
|
||||
}
|
||||
@ -341,12 +346,17 @@ impl VirtualMemoryManager for AddressSpace {
|
||||
}
|
||||
|
||||
fn deallocate(&self, addr: usize, len: usize) -> Result<(), Error> {
|
||||
assert_eq!(DAIF.read(DAIF::I), 1);
|
||||
|
||||
for page in (addr..addr + len).step_by(0x1000) {
|
||||
let Some(_phys) = self.translate(page) else {
|
||||
let Some(phys) = self.translate(page) else {
|
||||
todo!();
|
||||
};
|
||||
|
||||
self.write_entry(page, PageEntry::INVALID, true)?;
|
||||
unsafe {
|
||||
phys::free_page(phys);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -402,6 +412,8 @@ impl AddressSpace {
|
||||
}
|
||||
l3[l3i] = entry;
|
||||
|
||||
tlb_flush_vaae1(virt);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -416,11 +428,11 @@ impl AddressSpace {
|
||||
}
|
||||
}
|
||||
|
||||
/// Flushes the virtual address from TLB
|
||||
pub fn tlb_flush_vaae1(page: usize) {
|
||||
assert_eq!(page & 0xFFF, 0);
|
||||
/// Flush a virtual address from EL1/EL0 TLB for all ASIDs
|
||||
pub fn tlb_flush_vaae1(mut page: usize) {
|
||||
page >>= 12;
|
||||
unsafe {
|
||||
core::arch::asm!("tlbi vaae1, {addr}", addr = in(reg) page);
|
||||
core::arch::asm!("tlbi vaae1, {page}", page = in(reg) page);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,14 @@ impl PhysicalMemoryManager {
|
||||
Err(Error::OutOfMemory)
|
||||
}
|
||||
|
||||
pub unsafe fn free_page(&mut self, addr: usize) {
|
||||
assert!(addr > self.offset);
|
||||
let index = (addr - self.offset) / 0x1000;
|
||||
let page = &mut self.pages[index];
|
||||
assert_eq!(page.usage, PageUsage::Used);
|
||||
page.usage = PageUsage::Available;
|
||||
}
|
||||
|
||||
/// Marks a previously reserved page as available.
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -10,6 +10,7 @@ use crate::{
|
||||
phys::reserved::{is_reserved, reserve_region},
|
||||
ConvertAddress, KERNEL_PHYS_BASE,
|
||||
},
|
||||
sync::IrqSafeSpinlock,
|
||||
util::OneTimeInit,
|
||||
};
|
||||
|
||||
@ -64,7 +65,8 @@ impl PhysicalMemoryRegion {
|
||||
}
|
||||
|
||||
/// Global physical memory manager
|
||||
pub static PHYSICAL_MEMORY: OneTimeInit<Spinlock<PhysicalMemoryManager>> = OneTimeInit::new();
|
||||
pub static PHYSICAL_MEMORY: OneTimeInit<IrqSafeSpinlock<PhysicalMemoryManager>> =
|
||||
OneTimeInit::new();
|
||||
|
||||
/// Allocates a single physical page from the global manager
|
||||
pub fn alloc_page(usage: PageUsage) -> Result<usize, Error> {
|
||||
@ -79,6 +81,10 @@ pub fn alloc_pages_contiguous(count: usize, usage: PageUsage) -> Result<usize, E
|
||||
.alloc_contiguous_pages(count, usage)
|
||||
}
|
||||
|
||||
pub unsafe fn free_page(addr: usize) {
|
||||
PHYSICAL_MEMORY.get().lock().free_page(addr)
|
||||
}
|
||||
|
||||
fn physical_memory_range<I: Iterator<Item = PhysicalMemoryRegion>>(
|
||||
it: I,
|
||||
) -> Option<(usize, usize)> {
|
||||
@ -182,7 +188,7 @@ pub unsafe fn init_from_iter<I: Iterator<Item = PhysicalMemoryRegion> + Clone>(
|
||||
|
||||
infoln!("{} available pages", page_count);
|
||||
|
||||
PHYSICAL_MEMORY.init(Spinlock::new(manager));
|
||||
PHYSICAL_MEMORY.init(IrqSafeSpinlock::new(manager));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ where
|
||||
(_, 0) => PageAttributes::AP_BOTH_READWRITE,
|
||||
(0, _) => PageAttributes::AP_BOTH_READONLY,
|
||||
(_, _) => PageAttributes::AP_BOTH_READWRITE,
|
||||
};
|
||||
} | PageAttributes::NON_GLOBAL;
|
||||
|
||||
let dst_page_off = addr & 0xFFF;
|
||||
let dst_page_aligned = addr & !0xFFF;
|
||||
|
@ -32,7 +32,11 @@ fn setup_args(space: &AddressSpace, virt: usize, args: &[&str]) -> Result<(), Er
|
||||
|
||||
let phys_page = phys::alloc_page(PageUsage::Used)?;
|
||||
// TODO check if this doesn't overwrite anything
|
||||
space.map_page(virt, phys_page, PageAttributes::AP_BOTH_READWRITE)?;
|
||||
space.map_page(
|
||||
virt,
|
||||
phys_page,
|
||||
PageAttributes::AP_BOTH_READWRITE | PageAttributes::NON_GLOBAL,
|
||||
)?;
|
||||
|
||||
let write = unsafe { phys_page.virtualize() };
|
||||
|
||||
@ -70,7 +74,7 @@ fn setup_args(space: &AddressSpace, virt: usize, args: &[&str]) -> Result<(), Er
|
||||
fn setup_binary(space: AddressSpace, entry: usize, args: &[&str]) -> Result<Rc<Process>, Error> {
|
||||
const USER_STACK_PAGES: usize = 8;
|
||||
|
||||
let virt_stack_base = 0x10000000;
|
||||
let virt_stack_base = 0x3000000;
|
||||
// 0x1000 of guard page
|
||||
let virt_args_base = virt_stack_base + (USER_STACK_PAGES + 1) * 0x1000;
|
||||
|
||||
@ -79,7 +83,7 @@ fn setup_binary(space: AddressSpace, entry: usize, args: &[&str]) -> Result<Rc<P
|
||||
space.map_page(
|
||||
virt_stack_base + i * 0x1000,
|
||||
phys,
|
||||
PageAttributes::AP_BOTH_READWRITE,
|
||||
PageAttributes::AP_BOTH_READWRITE | PageAttributes::NON_GLOBAL,
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use core::alloc::Layout;
|
||||
|
||||
use abi::io::RawFd;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
pub(super) fn arg_buffer_ref<'a>(base: usize, len: usize) -> Result<&'a [u8], Error> {
|
||||
@ -18,6 +19,9 @@ pub(super) fn arg_buffer_mut<'a>(base: usize, len: usize) -> Result<&'a mut [u8]
|
||||
|
||||
pub(super) fn arg_user_str<'a>(base: usize, len: usize) -> Result<&'a str, Error> {
|
||||
let slice = arg_buffer_ref(base, len)?;
|
||||
if slice.contains(&0) {
|
||||
todo!("Incorrect ptr: {:#x}", base);
|
||||
}
|
||||
Ok(core::str::from_utf8(slice).unwrap())
|
||||
}
|
||||
|
||||
@ -30,3 +34,29 @@ pub(super) fn arg_user_ref<'a, T: Sized>(addr: usize) -> Result<&'a T, Error> {
|
||||
let value = unsafe { core::mem::transmute::<_, &'a T>(addr) };
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub(super) fn arg_user_slice_mut<'a, T: Sized>(
|
||||
base: usize,
|
||||
count: usize,
|
||||
) -> Result<&'a mut [T], Error> {
|
||||
let layout = Layout::array::<T>(count).unwrap();
|
||||
|
||||
if base % layout.align() != 0 {
|
||||
todo!("Misaligned buffer");
|
||||
}
|
||||
|
||||
if base + layout.size() > crate::mem::KERNEL_VIRT_OFFSET {
|
||||
panic!("Invalid argument");
|
||||
}
|
||||
|
||||
let slice = unsafe { core::slice::from_raw_parts_mut(base as *mut _, count) };
|
||||
Ok(slice)
|
||||
}
|
||||
|
||||
pub(super) fn arg_option_fd(raw: u32) -> Option<RawFd> {
|
||||
if raw == u32::MAX {
|
||||
None
|
||||
} else {
|
||||
Some(RawFd(raw))
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! System function call handlers
|
||||
use core::time::Duration;
|
||||
use core::{mem::MaybeUninit, sync::atomic::AtomicUsize, time::Duration};
|
||||
|
||||
use abi::{
|
||||
error::Error,
|
||||
io::{FileMode, OpenOptions, RawFd},
|
||||
io::{DirectoryEntry, FileMode, OpenOptions, RawFd},
|
||||
syscall::SyscallFunction,
|
||||
};
|
||||
use vfs::{Read, Write};
|
||||
use vfs::{Read, ReadDirectory, Write};
|
||||
use yggdrasil_abi::{
|
||||
error::SyscallResult,
|
||||
io::{MountOptions, UnmountOptions},
|
||||
@ -58,10 +58,11 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
todo!();
|
||||
}
|
||||
|
||||
let addr = space.allocate(None, len / 0x1000, PageAttributes::AP_BOTH_READWRITE);
|
||||
debugln!("mmap({:#x}) = {:x?}", len, addr);
|
||||
|
||||
addr
|
||||
space.allocate(
|
||||
None,
|
||||
len / 0x1000,
|
||||
PageAttributes::AP_BOTH_READWRITE | PageAttributes::NON_GLOBAL,
|
||||
)
|
||||
}
|
||||
SyscallFunction::UnmapMemory => {
|
||||
let addr = args[0] as usize;
|
||||
@ -74,7 +75,6 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
todo!();
|
||||
}
|
||||
|
||||
debugln!("munmap({:#x}, {:#x})", addr, len);
|
||||
space.deallocate(addr, len)?;
|
||||
|
||||
Ok(0)
|
||||
@ -154,6 +154,37 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
SyscallFunction::OpenDirectory => {
|
||||
let at = arg_option_fd(args[0] as u32);
|
||||
let path = arg_user_str(args[1] as usize, args[2] as usize)?;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
// TODO handle at
|
||||
assert!(at.is_none());
|
||||
|
||||
let node = io.ioctx().find(None, path, true, true)?;
|
||||
let file = node.open_directory()?;
|
||||
let fd = io.place_file(file)?;
|
||||
|
||||
Ok(fd.0 as usize)
|
||||
}
|
||||
SyscallFunction::ReadDirectory => {
|
||||
let fd = RawFd(args[0] as u32);
|
||||
let buffer = arg_user_slice_mut::<MaybeUninit<DirectoryEntry>>(
|
||||
args[1] as usize,
|
||||
args[2] as usize,
|
||||
)?;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
let file = io.file(fd)?;
|
||||
let mut file_borrow = file.borrow_mut();
|
||||
|
||||
file_borrow.read_dir_entries(buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user