Add guards for log operations and inode locking

This commit is contained in:
Garen Tyler 2023-10-28 22:31:29 -06:00
parent 9b7eb552d0
commit 41b7bc7555
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
2 changed files with 53 additions and 15 deletions

View File

@ -76,6 +76,25 @@ pub struct Inode {
addresses: [u32; crate::fs::NDIRECT + 1], addresses: [u32; crate::fs::NDIRECT + 1],
} }
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)]
@ -177,9 +196,8 @@ pub unsafe extern "C" fn fileclose(file: *mut File) {
match f.kind { match f.kind {
FileType::Pipe => pipe::pipeclose(f.pipe, f.writable as i32), FileType::Pipe => pipe::pipeclose(f.pipe, f.writable as i32),
FileType::Inode | FileType::Device => { FileType::Inode | FileType::Device => {
log::begin_op(); let _operation = log::LogOperation::new();
super::iput(f.ip); super::iput(f.ip);
log::end_op();
} }
FileType::None => {} FileType::None => {}
} }
@ -195,9 +213,10 @@ pub unsafe extern "C" fn filestat(file: *mut File, addr: u64) -> i32 {
let mut stat = Stat::default(); let mut stat = Stat::default();
if (*file).kind == FileType::Inode || (*file).kind == FileType::Device { if (*file).kind == FileType::Inode || (*file).kind == FileType::Device {
super::ilock((*file).ip); {
let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap());
super::stati((*file).ip, addr_of_mut!(stat)); super::stati((*file).ip, addr_of_mut!(stat));
super::iunlock((*file).ip); }
if copyout( if copyout(
(*p).pagetable, (*p).pagetable,
@ -237,12 +256,11 @@ pub unsafe extern "C" fn fileread(file: *mut File, addr: u64, n: i32) -> i32 {
read(1, addr, n) read(1, addr, n)
} }
FileType::Inode => { FileType::Inode => {
super::ilock((*file).ip); let _guard = InodeLockGuard::new((*file).ip.as_mut().unwrap());
let r = super::readi((*file).ip, 1, addr, (*file).off, n as u32); let r = super::readi((*file).ip, 1, addr, (*file).off, n as u32);
if r > 0 { if r > 0 {
(*file).off += r as u32; (*file).off += r as u32;
} }
super::iunlock((*file).ip);
r r
} }
_ => panic!("fileread"), _ => panic!("fileread"),
@ -285,14 +303,16 @@ pub unsafe extern "C" fn filewrite(file: *mut File, addr: u64, n: i32) -> i32 {
n1 = max as i32; n1 = max as i32;
} }
log::begin_op(); let r = {
super::ilock((*file).ip); 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, n1 as u32); let r = super::writei((*file).ip, 1, addr + i as u64, (*file).off, n1 as u32);
if r > 0 { if r > 0 {
(*file).off += r as u32; (*file).off += r as u32;
} }
super::iunlock((*file).ip); r
log::end_op(); };
if r != n1 { if r != n1 {
// Error from writei. // Error from writei.

View File

@ -25,3 +25,21 @@ extern "C" {
pub fn end_op(); pub fn end_op();
pub fn log_write(buffer: *mut Buffer); pub fn log_write(buffer: *mut Buffer);
} }
#[derive(Default)]
pub struct LogOperation;
impl LogOperation {
pub fn new() -> LogOperation {
unsafe {
begin_op();
}
LogOperation
}
}
impl core::ops::Drop for LogOperation {
fn drop(&mut self) {
unsafe {
end_op();
}
}
}