extract inode into new module
This commit is contained in:
parent
52cad30dad
commit
089e6d2cc1
@ -1,11 +1,12 @@
|
|||||||
//! Support functions for system calls that involve file descriptors.
|
//! Support functions for system calls that involve file descriptors.
|
||||||
|
|
||||||
|
use super::inode::{iput, readi, stati, writei, Inode, InodeLockGuard};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::virtual_memory::copyout,
|
arch::virtual_memory::copyout,
|
||||||
fs::{log, stat::Stat},
|
fs::{log, stat::Stat},
|
||||||
io::pipe::Pipe,
|
io::pipe::Pipe,
|
||||||
proc::process::Process,
|
proc::process::Process,
|
||||||
sync::{mutex::Mutex, sleeplock::Sleeplock, spinlock::Spinlock},
|
sync::mutex::Mutex,
|
||||||
};
|
};
|
||||||
use core::ptr::{addr_of_mut, null_mut};
|
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.
|
/// Map major device number to device functions.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Default)]
|
#[derive(Copy, Clone, Default)]
|
||||||
@ -114,12 +69,6 @@ impl Devsw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct FileTable {
|
|
||||||
lock: Spinlock,
|
|
||||||
files: [File; crate::NFILE],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub static mut devsw: [Devsw; crate::NDEV] = [Devsw::new(); crate::NDEV];
|
pub static mut devsw: [Devsw; crate::NDEV] = [Devsw::new(); crate::NDEV];
|
||||||
pub static FILES: Mutex<[File; crate::NFILE]> = Mutex::new([File::uninitialized(); crate::NFILE]);
|
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::Pipe => (*f.pipe).close(f.writable as i32),
|
||||||
FileType::Inode | FileType::Device => {
|
FileType::Inode | FileType::Device => {
|
||||||
let _operation = log::LogOperation::new();
|
let _operation = log::LogOperation::new();
|
||||||
super::iput(f.ip);
|
iput(f.ip);
|
||||||
}
|
}
|
||||||
FileType::None => {}
|
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 {
|
if (*file).kind == FileType::Inode || (*file).kind == FileType::Device {
|
||||||
{
|
{
|
||||||
let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap());
|
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(
|
if copyout(
|
||||||
@ -237,7 +186,7 @@ pub unsafe fn fileread(file: *mut File, addr: u64, num_bytes: i32) -> i32 {
|
|||||||
}
|
}
|
||||||
FileType::Inode => {
|
FileType::Inode => {
|
||||||
let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap());
|
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 {
|
if r > 0 {
|
||||||
(*file).off += r as u32;
|
(*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 _operation = log::LogOperation::new();
|
||||||
let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap());
|
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 {
|
if r > 0 {
|
||||||
(*file).off += r as u32;
|
(*file).off += r as u32;
|
||||||
}
|
}
|
||||||
|
66
kernel/rustkernel/src/fs/inode.rs
Normal file
66
kernel/rustkernel/src/fs/inode.rs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,10 @@
|
|||||||
//! Both the kernel and user programs use this header file.
|
//! Both the kernel and user programs use this header file.
|
||||||
|
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
pub mod inode;
|
||||||
pub mod log;
|
pub mod log;
|
||||||
pub mod stat;
|
pub mod stat;
|
||||||
|
|
||||||
use crate::fs::file::Inode;
|
|
||||||
|
|
||||||
// Root inode
|
// Root inode
|
||||||
pub const ROOTINO: u64 = 1;
|
pub const ROOTINO: u64 = 1;
|
||||||
/// Block size.
|
/// Block size.
|
||||||
@ -86,18 +85,4 @@ pub struct DirectoryEntry {
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn fsinit(dev: i32);
|
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()
|
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ pub unsafe fn main() -> ! {
|
|||||||
arch::interrupt::init();
|
arch::interrupt::init();
|
||||||
arch::interrupt::inithart();
|
arch::interrupt::inithart();
|
||||||
io::bio::binit();
|
io::bio::binit();
|
||||||
fs::iinit();
|
fs::inode::iinit();
|
||||||
hardware::virtio_disk::virtio_disk_init();
|
hardware::virtio_disk::virtio_disk_init();
|
||||||
proc::process::userinit();
|
proc::process::userinit();
|
||||||
STARTED = true;
|
STARTED = true;
|
||||||
|
@ -15,8 +15,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
fs::{
|
fs::{
|
||||||
file::{fileclose, filedup, File, Inode},
|
file::{fileclose, filedup, File},
|
||||||
idup, iput,
|
inode::{idup, iput, Inode},
|
||||||
log::LogOperation,
|
log::LogOperation,
|
||||||
},
|
},
|
||||||
mem::{
|
mem::{
|
||||||
|
@ -5,8 +5,8 @@ use crate::{
|
|||||||
virtual_memory::{copyin, copyinstr},
|
virtual_memory::{copyin, copyinstr},
|
||||||
},
|
},
|
||||||
fs::{
|
fs::{
|
||||||
self,
|
|
||||||
file::{self, File},
|
file::{self, File},
|
||||||
|
inode::{ilock, iput, iunlock, namei},
|
||||||
log::LogOperation,
|
log::LogOperation,
|
||||||
stat::KIND_DIR,
|
stat::KIND_DIR,
|
||||||
},
|
},
|
||||||
@ -112,18 +112,18 @@ impl Syscall {
|
|||||||
if argstr(0, addr_of_mut!(path).cast(), path.len() as i32) < 0 {
|
if argstr(0, addr_of_mut!(path).cast(), path.len() as i32) < 0 {
|
||||||
return -1i64 as u64;
|
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() {
|
if inode.is_null() {
|
||||||
return -1i64 as u64;
|
return -1i64 as u64;
|
||||||
}
|
}
|
||||||
fs::ilock(inode);
|
ilock(inode);
|
||||||
if (*inode).kind != KIND_DIR {
|
if (*inode).kind != KIND_DIR {
|
||||||
fs::iunlock(inode);
|
iunlock(inode);
|
||||||
fs::iput(inode);
|
iput(inode);
|
||||||
return -1i64 as u64;
|
return -1i64 as u64;
|
||||||
}
|
}
|
||||||
fs::iunlock(inode);
|
iunlock(inode);
|
||||||
fs::iput(proc.current_dir);
|
iput(proc.current_dir);
|
||||||
proc.current_dir = inode;
|
proc.current_dir = inode;
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user