mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-28 11:53:24 +00:00
Make the file lookup faster
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
fb8f493b43
commit
b9ce3e64ad
@ -4,6 +4,7 @@ use core::{num::NonZeroU64, sync::atomic::Ordering};
|
||||
|
||||
use ostd::{
|
||||
cpu::UserContext,
|
||||
sync::RwArc,
|
||||
task::Task,
|
||||
user::{UserContextApi, UserSpace},
|
||||
};
|
||||
@ -215,6 +216,7 @@ fn clone_child_task(
|
||||
|
||||
let Context {
|
||||
process,
|
||||
thread_local,
|
||||
posix_thread,
|
||||
..
|
||||
} = ctx;
|
||||
@ -223,7 +225,7 @@ fn clone_child_task(
|
||||
clone_sysvsem(clone_flags)?;
|
||||
|
||||
// clone file table
|
||||
let child_file_table = clone_files(posix_thread.file_table(), clone_flags);
|
||||
let child_file_table = clone_files(&thread_local.file_table().borrow(), clone_flags);
|
||||
|
||||
// clone fs
|
||||
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
|
||||
@ -281,6 +283,7 @@ fn clone_child_process(
|
||||
) -> Result<Arc<Process>> {
|
||||
let Context {
|
||||
process,
|
||||
thread_local,
|
||||
posix_thread,
|
||||
..
|
||||
} = ctx;
|
||||
@ -310,7 +313,7 @@ fn clone_child_process(
|
||||
};
|
||||
|
||||
// clone file table
|
||||
let child_file_table = clone_files(posix_thread.file_table(), clone_flags);
|
||||
let child_file_table = clone_files(&thread_local.file_table().borrow(), clone_flags);
|
||||
|
||||
// clone fs
|
||||
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
|
||||
@ -466,17 +469,14 @@ fn clone_fs(parent_fs: &Arc<ThreadFsInfo>, clone_flags: CloneFlags) -> Arc<Threa
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_files(
|
||||
parent_file_table: &Arc<SpinLock<FileTable>>,
|
||||
clone_flags: CloneFlags,
|
||||
) -> Arc<SpinLock<FileTable>> {
|
||||
fn clone_files(parent_file_table: &RwArc<FileTable>, clone_flags: CloneFlags) -> RwArc<FileTable> {
|
||||
// if CLONE_FILES is set, the child and parent shares the same file table
|
||||
// Otherwise, the child will deep copy a new file table.
|
||||
// FIXME: the clone may not be deep copy.
|
||||
if clone_flags.contains(CloneFlags::CLONE_FILES) {
|
||||
parent_file_table.clone()
|
||||
} else {
|
||||
Arc::new(SpinLock::new(parent_file_table.lock().clone()))
|
||||
RwArc::new(parent_file_table.read().clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use super::{posix_thread::PosixThread, process_table, Pid, Process};
|
||||
use super::{posix_thread::ThreadLocal, process_table, Pid, Process};
|
||||
use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
|
||||
|
||||
/// Exits the current POSIX process.
|
||||
@ -10,12 +10,12 @@ use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
|
||||
///
|
||||
/// [`do_exit`]: crate::process::posix_thread::do_exit
|
||||
/// [`do_exit_group`]: crate::process::posix_thread::do_exit_group
|
||||
pub(super) fn exit_process(current_thread: &PosixThread, current_process: &Process) {
|
||||
pub(super) fn exit_process(thread_local: &ThreadLocal, current_process: &Process) {
|
||||
current_process.status().set_zombie();
|
||||
|
||||
// FIXME: This is obviously wrong in a number of ways, since different threads can have
|
||||
// different file tables, and different processes can share the same file table.
|
||||
current_thread.file_table().lock().close_all();
|
||||
thread_local.file_table().borrow().write().close_all();
|
||||
|
||||
send_parent_death_signal(current_process);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use ostd::{cpu::CpuSet, task::Task, user::UserSpace};
|
||||
use ostd::{cpu::CpuSet, sync::RwArc, task::Task, user::UserSpace};
|
||||
|
||||
use super::{thread_table, PosixThread, ThreadLocal};
|
||||
use crate::{
|
||||
@ -30,7 +30,7 @@ pub struct PosixThreadBuilder {
|
||||
thread_name: Option<ThreadName>,
|
||||
set_child_tid: Vaddr,
|
||||
clear_child_tid: Vaddr,
|
||||
file_table: Option<Arc<SpinLock<FileTable>>>,
|
||||
file_table: Option<RwArc<FileTable>>,
|
||||
fs: Option<Arc<ThreadFsInfo>>,
|
||||
sig_mask: AtomicSigMask,
|
||||
sig_queues: SigQueues,
|
||||
@ -75,7 +75,7 @@ impl PosixThreadBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn file_table(mut self, file_table: Arc<SpinLock<FileTable>>) -> Self {
|
||||
pub fn file_table(mut self, file_table: RwArc<FileTable>) -> Self {
|
||||
self.file_table = Some(file_table);
|
||||
self
|
||||
}
|
||||
@ -111,8 +111,7 @@ impl PosixThreadBuilder {
|
||||
priority,
|
||||
} = self;
|
||||
|
||||
let file_table =
|
||||
file_table.unwrap_or_else(|| Arc::new(SpinLock::new(FileTable::new_with_stdio())));
|
||||
let file_table = file_table.unwrap_or_else(|| RwArc::new(FileTable::new_with_stdio()));
|
||||
|
||||
let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default()));
|
||||
|
||||
@ -127,7 +126,7 @@ impl PosixThreadBuilder {
|
||||
tid,
|
||||
name: Mutex::new(thread_name),
|
||||
credentials,
|
||||
file_table,
|
||||
file_table: file_table.clone_ro(),
|
||||
fs,
|
||||
sig_mask,
|
||||
sig_queues,
|
||||
@ -146,7 +145,7 @@ impl PosixThreadBuilder {
|
||||
cpu_affinity,
|
||||
));
|
||||
|
||||
let thread_local = ThreadLocal::new(set_child_tid, clear_child_tid);
|
||||
let thread_local = ThreadLocal::new(set_child_tid, clear_child_tid, file_table);
|
||||
|
||||
thread_table::add_thread(tid, thread.clone());
|
||||
task::create_new_user_task(user_space, thread, thread_local)
|
||||
|
@ -80,7 +80,7 @@ fn exit_internal(term_status: TermStatus, is_exiting_group: bool) {
|
||||
}
|
||||
|
||||
if is_last_thread {
|
||||
exit_process(posix_thread, &posix_process);
|
||||
exit_process(thread_local, &posix_process);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
use aster_rights::{ReadOp, WriteOp};
|
||||
use ostd::sync::Waker;
|
||||
use ostd::sync::{RoArc, Waker};
|
||||
|
||||
use super::{
|
||||
kill::SignalSenderIds,
|
||||
@ -57,7 +57,7 @@ pub struct PosixThread {
|
||||
|
||||
// Files
|
||||
/// File table
|
||||
file_table: Arc<SpinLock<FileTable>>,
|
||||
file_table: RoArc<FileTable>,
|
||||
/// File system
|
||||
fs: Arc<ThreadFsInfo>,
|
||||
|
||||
@ -98,7 +98,7 @@ impl PosixThread {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn file_table(&self) -> &Arc<SpinLock<FileTable>> {
|
||||
pub fn file_table(&self) -> &RoArc<FileTable> {
|
||||
&self.file_table
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
use core::cell::{Cell, RefCell};
|
||||
|
||||
use ostd::{mm::Vaddr, task::CurrentTask};
|
||||
use ostd::{mm::Vaddr, sync::RwArc, task::CurrentTask};
|
||||
|
||||
use super::RobustListHead;
|
||||
use crate::process::signal::SigStack;
|
||||
use crate::{fs::file_table::FileTable, process::signal::SigStack};
|
||||
|
||||
/// Local data for a POSIX thread.
|
||||
pub struct ThreadLocal {
|
||||
@ -18,6 +18,9 @@ pub struct ThreadLocal {
|
||||
// https://man7.org/linux/man-pages/man2/get_robust_list.2.html
|
||||
robust_list: RefCell<Option<RobustListHead>>,
|
||||
|
||||
// Files.
|
||||
file_table: RefCell<RwArc<FileTable>>,
|
||||
|
||||
// Signal.
|
||||
/// `ucontext` address for the signal handler.
|
||||
// FIXME: This field may be removed. For glibc applications with RESTORER flag set, the
|
||||
@ -28,11 +31,16 @@ pub struct ThreadLocal {
|
||||
}
|
||||
|
||||
impl ThreadLocal {
|
||||
pub(super) fn new(set_child_tid: Vaddr, clear_child_tid: Vaddr) -> Self {
|
||||
pub(super) fn new(
|
||||
set_child_tid: Vaddr,
|
||||
clear_child_tid: Vaddr,
|
||||
file_table: RwArc<FileTable>,
|
||||
) -> Self {
|
||||
Self {
|
||||
set_child_tid: Cell::new(set_child_tid),
|
||||
clear_child_tid: Cell::new(clear_child_tid),
|
||||
robust_list: RefCell::new(None),
|
||||
file_table: RefCell::new(file_table),
|
||||
sig_context: Cell::new(None),
|
||||
sig_stack: RefCell::new(None),
|
||||
}
|
||||
@ -50,6 +58,10 @@ impl ThreadLocal {
|
||||
&self.robust_list
|
||||
}
|
||||
|
||||
pub fn file_table(&self) -> &RefCell<RwArc<FileTable>> {
|
||||
&self.file_table
|
||||
}
|
||||
|
||||
pub fn sig_context(&self) -> &Cell<Option<Vaddr>> {
|
||||
&self.sig_context
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
fs::{
|
||||
fs_resolver::{FsPath, FsResolver, AT_FDCWD},
|
||||
path::Dentry,
|
||||
utils::Permission,
|
||||
utils::{InodeType, Permission},
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
@ -74,6 +74,10 @@ pub fn check_executable_file(dentry: &Dentry) -> Result<()> {
|
||||
return_errno_with_message!(Errno::EISDIR, "the file is a directory");
|
||||
}
|
||||
|
||||
if dentry.type_() == InodeType::SymLink {
|
||||
return_errno_with_message!(Errno::ELOOP, "the file is a symbolic link");
|
||||
}
|
||||
|
||||
if !dentry.type_().is_regular_file() {
|
||||
return_errno_with_message!(Errno::EACCES, "the dentry is not a regular file");
|
||||
}
|
||||
|
Reference in New Issue
Block a user