diff --git a/src/context/context.rs b/src/context/context.rs index 005580244e..3ea1abe8dc 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -5,13 +5,15 @@ use core::{ num::NonZeroUsize, sync::atomic::{AtomicU32, Ordering}, }; -use spin::RwLock; use syscall::{SigProcControl, Sigcontrol, UPPER_FDTBL_TAG}; use crate::{ arch::{interrupt::InterruptStack, paging::PAGE_SIZE}, common::aligned_box::AlignedBox, - context::{self, arch, file::FileDescriptor}, + context::{ + self, arch, + file::{FileDescriptor, LockedFileDescription}, + }, cpu_set::{LogicalCpuId, LogicalCpuSet}, cpu_stats, ipi::{ipi, IpiKind, IpiTarget}, @@ -19,7 +21,7 @@ use crate::{ paging::{RmmA, RmmArch}, percpu::PercpuBlock, scheme::{CallerCtx, FileHandle, SchemeId}, - sync::CleanLockToken, + sync::{CleanLockToken, RwLock, L1}, syscall::usercopy::UserSliceRw, }; @@ -27,7 +29,6 @@ use crate::syscall::error::{Error, Result, EAGAIN, EBADF, EEXIST, EINVAL, EMFILE use super::{ empty_cr3, - file::FileDescription, memory::{AddrSpaceWrapper, GrantFileRef}, }; @@ -130,7 +131,7 @@ pub struct Context { /// The name of the context pub name: ArrayString, /// The open files in the scheme - pub files: Arc>, + pub files: Arc>, /// All contexts except kmain will primarily live in userspace, and enter the kernel only when /// interrupts or syscalls occur. This flag is set for all contexts but kmain. pub userspace: bool, @@ -190,7 +191,7 @@ impl Context { kstack: None, addr_space: None, name: ArrayString::new(), - files: Arc::new(RwLock::new(FdTbl::new())), + files: Arc::new(spin::RwLock::new(FdTbl::new())), userspace: false, fmap_ret: None, being_sigkilled: false, @@ -823,11 +824,12 @@ impl FdTbl { &self, scheme_id: SchemeId, scheme_number: usize, + token: &mut CleanLockToken, ) -> Result { self.iter() .flatten() .find(|&context_fd| { - let desc = context_fd.description.read(); + let desc = context_fd.description.read(token.token()); desc.scheme == scheme_id && desc.number == scheme_number }) .cloned() @@ -940,7 +942,7 @@ impl FdTbl { } pub fn bulk_add_fds( - descriptions: Vec>>, + descriptions: Vec>, payload: UserSliceRw, cloexec: bool, token: &mut CleanLockToken, @@ -973,7 +975,7 @@ pub fn bulk_add_fds( } pub fn bulk_insert_fds( - descriptions: Vec>>, + descriptions: Vec>, payload: UserSliceRw, cloexec: bool, token: &mut CleanLockToken, diff --git a/src/context/file.rs b/src/context/file.rs index 5bc4adbaba..82aa0ffec6 100644 --- a/src/context/file.rs +++ b/src/context/file.rs @@ -3,13 +3,14 @@ use crate::{ event, scheme::{self, SchemeId}, - sync::CleanLockToken, + sync::{CleanLockToken, L1, RwLock}, syscall::error::Result, }; use alloc::sync::Arc; -use spin::RwLock; use syscall::{schemev2::NewFdFlags, RwFlags, O_APPEND, O_NONBLOCK}; +pub type LockedFileDescription = RwLock; + /// A file description #[derive(Clone, Copy, Debug)] pub struct FileDescription { @@ -64,7 +65,7 @@ impl InternalFlags { #[must_use = "File descriptors must be closed"] pub struct FileDescriptor { /// Corresponding file description - pub description: Arc>, + pub description: Arc>, /// Cloexec flag pub cloexec: bool, } @@ -84,7 +85,7 @@ impl FileDescription { impl FileDescriptor { pub fn close(self, token: &mut CleanLockToken) -> Result<()> { { - let description = self.description.read(); + let description = self.description.read(token.token()); if description .internal_flags .contains(InternalFlags::NOTIFY_ON_NEXT_DETACH) diff --git a/src/context/memory.rs b/src/context/memory.rs index beebab74cb..532cb153a8 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -14,11 +14,10 @@ use syscall::{error::*, flag::MapFlags, GrantFlags, MunmapFlags}; use crate::{ arch::paging::PAGE_SIZE, - context::arch::setup_new_utable, + context::{arch::setup_new_utable, file::LockedFileDescription}, cpu_set::LogicalCpuSet, memory::{ - deallocate_frame, get_page_info, init_frame, the_zeroed_frame, AddRefError, Enomem, Frame, - PageInfo, RaiiFrame, RefCount, RefKind, + AddRefError, Enomem, Frame, PageInfo, RaiiFrame, RefCount, RefKind, deallocate_frame, get_page_info, init_frame, the_zeroed_frame }, paging::{Page, PageFlags, PageMapper, RmmA, TableKind, VirtualAddress}, percpu::PercpuBlock, @@ -64,7 +63,7 @@ impl UnmapResult { }; let (scheme_id, number) = { - let desc = description.write(); + let desc = description.write(token.token()); (desc.scheme, desc.number) }; @@ -1144,7 +1143,7 @@ pub struct Grant { #[derive(Clone, Debug)] pub struct GrantFileRef { - pub description: Arc>, + pub description: Arc, pub base_offset: usize, } @@ -2664,7 +2663,7 @@ fn correct_inner<'l>( drop(addr_space_guard); let (scheme_id, scheme_number) = { - let desc = &file_ref.description.read(); + let desc = &file_ref.description.read(token.token()); (desc.scheme, desc.number) }; let user_inner = scheme::get_scheme(token.token(), scheme_id) diff --git a/src/event.rs b/src/event.rs index c23f8d2c66..80767abdeb 100644 --- a/src/event.rs +++ b/src/event.rs @@ -57,7 +57,7 @@ impl EventQueue { }; let (scheme, number) = { - let description = file.description.read(); + let description = file.description.read(token.token()); (description.scheme, description.number) }; diff --git a/src/scheme/memory.rs b/src/scheme/memory.rs index a2f4cb2407..e3817af4c5 100644 --- a/src/scheme/memory.rs +++ b/src/scheme/memory.rs @@ -5,7 +5,7 @@ use rmm::PhysicalAddress; use crate::{ context::{ - file::{FileDescription, InternalFlags}, + file::{FileDescription, InternalFlags, LockedFileDescription}, memory::{handle_notify_files, AddrSpace, AddrSpaceWrapper, Grant, PageSpan}, }, memory::{free_frames, used_frames, Frame, PAGE_SIZE}, @@ -338,7 +338,7 @@ impl KernelScheme for MemoryScheme { fn kstdfscall( &self, id: usize, - _desc: Arc>, + _desc: Arc, payload: UserSliceRw, _flags: CallFlags, metadata: &[u64], diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs index 92b459fb62..110d95c396 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs @@ -17,7 +17,7 @@ use core::{ sync::atomic::{AtomicUsize, Ordering}, }; use hashbrown::hash_map::{DefaultHashBuilder, HashMap}; -use spin::{Once, RwLock as SpinRwLock}; +use spin::Once; use syscall::{ data::{GlobalSchemes, NewFdParams}, error::*, @@ -26,12 +26,9 @@ use syscall::{ use crate::{ context::{ - self, - file::{FileDescription, InternalFlags}, - memory::AddrSpaceWrapper, - ContextLock, + self, ContextLock, file::{FileDescription, InternalFlags, LockedFileDescription}, memory::AddrSpaceWrapper }, - sync::{CleanLockToken, LockToken, RwLock, L0, L1}, + sync::{CleanLockToken, L0, L1, LockToken, RwLock}, syscall::usercopy::{UserSliceRo, UserSliceRw, UserSliceWo}, }; @@ -266,7 +263,7 @@ impl KernelScheme for SchemeList { let scheme = scheme_id; let params = unsafe { user_buf.read_exact::()? }; - return Ok(OpenResult::External(Arc::new(SpinRwLock::new( + return Ok(OpenResult::External(Arc::new(RwLock::new( FileDescription { scheme, number: params.number, @@ -361,7 +358,7 @@ impl KernelScheme for SchemeList { fn kfdwrite( &self, id: usize, - descs: Vec>>, + descs: Vec>, flags: CallFlags, arg: u64, metadata: &[u64], @@ -675,7 +672,7 @@ pub trait KernelScheme: Send + Sync + 'static { fn kstdfscall( &self, id: usize, - desc: Arc>, + desc: Arc, payload: UserSliceRw, flags: CallFlags, metadata: &[u64], @@ -686,7 +683,7 @@ pub trait KernelScheme: Send + Sync + 'static { fn kfdwrite( &self, id: usize, - descs: Vec>>, + descs: Vec>, flags: CallFlags, args: u64, metadata: &[u64], @@ -709,7 +706,7 @@ pub trait KernelScheme: Send + Sync + 'static { #[derive(Debug)] pub enum OpenResult { SchemeLocal(usize, InternalFlags), - External(Arc>), + External(Arc), } pub struct CallerCtx { pub pid: usize, diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs index d054e914f0..91b75f1dca 100644 --- a/src/scheme/pipe.rs +++ b/src/scheme/pipe.rs @@ -4,19 +4,19 @@ use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use syscall::{data::GlobalSchemes, CallFlags}; use hashbrown::{hash_map::DefaultHashBuilder, HashMap}; -use spin::{Mutex, RwLock as SpinRwLock}; +use spin::Mutex; use crate::{ context::{ context::{bulk_add_fds, bulk_insert_fds}, - file::{FileDescription, InternalFlags}, + file::{FileDescription, InternalFlags, LockedFileDescription}, }, event, - sync::{CleanLockToken, RwLock, WaitCondition, L1}, + sync::{CleanLockToken, L1, RwLock, WaitCondition}, syscall::{ data::Stat, - error::{Error, Result, EAGAIN, EBADF, EINTR, EINVAL, ENOENT, EPIPE}, - flag::{EventFlags, EVENT_READ, EVENT_WRITE, MODE_FIFO, O_NONBLOCK}, + error::{EAGAIN, EBADF, EINTR, EINVAL, ENOENT, EPIPE, Error, Result}, + flag::{EVENT_READ, EVENT_WRITE, EventFlags, MODE_FIFO, O_NONBLOCK}, usercopy::{UserSliceRo, UserSliceRw, UserSliceWo}, }, }; @@ -371,7 +371,7 @@ impl KernelScheme for PipeScheme { fn kfdwrite( &self, id: usize, - mut descs: Vec>>, + mut descs: Vec>, _flags: CallFlags, _args: u64, _metadata: &[u64], @@ -499,5 +499,5 @@ pub struct Pipe { reader_is_alive: AtomicBool, // starts set, unset when reader closes writer_is_alive: AtomicBool, // starts set, unset when writer closes has_run_dup: AtomicBool, - fd_queue: Mutex>>>, + fd_queue: Mutex>>, } diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index 732be724ea..e3f1d620d4 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -837,7 +837,7 @@ fn extract_scheme_number(fd: usize, token: &mut CleanLockToken) -> Result<(Kerne .read(token.token()) .get_file(FileHandle::from(fd)) .ok_or(Error::new(EBADF))?; - let desc = file_descriptor.description.read(); + let desc = file_descriptor.description.read(token.token()); let (scheme_id, number) = (desc.scheme, desc.number); let scheme = scheme::get_scheme(token.token(), scheme_id)?; diff --git a/src/scheme/sys/fdstat.rs b/src/scheme/sys/fdstat.rs index 8e2686de88..e462f4e9aa 100644 --- a/src/scheme/sys/fdstat.rs +++ b/src/scheme/sys/fdstat.rs @@ -29,7 +29,7 @@ pub fn resource(token: &mut CleanLockToken) -> Result> { owners: HashMap, String>, scheme: Box, } - let mut map = HashMap::>, Descr>::new(); + let mut map = HashMap::, Descr>::new(); let mut report = String::new(); 'contexts: for context in context::contexts(token.token()) diff --git a/src/scheme/sys/iostat.rs b/src/scheme/sys/iostat.rs index cc218d9417..0315f36772 100644 --- a/src/scheme/sys/iostat.rs +++ b/src/scheme/sys/iostat.rs @@ -40,7 +40,7 @@ fn inner(fpath_user: UserSliceRw, token: &mut CleanLockToken) -> Result> Some(ref file) => file.clone(), }; - let description = file.description.read(); + let description = file.description.read(token.token()); let _ = write!( string, diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 6085d17afe..494c0f5e2a 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -4,7 +4,7 @@ use alloc::{ }; use core::{mem, mem::size_of, num::NonZeroUsize}; use slab::Slab; -use spin::{Mutex, RwLock}; +use spin::Mutex; use syscall::{ schemev2::{Cqe, CqeOpcode, Opcode, Sqe, SqeFlags}, CallFlags, FmoveFdFlags, FobtainFdFlags, MunmapFlags, RecvFdFlags, SchemeSocketCall, @@ -15,7 +15,7 @@ use crate::{ context::{ self, context::{bulk_add_fds, bulk_insert_fds, HardBlockedReason}, - file::{FileDescription, FileDescriptor, InternalFlags}, + file::{FileDescription, FileDescriptor, InternalFlags, LockedFileDescription}, memory::{ AddrSpace, AddrSpaceWrapper, BorrowedFmapSource, Grant, GrantFileRef, MmapMode, PageSpan, DANGLING, @@ -26,7 +26,7 @@ use crate::{ memory::Frame, paging::{Page, VirtualAddress, PAGE_SIZE}, scheme::SchemeId, - sync::{CleanLockToken, WaitQueue}, + sync::{CleanLockToken, RwLock, WaitQueue}, syscall::{ data::Map, error::*, @@ -50,7 +50,7 @@ pub struct UserInner { enum State { Waiting { context: Weak, - fds: Vec>>, + fds: Vec>, callee_responsible: PageSpan, canceling: bool, }, @@ -62,8 +62,8 @@ enum State { #[derive(Debug)] enum Response { Regular(Result, u8, bool), - Fd(Arc>), - MultipleFds(Option>>>), + Fd(Arc), + MultipleFds(Option>>), } impl Response { @@ -176,7 +176,7 @@ impl UserInner { fn call( &self, ctx: CallerCtx, - fds: Vec>>, + fds: Vec>, opcode: Opcode, args: impl Args, caller_responsible: &mut PageSpan, @@ -203,7 +203,7 @@ impl UserInner { fn call_inner( &self, - fds: Vec>>, + fds: Vec>, sqe: Sqe, caller_responsible: &mut PageSpan, token: &mut CleanLockToken, @@ -1011,7 +1011,10 @@ impl UserInner { let (pid, desc) = { let context_lock = context::current(); let context = context_lock.read(token.token()); - let desc = context.files.read().find_by_scheme(self.scheme_id, file)?; + let desc = context + .files + .read() + .find_by_scheme(self.scheme_id, file, token)?; (context.pid, desc.description) }; @@ -1103,7 +1106,7 @@ impl UserInner { pub fn call_fdwrite( &self, - descs: Vec>>, + descs: Vec>, flags: CallFlags, _arg: u64, metadata: &[u64], @@ -1135,7 +1138,7 @@ impl UserInner { fn handle_movefd( &self, - descs: Vec>>, + descs: Vec>, request_id: usize, _flags: FmoveFdFlags, ) -> Result { @@ -1913,7 +1916,7 @@ impl KernelScheme for UserScheme { fn kstdfscall( &self, id: usize, - desc: Arc>, + desc: Arc, payload: UserSliceRw, _flags: CallFlags, metadata: &[u64], @@ -1947,7 +1950,7 @@ impl KernelScheme for UserScheme { match inner.call_inner(Vec::new(), sqe, address.span(), token)? { Response::Regular(res, _, notify_on_detach) => { address.release(token)?; - desc.write() + desc.write(token.token()) .internal_flags .set(InternalFlags::NOTIFY_ON_NEXT_DETACH, notify_on_detach); res @@ -1962,7 +1965,7 @@ impl KernelScheme for UserScheme { fn kfdwrite( &self, number: usize, - descs: Vec>>, + descs: Vec>, flags: CallFlags, arg: u64, _metadata: &[u64], diff --git a/src/sync/ordered.rs b/src/sync/ordered.rs index 4dc50fb36b..57cb67ee98 100644 --- a/src/sync/ordered.rs +++ b/src/sync/ordered.rs @@ -270,6 +270,7 @@ impl<'a, L: Level, T: ?Sized + 'a> core::ops::DerefMut for MutexGuard<'a, L, T> } } +#[derive(Debug)] pub struct RwLock { inner: spin::RwLock, _phantom: PhantomData, diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 0b97cecfff..1883e1f160 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -4,17 +4,16 @@ use core::{mem::size_of, num::NonZeroUsize}; use alloc::{string::String, sync::Arc, vec::Vec}; use redox_path::RedoxPath; -use spin::RwLock; use crate::{ context::{ self, - file::{FileDescription, FileDescriptor, InternalFlags}, + file::{FileDescription, FileDescriptor, InternalFlags, LockedFileDescription}, memory::{AddrSpace, GenericFlusher, Grant, PageSpan, TlbShootdownActions}, }, paging::{Page, VirtualAddress, PAGE_SIZE}, scheme::{self, FileHandle, KernelScheme, OpenResult, StrOrBytes}, - sync::CleanLockToken, + sync::{CleanLockToken, RwLock}, syscall::{data::Stat, error::*, flag::*}, }; @@ -32,7 +31,7 @@ pub fn file_op_generic_ext( token: &mut CleanLockToken, op: impl FnOnce( &dyn KernelScheme, - Arc>, + Arc, FileDescription, &mut CleanLockToken, ) -> Result, @@ -42,7 +41,7 @@ pub fn file_op_generic_ext( .read(token.token()) .get_file(fd) .ok_or(Error::new(EBADF))?; - let desc = *file.description.read(); + let desc = *file.description.read(token.token()); (file, desc) }; @@ -79,7 +78,7 @@ pub fn openat( .get_file(fh) .ok_or(Error::new(EBADF))?; - let description = pipe.description.read(); + let description = pipe.description.read(token.token()); let caller_ctx = context::current() .read(token.token()) @@ -135,7 +134,7 @@ pub fn unlinkat( .get_file(fh) .ok_or(Error::new(EBADF))?; - let description = pipe.description.read(); + let description = pipe.description.read(token.token()); let scheme = scheme::get_scheme(token.token(), description.scheme)?; @@ -183,7 +182,7 @@ fn duplicate_file( cloexec, }) } else { - let description = { *file.description.read() }; + let description = { *file.description.read(token.token()) }; let new_description = { let scheme = scheme::get_scheme(token.token(), description.scheme)?; @@ -282,7 +281,7 @@ fn call_normal( .ok_or(Error::new(EBADF))?; let (scheme_id, number) = { - let desc = file.description.read(); + let desc = file.description.read(token.token()); (desc.scheme, desc.number) }; let scheme = scheme::get_scheme(token.token(), scheme_id)?; @@ -330,7 +329,7 @@ fn fdwrite_inner( let current_lock = context::current(); let current = current_lock.read(token.token()); let file_descriptor = current.get_file(socket).ok_or(Error::new(EBADF))?; - let desc = &file_descriptor.description.read(); + let desc = &file_descriptor.description.read(token.token()); (desc.scheme, desc.number) }; let scheme = scheme::get_scheme(token.token(), scheme)?; @@ -381,7 +380,7 @@ fn call_fdread( let current_lock = context::current(); let current = current_lock.read(token.token()); let file_descriptor = current.get_file(fd).ok_or(Error::new(EBADF))?; - let desc = file_descriptor.description.read(); + let desc = file_descriptor.description.read(token.token()); (desc.scheme, desc.number) }; let scheme = scheme::get_scheme(token.token(), scheme)?; @@ -417,7 +416,7 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken) .get_file(fd) .ok_or(Error::new(EBADF))?; - let description = file.description.read(); + let description = file.description.read(token.token()); if cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC { // Not in match because 'files' cannot be locked @@ -463,7 +462,7 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken) let new_flags = (description.flags & O_ACCMODE as u32) | (arg as u32 & !O_ACCMODE as u32); drop(description); - file.description.write().flags = new_flags; + file.description.write(token.token()).flags = new_flags; Ok(0) } _ => Err(Error::new(EINVAL)), @@ -488,7 +487,7 @@ pub fn flink(fd: FileHandle, raw_path: UserSliceRo, token: &mut CleanLockToken) let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?; let (_, reference) = path.as_parts().ok_or(Error::new(EINVAL))?; - let description = file.description.read(); + let description = file.description.read(token.token()); let scheme = scheme::get_scheme(token.token(), description.scheme)?; @@ -517,7 +516,7 @@ pub fn frename(fd: FileHandle, raw_path: UserSliceRo, token: &mut CleanLockToken let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?; let (_, reference) = path.as_parts().ok_or(Error::new(EINVAL))?; - let description = file.description.read(); + let description = file.description.read(token.token()); let scheme = scheme::get_scheme(token.token(), description.scheme)?; @@ -679,7 +678,7 @@ pub fn lseek(fd: FileHandle, pos: i64, whence: usize, token: &mut CleanLockToken }) })?; - let mut guard = desc.write(); + let mut guard = desc.write(token.token()); let new_pos = match whence { SEEK_SET => pos, @@ -710,7 +709,7 @@ pub fn sys_read(fd: FileHandle, buf: UserSliceWo, token: &mut CleanLockToken) -> )) })?; if desc.internal_flags.contains(InternalFlags::POSITIONED) { - let offset = &mut desc_arc.write().offset; + let offset = &mut desc_arc.write(token.token()).offset; *offset = offset.saturating_add(bytes_read as u64) } Ok(bytes_read) @@ -730,7 +729,7 @@ pub fn sys_write(fd: FileHandle, buf: UserSliceRo, token: &mut CleanLockToken) - )) })?; if desc.internal_flags.contains(InternalFlags::POSITIONED) { - let offset = &mut desc_arc.write().offset; + let offset = &mut desc_arc.write(token.token()).offset; *offset = offset.saturating_add(bytes_written as u64) } Ok(bytes_written) diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 51c76ff499..f57e4a20c6 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -2,7 +2,6 @@ use alloc::sync::Arc; use core::{mem, num::NonZeroUsize}; use rmm::Arch; -use spin::RwLock; use syscall::data::GlobalSchemes; use crate::{ @@ -13,7 +12,7 @@ use crate::{ ContextRef, }, event, - sync::CleanLockToken, + sync::{CleanLockToken, RwLock}, syscall::flag::{EventFlags, O_CREAT, O_RDWR}, }; @@ -38,7 +37,7 @@ pub fn exit_this_context(excp: Option, token: &mut CleanLock { let mut context = context_lock.write(token.token()); close_files = Arc::try_unwrap(mem::take(&mut context.files)) - .map_or_else(|_| FdTbl::new(), RwLock::into_inner); + .map_or_else(|_| FdTbl::new(), spin::RwLock::into_inner); addrspace_opt = context .set_addr_space(None) .and_then(|a| Arc::try_unwrap(a).ok());