mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 13:26:48 +00:00
Make the file lookup faster
This commit is contained in:
parent
fb8f493b43
commit
b9ce3e64ad
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
|
|
||||||
|
use ostd::task::Task;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
current_userspace,
|
current_userspace,
|
||||||
device::tty::{line_discipline::LineDiscipline, new_job_control_and_ldisc},
|
device::tty::{line_discipline::LineDiscipline, new_job_control_and_ldisc},
|
||||||
@ -16,7 +18,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{
|
process::{
|
||||||
posix_thread::AsPosixThread,
|
posix_thread::{AsPosixThread, AsThreadLocal},
|
||||||
signal::{PollHandle, Pollable, Pollee},
|
signal::{PollHandle, Pollable, Pollee},
|
||||||
JobControl, Terminal,
|
JobControl, Terminal,
|
||||||
},
|
},
|
||||||
@ -192,8 +194,9 @@ impl FileIo for PtyMaster {
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
IoctlCmd::TIOCGPTPEER => {
|
IoctlCmd::TIOCGPTPEER => {
|
||||||
let current = current_thread!();
|
let current_task = Task::current().unwrap();
|
||||||
let current = current.as_posix_thread().unwrap();
|
let posix_thread = current_task.as_posix_thread().unwrap();
|
||||||
|
let thread_local = current_task.as_thread_local().unwrap();
|
||||||
|
|
||||||
// TODO: deal with open options
|
// TODO: deal with open options
|
||||||
let slave = {
|
let slave = {
|
||||||
@ -205,7 +208,7 @@ impl FileIo for PtyMaster {
|
|||||||
let fs_path = FsPath::try_from(slave_name.as_str())?;
|
let fs_path = FsPath::try_from(slave_name.as_str())?;
|
||||||
|
|
||||||
let inode_handle = {
|
let inode_handle = {
|
||||||
let fs = current.fs().resolver().read();
|
let fs = posix_thread.fs().resolver().read();
|
||||||
let flags = AccessMode::O_RDWR as u32;
|
let flags = AccessMode::O_RDWR as u32;
|
||||||
let mode = (InodeMode::S_IRUSR | InodeMode::S_IWUSR).bits();
|
let mode = (InodeMode::S_IRUSR | InodeMode::S_IWUSR).bits();
|
||||||
fs.open(&fs_path, flags, mode)?
|
fs.open(&fs_path, flags, mode)?
|
||||||
@ -214,9 +217,10 @@ impl FileIo for PtyMaster {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let fd = {
|
let fd = {
|
||||||
let mut file_table = current.file_table().lock();
|
let file_table = thread_local.file_table().borrow();
|
||||||
|
let mut file_table_locked = file_table.write();
|
||||||
// TODO: deal with the O_CLOEXEC flag
|
// TODO: deal with the O_CLOEXEC flag
|
||||||
file_table.insert(slave, FdFlags::empty())
|
file_table_locked.insert(slave, FdFlags::empty())
|
||||||
};
|
};
|
||||||
Ok(fd)
|
Ok(fd)
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@ use crate::{
|
|||||||
events::IoEvents,
|
events::IoEvents,
|
||||||
fs::{
|
fs::{
|
||||||
file_handle::FileLike,
|
file_handle::FileLike,
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
utils::{InodeMode, IoctlCmd, Metadata},
|
utils::{InodeMode, IoctlCmd, Metadata},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{
|
process::{
|
||||||
posix_thread::AsPosixThread,
|
posix_thread::ThreadLocal,
|
||||||
signal::{PollHandle, Pollable},
|
signal::{PollHandle, Pollable},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -56,19 +56,16 @@ impl EpollFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Controls the interest list of the epoll file.
|
/// Controls the interest list of the epoll file.
|
||||||
pub fn control(&self, cmd: &EpollCtl) -> Result<()> {
|
pub fn control(&self, thread_local: &ThreadLocal, cmd: &EpollCtl) -> Result<()> {
|
||||||
let fd = match cmd {
|
let fd = match cmd {
|
||||||
EpollCtl::Add(fd, ..) => *fd,
|
EpollCtl::Add(fd, ..) => *fd,
|
||||||
EpollCtl::Del(fd) => *fd,
|
EpollCtl::Del(fd) => *fd,
|
||||||
EpollCtl::Mod(fd, ..) => *fd,
|
EpollCtl::Mod(fd, ..) => *fd,
|
||||||
};
|
};
|
||||||
|
|
||||||
let file = {
|
let mut file_table = thread_local.file_table().borrow_mut();
|
||||||
let current = current_thread!();
|
let file = get_file_fast!(&mut file_table, fd).into_owned();
|
||||||
let current = current.as_posix_thread().unwrap();
|
drop(file_table);
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
match *cmd {
|
match *cmd {
|
||||||
EpollCtl::Add(fd, ep_event, ep_flags) => {
|
EpollCtl::Add(fd, ep_event, ep_flags) => {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
//! Opened File Handle
|
//! Opened File Handle
|
||||||
|
|
||||||
|
use super::inode_handle::InodeHandle;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::utils::{AccessMode, FallocMode, InodeMode, IoctlCmd, Metadata, SeekFrom, StatusFlags},
|
fs::utils::{AccessMode, FallocMode, InodeMode, IoctlCmd, Metadata, SeekFrom, StatusFlags},
|
||||||
net::socket::Socket,
|
net::socket::Socket,
|
||||||
@ -131,4 +132,10 @@ impl dyn FileLike {
|
|||||||
self.as_socket()
|
self.as_socket()
|
||||||
.ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the file is not a socket"))
|
.ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the file is not a socket"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_inode_or_err(&self) -> Result<&InodeHandle> {
|
||||||
|
self.downcast_ref().ok_or_else(|| {
|
||||||
|
Error::with_message(Errno::EINVAL, "the file is not related to an inode")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
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,
|
||||||
@ -237,6 +238,67 @@ impl Drop for FileTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A helper trait that provides methods to operate the file table.
|
||||||
|
pub trait WithFileTable {
|
||||||
|
/// Calls `f` with the file table.
|
||||||
|
///
|
||||||
|
/// This method is lockless if the file table is not shared. Otherwise, `f` is called while
|
||||||
|
/// holding the read lock on the file table.
|
||||||
|
fn read_with<R>(&mut self, f: impl FnOnce(&FileTable) -> R) -> R;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithFileTable for RwArc<FileTable> {
|
||||||
|
fn read_with<R>(&mut self, f: impl FnOnce(&FileTable) -> R) -> R {
|
||||||
|
if let Some(inner) = self.get() {
|
||||||
|
f(inner)
|
||||||
|
} else {
|
||||||
|
f(&self.read())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a file from a file descriptor as fast as possible.
|
||||||
|
///
|
||||||
|
/// `file_table` should be a mutable borrow of the file table contained in the `file_table` field
|
||||||
|
/// (which is a [`RefCell`]) in [`ThreadLocal`]. A mutable borrow is required because its
|
||||||
|
/// exclusivity can be useful for achieving lockless file lookups.
|
||||||
|
///
|
||||||
|
/// If the file table is not shared with another thread, this macro will be free of locks
|
||||||
|
/// ([`RwArc::read`]) and free of reference counting ([`Arc::clone`]).
|
||||||
|
///
|
||||||
|
/// If the file table is shared, the read lock is taken, the file is cloned, and then the read lock
|
||||||
|
/// is released. Cloning and releasing the lock is necessary because we cannot hold such locks when
|
||||||
|
/// operating on files, since many operations on files can block.
|
||||||
|
///
|
||||||
|
/// Note: This has to be a macro due to a limitation in the Rust borrow check implementation. Once
|
||||||
|
/// <https://github.com/rust-lang/rust/issues/58910> is fixed, we can try to convert this macro to
|
||||||
|
/// a function.
|
||||||
|
///
|
||||||
|
/// [`RefCell`]: core::cell::RefCell
|
||||||
|
/// [`ThreadLocal`]: crate::process::posix_thread::ThreadLocal
|
||||||
|
macro_rules! get_file_fast {
|
||||||
|
($file_table:expr, $file_desc:expr) => {{
|
||||||
|
use alloc::borrow::Cow;
|
||||||
|
|
||||||
|
use ostd::sync::RwArc;
|
||||||
|
|
||||||
|
use crate::fs::file_table::{FileDesc, FileTable};
|
||||||
|
|
||||||
|
let file_table: &mut RwArc<FileTable> = $file_table;
|
||||||
|
let file_desc: FileDesc = $file_desc;
|
||||||
|
|
||||||
|
if let Some(inner) = file_table.get() {
|
||||||
|
// Fast path: The file table is not shared, we can get the file in a lockless way.
|
||||||
|
Cow::Borrowed(inner.get_file(file_desc)?)
|
||||||
|
} else {
|
||||||
|
// Slow path: The file table is shared, we need to hold the lock and clone the file.
|
||||||
|
Cow::Owned(file_table.read().get_file(file_desc)?.clone())
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use get_file_fast;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum FdEvents {
|
pub enum FdEvents {
|
||||||
Close(FileDesc),
|
Close(FileDesc),
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
use alloc::str;
|
use alloc::str;
|
||||||
|
|
||||||
|
use ostd::task::Task;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
inode_handle::InodeHandle,
|
inode_handle::InodeHandle,
|
||||||
path::Dentry,
|
path::Dentry,
|
||||||
rootfs::root_mount,
|
rootfs::root_mount,
|
||||||
utils::{AccessMode, CreationFlags, InodeMode, InodeType, StatusFlags, PATH_MAX, SYMLINKS_MAX},
|
utils::{AccessMode, CreationFlags, InodeMode, InodeType, StatusFlags, PATH_MAX, SYMLINKS_MAX},
|
||||||
};
|
};
|
||||||
use crate::{prelude::*, process::posix_thread::AsPosixThread};
|
use crate::{prelude::*, process::posix_thread::AsThreadLocal};
|
||||||
|
|
||||||
/// The file descriptor of the current working directory.
|
/// The file descriptor of the current working directory.
|
||||||
pub const AT_FDCWD: FileDesc = -100;
|
pub const AT_FDCWD: FileDesc = -100;
|
||||||
@ -166,10 +168,17 @@ impl FsResolver {
|
|||||||
}
|
}
|
||||||
FsPathInner::Cwd => self.cwd.clone(),
|
FsPathInner::Cwd => self.cwd.clone(),
|
||||||
FsPathInner::FdRelative(fd, path) => {
|
FsPathInner::FdRelative(fd, path) => {
|
||||||
let parent = self.lookup_from_fd(fd)?;
|
let task = Task::current().unwrap();
|
||||||
self.lookup_from_parent(&parent, path, lookup_ctx)?
|
let mut file_table = task.as_thread_local().unwrap().file_table().borrow_mut();
|
||||||
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
|
self.lookup_from_parent(file.as_inode_or_err()?.dentry(), path, lookup_ctx)?
|
||||||
|
}
|
||||||
|
FsPathInner::Fd(fd) => {
|
||||||
|
let task = Task::current().unwrap();
|
||||||
|
let mut file_table = task.as_thread_local().unwrap().file_table().borrow_mut();
|
||||||
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
|
file.as_inode_or_err()?.dentry().clone()
|
||||||
}
|
}
|
||||||
FsPathInner::Fd(fd) => self.lookup_from_fd(fd)?,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(dentry)
|
Ok(dentry)
|
||||||
@ -280,18 +289,6 @@ impl FsResolver {
|
|||||||
Ok(dentry)
|
Ok(dentry)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lookups the target dentry according to the given `fd`.
|
|
||||||
pub fn lookup_from_fd(&self, fd: FileDesc) -> Result<Dentry> {
|
|
||||||
let current = current_thread!();
|
|
||||||
let current = current.as_posix_thread().unwrap();
|
|
||||||
let file_table = current.file_table().lock();
|
|
||||||
let inode_handle = file_table
|
|
||||||
.get_file(fd)?
|
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
Ok(inode_handle.dentry().clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lookups the target parent directory dentry and
|
/// Lookups the target parent directory dentry and
|
||||||
/// the base file name according to the given `path`.
|
/// the base file name according to the given `path`.
|
||||||
///
|
///
|
||||||
|
@ -25,7 +25,7 @@ impl FdDirOps {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let main_thread = process_ref.main_thread();
|
let main_thread = process_ref.main_thread();
|
||||||
let file_table = main_thread.as_posix_thread().unwrap().file_table().lock();
|
let file_table = main_thread.as_posix_thread().unwrap().file_table().read();
|
||||||
let weak_ptr = Arc::downgrade(&fd_inode);
|
let weak_ptr = Arc::downgrade(&fd_inode);
|
||||||
file_table.register_observer(weak_ptr);
|
file_table.register_observer(weak_ptr);
|
||||||
fd_inode
|
fd_inode
|
||||||
@ -52,7 +52,7 @@ impl DirOps for FdDirOps {
|
|||||||
.parse::<FileDesc>()
|
.parse::<FileDesc>()
|
||||||
.map_err(|_| Error::new(Errno::ENOENT))?;
|
.map_err(|_| Error::new(Errno::ENOENT))?;
|
||||||
let main_thread = self.0.main_thread();
|
let main_thread = self.0.main_thread();
|
||||||
let file_table = main_thread.as_posix_thread().unwrap().file_table().lock();
|
let file_table = main_thread.as_posix_thread().unwrap().file_table().read();
|
||||||
file_table
|
file_table
|
||||||
.get_file(fd)
|
.get_file(fd)
|
||||||
.map_err(|_| Error::new(Errno::ENOENT))?
|
.map_err(|_| Error::new(Errno::ENOENT))?
|
||||||
@ -68,7 +68,7 @@ impl DirOps for FdDirOps {
|
|||||||
};
|
};
|
||||||
let mut cached_children = this.cached_children().write();
|
let mut cached_children = this.cached_children().write();
|
||||||
let main_thread = self.0.main_thread();
|
let main_thread = self.0.main_thread();
|
||||||
let file_table = main_thread.as_posix_thread().unwrap().file_table().lock();
|
let file_table = main_thread.as_posix_thread().unwrap().file_table().read();
|
||||||
for (fd, file) in file_table.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())
|
||||||
|
@ -34,7 +34,7 @@ impl PidDirOps {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let main_thread = process_ref.main_thread();
|
let main_thread = process_ref.main_thread();
|
||||||
let file_table = main_thread.as_posix_thread().unwrap().file_table().lock();
|
let file_table = main_thread.as_posix_thread().unwrap().file_table().read();
|
||||||
let weak_ptr = Arc::downgrade(&pid_inode);
|
let weak_ptr = Arc::downgrade(&pid_inode);
|
||||||
file_table.register_observer(weak_ptr);
|
file_table.register_observer(weak_ptr);
|
||||||
pid_inode
|
pid_inode
|
||||||
|
@ -81,7 +81,7 @@ 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.lock().len()).unwrap();
|
writeln!(status_output, "FDSize:\t{}", file_table.read().len()).unwrap();
|
||||||
writeln!(
|
writeln!(
|
||||||
status_output,
|
status_output,
|
||||||
"Threads:\t{}",
|
"Threads:\t{}",
|
||||||
|
@ -4,6 +4,7 @@ use core::{num::NonZeroU64, sync::atomic::Ordering};
|
|||||||
|
|
||||||
use ostd::{
|
use ostd::{
|
||||||
cpu::UserContext,
|
cpu::UserContext,
|
||||||
|
sync::RwArc,
|
||||||
task::Task,
|
task::Task,
|
||||||
user::{UserContextApi, UserSpace},
|
user::{UserContextApi, UserSpace},
|
||||||
};
|
};
|
||||||
@ -215,6 +216,7 @@ fn clone_child_task(
|
|||||||
|
|
||||||
let Context {
|
let Context {
|
||||||
process,
|
process,
|
||||||
|
thread_local,
|
||||||
posix_thread,
|
posix_thread,
|
||||||
..
|
..
|
||||||
} = ctx;
|
} = ctx;
|
||||||
@ -223,7 +225,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(posix_thread.file_table(), clone_flags);
|
let child_file_table = clone_files(&thread_local.file_table().borrow(), 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);
|
||||||
@ -281,6 +283,7 @@ fn clone_child_process(
|
|||||||
) -> Result<Arc<Process>> {
|
) -> Result<Arc<Process>> {
|
||||||
let Context {
|
let Context {
|
||||||
process,
|
process,
|
||||||
|
thread_local,
|
||||||
posix_thread,
|
posix_thread,
|
||||||
..
|
..
|
||||||
} = ctx;
|
} = ctx;
|
||||||
@ -310,7 +313,7 @@ fn clone_child_process(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// clone file table
|
// 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
|
// clone fs
|
||||||
let child_fs = clone_fs(posix_thread.fs(), clone_flags);
|
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(
|
fn clone_files(parent_file_table: &RwArc<FileTable>, clone_flags: CloneFlags) -> RwArc<FileTable> {
|
||||||
parent_file_table: &Arc<SpinLock<FileTable>>,
|
|
||||||
clone_flags: CloneFlags,
|
|
||||||
) -> Arc<SpinLock<FileTable>> {
|
|
||||||
// if CLONE_FILES is set, the child and parent shares the same file table
|
// if CLONE_FILES is set, the child and parent shares the same file table
|
||||||
// Otherwise, the child will deep copy a new file table.
|
// Otherwise, the child will deep copy a new file table.
|
||||||
// FIXME: the clone may not be deep copy.
|
// FIXME: the clone may not be deep copy.
|
||||||
if clone_flags.contains(CloneFlags::CLONE_FILES) {
|
if clone_flags.contains(CloneFlags::CLONE_FILES) {
|
||||||
parent_file_table.clone()
|
parent_file_table.clone()
|
||||||
} else {
|
} 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
|
// 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};
|
use crate::{prelude::*, process::signal::signals::kernel::KernelSignal};
|
||||||
|
|
||||||
/// Exits the current POSIX process.
|
/// 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`]: 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(current_thread: &PosixThread, current_process: &Process) {
|
pub(super) fn exit_process(thread_local: &ThreadLocal, current_process: &Process) {
|
||||||
current_process.status().set_zombie();
|
current_process.status().set_zombie();
|
||||||
|
|
||||||
// FIXME: This is obviously wrong in a number of ways, since different threads can have
|
// 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.
|
// 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);
|
send_parent_death_signal(current_process);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![allow(dead_code)]
|
#![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 super::{thread_table, PosixThread, ThreadLocal};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -30,7 +30,7 @@ pub struct PosixThreadBuilder {
|
|||||||
thread_name: Option<ThreadName>,
|
thread_name: Option<ThreadName>,
|
||||||
set_child_tid: Vaddr,
|
set_child_tid: Vaddr,
|
||||||
clear_child_tid: Vaddr,
|
clear_child_tid: Vaddr,
|
||||||
file_table: Option<Arc<SpinLock<FileTable>>>,
|
file_table: Option<RwArc<FileTable>>,
|
||||||
fs: Option<Arc<ThreadFsInfo>>,
|
fs: Option<Arc<ThreadFsInfo>>,
|
||||||
sig_mask: AtomicSigMask,
|
sig_mask: AtomicSigMask,
|
||||||
sig_queues: SigQueues,
|
sig_queues: SigQueues,
|
||||||
@ -75,7 +75,7 @@ impl PosixThreadBuilder {
|
|||||||
self
|
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.file_table = Some(file_table);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -111,8 +111,7 @@ impl PosixThreadBuilder {
|
|||||||
priority,
|
priority,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let file_table =
|
let file_table = file_table.unwrap_or_else(|| RwArc::new(FileTable::new_with_stdio()));
|
||||||
file_table.unwrap_or_else(|| Arc::new(SpinLock::new(FileTable::new_with_stdio())));
|
|
||||||
|
|
||||||
let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default()));
|
let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default()));
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ impl PosixThreadBuilder {
|
|||||||
tid,
|
tid,
|
||||||
name: Mutex::new(thread_name),
|
name: Mutex::new(thread_name),
|
||||||
credentials,
|
credentials,
|
||||||
file_table,
|
file_table: file_table.clone_ro(),
|
||||||
fs,
|
fs,
|
||||||
sig_mask,
|
sig_mask,
|
||||||
sig_queues,
|
sig_queues,
|
||||||
@ -146,7 +145,7 @@ impl PosixThreadBuilder {
|
|||||||
cpu_affinity,
|
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());
|
thread_table::add_thread(tid, thread.clone());
|
||||||
task::create_new_user_task(user_space, thread, thread_local)
|
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 {
|
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 core::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
use aster_rights::{ReadOp, WriteOp};
|
use aster_rights::{ReadOp, WriteOp};
|
||||||
use ostd::sync::Waker;
|
use ostd::sync::{RoArc, Waker};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
kill::SignalSenderIds,
|
kill::SignalSenderIds,
|
||||||
@ -57,7 +57,7 @@ pub struct PosixThread {
|
|||||||
|
|
||||||
// Files
|
// Files
|
||||||
/// File table
|
/// File table
|
||||||
file_table: Arc<SpinLock<FileTable>>,
|
file_table: RoArc<FileTable>,
|
||||||
/// File system
|
/// File system
|
||||||
fs: Arc<ThreadFsInfo>,
|
fs: Arc<ThreadFsInfo>,
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ impl PosixThread {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_table(&self) -> &Arc<SpinLock<FileTable>> {
|
pub fn file_table(&self) -> &RoArc<FileTable> {
|
||||||
&self.file_table
|
&self.file_table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
use core::cell::{Cell, RefCell};
|
use core::cell::{Cell, RefCell};
|
||||||
|
|
||||||
use ostd::{mm::Vaddr, task::CurrentTask};
|
use ostd::{mm::Vaddr, sync::RwArc, task::CurrentTask};
|
||||||
|
|
||||||
use super::RobustListHead;
|
use super::RobustListHead;
|
||||||
use crate::process::signal::SigStack;
|
use crate::{fs::file_table::FileTable, process::signal::SigStack};
|
||||||
|
|
||||||
/// Local data for a POSIX thread.
|
/// Local data for a POSIX thread.
|
||||||
pub struct ThreadLocal {
|
pub struct ThreadLocal {
|
||||||
@ -18,6 +18,9 @@ pub struct ThreadLocal {
|
|||||||
// https://man7.org/linux/man-pages/man2/get_robust_list.2.html
|
// https://man7.org/linux/man-pages/man2/get_robust_list.2.html
|
||||||
robust_list: RefCell<Option<RobustListHead>>,
|
robust_list: RefCell<Option<RobustListHead>>,
|
||||||
|
|
||||||
|
// Files.
|
||||||
|
file_table: RefCell<RwArc<FileTable>>,
|
||||||
|
|
||||||
// Signal.
|
// Signal.
|
||||||
/// `ucontext` address for the signal handler.
|
/// `ucontext` address for the signal handler.
|
||||||
// FIXME: This field may be removed. For glibc applications with RESTORER flag set, the
|
// FIXME: This field may be removed. For glibc applications with RESTORER flag set, the
|
||||||
@ -28,11 +31,16 @@ pub struct ThreadLocal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
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),
|
||||||
robust_list: RefCell::new(None),
|
robust_list: RefCell::new(None),
|
||||||
|
file_table: RefCell::new(file_table),
|
||||||
sig_context: Cell::new(None),
|
sig_context: Cell::new(None),
|
||||||
sig_stack: RefCell::new(None),
|
sig_stack: RefCell::new(None),
|
||||||
}
|
}
|
||||||
@ -50,6 +58,10 @@ impl ThreadLocal {
|
|||||||
&self.robust_list
|
&self.robust_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn file_table(&self) -> &RefCell<RwArc<FileTable>> {
|
||||||
|
&self.file_table
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sig_context(&self) -> &Cell<Option<Vaddr>> {
|
pub fn sig_context(&self) -> &Cell<Option<Vaddr>> {
|
||||||
&self.sig_context
|
&self.sig_context
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
fs::{
|
fs::{
|
||||||
fs_resolver::{FsPath, FsResolver, AT_FDCWD},
|
fs_resolver::{FsPath, FsResolver, AT_FDCWD},
|
||||||
path::Dentry,
|
path::Dentry,
|
||||||
utils::Permission,
|
utils::{InodeType, Permission},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
@ -74,6 +74,10 @@ pub fn check_executable_file(dentry: &Dentry) -> Result<()> {
|
|||||||
return_errno_with_message!(Errno::EISDIR, "the file is a directory");
|
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() {
|
if !dentry.type_().is_regular_file() {
|
||||||
return_errno_with_message!(Errno::EACCES, "the dentry is not a regular file");
|
return_errno_with_message!(Errno::EACCES, "the dentry is not a regular file");
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::{FdFlags, FileDesc},
|
file_table::{get_file_fast, FdFlags, FileDesc},
|
||||||
utils::{CreationFlags, StatusFlags},
|
utils::{CreationFlags, StatusFlags},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -47,10 +47,8 @@ fn do_accept(
|
|||||||
flags: Flags,
|
flags: Flags,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<FileDesc> {
|
) -> Result<FileDesc> {
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let (connected_socket, socket_addr) = {
|
let (connected_socket, socket_addr) = {
|
||||||
@ -76,8 +74,8 @@ fn do_accept(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let fd = {
|
let fd = {
|
||||||
let mut file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table_locked = file_table.write();
|
||||||
file_table.insert(connected_socket, fd_flags)
|
file_table_locked.insert(connected_socket, fd_flags)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(fd)
|
Ok(fd)
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::net::read_socket_addr_from_user};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
util::net::read_socket_addr_from_user,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_bind(
|
pub fn sys_bind(
|
||||||
sockfd: FileDesc,
|
sockfd: FileDesc,
|
||||||
@ -12,10 +16,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
socket.bind(socket_addr)?;
|
socket.bind(socket_addr)?;
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{file_table::FileDesc, fs_resolver::FsPath, inode_handle::InodeHandle, utils::InodeType},
|
fs::{
|
||||||
|
file_table::{get_file_fast, FileDesc},
|
||||||
|
fs_resolver::FsPath,
|
||||||
|
utils::InodeType,
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syscall::constants::MAX_FILENAME_LEN,
|
syscall::constants::MAX_FILENAME_LEN,
|
||||||
};
|
};
|
||||||
@ -31,12 +35,9 @@ pub fn sys_fchdir(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let dentry = {
|
let dentry = {
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file = file_table.get_file(fd)?;
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
let inode_handle = file
|
file.as_inode_or_err()?.dentry().clone()
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
inode_handle.dentry().clone()
|
|
||||||
};
|
};
|
||||||
if dentry.type_() != InodeType::Dir {
|
if dentry.type_() != InodeType::Dir {
|
||||||
return_errno_with_message!(Errno::ENOTDIR, "must be directory");
|
return_errno_with_message!(Errno::ENOTDIR, "must be directory");
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
fs_resolver::{FsPath, AT_FDCWD},
|
fs_resolver::{FsPath, AT_FDCWD},
|
||||||
utils::{InodeMode, PATH_MAX},
|
utils::{InodeMode, PATH_MAX},
|
||||||
},
|
},
|
||||||
@ -13,10 +13,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
file.set_mode(InodeMode::from_bits_truncate(mode))?;
|
file.set_mode(InodeMode::from_bits_truncate(mode))?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
fs_resolver::{FsPath, AT_FDCWD},
|
fs_resolver::{FsPath, AT_FDCWD},
|
||||||
utils::PATH_MAX,
|
utils::PATH_MAX,
|
||||||
},
|
},
|
||||||
@ -20,10 +20,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
if let Some(uid) = uid {
|
if let Some(uid) = uid {
|
||||||
file.set_owner(uid)?;
|
file.set_owner(uid)?;
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,10 @@ pub fn sys_close(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
|||||||
debug!("fd = {}", fd);
|
debug!("fd = {}", fd);
|
||||||
|
|
||||||
let file = {
|
let file = {
|
||||||
let mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
let _ = file_table.get_file(fd)?;
|
let mut file_table_locked = file_table.write();
|
||||||
file_table.close_file(fd).unwrap()
|
let _ = file_table_locked.get_file(fd)?;
|
||||||
|
file_table_locked.close_file(fd).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Cleanup work needs to be done in the `Drop` impl.
|
// Cleanup work needs to be done in the `Drop` impl.
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::net::read_socket_addr_from_user};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
util::net::read_socket_addr_from_user,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_connect(
|
pub fn sys_connect(
|
||||||
sockfd: FileDesc,
|
sockfd: FileDesc,
|
||||||
@ -12,10 +16,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
socket
|
socket
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::{FdFlags, FileDesc},
|
fs::file_table::{get_file_fast, FdFlags, FileDesc},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
};
|
};
|
||||||
@ -10,8 +10,9 @@ 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 mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
let new_fd = file_table.dup(old_fd, 0, FdFlags::empty())?;
|
let mut file_table_locked = file_table.write();
|
||||||
|
let new_fd = file_table_locked.dup(old_fd, 0, FdFlags::empty())?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(new_fd as _))
|
Ok(SyscallReturn::Return(new_fd as _))
|
||||||
}
|
}
|
||||||
@ -20,8 +21,8 @@ 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 file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let _ = file_table.get_file(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,9 +67,10 @@ fn do_dup3(
|
|||||||
return_errno!(Errno::EBADF);
|
return_errno!(Errno::EBADF);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
let _ = file_table.close_file(new_fd);
|
let mut file_table_locked = file_table.write();
|
||||||
let new_fd = file_table.dup(old_fd, new_fd, flags)?;
|
let _ = file_table_locked.close_file(new_fd);
|
||||||
|
let new_fd = file_table_locked.dup(old_fd, new_fd, flags)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(new_fd as _))
|
Ok(SyscallReturn::Return(new_fd as _))
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
events::IoEvents,
|
events::IoEvents,
|
||||||
fs::{
|
fs::{
|
||||||
epoll::{EpollCtl, EpollEvent, EpollFile, EpollFlags},
|
epoll::{EpollCtl, EpollEvent, EpollFile, EpollFlags},
|
||||||
file_table::{FdFlags, FileDesc},
|
file_table::{get_file_fast, FdFlags, FileDesc},
|
||||||
utils::CreationFlags,
|
utils::CreationFlags,
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -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 mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
let fd = file_table.insert(epoll_file, fd_flags);
|
let fd = file_table.write().insert(epoll_file, fd_flags);
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,14 +79,15 @@ pub fn sys_epoll_ctl(
|
|||||||
_ => return_errno_with_message!(Errno::EINVAL, "invalid op"),
|
_ => return_errno_with_message!(Errno::EINVAL, "invalid op"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, epfd).into_owned();
|
||||||
file_table.get_file(epfd)?.clone()
|
// Drop `file_table` as `EpollFile::control` also performs `file_table().borrow_mut()`.
|
||||||
};
|
drop(file_table);
|
||||||
|
|
||||||
let epoll_file = file
|
let epoll_file = file
|
||||||
.downcast_ref::<EpollFile>()
|
.downcast_ref::<EpollFile>()
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "not epoll file"))?;
|
.ok_or(Error::with_message(Errno::EINVAL, "not epoll file"))?;
|
||||||
epoll_file.control(&cmd)?;
|
epoll_file.control(ctx.thread_local, &cmd)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0 as _))
|
Ok(SyscallReturn::Return(0 as _))
|
||||||
}
|
}
|
||||||
@ -109,13 +110,12 @@ fn do_epoll_wait(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let epoll_file_arc = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, epfd);
|
||||||
file_table.get_file(epfd)?.clone()
|
let epoll_file = file
|
||||||
};
|
|
||||||
let epoll_file = epoll_file_arc
|
|
||||||
.downcast_ref::<EpollFile>()
|
.downcast_ref::<EpollFile>()
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "not epoll file"))?;
|
.ok_or(Error::with_message(Errno::EINVAL, "not epoll file"))?;
|
||||||
|
|
||||||
let result = epoll_file.wait(max_events, timeout.as_ref());
|
let result = epoll_file.wait(max_events, timeout.as_ref());
|
||||||
|
|
||||||
// As mentioned in the manual, the return value should be zero if no file descriptor becomes ready
|
// As mentioned in the manual, the return value should be zero if no file descriptor becomes ready
|
||||||
|
@ -54,13 +54,14 @@ 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 mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
|
let mut file_table_locked = file_table.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 {
|
||||||
FdFlags::empty()
|
FdFlags::empty()
|
||||||
};
|
};
|
||||||
file_table.insert(Arc::new(event_file), fd_flags)
|
file_table_locked.insert(Arc::new(event_file), fd_flags)
|
||||||
};
|
};
|
||||||
fd
|
fd
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,9 @@ use ostd::{
|
|||||||
use super::{constants::*, SyscallReturn};
|
use super::{constants::*, SyscallReturn};
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
fs_resolver::{FsPath, AT_FDCWD},
|
fs_resolver::{FsPath, AT_FDCWD},
|
||||||
path::Dentry,
|
path::Dentry,
|
||||||
utils::InodeType,
|
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{
|
process::{
|
||||||
@ -62,22 +61,22 @@ fn lookup_executable_file(
|
|||||||
flags: OpenFlags,
|
flags: OpenFlags,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<Dentry> {
|
) -> Result<Dentry> {
|
||||||
let fs_resolver = ctx.posix_thread.fs().resolver().read();
|
|
||||||
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
|
let dentry = if flags.contains(OpenFlags::AT_EMPTY_PATH) && filename.is_empty() {
|
||||||
fs_resolver.lookup_from_fd(dfd)
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
|
let file = get_file_fast!(&mut file_table, dfd);
|
||||||
|
file.as_inode_or_err()?.dentry().clone()
|
||||||
} else {
|
} else {
|
||||||
|
let fs_resolver = ctx.posix_thread.fs().resolver().read();
|
||||||
let fs_path = FsPath::new(dfd, &filename)?;
|
let fs_path = FsPath::new(dfd, &filename)?;
|
||||||
if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) {
|
if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) {
|
||||||
let dentry = fs_resolver.lookup_no_follow(&fs_path)?;
|
fs_resolver.lookup_no_follow(&fs_path)?
|
||||||
if dentry.type_() == InodeType::SymLink {
|
|
||||||
return_errno_with_message!(Errno::ELOOP, "the executable file is a symlink");
|
|
||||||
}
|
|
||||||
Ok(dentry)
|
|
||||||
} else {
|
} else {
|
||||||
fs_resolver.lookup(&fs_path)
|
fs_resolver.lookup(&fs_path)?
|
||||||
}
|
}
|
||||||
}?;
|
};
|
||||||
|
|
||||||
check_executable_file(&dentry)?;
|
check_executable_file(&dentry)?;
|
||||||
|
|
||||||
Ok(dentry)
|
Ok(dentry)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +110,11 @@ 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 = posix_thread.file_table().lock().close_files_on_exec();
|
let closed_files = thread_local
|
||||||
|
.file_table()
|
||||||
|
.borrow()
|
||||||
|
.write()
|
||||||
|
.close_files_on_exec();
|
||||||
drop(closed_files);
|
drop(closed_files);
|
||||||
|
|
||||||
debug!("load program to root vmar");
|
debug!("load program to root vmar");
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{file_table::FileDesc, utils::FallocMode},
|
fs::{
|
||||||
|
file_table::{get_file_fast, FileDesc},
|
||||||
|
utils::FallocMode,
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::ResourceType,
|
process::ResourceType,
|
||||||
};
|
};
|
||||||
@ -21,10 +24,8 @@ pub fn sys_fallocate(
|
|||||||
|
|
||||||
check_offset_and_len(offset, len, ctx)?;
|
check_offset_and_len(offset, len, ctx)?;
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
let falloc_mode = FallocMode::try_from(
|
let falloc_mode = FallocMode::try_from(
|
||||||
RawFallocMode::from_bits(mode as _)
|
RawFallocMode::from_bits(mode as _)
|
||||||
|
@ -4,8 +4,7 @@ use super::SyscallReturn;
|
|||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_handle::FileLike,
|
file_handle::FileLike,
|
||||||
file_table::{FdFlags, FileDesc},
|
file_table::{get_file_fast, FdFlags, FileDesc, WithFileTable},
|
||||||
inode_handle::InodeHandle,
|
|
||||||
utils::{
|
utils::{
|
||||||
FileRange, RangeLockItem, RangeLockItemBuilder, RangeLockType, StatusFlags, OFFSET_MAX,
|
FileRange, RangeLockItem, RangeLockItemBuilder, RangeLockType, StatusFlags, OFFSET_MAX,
|
||||||
},
|
},
|
||||||
@ -36,16 +35,17 @@ 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 mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
let new_fd = file_table.dup(fd, arg as FileDesc, flags)?;
|
let new_fd = file_table.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 file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let entry = file_table.get_entry(fd)?;
|
file_table.read_with(|inner| {
|
||||||
let fd_flags = entry.flags();
|
let fd_flags = inner.get_entry(fd)?.flags();
|
||||||
Ok(SyscallReturn::Return(fd_flags.bits() as _))
|
Ok(SyscallReturn::Return(fd_flags.bits() as _))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_setfd(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
|
fn handle_setfd(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
@ -54,17 +54,16 @@ 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 file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let entry = file_table.get_entry(fd)?;
|
file_table.read_with(|inner| {
|
||||||
entry.set_flags(flags);
|
inner.get_entry(fd)?.set_flags(flags);
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_getfl(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
fn handle_getfl(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
let status_flags = file.status_flags();
|
let status_flags = file.status_flags();
|
||||||
let access_mode = file.access_mode();
|
let access_mode = file.access_mode();
|
||||||
Ok(SyscallReturn::Return(
|
Ok(SyscallReturn::Return(
|
||||||
@ -73,10 +72,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
let valid_flags_mask = StatusFlags::O_APPEND
|
let valid_flags_mask = StatusFlags::O_APPEND
|
||||||
| StatusFlags::O_ASYNC
|
| StatusFlags::O_ASYNC
|
||||||
| StatusFlags::O_DIRECT
|
| StatusFlags::O_DIRECT
|
||||||
@ -90,10 +87,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
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)?;
|
||||||
let lock_type = RangeLockType::try_from(lock_mut_c.l_type)?;
|
let lock_type = RangeLockType::try_from(lock_mut_c.l_type)?;
|
||||||
@ -102,11 +97,9 @@ fn handle_getlk(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
|
|||||||
}
|
}
|
||||||
let mut lock = RangeLockItemBuilder::new()
|
let mut lock = RangeLockItemBuilder::new()
|
||||||
.type_(lock_type)
|
.type_(lock_type)
|
||||||
.range(from_c_flock_and_file(&lock_mut_c, file.clone())?)
|
.range(from_c_flock_and_file(&lock_mut_c, &**file)?)
|
||||||
.build()?;
|
.build()?;
|
||||||
let inode_file = file
|
let inode_file = file.as_inode_or_err()?;
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
lock = inode_file.test_range_lock(lock)?;
|
lock = inode_file.test_range_lock(lock)?;
|
||||||
lock_mut_c.copy_from_range_lock(&lock);
|
lock_mut_c.copy_from_range_lock(&lock);
|
||||||
ctx.user_space().write_val(lock_mut_ptr, &lock_mut_c)?;
|
ctx.user_space().write_val(lock_mut_ptr, &lock_mut_c)?;
|
||||||
@ -119,29 +112,26 @@ fn handle_setlk(
|
|||||||
is_nonblocking: bool,
|
is_nonblocking: bool,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
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)?;
|
||||||
let lock_type = RangeLockType::try_from(lock_mut_c.l_type)?;
|
let lock_type = RangeLockType::try_from(lock_mut_c.l_type)?;
|
||||||
let lock = RangeLockItemBuilder::new()
|
let lock = RangeLockItemBuilder::new()
|
||||||
.type_(lock_type)
|
.type_(lock_type)
|
||||||
.range(from_c_flock_and_file(&lock_mut_c, file.clone())?)
|
.range(from_c_flock_and_file(&lock_mut_c, &**file)?)
|
||||||
.build()?;
|
.build()?;
|
||||||
let inode_file = file
|
let inode_file = file.as_inode_or_err()?;
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
inode_file.set_range_lock(&lock, is_nonblocking)?;
|
inode_file.set_range_lock(&lock, is_nonblocking)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_getown(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
fn handle_getown(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_entry = file_table.get_entry(fd)?;
|
file_table.read_with(|inner| {
|
||||||
let pid = file_entry.owner().unwrap_or(0);
|
let pid = inner.get_entry(fd)?.owner().unwrap_or(0);
|
||||||
Ok(SyscallReturn::Return(pid as _))
|
Ok(SyscallReturn::Return(pid as _))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_setown(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
|
fn handle_setown(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
@ -162,8 +152,9 @@ fn handle_setown(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
|
|||||||
))?)
|
))?)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
let file_entry = file_table.get_entry_mut(fd)?;
|
let mut file_table_locked = file_table.write();
|
||||||
|
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))
|
||||||
}
|
}
|
||||||
@ -230,15 +221,12 @@ impl c_flock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create the file range through C flock and opened file reference
|
/// Create the file range through C flock and opened file reference
|
||||||
fn from_c_flock_and_file(lock: &c_flock, file: Arc<dyn FileLike>) -> Result<FileRange> {
|
fn from_c_flock_and_file(lock: &c_flock, file: &dyn FileLike) -> Result<FileRange> {
|
||||||
let start = {
|
let start = {
|
||||||
let whence = RangeLockWhence::try_from(lock.l_whence)?;
|
let whence = RangeLockWhence::try_from(lock.l_whence)?;
|
||||||
match whence {
|
match whence {
|
||||||
RangeLockWhence::SEEK_SET => lock.l_start,
|
RangeLockWhence::SEEK_SET => lock.l_start,
|
||||||
RangeLockWhence::SEEK_CUR => (file
|
RangeLockWhence::SEEK_CUR => (file.as_inode_or_err()?.offset() as off_t)
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?
|
|
||||||
.offset() as off_t)
|
|
||||||
.checked_add(lock.l_start)
|
.checked_add(lock.l_start)
|
||||||
.ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?,
|
.ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?,
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
inode_handle::InodeHandle,
|
|
||||||
utils::{FlockItem, FlockType},
|
utils::{FlockItem, FlockType},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -13,14 +12,9 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let current = ctx.posix_thread;
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
let file_table = current.file_table().lock();
|
let inode_file = file.as_inode_or_err()?;
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
let inode_file = file
|
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
let ops: FlockOps = FlockOps::from_i32(ops)?;
|
let ops: FlockOps = FlockOps::from_i32(ops)?;
|
||||||
if ops.contains(FlockOps::LOCK_UN) {
|
if ops.contains(FlockOps::LOCK_UN) {
|
||||||
inode_file.unlock_flock();
|
inode_file.unlock_flock();
|
||||||
|
@ -2,21 +2,16 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{file_table::FileDesc, inode_handle::InodeHandle},
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
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 dentry = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
let file = file_table.get_file(fd)?;
|
let dentry = file.as_inode_or_err()?.dentry();
|
||||||
let inode_handle = file
|
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "not inode"))?;
|
|
||||||
inode_handle.dentry().clone()
|
|
||||||
};
|
|
||||||
dentry.sync_all()?;
|
dentry.sync_all()?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
@ -24,14 +19,9 @@ 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 dentry = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
let file = file_table.get_file(fd)?;
|
let dentry = file.as_inode_or_err()?.dentry();
|
||||||
let inode_handle = file
|
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "not inode"))?;
|
|
||||||
inode_handle.dentry().clone()
|
|
||||||
};
|
|
||||||
dentry.sync_data()?;
|
dentry.sync_data()?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,7 @@ use core::marker::PhantomData;
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
inode_handle::InodeHandle,
|
|
||||||
utils::{DirentVisitor, InodeType},
|
utils::{DirentVisitor, InodeType},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -23,13 +22,9 @@ pub fn sys_getdents(
|
|||||||
fd, buf_addr, buf_len
|
fd, buf_addr, buf_len
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
let inode_handle = file.as_inode_or_err()?;
|
||||||
};
|
|
||||||
let inode_handle = file
|
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
if inode_handle.dentry().type_() != InodeType::Dir {
|
if inode_handle.dentry().type_() != InodeType::Dir {
|
||||||
return_errno!(Errno::ENOTDIR);
|
return_errno!(Errno::ENOTDIR);
|
||||||
}
|
}
|
||||||
@ -53,13 +48,9 @@ pub fn sys_getdents64(
|
|||||||
fd, buf_addr, buf_len
|
fd, buf_addr, buf_len
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
let inode_handle = file.as_inode_or_err()?;
|
||||||
};
|
|
||||||
let inode_handle = file
|
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
if inode_handle.dentry().type_() != InodeType::Dir {
|
if inode_handle.dentry().type_() != InodeType::Dir {
|
||||||
return_errno!(Errno::ENOTDIR);
|
return_errno!(Errno::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::net::write_socket_addr_to_user};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
util::net::write_socket_addr_to_user,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_getpeername(
|
pub fn sys_getpeername(
|
||||||
sockfd: FileDesc,
|
sockfd: FileDesc,
|
||||||
@ -11,10 +15,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let peer_addr = socket.peer_addr()?;
|
let peer_addr = socket.peer_addr()?;
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::net::write_socket_addr_to_user};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
util::net::write_socket_addr_to_user,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_getsockname(
|
pub fn sys_getsockname(
|
||||||
sockfd: FileDesc,
|
sockfd: FileDesc,
|
||||||
@ -11,10 +15,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let socket_addr = socket.addr()?;
|
let socket_addr = socket.addr()?;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::net::{new_raw_socket_option, CSocketOptionLevel},
|
util::net::{new_raw_socket_option, CSocketOptionLevel},
|
||||||
};
|
};
|
||||||
@ -25,10 +25,8 @@ pub fn sys_getsockopt(
|
|||||||
|
|
||||||
debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}");
|
debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}");
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let mut raw_option = new_raw_socket_option(level, optname)?;
|
let mut raw_option = new_raw_socket_option(level, optname)?;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::{FdFlags, FileDesc},
|
file_table::{get_file_fast, FdFlags, FileDesc, WithFileTable},
|
||||||
utils::{IoctlCmd, StatusFlags},
|
utils::{IoctlCmd, StatusFlags},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -16,10 +16,8 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, ctx: &Context) -> Result<Sy
|
|||||||
fd, ioctl_cmd, arg
|
fd, ioctl_cmd, arg
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
let res = match ioctl_cmd {
|
let res = match ioctl_cmd {
|
||||||
IoctlCmd::FIONBIO => {
|
IoctlCmd::FIONBIO => {
|
||||||
let is_nonblocking = ctx.user_space().read_val::<i32>(arg)? != 0;
|
let is_nonblocking = ctx.user_space().read_val::<i32>(arg)? != 0;
|
||||||
@ -43,21 +41,31 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, ctx: &Context) -> Result<Sy
|
|||||||
// Sets the close-on-exec flag of the file.
|
// Sets the close-on-exec flag of the file.
|
||||||
// Follow the implementation of fcntl()
|
// Follow the implementation of fcntl()
|
||||||
|
|
||||||
let flags = FdFlags::CLOEXEC;
|
file_table.read_with(|inner| {
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let entry = inner.get_entry(fd)?;
|
||||||
let entry = file_table.get_entry(fd)?;
|
entry.set_flags(entry.flags() | FdFlags::CLOEXEC);
|
||||||
entry.set_flags(flags);
|
Ok::<_, Error>(0)
|
||||||
0
|
})?
|
||||||
}
|
}
|
||||||
IoctlCmd::FIONCLEX => {
|
IoctlCmd::FIONCLEX => {
|
||||||
// Clears the close-on-exec flag of the file.
|
// Clears the close-on-exec flag of the file.
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
// Follow the implementation of fcntl()
|
||||||
let entry = file_table.get_entry(fd)?;
|
|
||||||
entry.set_flags(entry.flags() & (!FdFlags::CLOEXEC));
|
file_table.read_with(|inner| {
|
||||||
0
|
let entry = inner.get_entry(fd)?;
|
||||||
|
entry.set_flags(entry.flags() - FdFlags::CLOEXEC);
|
||||||
|
Ok::<_, Error>(0)
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
// FIXME: ioctl operations involving blocking I/O should be able to restart if interrupted
|
// FIXME: ioctl operations involving blocking I/O should be able to restart if interrupted
|
||||||
_ => file.ioctl(ioctl_cmd, arg)?,
|
_ => {
|
||||||
|
let file_owned = file.into_owned();
|
||||||
|
// We have to drop `file_table` because some I/O command will modify the file table
|
||||||
|
// (e.g., TIOCGPTPEER).
|
||||||
|
drop(file_table);
|
||||||
|
|
||||||
|
file_owned.ioctl(ioctl_cmd, arg)?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(SyscallReturn::Return(res as _))
|
Ok(SyscallReturn::Return(res as _))
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
socket.listen(backlog as usize)?;
|
socket.listen(backlog as usize)?;
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{file_table::FileDesc, utils::SeekFrom},
|
fs::{
|
||||||
|
file_table::{get_file_fast, FileDesc},
|
||||||
|
utils::SeekFrom,
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20,10 +23,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
let offset = file.seek(seek_from)?;
|
let offset = file.seek(seek_from)?;
|
||||||
Ok(SyscallReturn::Return(offset as _))
|
Ok(SyscallReturn::Return(offset as _))
|
||||||
|
@ -7,7 +7,10 @@ use aster_rights::Rights;
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{file_handle::FileLike, file_table::FileDesc, inode_handle::InodeHandle},
|
fs::{
|
||||||
|
file_handle::FileLike,
|
||||||
|
file_table::{get_file_fast, FileDesc},
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
vm::{
|
vm::{
|
||||||
perms::VmPerms,
|
perms::VmPerms,
|
||||||
@ -121,11 +124,9 @@ fn do_sys_mmap(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let vmo = {
|
let vmo = {
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file = file_table.get_file(fd)?;
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
let inode_handle = file
|
let inode_handle = file.as_inode_or_err()?;
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EINVAL, "no inode"))?;
|
|
||||||
|
|
||||||
let access_mode = inode_handle.access_mode();
|
let access_mode = inode_handle.access_mode();
|
||||||
if vm_perms.contains(VmPerms::READ) && !access_mode.is_readable() {
|
if vm_perms.contains(VmPerms::READ) && !access_mode.is_readable() {
|
||||||
|
@ -40,16 +40,19 @@ pub fn sys_openat(
|
|||||||
})?;
|
})?;
|
||||||
Arc::new(inode_handle)
|
Arc::new(inode_handle)
|
||||||
};
|
};
|
||||||
let mut file_table = current.file_table().lock();
|
|
||||||
let fd = {
|
let fd = {
|
||||||
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
|
let mut file_table_locked = file_table.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
|
||||||
} else {
|
} else {
|
||||||
FdFlags::empty()
|
FdFlags::empty()
|
||||||
};
|
};
|
||||||
file_table.insert(file_handle, fd_flags)
|
file_table_locked.insert(file_handle, fd_flags)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,17 +21,18 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32, ctx: &Context) -> Result<SyscallReturn>
|
|||||||
FdFlags::empty()
|
FdFlags::empty()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
|
let mut file_table_locked = file_table.write();
|
||||||
|
|
||||||
let pipe_fds = PipeFds {
|
let pipe_fds = PipeFds {
|
||||||
reader_fd: file_table.insert(pipe_reader, fd_flags),
|
reader_fd: file_table_locked.insert(pipe_reader, fd_flags),
|
||||||
writer_fd: file_table.insert(pipe_writer, fd_flags),
|
writer_fd: file_table_locked.insert(pipe_writer, fd_flags),
|
||||||
};
|
};
|
||||||
debug!("pipe_fds: {:?}", pipe_fds);
|
debug!("pipe_fds: {:?}", pipe_fds);
|
||||||
|
|
||||||
if let Err(err) = ctx.user_space().write_val(fds, &pipe_fds) {
|
if let Err(err) = ctx.user_space().write_val(fds, &pipe_fds) {
|
||||||
file_table.close_file(pipe_fds.reader_fd).unwrap();
|
file_table_locked.close_file(pipe_fds.reader_fd).unwrap();
|
||||||
file_table.close_file(pipe_fds.writer_fd).unwrap();
|
file_table_locked.close_file(pipe_fds.writer_fd).unwrap();
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use alloc::borrow::Cow;
|
||||||
use core::{cell::Cell, time::Duration};
|
use core::{cell::Cell, time::Duration};
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
events::IoEvents,
|
events::IoEvents,
|
||||||
fs::{file_handle::FileLike, file_table::FileDesc},
|
fs::{
|
||||||
|
file_handle::FileLike,
|
||||||
|
file_table::{FileDesc, FileTable},
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::signal::Poller,
|
process::signal::Poller,
|
||||||
};
|
};
|
||||||
@ -56,7 +60,15 @@ 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 (result, files) = hold_files(poll_fds, ctx);
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
|
let (result, files) = if let Some(file_table_inner) = file_table.get() {
|
||||||
|
hold_files(poll_fds, file_table_inner, Cow::Borrowed)
|
||||||
|
} else {
|
||||||
|
let file_table_locked = file_table.read();
|
||||||
|
hold_files(poll_fds, &file_table_locked, |file| {
|
||||||
|
Cow::Owned(file.clone())
|
||||||
|
})
|
||||||
|
};
|
||||||
match result {
|
match result {
|
||||||
FileResult::AllValid => (),
|
FileResult::AllValid => (),
|
||||||
FileResult::SomeInvalid => {
|
FileResult::SomeInvalid => {
|
||||||
@ -99,9 +111,14 @@ enum FileResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Holds all the files we're going to poll.
|
/// Holds all the files we're going to poll.
|
||||||
fn hold_files(poll_fds: &[PollFd], ctx: &Context) -> (FileResult, Vec<Option<Arc<dyn FileLike>>>) {
|
fn hold_files<'a, F, R>(
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
poll_fds: &[PollFd],
|
||||||
|
file_table: &'a FileTable,
|
||||||
|
f: F,
|
||||||
|
) -> (FileResult, Vec<Option<R>>)
|
||||||
|
where
|
||||||
|
F: Fn(&'a Arc<dyn FileLike>) -> R,
|
||||||
|
{
|
||||||
let mut files = Vec::with_capacity(poll_fds.len());
|
let mut files = Vec::with_capacity(poll_fds.len());
|
||||||
let mut result = FileResult::AllValid;
|
let mut result = FileResult::AllValid;
|
||||||
|
|
||||||
@ -119,7 +136,7 @@ fn hold_files(poll_fds: &[PollFd], ctx: &Context) -> (FileResult, Vec<Option<Arc
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
files.push(Some(file.clone()));
|
files.push(Some(f(file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
(result, files)
|
(result, files)
|
||||||
@ -131,7 +148,7 @@ enum PollerResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Registers the files with a poller, or exits early if some events are detected.
|
/// Registers the files with a poller, or exits early if some events are detected.
|
||||||
fn register_poller(poll_fds: &[PollFd], files: &[Option<Arc<dyn FileLike>>]) -> PollerResult {
|
fn register_poller(poll_fds: &[PollFd], files: &[Option<Cow<Arc<dyn FileLike>>>]) -> PollerResult {
|
||||||
let mut poller = Poller::new();
|
let mut poller = Poller::new();
|
||||||
|
|
||||||
for (i, (poll_fd, file)) in poll_fds.iter().zip(files.iter()).enumerate() {
|
for (i, (poll_fd, file)) in poll_fds.iter().zip(files.iter()).enumerate() {
|
||||||
@ -152,7 +169,7 @@ fn register_poller(poll_fds: &[PollFd], files: &[Option<Arc<dyn FileLike>>]) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Counts the number of the ready files.
|
/// Counts the number of the ready files.
|
||||||
fn count_all_events(poll_fds: &[PollFd], files: &[Option<Arc<dyn FileLike>>]) -> usize {
|
fn count_all_events(poll_fds: &[PollFd], files: &[Option<Cow<Arc<dyn FileLike>>>]) -> usize {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
|
|
||||||
for (poll_fd, file) in poll_fds.iter().zip(files.iter()) {
|
for (poll_fd, file) in poll_fds.iter().zip(files.iter()) {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_pread64(
|
pub fn sys_pread64(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -18,10 +21,10 @@ pub fn sys_pread64(
|
|||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
let file = {
|
|
||||||
let filetable = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
filetable.get_file(fd)?.clone()
|
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
|
||||||
if user_buf_len == 0 {
|
if user_buf_len == 0 {
|
||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::{MultiWrite, VmWriterArray},
|
util::{MultiWrite, VmWriterArray},
|
||||||
};
|
};
|
||||||
@ -65,10 +65,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let filetable = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
filetable.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if io_vec_count == 0 {
|
if io_vec_count == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@ -127,10 +125,8 @@ fn do_sys_readv(
|
|||||||
fd, io_vec_ptr, io_vec_count
|
fd, io_vec_ptr, io_vec_count
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let filetable = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
filetable.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if io_vec_count == 0 {
|
if io_vec_count == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_pwrite64(
|
pub fn sys_pwrite64(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -14,13 +17,14 @@ pub fn sys_pwrite64(
|
|||||||
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
"fd = {}, user_buf_ptr = 0x{:x}, user_buf_len = 0x{:x}, offset = 0x{:x}",
|
||||||
fd, user_buf_ptr, user_buf_len, offset
|
fd, user_buf_ptr, user_buf_len, offset
|
||||||
);
|
);
|
||||||
|
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
let file = {
|
|
||||||
let filetable = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
filetable.get_file(fd)?.clone()
|
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
|
||||||
if user_buf_len == 0 {
|
if user_buf_len == 0 {
|
||||||
return Ok(SyscallReturn::Return(0));
|
return Ok(SyscallReturn::Return(0));
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*, util::VmReaderArray};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
util::VmReaderArray,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_writev(
|
pub fn sys_writev(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -57,13 +61,14 @@ fn do_sys_pwritev(
|
|||||||
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}, offset = 0x{:x}",
|
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}, offset = 0x{:x}",
|
||||||
fd, io_vec_ptr, io_vec_count, offset
|
fd, io_vec_ptr, io_vec_count, offset
|
||||||
);
|
);
|
||||||
|
|
||||||
if offset < 0 {
|
if offset < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
|
||||||
}
|
}
|
||||||
let file = {
|
|
||||||
let filetable = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
filetable.get_file(fd)?.clone()
|
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
|
||||||
if io_vec_count == 0 {
|
if io_vec_count == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@ -116,10 +121,10 @@ fn do_sys_writev(
|
|||||||
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}",
|
"fd = {}, io_vec_ptr = 0x{:x}, io_vec_counter = 0x{:x}",
|
||||||
fd, io_vec_ptr, io_vec_count
|
fd, io_vec_ptr, io_vec_count
|
||||||
);
|
);
|
||||||
let file = {
|
|
||||||
let filetable = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
filetable.get_file(fd)?.clone()
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
};
|
|
||||||
let mut total_len = 0;
|
let mut total_len = 0;
|
||||||
|
|
||||||
let mut reader_array = VmReaderArray::from_user_io_vecs(ctx, io_vec_ptr, io_vec_count)?;
|
let mut reader_array = VmReaderArray::from_user_io_vecs(ctx, io_vec_ptr, io_vec_count)?;
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_read(
|
pub fn sys_read(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -14,10 +17,8 @@ pub fn sys_read(
|
|||||||
fd, user_buf_addr, buf_len
|
fd, user_buf_addr, buf_len
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
||||||
// the user specified an empty buffer, we should detect errors by checking
|
// the user specified an empty buffer, we should detect errors by checking
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc, net::socket::SendRecvFlags, prelude::*,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
net::socket::SendRecvFlags,
|
||||||
|
prelude::*,
|
||||||
util::net::write_socket_addr_to_user,
|
util::net::write_socket_addr_to_user,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,10 +20,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let mut writers = {
|
let mut writers = {
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc, net::socket::SendRecvFlags, prelude::*, util::net::CUserMsgHdr,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
net::socket::SendRecvFlags,
|
||||||
|
prelude::*,
|
||||||
|
util::net::CUserMsgHdr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn sys_recvmsg(
|
pub fn sys_recvmsg(
|
||||||
@ -19,10 +22,8 @@ pub fn sys_recvmsg(
|
|||||||
sockfd, c_user_msghdr, flags
|
sockfd, c_user_msghdr, flags
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let (total_bytes, message_header) = {
|
let (total_bytes, message_header) = {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{FileDesc, WithFileTable},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_sendfile(
|
pub fn sys_sendfile(
|
||||||
out_fd: FileDesc,
|
out_fd: FileDesc,
|
||||||
@ -33,13 +36,16 @@ pub fn sys_sendfile(
|
|||||||
count as usize
|
count as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
let (out_file, in_file) = {
|
let (out_file, in_file) = ctx
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
.thread_local
|
||||||
let out_file = file_table.get_file(out_fd)?.clone();
|
.file_table()
|
||||||
|
.borrow_mut()
|
||||||
|
.read_with(|inner| {
|
||||||
|
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).
|
||||||
let in_file = file_table.get_file(in_fd)?.clone();
|
let in_file = inner.get_file(in_fd)?.clone();
|
||||||
(out_file, in_file)
|
Ok::<_, Error>((out_file, in_file))
|
||||||
};
|
})?;
|
||||||
|
|
||||||
// sendfile can send at most `MAX_COUNT` bytes
|
// sendfile can send at most `MAX_COUNT` bytes
|
||||||
const MAX_COUNT: usize = 0x7fff_f000;
|
const MAX_COUNT: usize = 0x7fff_f000;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
net::socket::{MessageHeader, SendRecvFlags},
|
net::socket::{MessageHeader, SendRecvFlags},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::net::CUserMsgHdr,
|
util::net::CUserMsgHdr,
|
||||||
@ -22,10 +22,8 @@ pub fn sys_sendmsg(
|
|||||||
sockfd, c_user_msghdr, flags
|
sockfd, c_user_msghdr, flags
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let (mut io_vec_reader, message_header) = {
|
let (mut io_vec_reader, message_header) = {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
net::socket::{MessageHeader, SendRecvFlags},
|
net::socket::{MessageHeader, SendRecvFlags},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::net::read_socket_addr_from_user,
|
util::net::read_socket_addr_from_user,
|
||||||
@ -26,10 +26,8 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let message_header = MessageHeader::new(socket_addr, None);
|
let message_header = MessageHeader::new(socket_addr, None);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::file_table::FileDesc,
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
util::net::{new_raw_socket_option, CSocketOptionLevel},
|
util::net::{new_raw_socket_option, CSocketOptionLevel},
|
||||||
};
|
};
|
||||||
@ -25,10 +25,8 @@ pub fn sys_setsockopt(
|
|||||||
level, sockfd, optname, optlen
|
level, sockfd, optname, optlen
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
let raw_option = {
|
let raw_option = {
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, net::socket::SockShutdownCmd, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
net::socket::SockShutdownCmd,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_shutdown(sockfd: FileDesc, how: i32, ctx: &Context) -> Result<SyscallReturn> {
|
pub fn sys_shutdown(sockfd: FileDesc, how: i32, ctx: &Context) -> Result<SyscallReturn> {
|
||||||
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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, sockfd);
|
||||||
file_table.get_file(sockfd)?.clone()
|
|
||||||
};
|
|
||||||
let socket = file.as_socket_or_err()?;
|
let socket = file.as_socket_or_err()?;
|
||||||
|
|
||||||
socket.shutdown(shutdown_cmd)?;
|
socket.shutdown(shutdown_cmd)?;
|
||||||
|
@ -43,13 +43,14 @@ 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 mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
|
let mut file_table_locked = file_table.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 {
|
||||||
FdFlags::empty()
|
FdFlags::empty()
|
||||||
};
|
};
|
||||||
file_table.insert(file_like, fd_flags)
|
file_table_locked.insert(file_like, fd_flags)
|
||||||
};
|
};
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
@ -37,14 +37,15 @@ pub fn sys_socketpair(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let socket_fds = {
|
let socket_fds = {
|
||||||
let mut file_table = ctx.posix_thread.file_table().lock();
|
let file_table = ctx.thread_local.file_table().borrow();
|
||||||
|
let mut file_table_locked = file_table.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 {
|
||||||
FdFlags::empty()
|
FdFlags::empty()
|
||||||
};
|
};
|
||||||
let fd_a = file_table.insert(socket_a, fd_flags);
|
let fd_a = file_table_locked.insert(socket_a, fd_flags);
|
||||||
let fd_b = file_table.insert(socket_b, fd_flags);
|
let fd_b = file_table_locked.insert(socket_b, fd_flags);
|
||||||
SocketFds(fd_a, fd_b)
|
SocketFds(fd_a, fd_b)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
fs_resolver::{FsPath, AT_FDCWD},
|
fs_resolver::{FsPath, AT_FDCWD},
|
||||||
utils::Metadata,
|
utils::Metadata,
|
||||||
},
|
},
|
||||||
@ -15,13 +15,12 @@ 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 file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
let stat = Stat::from(file.metadata());
|
let stat = Stat::from(file.metadata());
|
||||||
ctx.user_space().write_val(stat_buf_ptr, &stat)?;
|
ctx.user_space().write_val(stat_buf_ptr, &stat)?;
|
||||||
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
fs_resolver::FsPath,
|
fs_resolver::FsPath,
|
||||||
inode_handle::InodeHandle,
|
|
||||||
utils::{SuperBlock, PATH_MAX},
|
utils::{SuperBlock, PATH_MAX},
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -30,12 +29,9 @@ 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 file_table = ctx.posix_thread.file_table().lock();
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file = file_table.get_file(fd)?;
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
let inode_handle = file
|
file.as_inode_or_err()?.dentry().fs()
|
||||||
.downcast_ref::<InodeHandle>()
|
|
||||||
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
|
|
||||||
inode_handle.dentry().fs()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let statfs = Statfs::from(fs.sb());
|
let statfs = Statfs::from(fs.sb());
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{
|
use crate::{
|
||||||
fs::{
|
fs::{
|
||||||
file_table::FileDesc,
|
file_table::{get_file_fast, FileDesc},
|
||||||
fs_resolver::{FsPath, AT_FDCWD},
|
fs_resolver::{FsPath, AT_FDCWD},
|
||||||
utils::PATH_MAX,
|
utils::PATH_MAX,
|
||||||
},
|
},
|
||||||
@ -16,11 +16,8 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize, ctx: &Context) -> Result<SyscallR
|
|||||||
|
|
||||||
check_length(len, ctx)?;
|
check_length(len, ctx)?;
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
file.resize(len as usize)?;
|
file.resize(len as usize)?;
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use crate::{fs::file_table::FileDesc, prelude::*};
|
use crate::{
|
||||||
|
fs::file_table::{get_file_fast, FileDesc},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn sys_write(
|
pub fn sys_write(
|
||||||
fd: FileDesc,
|
fd: FileDesc,
|
||||||
@ -14,10 +17,8 @@ pub fn sys_write(
|
|||||||
fd, user_buf_ptr, user_buf_len
|
fd, user_buf_ptr, user_buf_len
|
||||||
);
|
);
|
||||||
|
|
||||||
let file = {
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
||||||
let file_table = ctx.posix_thread.file_table().lock();
|
let file = get_file_fast!(&mut file_table, fd);
|
||||||
file_table.get_file(fd)?.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
||||||
// the user specified an empty buffer, we should detect errors by checking
|
// the user specified an empty buffer, we should detect errors by checking
|
||||||
|
Loading…
x
Reference in New Issue
Block a user