Solve borrow rules to LockedFdTbl
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
};
|
||||
|
||||
@@ -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
@@ -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
@@ -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()?;
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user