diff --git a/kernel/rustkernel/src/fs/file.rs b/kernel/rustkernel/src/fs/file.rs index 9a7d93f..761324a 100644 --- a/kernel/rustkernel/src/fs/file.rs +++ b/kernel/rustkernel/src/fs/file.rs @@ -1,11 +1,12 @@ //! Support functions for system calls that involve file descriptors. +use super::inode::{iput, readi, stati, writei, Inode, InodeLockGuard}; use crate::{ arch::virtual_memory::copyout, fs::{log, stat::Stat}, io::pipe::Pipe, proc::process::Process, - sync::{mutex::Mutex, sleeplock::Sleeplock, spinlock::Spinlock}, + sync::mutex::Mutex, }; use core::ptr::{addr_of_mut, null_mut}; @@ -52,52 +53,6 @@ impl File { } } -#[repr(C)] -pub struct Inode { - /// Device number. - pub device: u32, - /// Inode number. - pub inum: u32, - /// Reference count. - pub references: i32, - - pub lock: Sleeplock, - /// Inode has been read from disk? - pub valid: i32, - - // Copy of DiskInode - pub kind: i16, - pub major: i16, - pub minor: i16, - pub num_links: i16, - pub size: u32, - pub addresses: [u32; crate::fs::NDIRECT + 1], -} -impl Inode { - pub fn lock(&mut self) -> InodeLockGuard<'_> { - InodeLockGuard::new(self) - } -} - -pub struct InodeLockGuard<'i> { - pub inode: &'i mut Inode, -} -impl<'i> InodeLockGuard<'i> { - pub fn new(inode: &mut Inode) -> InodeLockGuard<'_> { - unsafe { - super::ilock(inode as *mut Inode); - } - InodeLockGuard { inode } - } -} -impl<'i> core::ops::Drop for InodeLockGuard<'i> { - fn drop(&mut self) { - unsafe { - super::iunlock(self.inode as *mut Inode); - } - } -} - /// Map major device number to device functions. #[repr(C)] #[derive(Copy, Clone, Default)] @@ -114,12 +69,6 @@ impl Devsw { } } -#[repr(C)] -pub struct FileTable { - lock: Spinlock, - files: [File; crate::NFILE], -} - #[no_mangle] pub static mut devsw: [Devsw; crate::NDEV] = [Devsw::new(); crate::NDEV]; pub static FILES: Mutex<[File; crate::NFILE]> = Mutex::new([File::uninitialized(); crate::NFILE]); @@ -176,7 +125,7 @@ pub unsafe extern "C" fn fileclose(file: *mut File) { FileType::Pipe => (*f.pipe).close(f.writable as i32), FileType::Inode | FileType::Device => { let _operation = log::LogOperation::new(); - super::iput(f.ip); + iput(f.ip); } FileType::None => {} } @@ -193,7 +142,7 @@ pub unsafe fn filestat(file: *mut File, addr: u64) -> i32 { if (*file).kind == FileType::Inode || (*file).kind == FileType::Device { { let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap()); - super::stati((*file).ip, addr_of_mut!(stat)); + stati((*file).ip, addr_of_mut!(stat)); } if copyout( @@ -237,7 +186,7 @@ pub unsafe fn fileread(file: *mut File, addr: u64, num_bytes: i32) -> i32 { } FileType::Inode => { let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap()); - let r = super::readi((*file).ip, 1, addr, (*file).off, num_bytes as u32); + let r = readi((*file).ip, 1, addr, (*file).off, num_bytes as u32); if r > 0 { (*file).off += r as u32; } @@ -289,7 +238,7 @@ pub unsafe fn filewrite(file: *mut File, addr: u64, num_bytes: i32) -> i32 { let _operation = log::LogOperation::new(); let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap()); - let r = super::writei((*file).ip, 1, addr + i as u64, (*file).off, n as u32); + let r = writei((*file).ip, 1, addr + i as u64, (*file).off, n as u32); if r > 0 { (*file).off += r as u32; } diff --git a/kernel/rustkernel/src/fs/inode.rs b/kernel/rustkernel/src/fs/inode.rs new file mode 100644 index 0000000..a26ae28 --- /dev/null +++ b/kernel/rustkernel/src/fs/inode.rs @@ -0,0 +1,66 @@ +use super::stat::Stat; +use crate::sync::sleeplock::Sleeplock; + +extern "C" { + pub fn iinit(); + pub fn ialloc(dev: u32, kind: i16) -> *mut Inode; + pub fn iupdate(ip: *mut Inode); + pub fn idup(ip: *mut Inode) -> *mut Inode; + pub fn ilock(ip: *mut Inode); + pub fn iunlock(ip: *mut Inode); + pub fn iput(ip: *mut Inode); + pub fn iunlockput(ip: *mut Inode); + pub fn itrunc(ip: *mut Inode); + pub fn stati(ip: *mut Inode, st: *mut Stat); + pub fn readi(ip: *mut Inode, user_dst: i32, dst: u64, off: u32, n: u32) -> i32; + pub fn writei(ip: *mut Inode, user_src: i32, src: u64, off: u32, n: u32) -> i32; + pub fn namei(path: *mut u8) -> *mut Inode; + // pub fn namecmp() +} + +#[repr(C)] +#[derive(Clone)] +pub struct Inode { + /// Device number. + pub device: u32, + /// Inode number. + pub inum: u32, + /// Reference count. + pub references: i32, + + pub lock: Sleeplock, + /// Inode has been read from disk? + pub valid: i32, + + // Copy of DiskInode + pub kind: i16, + pub major: i16, + pub minor: i16, + pub num_links: i16, + pub size: u32, + pub addresses: [u32; crate::fs::NDIRECT + 1], +} +impl Inode { + pub fn lock(&mut self) -> InodeLockGuard<'_> { + InodeLockGuard::new(self) + } +} + +pub struct InodeLockGuard<'i> { + pub inode: &'i mut Inode, +} +impl<'i> InodeLockGuard<'i> { + pub fn new(inode: &mut Inode) -> InodeLockGuard<'_> { + unsafe { + ilock(inode as *mut Inode); + } + InodeLockGuard { inode } + } +} +impl<'i> core::ops::Drop for InodeLockGuard<'i> { + fn drop(&mut self) { + unsafe { + iunlock(self.inode as *mut Inode); + } + } +} diff --git a/kernel/rustkernel/src/fs/mod.rs b/kernel/rustkernel/src/fs/mod.rs index 458997b..23e42c0 100644 --- a/kernel/rustkernel/src/fs/mod.rs +++ b/kernel/rustkernel/src/fs/mod.rs @@ -2,11 +2,10 @@ //! Both the kernel and user programs use this header file. pub mod file; +pub mod inode; pub mod log; pub mod stat; -use crate::fs::file::Inode; - // Root inode pub const ROOTINO: u64 = 1; /// Block size. @@ -86,18 +85,4 @@ pub struct DirectoryEntry { extern "C" { pub fn fsinit(dev: i32); - pub fn iinit(); - pub fn ialloc(dev: u32, kind: i16) -> *mut DiskInode; - pub fn iupdate(ip: *mut DiskInode); - pub fn idup(ip: *mut Inode) -> *mut Inode; - pub fn ilock(ip: *mut Inode); - pub fn iunlock(ip: *mut Inode); - pub fn iput(ip: *mut Inode); - pub fn iunlockput(ip: *mut DiskInode); - pub fn itrunc(ip: *mut DiskInode); - pub fn stati(ip: *mut Inode, st: *mut stat::Stat); - pub fn readi(ip: *mut Inode, user_dst: i32, dst: u64, off: u32, n: u32) -> i32; - pub fn writei(ip: *mut Inode, user_src: i32, src: u64, off: u32, n: u32) -> i32; - pub fn namei(path: *mut u8) -> *mut Inode; - // pub fn namecmp() } diff --git a/kernel/rustkernel/src/lib.rs b/kernel/rustkernel/src/lib.rs index 38820da..fd341a8 100644 --- a/kernel/rustkernel/src/lib.rs +++ b/kernel/rustkernel/src/lib.rs @@ -67,7 +67,7 @@ pub unsafe fn main() -> ! { arch::interrupt::init(); arch::interrupt::inithart(); io::bio::binit(); - fs::iinit(); + fs::inode::iinit(); hardware::virtio_disk::virtio_disk_init(); proc::process::userinit(); STARTED = true; diff --git a/kernel/rustkernel/src/proc/process.rs b/kernel/rustkernel/src/proc/process.rs index f50ef8a..cec756a 100644 --- a/kernel/rustkernel/src/proc/process.rs +++ b/kernel/rustkernel/src/proc/process.rs @@ -15,8 +15,8 @@ use crate::{ }, }, fs::{ - file::{fileclose, filedup, File, Inode}, - idup, iput, + file::{fileclose, filedup, File}, + inode::{idup, iput, Inode}, log::LogOperation, }, mem::{ diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index b6b2b47..2f39389 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -5,8 +5,8 @@ use crate::{ virtual_memory::{copyin, copyinstr}, }, fs::{ - self, file::{self, File}, + inode::{ilock, iput, iunlock, namei}, log::LogOperation, stat::KIND_DIR, }, @@ -112,18 +112,18 @@ impl Syscall { if argstr(0, addr_of_mut!(path).cast(), path.len() as i32) < 0 { return -1i64 as u64; } - let inode = fs::namei(addr_of_mut!(path).cast()); + let inode = namei(addr_of_mut!(path).cast()); if inode.is_null() { return -1i64 as u64; } - fs::ilock(inode); + ilock(inode); if (*inode).kind != KIND_DIR { - fs::iunlock(inode); - fs::iput(inode); + iunlock(inode); + iput(inode); return -1i64 as u64; } - fs::iunlock(inode); - fs::iput(proc.current_dir); + iunlock(inode); + iput(proc.current_dir); proc.current_dir = inode; 0 }