Drop files at the correct time

This commit is contained in:
Ruihan Li 2025-04-05 14:28:15 +08:00 committed by Tate, Hongliang Tian
parent 7e1abc1fbb
commit 8600278a5f
62 changed files with 223 additions and 141 deletions

View File

@ -217,8 +217,8 @@ impl FileIo for PtyMaster {
}; };
let fd = { let fd = {
let file_table = thread_local.file_table().borrow(); let file_table = thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
// TODO: deal with the O_CLOEXEC flag // TODO: deal with the O_CLOEXEC flag
file_table_locked.insert(slave, FdFlags::empty()) file_table_locked.insert(slave, FdFlags::empty())
}; };

View File

@ -63,7 +63,7 @@ impl EpollFile {
EpollCtl::Mod(fd, ..) => *fd, EpollCtl::Mod(fd, ..) => *fd,
}; };
let mut file_table = thread_local.file_table().borrow_mut(); let mut file_table = thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd).into_owned(); let file = get_file_fast!(&mut file_table, fd).into_owned();
drop(file_table); drop(file_table);

View File

@ -3,7 +3,6 @@
use core::sync::atomic::{AtomicU8, Ordering}; use core::sync::atomic::{AtomicU8, Ordering};
use aster_util::slot_vec::SlotVec; use aster_util::slot_vec::SlotVec;
use ostd::sync::RwArc;
use super::{ use super::{
file_handle::FileLike, file_handle::FileLike,
@ -15,6 +14,7 @@ use crate::{
fs::utils::StatusFlags, fs::utils::StatusFlags,
prelude::*, prelude::*,
process::{ process::{
posix_thread::FileTableRefMut,
signal::{constants::SIGIO, signals::kernel::KernelSignal, PollAdaptor}, signal::{constants::SIGIO, signals::kernel::KernelSignal, PollAdaptor},
Pid, Process, Pid, Process,
}, },
@ -130,24 +130,20 @@ impl FileTable {
Some(removed_entry.file) Some(removed_entry.file)
} }
pub fn close_all(&mut self) -> Vec<Arc<dyn FileLike>> {
self.close_files(|_, _| true)
}
pub fn close_files_on_exec(&mut self) -> Vec<Arc<dyn FileLike>> { pub fn close_files_on_exec(&mut self) -> Vec<Arc<dyn FileLike>> {
self.close_files(|_, entry| entry.flags().contains(FdFlags::CLOEXEC)) self.close_files(|entry| entry.flags().contains(FdFlags::CLOEXEC))
} }
fn close_files<F>(&mut self, should_close: F) -> Vec<Arc<dyn FileLike>> fn close_files<F>(&mut self, should_close: F) -> Vec<Arc<dyn FileLike>>
where where
F: Fn(FileDesc, &FileTableEntry) -> bool, F: Fn(&FileTableEntry) -> bool,
{ {
let mut closed_files = Vec::new(); let mut closed_files = Vec::new();
let closed_fds: Vec<FileDesc> = self let closed_fds: Vec<FileDesc> = self
.table .table
.idxes_and_items() .idxes_and_items()
.filter_map(|(idx, entry)| { .filter_map(|(idx, entry)| {
if should_close(idx as FileDesc, entry) { if should_close(entry) {
Some(idx as FileDesc) Some(idx as FileDesc)
} else { } else {
None None
@ -221,6 +217,9 @@ impl Clone for FileTable {
impl Drop for FileTable { impl Drop for FileTable {
fn drop(&mut self) { fn drop(&mut self) {
// Closes all files first.
self.close_files(|_| true);
let events = FdEvents::DropFileTable; let events = FdEvents::DropFileTable;
self.subject.notify_observers(&events); self.subject.notify_observers(&events);
} }
@ -235,12 +234,14 @@ pub trait WithFileTable {
fn read_with<R>(&mut self, f: impl FnOnce(&FileTable) -> R) -> R; fn read_with<R>(&mut self, f: impl FnOnce(&FileTable) -> R) -> R;
} }
impl WithFileTable for RwArc<FileTable> { impl WithFileTable for FileTableRefMut<'_> {
fn read_with<R>(&mut self, f: impl FnOnce(&FileTable) -> R) -> R { fn read_with<R>(&mut self, f: impl FnOnce(&FileTable) -> R) -> R {
if let Some(inner) = self.get() { let file_table = self.unwrap();
if let Some(inner) = file_table.get() {
f(inner) f(inner)
} else { } else {
f(&self.read()) f(&file_table.read())
} }
} }
} }
@ -269,10 +270,13 @@ macro_rules! get_file_fast {
use alloc::borrow::Cow; use alloc::borrow::Cow;
use ostd::sync::RwArc; use ostd::sync::RwArc;
use $crate::{
fs::file_table::{FileDesc, FileTable},
process::posix_thread::FileTableRefMut,
};
use crate::fs::file_table::{FileDesc, FileTable}; let file_table: &mut FileTableRefMut<'_> = $file_table;
let file_table: &mut RwArc<FileTable> = file_table.unwrap();
let file_table: &mut RwArc<FileTable> = $file_table;
let file_desc: FileDesc = $file_desc; let file_desc: FileDesc = $file_desc;
if let Some(inner) = file_table.get() { if let Some(inner) = file_table.get() {

View File

@ -169,13 +169,13 @@ impl FsResolver {
FsPathInner::Cwd => self.cwd.clone(), FsPathInner::Cwd => self.cwd.clone(),
FsPathInner::FdRelative(fd, path) => { FsPathInner::FdRelative(fd, path) => {
let task = Task::current().unwrap(); let task = Task::current().unwrap();
let mut file_table = task.as_thread_local().unwrap().file_table().borrow_mut(); let mut file_table = task.as_thread_local().unwrap().borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
self.lookup_from_parent(file.as_inode_or_err()?.dentry(), path, lookup_ctx)? self.lookup_from_parent(file.as_inode_or_err()?.dentry(), path, lookup_ctx)?
} }
FsPathInner::Fd(fd) => { FsPathInner::Fd(fd) => {
let task = Task::current().unwrap(); let task = Task::current().unwrap();
let mut file_table = task.as_thread_local().unwrap().file_table().borrow_mut(); let mut file_table = task.as_thread_local().unwrap().borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
file.as_inode_or_err()?.dentry().clone() file.as_inode_or_err()?.dentry().clone()
} }

View File

@ -20,14 +20,20 @@ pub struct FdDirOps(Arc<Process>);
impl FdDirOps { impl FdDirOps {
pub fn new_inode(process_ref: Arc<Process>, parent: Weak<dyn Inode>) -> Arc<dyn Inode> { pub fn new_inode(process_ref: Arc<Process>, parent: Weak<dyn Inode>) -> Arc<dyn Inode> {
let main_thread = process_ref.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table();
let fd_inode = ProcDirBuilder::new(Self(process_ref.clone())) let fd_inode = ProcDirBuilder::new(Self(process_ref.clone()))
.parent(parent) .parent(parent)
.build() .build()
.unwrap(); .unwrap();
let main_thread = process_ref.main_thread(); file_table
let file_table = main_thread.as_posix_thread().unwrap().file_table().read(); .lock()
let weak_ptr = Arc::downgrade(&fd_inode); .as_ref()
file_table.register_observer(weak_ptr); .unwrap()
.read()
.register_observer(Arc::downgrade(&fd_inode) as _);
fd_inode fd_inode
} }
} }
@ -47,29 +53,40 @@ impl Observer<FdEvents> for ProcDir<FdDirOps> {
impl DirOps for FdDirOps { impl DirOps for FdDirOps {
fn lookup_child(&self, this_ptr: Weak<dyn Inode>, name: &str) -> Result<Arc<dyn Inode>> { fn lookup_child(&self, this_ptr: Weak<dyn Inode>, name: &str) -> Result<Arc<dyn Inode>> {
let main_thread = self.0.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table().lock();
let file_table = file_table
.as_ref()
.ok_or_else(|| Error::new(Errno::ENOENT))?;
let file = { let file = {
let fd = name let fd = name
.parse::<FileDesc>() .parse::<FileDesc>()
.map_err(|_| Error::new(Errno::ENOENT))?; .map_err(|_| Error::new(Errno::ENOENT))?;
let main_thread = self.0.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table().read();
file_table file_table
.read()
.get_file(fd) .get_file(fd)
.map_err(|_| Error::new(Errno::ENOENT))? .map_err(|_| Error::new(Errno::ENOENT))?
.clone() .clone()
}; };
Ok(FileSymOps::new_inode(file, this_ptr.clone())) Ok(FileSymOps::new_inode(file, this_ptr.clone()))
} }
fn populate_children(&self, this_ptr: Weak<dyn Inode>) { fn populate_children(&self, this_ptr: Weak<dyn Inode>) {
let main_thread = self.0.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table().lock();
let Some(file_table) = file_table.as_ref() else {
return;
};
let this = { let this = {
let this = this_ptr.upgrade().unwrap(); let this = this_ptr.upgrade().unwrap();
this.downcast_ref::<ProcDir<FdDirOps>>().unwrap().this() this.downcast_ref::<ProcDir<FdDirOps>>().unwrap().this()
}; };
let mut cached_children = this.cached_children().write(); let mut cached_children = this.cached_children().write();
let main_thread = self.0.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table().read(); for (fd, file) in file_table.read().fds_and_files() {
for (fd, file) in file_table.fds_and_files() {
cached_children.put_entry_if_not_found(&fd.to_string(), || { cached_children.put_entry_if_not_found(&fd.to_string(), || {
FileSymOps::new_inode(file.clone(), this_ptr.clone()) FileSymOps::new_inode(file.clone(), this_ptr.clone())
}); });

View File

@ -27,16 +27,22 @@ pub struct PidDirOps(Arc<Process>);
impl PidDirOps { impl PidDirOps {
pub fn new_inode(process_ref: Arc<Process>, parent: Weak<dyn Inode>) -> Arc<dyn Inode> { pub fn new_inode(process_ref: Arc<Process>, parent: Weak<dyn Inode>) -> Arc<dyn Inode> {
let main_thread = process_ref.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table();
let pid_inode = ProcDirBuilder::new(Self(process_ref.clone())) let pid_inode = ProcDirBuilder::new(Self(process_ref.clone()))
.parent(parent) .parent(parent)
// The pid directories must be volatile, because it is just associated with one process. // The pid directories must be volatile, because it is just associated with one process.
.volatile() .volatile()
.build() .build()
.unwrap(); .unwrap();
let main_thread = process_ref.main_thread(); file_table
let file_table = main_thread.as_posix_thread().unwrap().file_table().read(); .lock()
let weak_ptr = Arc::downgrade(&pid_inode); .as_ref()
file_table.register_observer(weak_ptr); .unwrap()
.read()
.register_observer(Arc::downgrade(&pid_inode) as _);
pid_inode pid_inode
} }
} }

View File

@ -81,7 +81,16 @@ impl FileOps for StatusFileOps {
writeln!(status_output, "Pid:\t{}", process.pid()).unwrap(); writeln!(status_output, "Pid:\t{}", process.pid()).unwrap();
writeln!(status_output, "PPid:\t{}", process.parent().pid()).unwrap(); writeln!(status_output, "PPid:\t{}", process.parent().pid()).unwrap();
writeln!(status_output, "TracerPid:\t{}", process.parent().pid()).unwrap(); // Assuming TracerPid is the same as PPid writeln!(status_output, "TracerPid:\t{}", process.parent().pid()).unwrap(); // Assuming TracerPid is the same as PPid
writeln!(status_output, "FDSize:\t{}", file_table.read().len()).unwrap(); writeln!(
status_output,
"FDSize:\t{}",
file_table
.lock()
.as_ref()
.map(|file_table| file_table.read().len())
.unwrap_or(0)
)
.unwrap();
writeln!( writeln!(
status_output, status_output,
"Threads:\t{}", "Threads:\t{}",

View File

@ -239,7 +239,7 @@ fn clone_child_task(
clone_sysvsem(clone_flags)?; clone_sysvsem(clone_flags)?;
// clone file table // clone file table
let child_file_table = clone_files(&thread_local.file_table().borrow(), clone_flags); let child_file_table = clone_files(thread_local.borrow_file_table().unwrap(), clone_flags);
// clone fs // clone fs
let child_fs = clone_fs(posix_thread.fs(), clone_flags); let child_fs = clone_fs(posix_thread.fs(), clone_flags);
@ -315,7 +315,7 @@ fn clone_child_process(
)); ));
// clone file table // clone file table
let child_file_table = clone_files(&thread_local.file_table().borrow(), clone_flags); let child_file_table = clone_files(thread_local.borrow_file_table().unwrap(), clone_flags);
// clone fs // clone fs
let child_fs = clone_fs(posix_thread.fs(), clone_flags); let child_fs = clone_fs(posix_thread.fs(), clone_flags);

View File

@ -2,7 +2,7 @@
use core::sync::atomic::Ordering; use core::sync::atomic::Ordering;
use super::{posix_thread::ThreadLocal, process_table, Pid, Process}; use super::{process_table, Pid, Process};
use crate::{prelude::*, process::signal::signals::kernel::KernelSignal}; use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
/// Exits the current POSIX process. /// Exits the current POSIX process.
@ -12,21 +12,18 @@ use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
/// ///
/// [`do_exit`]: crate::process::posix_thread::do_exit /// [`do_exit`]: crate::process::posix_thread::do_exit
/// [`do_exit_group`]: crate::process::posix_thread::do_exit_group /// [`do_exit_group`]: crate::process::posix_thread::do_exit_group
pub(super) fn exit_process(thread_local: &ThreadLocal, current_process: &Process) { pub(super) fn exit_process(current_process: &Process) {
current_process.status().set_zombie(); current_process.status().set_zombie();
current_process.status().set_vfork_child(false); current_process.status().set_vfork_child(false);
// FIXME: This is obviously wrong in a number of ways, since different threads can have // Drop fields in `Process`.
// different file tables, and different processes can share the same file table. current_process.lock_root_vmar().set_vmar(None);
thread_local.file_table().borrow().write().close_all();
send_parent_death_signal(current_process); send_parent_death_signal(current_process);
move_children_to_reaper_process(current_process); move_children_to_reaper_process(current_process);
send_child_death_signal(current_process); send_child_death_signal(current_process);
current_process.lock_root_vmar().set_vmar(None);
} }
/// Sends parent-death signals to the children. /// Sends parent-death signals to the children.

View File

@ -119,11 +119,15 @@ impl PosixThreadBuilder {
let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default())); let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default()));
Arc::new_cyclic(|weak_task| { let root_vmar = process
let root_vmar = process .upgrade()
.upgrade() .unwrap()
.map(|process| process.lock_root_vmar().unwrap().dup().unwrap()); .lock_root_vmar()
.unwrap()
.dup()
.unwrap();
Arc::new_cyclic(|weak_task| {
let posix_thread = { let posix_thread = {
let prof_clock = ProfClock::new(); let prof_clock = ProfClock::new();
let virtual_timer_manager = TimerManager::new(prof_clock.user_clock().clone()); let virtual_timer_manager = TimerManager::new(prof_clock.user_clock().clone());
@ -134,7 +138,7 @@ impl PosixThreadBuilder {
tid, tid,
name: Mutex::new(thread_name), name: Mutex::new(thread_name),
credentials, credentials,
file_table: file_table.clone_ro(), file_table: Mutex::new(Some(file_table.clone_ro())),
fs, fs,
sig_mask, sig_mask,
sig_queues, sig_queues,

View File

@ -79,10 +79,15 @@ fn exit_internal(term_status: TermStatus, is_exiting_group: bool) {
thread_table::remove_thread(posix_thread.tid()); thread_table::remove_thread(posix_thread.tid());
} }
// Drop fields in `PosixThread`.
*posix_thread.file_table().lock() = None;
// Drop fields in `ThreadLocal`.
*thread_local.root_vmar().borrow_mut() = None; *thread_local.root_vmar().borrow_mut() = None;
thread_local.borrow_file_table_mut().remove();
if is_last_thread { if is_last_thread {
exit_process(thread_local, &posix_process); exit_process(&posix_process);
} }
} }

View File

@ -40,7 +40,7 @@ pub use exit::{do_exit, do_exit_group};
pub use name::{ThreadName, MAX_THREAD_NAME_LEN}; pub use name::{ThreadName, MAX_THREAD_NAME_LEN};
pub use posix_thread_ext::{create_posix_task_from_executable, AsPosixThread}; pub use posix_thread_ext::{create_posix_task_from_executable, AsPosixThread};
pub use robust_list::RobustListHead; pub use robust_list::RobustListHead;
pub use thread_local::{AsThreadLocal, ThreadLocal}; pub use thread_local::{AsThreadLocal, FileTableRefMut, ThreadLocal};
pub struct PosixThread { pub struct PosixThread {
// Immutable part // Immutable part
@ -55,7 +55,7 @@ pub struct PosixThread {
// Files // Files
/// File table /// File table
file_table: RoArc<FileTable>, file_table: Mutex<Option<RoArc<FileTable>>>,
/// File system /// File system
fs: Arc<ThreadFsInfo>, fs: Arc<ThreadFsInfo>,
@ -96,7 +96,7 @@ impl PosixThread {
&self.name &self.name
} }
pub fn file_table(&self) -> &RoArc<FileTable> { pub fn file_table(&self) -> &Mutex<Option<RoArc<FileTable>>> {
&self.file_table &self.file_table
} }

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use core::cell::{Cell, RefCell}; use core::cell::{Cell, Ref, RefCell, RefMut};
use aster_rights::Full; use aster_rights::Full;
use ostd::{mm::Vaddr, sync::RwArc, task::CurrentTask}; use ostd::{mm::Vaddr, sync::RwArc, task::CurrentTask};
@ -23,7 +23,7 @@ pub struct ThreadLocal {
robust_list: RefCell<Option<RobustListHead>>, robust_list: RefCell<Option<RobustListHead>>,
// Files. // Files.
file_table: RefCell<RwArc<FileTable>>, file_table: RefCell<Option<RwArc<FileTable>>>,
// Signal. // Signal.
/// `ucontext` address for the signal handler. /// `ucontext` address for the signal handler.
@ -38,15 +38,15 @@ impl ThreadLocal {
pub(super) fn new( pub(super) fn new(
set_child_tid: Vaddr, set_child_tid: Vaddr,
clear_child_tid: Vaddr, clear_child_tid: Vaddr,
root_vmar: Option<Vmar<Full>>, root_vmar: Vmar<Full>,
file_table: RwArc<FileTable>, file_table: RwArc<FileTable>,
) -> Self { ) -> Self {
Self { Self {
set_child_tid: Cell::new(set_child_tid), set_child_tid: Cell::new(set_child_tid),
clear_child_tid: Cell::new(clear_child_tid), clear_child_tid: Cell::new(clear_child_tid),
root_vmar: RefCell::new(root_vmar), root_vmar: RefCell::new(Some(root_vmar)),
robust_list: RefCell::new(None), robust_list: RefCell::new(None),
file_table: RefCell::new(file_table), file_table: RefCell::new(Some(file_table)),
sig_context: Cell::new(None), sig_context: Cell::new(None),
sig_stack: RefCell::new(None), sig_stack: RefCell::new(None),
} }
@ -68,8 +68,12 @@ impl ThreadLocal {
&self.robust_list &self.robust_list
} }
pub fn file_table(&self) -> &RefCell<RwArc<FileTable>> { pub fn borrow_file_table(&self) -> FileTableRef {
&self.file_table FileTableRef(self.file_table.borrow())
}
pub fn borrow_file_table_mut(&self) -> FileTableRefMut {
FileTableRefMut(self.file_table.borrow_mut())
} }
pub fn sig_context(&self) -> &Cell<Option<Vaddr>> { pub fn sig_context(&self) -> &Cell<Option<Vaddr>> {
@ -81,6 +85,39 @@ impl ThreadLocal {
} }
} }
/// An immutable, shared reference to the file table in [`ThreadLocal`].
pub struct FileTableRef<'a>(Ref<'a, Option<RwArc<FileTable>>>);
impl FileTableRef<'_> {
/// Unwraps and returns a reference to the file table.
///
/// # Panics
///
/// This method will panic if the thread has exited and the file table has been dropped.
pub fn unwrap(&self) -> &RwArc<FileTable> {
self.0.as_ref().unwrap()
}
}
/// A mutable, exclusive reference to the file table in [`ThreadLocal`].
pub struct FileTableRefMut<'a>(RefMut<'a, Option<RwArc<FileTable>>>);
impl FileTableRefMut<'_> {
/// Unwraps and returns a reference to the file table.
///
/// # Panics
///
/// This method will panic if the thread has exited and the file table has been dropped.
pub fn unwrap(&mut self) -> &mut RwArc<FileTable> {
self.0.as_mut().unwrap()
}
/// Removes the file table and drops it.
pub(super) fn remove(&mut self) {
*self.0 = None;
}
}
/// A trait to provide the `as_thread_local` method for tasks. /// A trait to provide the `as_thread_local` method for tasks.
pub trait AsThreadLocal { pub trait AsThreadLocal {
/// Returns the associated [`ThreadLocal`]. /// Returns the associated [`ThreadLocal`].

View File

@ -47,7 +47,7 @@ fn do_accept(
flags: Flags, flags: Flags,
ctx: &Context, ctx: &Context,
) -> Result<FileDesc> { ) -> Result<FileDesc> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;
@ -74,7 +74,7 @@ fn do_accept(
} }
let fd = { let fd = {
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
file_table_locked.insert(connected_socket, fd_flags) file_table_locked.insert(connected_socket, fd_flags)
}; };

View File

@ -16,7 +16,7 @@ pub fn sys_bind(
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addrlen as usize)?; let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addrlen as usize)?;
debug!("sockfd = {sockfd}, socket_addr = {socket_addr:?}"); debug!("sockfd = {sockfd}, socket_addr = {socket_addr:?}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -35,7 +35,7 @@ pub fn sys_fchdir(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd); debug!("fd = {}", fd);
let dentry = { let dentry = {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
file.as_inode_or_err()?.dentry().clone() file.as_inode_or_err()?.dentry().clone()
}; };

View File

@ -13,7 +13,7 @@ use crate::{
pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}, mode = 0o{:o}", fd, mode); debug!("fd = {}, mode = 0o{:o}", fd, mode);
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
file.set_mode(InodeMode::from_bits_truncate(mode))?; file.set_mode(InodeMode::from_bits_truncate(mode))?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))

View File

@ -20,7 +20,7 @@ pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, ctx: &Context) -> Result<Sys
return Ok(SyscallReturn::Return(0)); return Ok(SyscallReturn::Return(0));
} }
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
if let Some(uid) = uid { if let Some(uid) = uid {
file.set_owner(uid)?; file.set_owner(uid)?;

View File

@ -7,8 +7,8 @@ pub fn sys_close(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd); debug!("fd = {}", fd);
let file = { let file = {
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let _ = file_table_locked.get_file(fd)?; let _ = file_table_locked.get_file(fd)?;
file_table_locked.close_file(fd).unwrap() file_table_locked.close_file(fd).unwrap()
}; };

View File

@ -16,7 +16,7 @@ pub fn sys_connect(
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addr_len as _)?; let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addr_len as _)?;
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}"); debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -10,8 +10,8 @@ use crate::{
pub fn sys_dup(old_fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_dup(old_fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("old_fd = {}", old_fd); debug!("old_fd = {}", old_fd);
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let new_fd = file_table_locked.dup(old_fd, 0, FdFlags::empty())?; let new_fd = file_table_locked.dup(old_fd, 0, FdFlags::empty())?;
Ok(SyscallReturn::Return(new_fd as _)) Ok(SyscallReturn::Return(new_fd as _))
@ -21,7 +21,7 @@ pub fn sys_dup2(old_fd: FileDesc, new_fd: FileDesc, ctx: &Context) -> Result<Sys
debug!("old_fd = {}, new_fd = {}", old_fd, new_fd); debug!("old_fd = {}, new_fd = {}", old_fd, new_fd);
if old_fd == new_fd { if old_fd == new_fd {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let _file = get_file_fast!(&mut file_table, old_fd); let _file = get_file_fast!(&mut file_table, old_fd);
return Ok(SyscallReturn::Return(new_fd as _)); return Ok(SyscallReturn::Return(new_fd as _));
} }
@ -66,8 +66,8 @@ fn do_dup3(
return_errno!(Errno::EBADF); return_errno!(Errno::EBADF);
} }
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let _ = file_table_locked.close_file(new_fd); let _ = file_table_locked.close_file(new_fd);
let new_fd = file_table_locked.dup(old_fd, new_fd, flags)?; let new_fd = file_table_locked.dup(old_fd, new_fd, flags)?;

View File

@ -41,8 +41,8 @@ pub fn sys_epoll_create1(flags: u32, ctx: &Context) -> Result<SyscallReturn> {
}; };
let epoll_file: Arc<EpollFile> = EpollFile::new(); let epoll_file: Arc<EpollFile> = EpollFile::new();
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let fd = file_table.write().insert(epoll_file, fd_flags); let fd = file_table.unwrap().write().insert(epoll_file, fd_flags);
Ok(SyscallReturn::Return(fd as _)) Ok(SyscallReturn::Return(fd as _))
} }
@ -79,9 +79,9 @@ pub fn sys_epoll_ctl(
_ => return_errno_with_message!(Errno::EINVAL, "invalid op"), _ => return_errno_with_message!(Errno::EINVAL, "invalid op"),
}; };
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, epfd).into_owned(); let file = get_file_fast!(&mut file_table, epfd).into_owned();
// Drop `file_table` as `EpollFile::control` also performs `file_table().borrow_mut()`. // Drop `file_table` as `EpollFile::control` also performs `borrow_file_table_mut()`.
drop(file_table); drop(file_table);
let epoll_file = file let epoll_file = file
@ -110,7 +110,7 @@ fn do_epoll_wait(
None None
}; };
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, epfd); let file = get_file_fast!(&mut file_table, epfd);
let epoll_file = file let epoll_file = file
.downcast_ref::<EpollFile>() .downcast_ref::<EpollFile>()

View File

@ -54,8 +54,8 @@ pub fn sys_eventfd2(init_val: u64, flags: u32, ctx: &Context) -> Result<SyscallR
fn do_sys_eventfd2(init_val: u64, flags: Flags, ctx: &Context) -> FileDesc { fn do_sys_eventfd2(init_val: u64, flags: Flags, ctx: &Context) -> FileDesc {
let event_file = EventFile::new(init_val, flags); let event_file = EventFile::new(init_val, flags);
let fd = { let fd = {
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let fd_flags = if flags.contains(Flags::EFD_CLOEXEC) { let fd_flags = if flags.contains(Flags::EFD_CLOEXEC) {
FdFlags::CLOEXEC FdFlags::CLOEXEC
} else { } else {

View File

@ -62,7 +62,7 @@ fn lookup_executable_file(
ctx: &Context, ctx: &Context,
) -> Result<Dentry> { ) -> Result<Dentry> {
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() { let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, dfd); let file = get_file_fast!(&mut file_table, dfd);
file.as_inode_or_err()?.dentry().clone() file.as_inode_or_err()?.dentry().clone()
} else { } else {
@ -111,8 +111,8 @@ fn do_execve(
// Ensure that the file descriptors with the close-on-exec flag are closed. // Ensure that the file descriptors with the close-on-exec flag are closed.
// FIXME: This is just wrong if the file table is shared with other processes. // FIXME: This is just wrong if the file table is shared with other processes.
let closed_files = thread_local let closed_files = thread_local
.file_table() .borrow_file_table()
.borrow() .unwrap()
.write() .write()
.close_files_on_exec(); .close_files_on_exec();
drop(closed_files); drop(closed_files);

View File

@ -24,7 +24,7 @@ pub fn sys_fallocate(
check_offset_and_len(offset, len, ctx)?; check_offset_and_len(offset, len, ctx)?;
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let falloc_mode = FallocMode::try_from( let falloc_mode = FallocMode::try_from(

View File

@ -35,13 +35,16 @@ pub fn sys_fcntl(fd: FileDesc, cmd: i32, arg: u64, ctx: &Context) -> Result<Sysc
} }
fn handle_dupfd(fd: FileDesc, arg: u64, flags: FdFlags, ctx: &Context) -> Result<SyscallReturn> { fn handle_dupfd(fd: FileDesc, arg: u64, flags: FdFlags, ctx: &Context) -> Result<SyscallReturn> {
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let new_fd = file_table.write().dup(fd, arg as FileDesc, flags)?; let new_fd = file_table
.unwrap()
.write()
.dup(fd, arg as FileDesc, flags)?;
Ok(SyscallReturn::Return(new_fd as _)) Ok(SyscallReturn::Return(new_fd as _))
} }
fn handle_getfd(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> { fn handle_getfd(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
file_table.read_with(|inner| { file_table.read_with(|inner| {
let fd_flags = inner.get_entry(fd)?.flags(); let fd_flags = inner.get_entry(fd)?.flags();
Ok(SyscallReturn::Return(fd_flags.bits() as _)) Ok(SyscallReturn::Return(fd_flags.bits() as _))
@ -54,7 +57,7 @@ fn handle_setfd(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
} else { } else {
FdFlags::from_bits(arg as u8).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))? FdFlags::from_bits(arg as u8).ok_or(Error::with_message(Errno::EINVAL, "invalid flags"))?
}; };
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
file_table.read_with(|inner| { file_table.read_with(|inner| {
inner.get_entry(fd)?.set_flags(flags); inner.get_entry(fd)?.set_flags(flags);
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
@ -62,7 +65,7 @@ fn handle_setfd(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
} }
fn handle_getfl(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> { fn handle_getfl(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let status_flags = file.status_flags(); let status_flags = file.status_flags();
let access_mode = file.access_mode(); let access_mode = file.access_mode();
@ -72,7 +75,7 @@ fn handle_getfl(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
} }
fn handle_setfl(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> { fn handle_setfl(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let valid_flags_mask = StatusFlags::O_APPEND let valid_flags_mask = StatusFlags::O_APPEND
| StatusFlags::O_ASYNC | StatusFlags::O_ASYNC
@ -87,7 +90,7 @@ fn handle_setfl(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
} }
fn handle_getlk(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> { fn handle_getlk(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let lock_mut_ptr = arg as Vaddr; let lock_mut_ptr = arg as Vaddr;
let mut lock_mut_c = ctx.user_space().read_val::<c_flock>(lock_mut_ptr)?; let mut lock_mut_c = ctx.user_space().read_val::<c_flock>(lock_mut_ptr)?;
@ -112,7 +115,7 @@ fn handle_setlk(
is_nonblocking: bool, is_nonblocking: bool,
ctx: &Context, ctx: &Context,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let lock_mut_ptr = arg as Vaddr; let lock_mut_ptr = arg as Vaddr;
let lock_mut_c = ctx.user_space().read_val::<c_flock>(lock_mut_ptr)?; let lock_mut_c = ctx.user_space().read_val::<c_flock>(lock_mut_ptr)?;
@ -127,7 +130,7 @@ fn handle_setlk(
} }
fn handle_getown(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> { fn handle_getown(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
file_table.read_with(|inner| { file_table.read_with(|inner| {
let pid = inner.get_entry(fd)?.owner().unwrap_or(0); let pid = inner.get_entry(fd)?.owner().unwrap_or(0);
Ok(SyscallReturn::Return(pid as _)) Ok(SyscallReturn::Return(pid as _))
@ -152,8 +155,8 @@ fn handle_setown(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
))?) ))?)
}; };
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let file_entry = file_table_locked.get_entry_mut(fd)?; let file_entry = file_table_locked.get_entry_mut(fd)?;
file_entry.set_owner(owner_process.as_ref())?; file_entry.set_owner(owner_process.as_ref())?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))

View File

@ -12,7 +12,7 @@ use crate::{
pub fn sys_flock(fd: FileDesc, ops: i32, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_flock(fd: FileDesc, ops: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("flock: fd: {}, ops: {:?}", fd, ops); debug!("flock: fd: {}, ops: {:?}", fd, ops);
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let inode_file = file.as_inode_or_err()?; let inode_file = file.as_inode_or_err()?;
let ops: FlockOps = FlockOps::from_i32(ops)?; let ops: FlockOps = FlockOps::from_i32(ops)?;

View File

@ -9,7 +9,7 @@ use crate::{
pub fn sys_fsync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_fsync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd); debug!("fd = {}", fd);
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let dentry = file.as_inode_or_err()?.dentry(); let dentry = file.as_inode_or_err()?.dentry();
dentry.sync_all()?; dentry.sync_all()?;
@ -19,7 +19,7 @@ pub fn sys_fsync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
pub fn sys_fdatasync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_fdatasync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd); debug!("fd = {}", fd);
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let dentry = file.as_inode_or_err()?.dentry(); let dentry = file.as_inode_or_err()?.dentry();
dentry.sync_data()?; dentry.sync_data()?;

View File

@ -22,7 +22,7 @@ pub fn sys_getdents(
fd, buf_addr, buf_len fd, buf_addr, buf_len
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let inode_handle = file.as_inode_or_err()?; let inode_handle = file.as_inode_or_err()?;
if inode_handle.dentry().type_() != InodeType::Dir { if inode_handle.dentry().type_() != InodeType::Dir {
@ -48,7 +48,7 @@ pub fn sys_getdents64(
fd, buf_addr, buf_len fd, buf_addr, buf_len
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let inode_handle = file.as_inode_or_err()?; let inode_handle = file.as_inode_or_err()?;
if inode_handle.dentry().type_() != InodeType::Dir { if inode_handle.dentry().type_() != InodeType::Dir {

View File

@ -15,7 +15,7 @@ pub fn sys_getpeername(
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -15,7 +15,7 @@ pub fn sys_getsockname(
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -25,7 +25,7 @@ pub fn sys_getsockopt(
debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}"); debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -67,7 +67,7 @@ pub fn sys_fgetxattr(
value_len: usize, value_len: usize,
ctx: &Context, ctx: &Context,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let user_space = ctx.user_space(); let user_space = ctx.user_space();

View File

@ -16,7 +16,7 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, ctx: &Context) -> Result<Sy
fd, ioctl_cmd, arg fd, ioctl_cmd, arg
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let res = match ioctl_cmd { let res = match ioctl_cmd {
IoctlCmd::FIONBIO => { IoctlCmd::FIONBIO => {

View File

@ -9,7 +9,7 @@ use crate::{
pub fn sys_listen(sockfd: FileDesc, backlog: i32, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_listen(sockfd: FileDesc, backlog: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("sockfd = {sockfd}, backlog = {backlog}"); debug!("sockfd = {sockfd}, backlog = {backlog}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -60,7 +60,7 @@ pub fn sys_flistxattr(
list_len: usize, list_len: usize,
ctx: &Context, ctx: &Context,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let user_space = ctx.user_space(); let user_space = ctx.user_space();

View File

@ -23,7 +23,7 @@ pub fn sys_lseek(fd: FileDesc, offset: isize, whence: u32, ctx: &Context) -> Res
2 => SeekFrom::End(offset), 2 => SeekFrom::End(offset),
_ => return_errno!(Errno::EINVAL), _ => return_errno!(Errno::EINVAL),
}; };
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let offset = file.seek(seek_from)?; let offset = file.seek(seek_from)?;

View File

@ -125,7 +125,7 @@ fn do_sys_mmap(
} }
} else { } else {
let vmo = { let vmo = {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let inode_handle = file.as_inode_or_err()?; let inode_handle = file.as_inode_or_err()?;

View File

@ -42,8 +42,8 @@ pub fn sys_openat(
}; };
let fd = { let fd = {
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let fd_flags = let fd_flags =
if CreationFlags::from_bits_truncate(flags).contains(CreationFlags::O_CLOEXEC) { if CreationFlags::from_bits_truncate(flags).contains(CreationFlags::O_CLOEXEC) {
FdFlags::CLOEXEC FdFlags::CLOEXEC

View File

@ -21,8 +21,8 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32, ctx: &Context) -> Result<SyscallReturn>
FdFlags::empty() FdFlags::empty()
}; };
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let pipe_fds = PipeFds { let pipe_fds = PipeFds {
reader_fd: file_table_locked.insert(pipe_reader, fd_flags), reader_fd: file_table_locked.insert(pipe_reader, fd_flags),

View File

@ -59,7 +59,8 @@ pub fn sys_poll(fds: Vaddr, nfds: u64, timeout: i32, ctx: &Context) -> Result<Sy
} }
pub fn do_poll(poll_fds: &[PollFd], timeout: Option<&Duration>, ctx: &Context) -> Result<usize> { pub fn do_poll(poll_fds: &[PollFd], timeout: Option<&Duration>, ctx: &Context) -> Result<usize> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file_table = file_table.unwrap();
let poll_files = if let Some(file_table_inner) = file_table.get() { let poll_files = if let Some(file_table_inner) = file_table.get() {
PollFiles::new_borrowed(poll_fds, file_table_inner) PollFiles::new_borrowed(poll_fds, file_table_inner)

View File

@ -22,7 +22,7 @@ pub fn sys_pread64(
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative"); return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
} }
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
// TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait // TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait

View File

@ -65,7 +65,7 @@ fn do_sys_preadv(
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative"); return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
} }
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
if io_vec_count == 0 { if io_vec_count == 0 {
@ -126,7 +126,7 @@ fn do_sys_readv(
fd, io_vec_ptr, io_vec_count fd, io_vec_ptr, io_vec_count
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
if io_vec_count == 0 { if io_vec_count == 0 {

View File

@ -22,7 +22,7 @@ pub fn sys_pwrite64(
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative"); return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
} }
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
// TODO: Check (f.file->f_mode & FMODE_PWRITE); We don't have f_mode in our FileLike trait // TODO: Check (f.file->f_mode & FMODE_PWRITE); We don't have f_mode in our FileLike trait

View File

@ -66,7 +66,7 @@ fn do_sys_pwritev(
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative"); return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
} }
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
// TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait // TODO: Check (f.file->f_mode & FMODE_PREAD); We don't have f_mode in our FileLike trait
@ -123,7 +123,7 @@ fn do_sys_writev(
fd, io_vec_ptr, io_vec_count fd, io_vec_ptr, io_vec_count
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let mut total_len = 0; let mut total_len = 0;

View File

@ -17,7 +17,7 @@ pub fn sys_read(
fd, user_buf_addr, buf_len fd, user_buf_addr, buf_len
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
// According to <https://man7.org/linux/man-pages/man2/read.2.html>, if // According to <https://man7.org/linux/man-pages/man2/read.2.html>, if

View File

@ -20,7 +20,7 @@ pub fn sys_recvfrom(
let flags = SendRecvFlags::from_bits_truncate(flags); let flags = SendRecvFlags::from_bits_truncate(flags);
debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}"); debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = {len}, flags = {flags:?}, src_addr = 0x{src_addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -22,7 +22,7 @@ pub fn sys_recvmsg(
sockfd, c_user_msghdr, flags sockfd, c_user_msghdr, flags
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -32,7 +32,7 @@ pub fn sys_lremovexattr(path_ptr: Vaddr, name_ptr: Vaddr, ctx: &Context) -> Resu
} }
pub fn sys_fremovexattr(fd: FileDesc, name_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_fremovexattr(fd: FileDesc, name_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let user_space = ctx.user_space(); let user_space = ctx.user_space();

View File

@ -38,8 +38,7 @@ pub fn sys_sendfile(
let (out_file, in_file) = ctx let (out_file, in_file) = ctx
.thread_local .thread_local
.file_table() .borrow_file_table_mut()
.borrow_mut()
.read_with(|inner| { .read_with(|inner| {
let out_file = inner.get_file(out_fd)?.clone(); let out_file = inner.get_file(out_fd)?.clone();
// FIXME: the in_file must support mmap-like operations (i.e., it cannot be a socket). // FIXME: the in_file must support mmap-like operations (i.e., it cannot be a socket).

View File

@ -22,7 +22,7 @@ pub fn sys_sendmsg(
sockfd, c_user_msghdr, flags sockfd, c_user_msghdr, flags
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -26,7 +26,7 @@ pub fn sys_sendto(
}; };
debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = 0x{len:x}, flags = {flags:?}, socket_addr = {socket_addr:?}"); debug!("sockfd = {sockfd}, buf = 0x{buf:x}, len = 0x{len:x}, flags = {flags:?}, socket_addr = {socket_addr:?}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -25,7 +25,7 @@ pub fn sys_setsockopt(
level, sockfd, optname, optlen level, sockfd, optname, optlen
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -74,7 +74,7 @@ pub fn sys_fsetxattr(
flags: i32, flags: i32,
ctx: &Context, ctx: &Context,
) -> Result<SyscallReturn> { ) -> Result<SyscallReturn> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let user_space = ctx.user_space(); let user_space = ctx.user_space();

View File

@ -11,7 +11,7 @@ pub fn sys_shutdown(sockfd: FileDesc, how: i32, ctx: &Context) -> Result<Syscall
let shutdown_cmd = SockShutdownCmd::try_from(how)?; let shutdown_cmd = SockShutdownCmd::try_from(how)?;
debug!("sockfd = {sockfd}, cmd = {shutdown_cmd:?}"); debug!("sockfd = {sockfd}, cmd = {shutdown_cmd:?}");
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, sockfd); let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?; let socket = file.as_socket_or_err()?;

View File

@ -94,8 +94,8 @@ fn create_new_signalfd(
register_observer(ctx, &signal_file, mask)?; register_observer(ctx, &signal_file, mask)?;
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let fd = file_table.write().insert(signal_file, fd_flags); let fd = file_table.unwrap().write().insert(signal_file, fd_flags);
Ok(fd) Ok(fd)
} }
@ -105,7 +105,7 @@ fn update_existing_signalfd(
new_mask: SigMask, new_mask: SigMask,
non_blocking: bool, non_blocking: bool,
) -> Result<FileDesc> { ) -> Result<FileDesc> {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let signal_file = file let signal_file = file
.downcast_ref::<SignalFile>() .downcast_ref::<SignalFile>()

View File

@ -43,8 +43,8 @@ pub fn sys_socket(domain: i32, type_: i32, protocol: i32, ctx: &Context) -> Resu
_ => return_errno_with_message!(Errno::EAFNOSUPPORT, "unsupported domain"), _ => return_errno_with_message!(Errno::EAFNOSUPPORT, "unsupported domain"),
}; };
let fd = { let fd = {
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) { let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) {
FdFlags::CLOEXEC FdFlags::CLOEXEC
} else { } else {

View File

@ -37,8 +37,8 @@ pub fn sys_socketpair(
}; };
let socket_fds = { let socket_fds = {
let file_table = ctx.thread_local.file_table().borrow(); let file_table = ctx.thread_local.borrow_file_table();
let mut file_table_locked = file_table.write(); let mut file_table_locked = file_table.unwrap().write();
let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) { let fd_flags = if sock_flags.contains(SockFlags::SOCK_CLOEXEC) {
FdFlags::CLOEXEC FdFlags::CLOEXEC
} else { } else {

View File

@ -15,7 +15,7 @@ use crate::{
pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}, stat_buf_addr = 0x{:x}", fd, stat_buf_ptr); debug!("fd = {}, stat_buf_addr = 0x{:x}", fd, stat_buf_ptr);
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
let stat = Stat::from(file.metadata()); let stat = Stat::from(file.metadata());

View File

@ -29,7 +29,7 @@ pub fn sys_fstatfs(fd: FileDesc, statfs_buf_ptr: Vaddr, ctx: &Context) -> Result
debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr); debug!("fd = {}, statfs_buf_addr = 0x{:x}", fd, statfs_buf_ptr);
let fs = { let fs = {
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
file.as_inode_or_err()?.dentry().fs() file.as_inode_or_err()?.dentry().fs()
}; };

View File

@ -16,7 +16,7 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize, ctx: &Context) -> Result<SyscallR
check_length(len, ctx)?; check_length(len, ctx)?;
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
file.resize(len as usize)?; file.resize(len as usize)?;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))

View File

@ -17,7 +17,7 @@ pub fn sys_write(
fd, user_buf_ptr, user_buf_len fd, user_buf_ptr, user_buf_len
); );
let mut file_table = ctx.thread_local.file_table().borrow_mut(); let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd); let file = get_file_fast!(&mut file_table, fd);
// According to <https://man7.org/linux/man-pages/man2/write.2.html>, if // According to <https://man7.org/linux/man-pages/man2/write.2.html>, if