Make the file lookup faster

This commit is contained in:
Ruihan Li
2024-12-26 21:35:56 +08:00
committed by Tate, Hongliang Tian
parent fb8f493b43
commit b9ce3e64ad
59 changed files with 483 additions and 390 deletions

View File

@ -3,7 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::{FdFlags, FileDesc},
file_table::{get_file_fast, FdFlags, FileDesc},
utils::{CreationFlags, StatusFlags},
},
prelude::*,
@ -47,10 +47,8 @@ fn do_accept(
flags: Flags,
ctx: &Context,
) -> Result<FileDesc> {
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let (connected_socket, socket_addr) = {
@ -76,8 +74,8 @@ fn do_accept(
}
let fd = {
let mut file_table = ctx.posix_thread.file_table().lock();
file_table.insert(connected_socket, fd_flags)
let mut file_table_locked = file_table.write();
file_table_locked.insert(connected_socket, fd_flags)
};
Ok(fd)

View File

@ -1,7 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
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(
sockfd: FileDesc,
@ -12,10 +16,8 @@ pub fn sys_bind(
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addrlen as usize)?;
debug!("sockfd = {sockfd}, socket_addr = {socket_addr:?}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
socket.bind(socket_addr)?;

View File

@ -2,7 +2,11 @@
use super::SyscallReturn;
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::*,
syscall::constants::MAX_FILENAME_LEN,
};
@ -31,12 +35,9 @@ pub fn sys_fchdir(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd);
let dentry = {
let file_table = ctx.posix_thread.file_table().lock();
let file = file_table.get_file(fd)?;
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
inode_handle.dentry().clone()
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
file.as_inode_or_err()?.dentry().clone()
};
if dentry.type_() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "must be directory");

View File

@ -3,7 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
file_table::{get_file_fast, FileDesc},
fs_resolver::{FsPath, AT_FDCWD},
utils::{InodeMode, PATH_MAX},
},
@ -13,10 +13,8 @@ use crate::{
pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}, mode = 0o{:o}", fd, mode);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
file.set_mode(InodeMode::from_bits_truncate(mode))?;
Ok(SyscallReturn::Return(0))
}

View File

@ -3,7 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
file_table::{get_file_fast, FileDesc},
fs_resolver::{FsPath, AT_FDCWD},
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));
}
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
if let Some(uid) = uid {
file.set_owner(uid)?;
}

View File

@ -7,9 +7,10 @@ pub fn sys_close(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd);
let file = {
let mut file_table = ctx.posix_thread.file_table().lock();
let _ = file_table.get_file(fd)?;
file_table.close_file(fd).unwrap()
let file_table = ctx.thread_local.file_table().borrow();
let mut file_table_locked = file_table.write();
let _ = file_table_locked.get_file(fd)?;
file_table_locked.close_file(fd).unwrap()
};
// Cleanup work needs to be done in the `Drop` impl.

View File

@ -1,7 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
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(
sockfd: FileDesc,
@ -12,10 +16,8 @@ pub fn sys_connect(
let socket_addr = read_socket_addr_from_user(sockaddr_ptr, addr_len as _)?;
debug!("fd = {sockfd}, socket_addr = {socket_addr:?}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
socket

View File

@ -2,7 +2,7 @@
use super::SyscallReturn;
use crate::{
fs::file_table::{FdFlags, FileDesc},
fs::file_table::{get_file_fast, FdFlags, FileDesc},
prelude::*,
process::ResourceType,
};
@ -10,8 +10,9 @@ use crate::{
pub fn sys_dup(old_fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("old_fd = {}", old_fd);
let mut file_table = ctx.posix_thread.file_table().lock();
let new_fd = file_table.dup(old_fd, 0, FdFlags::empty())?;
let file_table = ctx.thread_local.file_table().borrow();
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 _))
}
@ -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);
if old_fd == new_fd {
let file_table = ctx.posix_thread.file_table().lock();
let _ = file_table.get_file(old_fd)?;
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let _file = get_file_fast!(&mut file_table, old_fd);
return Ok(SyscallReturn::Return(new_fd as _));
}
@ -66,9 +67,10 @@ fn do_dup3(
return_errno!(Errno::EBADF);
}
let mut file_table = ctx.posix_thread.file_table().lock();
let _ = file_table.close_file(new_fd);
let new_fd = file_table.dup(old_fd, new_fd, flags)?;
let file_table = ctx.thread_local.file_table().borrow();
let mut file_table_locked = file_table.write();
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 _))
}

View File

@ -7,7 +7,7 @@ use crate::{
events::IoEvents,
fs::{
epoll::{EpollCtl, EpollEvent, EpollFile, EpollFlags},
file_table::{FdFlags, FileDesc},
file_table::{get_file_fast, FdFlags, FileDesc},
utils::CreationFlags,
},
prelude::*,
@ -41,8 +41,8 @@ pub fn sys_epoll_create1(flags: u32, ctx: &Context) -> Result<SyscallReturn> {
};
let epoll_file: Arc<EpollFile> = EpollFile::new();
let mut file_table = ctx.posix_thread.file_table().lock();
let fd = file_table.insert(epoll_file, fd_flags);
let file_table = ctx.thread_local.file_table().borrow();
let fd = file_table.write().insert(epoll_file, fd_flags);
Ok(SyscallReturn::Return(fd as _))
}
@ -79,14 +79,15 @@ pub fn sys_epoll_ctl(
_ => return_errno_with_message!(Errno::EINVAL, "invalid op"),
};
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(epfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, epfd).into_owned();
// Drop `file_table` as `EpollFile::control` also performs `file_table().borrow_mut()`.
drop(file_table);
let epoll_file = file
.downcast_ref::<EpollFile>()
.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 _))
}
@ -109,13 +110,12 @@ fn do_epoll_wait(
None
};
let epoll_file_arc = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(epfd)?.clone()
};
let epoll_file = epoll_file_arc
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, epfd);
let epoll_file = file
.downcast_ref::<EpollFile>()
.ok_or(Error::with_message(Errno::EINVAL, "not epoll file"))?;
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

View File

@ -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 {
let event_file = EventFile::new(init_val, flags);
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) {
FdFlags::CLOEXEC
} else {
FdFlags::empty()
};
file_table.insert(Arc::new(event_file), fd_flags)
file_table_locked.insert(Arc::new(event_file), fd_flags)
};
fd
}

View File

@ -9,10 +9,9 @@ use ostd::{
use super::{constants::*, SyscallReturn};
use crate::{
fs::{
file_table::FileDesc,
file_table::{get_file_fast, FileDesc},
fs_resolver::{FsPath, AT_FDCWD},
path::Dentry,
utils::InodeType,
},
prelude::*,
process::{
@ -62,22 +61,22 @@ fn lookup_executable_file(
flags: OpenFlags,
ctx: &Context,
) -> Result<Dentry> {
let fs_resolver = ctx.posix_thread.fs().resolver().read();
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 {
let fs_resolver = ctx.posix_thread.fs().resolver().read();
let fs_path = FsPath::new(dfd, &filename)?;
if flags.contains(OpenFlags::AT_SYMLINK_NOFOLLOW) {
let dentry = 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)
fs_resolver.lookup_no_follow(&fs_path)?
} else {
fs_resolver.lookup(&fs_path)
fs_resolver.lookup(&fs_path)?
}
}?;
};
check_executable_file(&dentry)?;
Ok(dentry)
}
@ -111,7 +110,11 @@ fn do_execve(
// 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.
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);
debug!("load program to root vmar");

View File

@ -2,7 +2,10 @@
use super::SyscallReturn;
use crate::{
fs::{file_table::FileDesc, utils::FallocMode},
fs::{
file_table::{get_file_fast, FileDesc},
utils::FallocMode,
},
prelude::*,
process::ResourceType,
};
@ -21,10 +24,8 @@ pub fn sys_fallocate(
check_offset_and_len(offset, len, ctx)?;
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let falloc_mode = FallocMode::try_from(
RawFallocMode::from_bits(mode as _)

View File

@ -4,8 +4,7 @@ use super::SyscallReturn;
use crate::{
fs::{
file_handle::FileLike,
file_table::{FdFlags, FileDesc},
inode_handle::InodeHandle,
file_table::{get_file_fast, FdFlags, FileDesc, WithFileTable},
utils::{
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> {
let mut file_table = ctx.posix_thread.file_table().lock();
let new_fd = file_table.dup(fd, arg as FileDesc, flags)?;
let file_table = ctx.thread_local.file_table().borrow();
let new_fd = file_table.write().dup(fd, arg as FileDesc, flags)?;
Ok(SyscallReturn::Return(new_fd as _))
}
fn handle_getfd(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
let file_table = ctx.posix_thread.file_table().lock();
let entry = file_table.get_entry(fd)?;
let fd_flags = entry.flags();
Ok(SyscallReturn::Return(fd_flags.bits() as _))
let mut file_table = ctx.thread_local.file_table().borrow_mut();
file_table.read_with(|inner| {
let fd_flags = inner.get_entry(fd)?.flags();
Ok(SyscallReturn::Return(fd_flags.bits() as _))
})
}
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 {
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 entry = file_table.get_entry(fd)?;
entry.set_flags(flags);
Ok(SyscallReturn::Return(0))
let mut file_table = ctx.thread_local.file_table().borrow_mut();
file_table.read_with(|inner| {
inner.get_entry(fd)?.set_flags(flags);
Ok(SyscallReturn::Return(0))
})
}
fn handle_getfl(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let status_flags = file.status_flags();
let access_mode = file.access_mode();
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> {
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let valid_flags_mask = StatusFlags::O_APPEND
| StatusFlags::O_ASYNC
| 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> {
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let lock_mut_ptr = arg as Vaddr;
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)?;
@ -102,11 +97,9 @@ fn handle_getlk(fd: FileDesc, arg: u64, ctx: &Context) -> Result<SyscallReturn>
}
let mut lock = RangeLockItemBuilder::new()
.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()?;
let inode_file = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
let inode_file = file.as_inode_or_err()?;
lock = inode_file.test_range_lock(lock)?;
lock_mut_c.copy_from_range_lock(&lock);
ctx.user_space().write_val(lock_mut_ptr, &lock_mut_c)?;
@ -119,29 +112,26 @@ fn handle_setlk(
is_nonblocking: bool,
ctx: &Context,
) -> Result<SyscallReturn> {
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let lock_mut_ptr = arg as Vaddr;
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 = RangeLockItemBuilder::new()
.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()?;
let inode_file = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
let inode_file = file.as_inode_or_err()?;
inode_file.set_range_lock(&lock, is_nonblocking)?;
Ok(SyscallReturn::Return(0))
}
fn handle_getown(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
let file_table = ctx.posix_thread.file_table().lock();
let file_entry = file_table.get_entry(fd)?;
let pid = file_entry.owner().unwrap_or(0);
Ok(SyscallReturn::Return(pid as _))
let mut file_table = ctx.thread_local.file_table().borrow_mut();
file_table.read_with(|inner| {
let pid = inner.get_entry(fd)?.owner().unwrap_or(0);
Ok(SyscallReturn::Return(pid as _))
})
}
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_entry = file_table.get_entry_mut(fd)?;
let file_table = ctx.thread_local.file_table().borrow();
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())?;
Ok(SyscallReturn::Return(0))
}
@ -230,15 +221,12 @@ impl c_flock {
}
/// 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 whence = RangeLockWhence::try_from(lock.l_whence)?;
match whence {
RangeLockWhence::SEEK_SET => lock.l_start,
RangeLockWhence::SEEK_CUR => (file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?
.offset() as off_t)
RangeLockWhence::SEEK_CUR => (file.as_inode_or_err()?.offset() as off_t)
.checked_add(lock.l_start)
.ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?,

View File

@ -3,8 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
inode_handle::InodeHandle,
file_table::{get_file_fast, FileDesc},
utils::{FlockItem, FlockType},
},
prelude::*,
@ -13,14 +12,9 @@ use crate::{
pub fn sys_flock(fd: FileDesc, ops: i32, ctx: &Context) -> Result<SyscallReturn> {
debug!("flock: fd: {}, ops: {:?}", fd, ops);
let file = {
let current = ctx.posix_thread;
let file_table = current.file_table().lock();
file_table.get_file(fd)?.clone()
};
let inode_file = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let inode_file = file.as_inode_or_err()?;
let ops: FlockOps = FlockOps::from_i32(ops)?;
if ops.contains(FlockOps::LOCK_UN) {
inode_file.unlock_flock();

View File

@ -2,21 +2,16 @@
use super::SyscallReturn;
use crate::{
fs::{file_table::FileDesc, inode_handle::InodeHandle},
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
};
pub fn sys_fsync(fd: FileDesc, ctx: &Context) -> Result<SyscallReturn> {
debug!("fd = {}", fd);
let dentry = {
let file_table = ctx.posix_thread.file_table().lock();
let file = file_table.get_file(fd)?;
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EINVAL, "not inode"))?;
inode_handle.dentry().clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let dentry = file.as_inode_or_err()?.dentry();
dentry.sync_all()?;
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> {
debug!("fd = {}", fd);
let dentry = {
let file_table = ctx.posix_thread.file_table().lock();
let file = file_table.get_file(fd)?;
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EINVAL, "not inode"))?;
inode_handle.dentry().clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let dentry = file.as_inode_or_err()?.dentry();
dentry.sync_data()?;
Ok(SyscallReturn::Return(0))
}

View File

@ -5,8 +5,7 @@ use core::marker::PhantomData;
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
inode_handle::InodeHandle,
file_table::{get_file_fast, FileDesc},
utils::{DirentVisitor, InodeType},
},
prelude::*,
@ -23,13 +22,9 @@ pub fn sys_getdents(
fd, buf_addr, buf_len
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let inode_handle = file.as_inode_or_err()?;
if inode_handle.dentry().type_() != InodeType::Dir {
return_errno!(Errno::ENOTDIR);
}
@ -53,13 +48,9 @@ pub fn sys_getdents64(
fd, buf_addr, buf_len
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let inode_handle = file.as_inode_or_err()?;
if inode_handle.dentry().type_() != InodeType::Dir {
return_errno!(Errno::ENOTDIR);
}

View File

@ -1,7 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
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(
sockfd: FileDesc,
@ -11,10 +15,8 @@ pub fn sys_getpeername(
) -> Result<SyscallReturn> {
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let peer_addr = socket.peer_addr()?;

View File

@ -1,7 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
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(
sockfd: FileDesc,
@ -11,10 +15,8 @@ pub fn sys_getsockname(
) -> Result<SyscallReturn> {
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen_ptr = 0x{addrlen_ptr:x}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let socket_addr = socket.addr()?;

View File

@ -2,7 +2,7 @@
use super::SyscallReturn;
use crate::{
fs::file_table::FileDesc,
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
util::net::{new_raw_socket_option, CSocketOptionLevel},
};
@ -25,10 +25,8 @@ pub fn sys_getsockopt(
debug!("level = {level:?}, sockfd = {sockfd}, optname = {optname:?}, optlen = {optlen}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let mut raw_option = new_raw_socket_option(level, optname)?;

View File

@ -3,7 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::{FdFlags, FileDesc},
file_table::{get_file_fast, FdFlags, FileDesc, WithFileTable},
utils::{IoctlCmd, StatusFlags},
},
prelude::*,
@ -16,10 +16,8 @@ pub fn sys_ioctl(fd: FileDesc, cmd: u32, arg: Vaddr, ctx: &Context) -> Result<Sy
fd, ioctl_cmd, arg
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let res = match ioctl_cmd {
IoctlCmd::FIONBIO => {
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.
// Follow the implementation of fcntl()
let flags = FdFlags::CLOEXEC;
let file_table = ctx.posix_thread.file_table().lock();
let entry = file_table.get_entry(fd)?;
entry.set_flags(flags);
0
file_table.read_with(|inner| {
let entry = inner.get_entry(fd)?;
entry.set_flags(entry.flags() | FdFlags::CLOEXEC);
Ok::<_, Error>(0)
})?
}
IoctlCmd::FIONCLEX => {
// Clears the close-on-exec flag of the file.
let file_table = ctx.posix_thread.file_table().lock();
let entry = file_table.get_entry(fd)?;
entry.set_flags(entry.flags() & (!FdFlags::CLOEXEC));
0
// Follow the implementation of fcntl()
file_table.read_with(|inner| {
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
_ => 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 _))
}

View File

@ -1,15 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
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> {
debug!("sockfd = {sockfd}, backlog = {backlog}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
socket.listen(backlog as usize)?;

View File

@ -2,7 +2,10 @@
use super::SyscallReturn;
use crate::{
fs::{file_table::FileDesc, utils::SeekFrom},
fs::{
file_table::{get_file_fast, FileDesc},
utils::SeekFrom,
},
prelude::*,
};
@ -20,10 +23,8 @@ pub fn sys_lseek(fd: FileDesc, offset: isize, whence: u32, ctx: &Context) -> Res
2 => SeekFrom::End(offset),
_ => return_errno!(Errno::EINVAL),
};
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let offset = file.seek(seek_from)?;
Ok(SyscallReturn::Return(offset as _))

View File

@ -7,7 +7,10 @@ use aster_rights::Rights;
use super::SyscallReturn;
use crate::{
fs::{file_handle::FileLike, file_table::FileDesc, inode_handle::InodeHandle},
fs::{
file_handle::FileLike,
file_table::{get_file_fast, FileDesc},
},
prelude::*,
vm::{
perms::VmPerms,
@ -121,11 +124,9 @@ fn do_sys_mmap(
}
} else {
let vmo = {
let file_table = ctx.posix_thread.file_table().lock();
let file = file_table.get_file(fd)?;
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EINVAL, "no inode"))?;
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let inode_handle = file.as_inode_or_err()?;
let access_mode = inode_handle.access_mode();
if vm_perms.contains(VmPerms::READ) && !access_mode.is_readable() {

View File

@ -40,16 +40,19 @@ pub fn sys_openat(
})?;
Arc::new(inode_handle)
};
let mut file_table = current.file_table().lock();
let fd = {
let file_table = ctx.thread_local.file_table().borrow();
let mut file_table_locked = file_table.write();
let fd_flags =
if CreationFlags::from_bits_truncate(flags).contains(CreationFlags::O_CLOEXEC) {
FdFlags::CLOEXEC
} else {
FdFlags::empty()
};
file_table.insert(file_handle, fd_flags)
file_table_locked.insert(file_handle, fd_flags)
};
Ok(SyscallReturn::Return(fd as _))
}

View File

@ -21,17 +21,18 @@ pub fn sys_pipe2(fds: Vaddr, flags: u32, ctx: &Context) -> Result<SyscallReturn>
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 {
reader_fd: file_table.insert(pipe_reader, fd_flags),
writer_fd: file_table.insert(pipe_writer, fd_flags),
reader_fd: file_table_locked.insert(pipe_reader, fd_flags),
writer_fd: file_table_locked.insert(pipe_writer, fd_flags),
};
debug!("pipe_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.close_file(pipe_fds.writer_fd).unwrap();
file_table_locked.close_file(pipe_fds.reader_fd).unwrap();
file_table_locked.close_file(pipe_fds.writer_fd).unwrap();
return Err(err);
}

View File

@ -1,11 +1,15 @@
// SPDX-License-Identifier: MPL-2.0
use alloc::borrow::Cow;
use core::{cell::Cell, time::Duration};
use super::SyscallReturn;
use crate::{
events::IoEvents,
fs::{file_handle::FileLike, file_table::FileDesc},
fs::{
file_handle::FileLike,
file_table::{FileDesc, FileTable},
},
prelude::*,
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> {
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 {
FileResult::AllValid => (),
FileResult::SomeInvalid => {
@ -99,9 +111,14 @@ enum FileResult {
}
/// Holds all the files we're going to poll.
fn hold_files(poll_fds: &[PollFd], ctx: &Context) -> (FileResult, Vec<Option<Arc<dyn FileLike>>>) {
let file_table = ctx.posix_thread.file_table().lock();
fn hold_files<'a, F, R>(
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 result = FileResult::AllValid;
@ -119,7 +136,7 @@ fn hold_files(poll_fds: &[PollFd], ctx: &Context) -> (FileResult, Vec<Option<Arc
continue;
};
files.push(Some(file.clone()));
files.push(Some(f(file)));
}
(result, files)
@ -131,7 +148,7 @@ enum PollerResult {
}
/// 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();
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.
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;
for (poll_fd, file) in poll_fds.iter().zip(files.iter()) {

View File

@ -1,7 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{fs::file_table::FileDesc, prelude::*};
use crate::{
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
};
pub fn sys_pread64(
fd: FileDesc,
@ -18,10 +21,10 @@ pub fn sys_pread64(
if offset < 0 {
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
}
let file = {
let filetable = ctx.posix_thread.file_table().lock();
filetable.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
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
if user_buf_len == 0 {
return Ok(SyscallReturn::Return(0));

View File

@ -2,7 +2,7 @@
use super::SyscallReturn;
use crate::{
fs::file_table::FileDesc,
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
util::{MultiWrite, VmWriterArray},
};
@ -65,10 +65,8 @@ fn do_sys_preadv(
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
}
let file = {
let filetable = ctx.posix_thread.file_table().lock();
filetable.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
if io_vec_count == 0 {
return Ok(0);
@ -127,10 +125,8 @@ fn do_sys_readv(
fd, io_vec_ptr, io_vec_count
);
let file = {
let filetable = ctx.posix_thread.file_table().lock();
filetable.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
if io_vec_count == 0 {
return Ok(0);

View File

@ -1,7 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{fs::file_table::FileDesc, prelude::*};
use crate::{
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
};
pub fn sys_pwrite64(
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, user_buf_len, offset
);
if offset < 0 {
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
}
let file = {
let filetable = ctx.posix_thread.file_table().lock();
filetable.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
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
if user_buf_len == 0 {
return Ok(SyscallReturn::Return(0));

View File

@ -1,7 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
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(
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, io_vec_count, offset
);
if offset < 0 {
return_errno_with_message!(Errno::EINVAL, "offset cannot be negative");
}
let file = {
let filetable = ctx.posix_thread.file_table().lock();
filetable.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
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
if io_vec_count == 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, io_vec_count
);
let file = {
let filetable = ctx.posix_thread.file_table().lock();
filetable.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let mut total_len = 0;
let mut reader_array = VmReaderArray::from_user_io_vecs(ctx, io_vec_ptr, io_vec_count)?;

View File

@ -1,7 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{fs::file_table::FileDesc, prelude::*};
use crate::{
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
};
pub fn sys_read(
fd: FileDesc,
@ -14,10 +17,8 @@ pub fn sys_read(
fd, user_buf_addr, buf_len
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
// 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

View File

@ -2,7 +2,9 @@
use super::SyscallReturn;
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,
};
@ -18,10 +20,8 @@ pub fn sys_recvfrom(
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}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let mut writers = {

View File

@ -2,7 +2,10 @@
use super::SyscallReturn;
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(
@ -19,10 +22,8 @@ pub fn sys_recvmsg(
sockfd, c_user_msghdr, flags
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let (total_bytes, message_header) = {

View File

@ -1,7 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{fs::file_table::FileDesc, prelude::*};
use crate::{
fs::file_table::{FileDesc, WithFileTable},
prelude::*,
};
pub fn sys_sendfile(
out_fd: FileDesc,
@ -33,13 +36,16 @@ pub fn sys_sendfile(
count as usize
};
let (out_file, in_file) = {
let file_table = ctx.posix_thread.file_table().lock();
let out_file = file_table.get_file(out_fd)?.clone();
// 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();
(out_file, in_file)
};
let (out_file, in_file) = ctx
.thread_local
.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).
let in_file = inner.get_file(in_fd)?.clone();
Ok::<_, Error>((out_file, in_file))
})?;
// sendfile can send at most `MAX_COUNT` bytes
const MAX_COUNT: usize = 0x7fff_f000;

View File

@ -2,7 +2,7 @@
use super::SyscallReturn;
use crate::{
fs::file_table::FileDesc,
fs::file_table::{get_file_fast, FileDesc},
net::socket::{MessageHeader, SendRecvFlags},
prelude::*,
util::net::CUserMsgHdr,
@ -22,10 +22,8 @@ pub fn sys_sendmsg(
sockfd, c_user_msghdr, flags
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let (mut io_vec_reader, message_header) = {

View File

@ -2,7 +2,7 @@
use super::SyscallReturn;
use crate::{
fs::file_table::FileDesc,
fs::file_table::{get_file_fast, FileDesc},
net::socket::{MessageHeader, SendRecvFlags},
prelude::*,
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:?}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let message_header = MessageHeader::new(socket_addr, None);

View File

@ -2,7 +2,7 @@
use super::SyscallReturn;
use crate::{
fs::file_table::FileDesc,
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
util::net::{new_raw_socket_option, CSocketOptionLevel},
};
@ -25,10 +25,8 @@ pub fn sys_setsockopt(
level, sockfd, optname, optlen
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
let raw_option = {

View File

@ -1,16 +1,18 @@
// SPDX-License-Identifier: MPL-2.0
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> {
let shutdown_cmd = SockShutdownCmd::try_from(how)?;
debug!("sockfd = {sockfd}, cmd = {shutdown_cmd:?}");
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(sockfd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, sockfd);
let socket = file.as_socket_or_err()?;
socket.shutdown(shutdown_cmd)?;

View File

@ -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"),
};
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) {
FdFlags::CLOEXEC
} else {
FdFlags::empty()
};
file_table.insert(file_like, fd_flags)
file_table_locked.insert(file_like, fd_flags)
};
Ok(SyscallReturn::Return(fd as _))
}

View File

@ -37,14 +37,15 @@ pub fn sys_socketpair(
};
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) {
FdFlags::CLOEXEC
} else {
FdFlags::empty()
};
let fd_a = file_table.insert(socket_a, fd_flags);
let fd_b = file_table.insert(socket_b, fd_flags);
let fd_a = file_table_locked.insert(socket_a, fd_flags);
let fd_b = file_table_locked.insert(socket_b, fd_flags);
SocketFds(fd_a, fd_b)
};

View File

@ -3,7 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
file_table::{get_file_fast, FileDesc},
fs_resolver::{FsPath, AT_FDCWD},
utils::Metadata,
},
@ -15,13 +15,12 @@ use crate::{
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);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
let stat = Stat::from(file.metadata());
ctx.user_space().write_val(stat_buf_ptr, &stat)?;
Ok(SyscallReturn::Return(0))
}

View File

@ -3,9 +3,8 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
file_table::{get_file_fast, FileDesc},
fs_resolver::FsPath,
inode_handle::InodeHandle,
utils::{SuperBlock, PATH_MAX},
},
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);
let fs = {
let file_table = ctx.posix_thread.file_table().lock();
let file = file_table.get_file(fd)?;
let inode_handle = file
.downcast_ref::<InodeHandle>()
.ok_or(Error::with_message(Errno::EBADF, "not inode"))?;
inode_handle.dentry().fs()
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
file.as_inode_or_err()?.dentry().fs()
};
let statfs = Statfs::from(fs.sb());

View File

@ -3,7 +3,7 @@
use super::SyscallReturn;
use crate::{
fs::{
file_table::FileDesc,
file_table::{get_file_fast, FileDesc},
fs_resolver::{FsPath, AT_FDCWD},
utils::PATH_MAX,
},
@ -16,11 +16,8 @@ pub fn sys_ftruncate(fd: FileDesc, len: isize, ctx: &Context) -> Result<SyscallR
check_length(len, ctx)?;
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
file.resize(len as usize)?;
Ok(SyscallReturn::Return(0))
}

View File

@ -1,7 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{fs::file_table::FileDesc, prelude::*};
use crate::{
fs::file_table::{get_file_fast, FileDesc},
prelude::*,
};
pub fn sys_write(
fd: FileDesc,
@ -14,10 +17,8 @@ pub fn sys_write(
fd, user_buf_ptr, user_buf_len
);
let file = {
let file_table = ctx.posix_thread.file_table().lock();
file_table.get_file(fd)?.clone()
};
let mut file_table = ctx.thread_local.file_table().borrow_mut();
let file = get_file_fast!(&mut file_table, fd);
// 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