Solve borrow rules to LockedFdTbl

This commit is contained in:
Wildan M
2026-03-09 15:57:38 +07:00
parent 8412321568
commit 6307446ede
8 changed files with 132 additions and 99 deletions
+1 -1
View File
@@ -865,7 +865,7 @@ impl FdTbl {
&self,
scheme_id: SchemeId,
scheme_number: usize,
token: &mut LockToken<L4>,
token: &mut LockToken<L5>,
) -> Result<FileDescriptor> {
self.iter()
.flatten()
+2 -2
View File
@@ -3,13 +3,13 @@
use crate::{
event,
scheme::{self, SchemeId},
sync::{CleanLockToken, RwLock, L5},
sync::{CleanLockToken, RwLock, L6},
syscall::error::Result,
};
use alloc::sync::Arc;
use syscall::{schemev2::NewFdFlags, RwFlags, O_APPEND, O_NONBLOCK};
pub type LockedFileDescription = RwLock<L5, FileDescription>;
pub type LockedFileDescription = RwLock<L6, FileDescription>;
/// A file description
#[derive(Clone, Copy, Debug)]
+2 -2
View File
@@ -47,8 +47,8 @@ impl EventQueue {
for event in events {
let file = {
let context_ref = context::current();
let context = context_ref.read(token.token());
let mut context = context_ref.read(token.token());
let (context, mut token) = context.token_split();
let files = context.files.read(token.token());
match files.get(event.id).ok_or(Error::new(EBADF))? {
Some(file) => file.clone(),
+6 -4
View File
@@ -834,11 +834,13 @@ impl KernelScheme for ProcScheme {
}
}
fn extract_scheme_number(fd: usize, token: &mut CleanLockToken) -> Result<(KernelSchemes, usize)> {
let file_descriptor = context::current()
.read(token.token())
.get_file(FileHandle::from(fd), token)
.ok_or(Error::new(EBADF))?;
let (scheme_id, number) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let file_descriptor = context
.get_file(FileHandle::from(fd), &mut token)
.ok_or(Error::new(EBADF))?;
let desc = file_descriptor.description.read(token.token());
(desc.scheme, desc.number)
};
+2 -1
View File
@@ -25,7 +25,8 @@ fn inner(fpath_user: UserSliceRw, token: &mut CleanLockToken) -> Result<Vec<u8>>
let mut contexts = context::contexts(token.token());
let (contexts, mut token) = contexts.token_split();
for context_ref in contexts.iter().filter_map(|r| r.upgrade()) {
let context = context_ref.read(token.token());
let mut current = context_ref.read(token.token());
let (context, mut token) = current.token_split();
rows.push((
context.pid,
context.name,
+24 -18
View File
@@ -752,11 +752,14 @@ impl UserInner {
ParsedCqe::ResponseWithFd { tag, fd } => self.respond(
tag,
Response::Fd({
context::current()
.read(token.token())
.remove_file(FileHandle::from(fd), token)
.ok_or(Error::new(EINVAL))?
.description
{
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context.remove_file(FileHandle::from(fd), &mut token)
}
.ok_or(Error::new(EINVAL))?
.description
}),
token,
)?,
@@ -787,23 +790,28 @@ impl UserInner {
// FIXME: Description can leak if there is no additional file table space.
if flags.contains(FobtainFdFlags::MANUAL_FD) {
context::current().read(token.token()).insert_file(
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context.insert_file(
FileHandle::from(dst_fd_or_ptr),
FileDescriptor {
description,
cloexec: true,
},
token,
&mut token,
);
} else {
let fd = context::current()
.read(token.token())
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let fd = context
.add_file(
FileDescriptor {
description,
cloexec: true,
},
token,
&mut token,
)
.ok_or(Error::new(EMFILE))?;
UserSlice::wo(dst_fd_or_ptr, size_of::<usize>())?.write_usize(fd.get())?;
@@ -1013,14 +1021,12 @@ impl UserInner {
}
let (pid, desc) = {
let context_lock = context::current();
let mut context = context_lock.read(token.token());
let (context, mut lock_token) = context.token_split();
let desc = context.files.read(token.token()).find_by_scheme(
self.scheme_id,
file,
&mut lock_token,
)?;
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let mut files = context.files.read(token.token());
let (files, mut token) = files.token_split();
let desc = files.find_by_scheme(self.scheme_id, file, &mut token)?;
(context.pid, desc.description)
};
+90 -68
View File
@@ -37,10 +37,10 @@ pub fn file_op_generic_ext<T>(
) -> Result<T>,
) -> Result<T> {
let (file, desc) = {
let file = context::current()
.read(token.token())
.get_file(fd, token)
.ok_or(Error::new(EBADF))?;
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let file = context.get_file(fd, &mut token).ok_or(Error::new(EBADF))?;
let desc = *file.description.read(token.token());
(file, desc)
};
@@ -73,12 +73,11 @@ pub fn openat(
) -> Result<FileHandle> {
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
let pipe = context::current()
.read(token.token())
.get_file(fh, token)
.ok_or(Error::new(EBADF))?;
let (scheme_id, number) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let pipe = context.get_file(fh, &mut token).ok_or(Error::new(EBADF))?;
let desc = pipe.description.read(token.token());
(desc.scheme, desc.number)
};
@@ -114,14 +113,16 @@ pub fn openat(
}
};
context::current()
.read(token.token())
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context
.add_file(
FileDescriptor {
description: new_description,
cloexec: flags as usize & O_CLOEXEC == O_CLOEXEC,
},
token,
&mut token,
)
.ok_or(Error::new(EMFILE))
}
@@ -135,12 +136,12 @@ pub fn unlinkat(
token: &mut CleanLockToken,
) -> Result<()> {
let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?;
let pipe = context::current()
.read(token.token())
.get_file(fh, token)
.ok_or(Error::new(EBADF))?;
let (number, scheme_id) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let pipe = context.get_file(fh, &mut token).ok_or(Error::new(EBADF))?;
let desc = pipe.description.read(token.token());
(desc.number, desc.scheme)
};
@@ -162,9 +163,12 @@ pub fn unlinkat(
/// Close syscall
pub fn close(fd: FileHandle, token: &mut CleanLockToken) -> Result<()> {
let file = {
let context_lock = context::current();
let context = context_lock.read(token.token());
context.remove_file(fd, token).ok_or(Error::new(EBADF))?
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context
.remove_file(fd, &mut token)
.ok_or(Error::new(EBADF))?
};
file.close(token)
@@ -177,11 +181,12 @@ fn duplicate_file(
token: &mut CleanLockToken,
) -> Result<FileDescriptor> {
let (caller_ctx, file) = {
let context_lock = context::current();
let context = context_lock.read(token.token());
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
(
context.caller_ctx(),
context.get_file(fd, token).ok_or(Error::new(EBADF))?,
context.get_file(fd, &mut token).ok_or(Error::new(EBADF))?,
)
};
@@ -220,10 +225,11 @@ fn duplicate_file(
/// Duplicate file descriptor
pub fn dup(fd: FileHandle, buf: UserSliceRo, token: &mut CleanLockToken) -> Result<FileHandle> {
let new_file = duplicate_file(fd, buf, false, token)?;
context::current()
.read(token.token())
.add_file(new_file, token)
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context
.add_file(new_file, &mut token)
.ok_or(Error::new(EMFILE))
}
@@ -240,11 +246,11 @@ pub fn dup2(
let _ = close(new_fd, token);
let new_file = duplicate_file(fd, buf, false, token)?;
let context_ref = context::current();
let context = context_ref.read(token.token());
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context
.insert_file(new_fd, new_file, token)
.insert_file(new_fd, new_file, &mut token)
.ok_or(Error::new(EMFILE))
}
}
@@ -280,13 +286,14 @@ fn call_normal(
metadata: &[u64],
token: &mut CleanLockToken,
) -> Result<usize> {
let file = (match (
context::current().read(token.token()),
flags.contains(CallFlags::CONSUME),
) {
(ctxt, true) => ctxt.remove_file(fd, token),
(ctxt, false) => ctxt.get_file(fd, token),
})
let file = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
match (current.token_split(), flags.contains(CallFlags::CONSUME)) {
((ctxt, mut token), true) => ctxt.remove_file(fd, &mut token),
((ctxt, mut token), false) => ctxt.get_file(fd, &mut token),
}
}
.ok_or(Error::new(EBADF))?;
let (scheme_id, number) = {
@@ -337,22 +344,25 @@ fn fdwrite_inner(
let (scheme, number) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (current, mut lock_token) = current.token_split();
let file_descriptor = current.get_file(socket, token).ok_or(Error::new(EBADF))?;
let desc = &file_descriptor.description.read(lock_token.token());
let (context, mut token) = current.token_split();
let file_descriptor = context
.get_file(socket, &mut token)
.ok_or(Error::new(EBADF))?;
let desc = &file_descriptor.description.read(token.token());
(desc.scheme, desc.number)
};
let scheme = scheme::get_scheme(token.token(), scheme)?;
let current_lock = context::current();
let current = current_lock.read(token.token());
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
(
scheme,
number,
if flags.contains(CallFlags::FD_CLONE) {
current.bulk_get_files(&target_fds, token)
context.bulk_get_files(&target_fds, &mut token)
} else {
current.bulk_remove_files(&target_fds, token)
context.bulk_remove_files(&target_fds, &mut token)
}?
.into_iter()
.map(|f| f.description)
@@ -389,9 +399,9 @@ fn call_fdread(
let (scheme, number) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (current, mut lock_token) = current.token_split();
let file_descriptor = current.get_file(fd, token).ok_or(Error::new(EBADF))?;
let desc = file_descriptor.description.read(lock_token.token());
let (context, mut token) = current.token_split();
let file_descriptor = context.get_file(fd, &mut token).ok_or(Error::new(EBADF))?;
let desc = file_descriptor.description.read(token.token());
(desc.scheme, desc.number)
};
let scheme = scheme::get_scheme(token.token(), scheme)?;
@@ -422,10 +432,13 @@ pub fn sendfd(
/// File descriptor controls
pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken) -> Result<usize> {
let file = context::current()
.read(token.token())
.get_file(fd, token)
.ok_or(Error::new(EBADF))?;
let file = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context.get_file(fd, &mut token)
}
.ok_or(Error::new(EBADF))?;
let (scheme_id, number, flags) = {
let desc = file.description.write(token.token());
@@ -436,11 +449,11 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken)
// Not in match because 'files' cannot be locked
let new_file = duplicate_file(fd, UserSlice::empty(), cmd == F_DUPFD_CLOEXEC, token)?;
let context_lock = context::current();
let context = context_lock.read(token.token());
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
return context
.add_file_min(new_file, arg, token)
.add_file_min(new_file, arg, &mut token)
.ok_or(Error::new(EMFILE))
.map(FileHandle::into);
}
@@ -454,11 +467,12 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken)
// Perform kernel operation if scheme agrees
{
let context_lock = context::current();
let mut context = context_lock.read(token.token());
let (context, mut lock_token) = context.token_split();
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
let mut files = context.files.write(token.token());
let (files, mut token) = files.token_split();
match *files.get_mut(fd.get()).ok_or(Error::new(EBADF))? {
Some(ref mut file) => match cmd {
F_GETFD => {
@@ -475,7 +489,7 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken)
F_GETFL => Ok(flags as usize),
F_SETFL => {
let new_flags = (flags & O_ACCMODE as u32) | (arg as u32 & !O_ACCMODE as u32);
file.description.write(lock_token.token()).flags = new_flags;
file.description.write(token.token()).flags = new_flags;
Ok(0)
}
_ => Err(Error::new(EINVAL)),
@@ -486,11 +500,15 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize, token: &mut CleanLockToken)
}
pub fn flink(fd: FileHandle, raw_path: UserSliceRo, token: &mut CleanLockToken) -> Result<()> {
let caller_ctx = context::current().read(token.token()).caller_ctx();
let file = context::current()
.read(token.token())
.get_file(fd, token)
.ok_or(Error::new(EBADF))?;
let (caller_ctx, file) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
(
context.caller_ctx(),
context.get_file(fd, &mut token).ok_or(Error::new(EBADF))?,
)
};
/*
let mut path_buf = BorrowedHtBuf::head()?;
@@ -518,11 +536,15 @@ pub fn flink(fd: FileHandle, raw_path: UserSliceRo, token: &mut CleanLockToken)
}
pub fn frename(fd: FileHandle, raw_path: UserSliceRo, token: &mut CleanLockToken) -> Result<()> {
let caller_ctx = context::current().read(token.token()).caller_ctx();
let file = context::current()
.read(token.token())
.get_file(fd, token)
.ok_or(Error::new(EBADF))?;
let (caller_ctx, file) = {
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
(
context.caller_ctx(),
context.get_file(fd, &mut token).ok_or(Error::new(EBADF))?,
)
};
/*
let mut path_buf = BorrowedHtBuf::head()?;
+5 -3
View File
@@ -253,8 +253,10 @@ unsafe fn bootstrap_mem(bootstrap: &crate::Bootstrap) -> &'static [u8] {
}
fn insert_fd(scheme: SchemeId, number: usize, cloexec: bool, token: &mut CleanLockToken) -> usize {
context::current()
.write(token.token())
let current_lock = context::current();
let mut current = current_lock.read(token.token());
let (context, mut token) = current.token_split();
context
.add_file_min(
FileDescriptor {
description: Arc::new(RwLock::new(FileDescription {
@@ -267,7 +269,7 @@ fn insert_fd(scheme: SchemeId, number: usize, cloexec: bool, token: &mut CleanLo
cloexec,
},
syscall::flag::UPPER_FDTBL_TAG + scheme.get(),
token,
&mut token,
)
.expect("failed to insert fd to current context")
.get()