feat: Implement translation of std_fs_call to each function
This commit is contained in:
+2
-30
@@ -5,7 +5,7 @@ use rmm::PhysicalAddress;
|
||||
|
||||
use crate::{
|
||||
context::{
|
||||
file::{FileDescription, InternalFlags, LockedFileDescription},
|
||||
file::InternalFlags,
|
||||
memory::{handle_notify_files, AddrSpace, AddrSpaceWrapper, Grant, PageSpan},
|
||||
},
|
||||
memory::{free_frames, used_frames, Frame, PAGE_SIZE},
|
||||
@@ -19,7 +19,7 @@ use crate::paging::entry::EntryFlags;
|
||||
use crate::syscall::{
|
||||
data::{Map, StatVfs},
|
||||
error::*,
|
||||
flag::{CallFlags, MapFlags},
|
||||
flag::MapFlags,
|
||||
usercopy::UserSliceWo,
|
||||
};
|
||||
|
||||
@@ -335,32 +335,4 @@ impl KernelScheme for MemoryScheme {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn kstdfscall(
|
||||
&self,
|
||||
id: usize,
|
||||
_desc: Arc<LockedFileDescription>,
|
||||
payload: UserSliceRw,
|
||||
_flags: CallFlags,
|
||||
metadata: &[u64],
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<usize> {
|
||||
use syscall::flag::StdFsCallKind::{self, *};
|
||||
let Some(raw_kind) = metadata.first().map(|v| *v as u8) else {
|
||||
return Err(Error::new(EOPNOTSUPP));
|
||||
};
|
||||
let Some(kind) = StdFsCallKind::try_from_raw(raw_kind) else {
|
||||
return Err(Error::new(EOPNOTSUPP));
|
||||
};
|
||||
|
||||
match kind {
|
||||
Fstatvfs => {
|
||||
if payload.len() != core::mem::size_of::<StatVfs>() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
self.kfstatvfs(id, UserSliceWo::new(payload.addr(), payload.len())?, token)
|
||||
.map(|_| 0)
|
||||
}
|
||||
_ => Err(Error::new(EOPNOTSUPP)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+43
-3
@@ -19,9 +19,9 @@ use core::{
|
||||
use hashbrown::hash_map::{DefaultHashBuilder, HashMap};
|
||||
use spin::Once;
|
||||
use syscall::{
|
||||
data::{GlobalSchemes, NewFdParams},
|
||||
data::{GlobalSchemes, NewFdParams, StdFsCallMeta},
|
||||
error::*,
|
||||
CallFlags, EventFlags, MunmapFlags,
|
||||
CallFlags, EventFlags, MunmapFlags, StdFsCallKind,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -675,10 +675,11 @@ pub trait KernelScheme: Send + Sync + 'static {
|
||||
fn kstdfscall(
|
||||
&self,
|
||||
id: usize,
|
||||
kind: StdFsCallKind,
|
||||
desc: Arc<LockedFileDescription>,
|
||||
payload: UserSliceRw,
|
||||
flags: CallFlags,
|
||||
metadata: &[u64],
|
||||
metadata: StdFsCallMeta,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<usize> {
|
||||
Err(Error::new(EOPNOTSUPP))
|
||||
@@ -704,6 +705,45 @@ pub trait KernelScheme: Send + Sync + 'static {
|
||||
) -> Result<usize> {
|
||||
Err(Error::new(EOPNOTSUPP))
|
||||
}
|
||||
|
||||
fn translate_std_fs_call(
|
||||
&self,
|
||||
id: usize,
|
||||
desc: Arc<LockedFileDescription>,
|
||||
payload: UserSliceRw,
|
||||
flags: CallFlags,
|
||||
metadata: &[u64],
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<usize> {
|
||||
let &[kind, arg1, arg2, ..] = metadata else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
let Some(kind) = StdFsCallKind::try_from_raw(kind as u8) else {
|
||||
return Err(Error::new(EOPNOTSUPP));
|
||||
};
|
||||
let metadata = StdFsCallMeta::new(kind, arg1, arg2);
|
||||
use syscall::flag::StdFsCallKind::*;
|
||||
match kind {
|
||||
Fchmod => self.fchmod(id, metadata.arg1 as u16, token).map(|_| 0),
|
||||
Getdents => self.getdents(
|
||||
id,
|
||||
payload.into_wo()?,
|
||||
metadata.arg2 as u16,
|
||||
metadata.arg1,
|
||||
token,
|
||||
),
|
||||
Fstat => self.kfstat(id, payload.into_wo()?, token).map(|_| 0),
|
||||
Fstatvfs => self.kfstatvfs(id, payload.into_wo()?, token).map(|_| 0),
|
||||
Fsync => self.fsync(id, token).map(|_| 0),
|
||||
Ftruncate => self.ftruncate(id, metadata.arg1 as usize, token).map(|_| 0),
|
||||
Futimens => self.kfutimens(id, payload.into_ro()?, token),
|
||||
/* TODO: Support Fchown and Unlinkat using std_fs_call
|
||||
Fchown => self.kstdfscall(id, kind, desc, payload, flags, metadata, token),
|
||||
Unlinkat => self.kstdfscall(fd, kind, payload, metadata, &caller).map(|_| 0)
|
||||
*/
|
||||
_ => Err(Error::new(EOPNOTSUPP)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
+22
-3
@@ -7,7 +7,7 @@ use slab::Slab;
|
||||
use syscall::{
|
||||
schemev2::{Cqe, CqeOpcode, Opcode, Sqe, SqeFlags},
|
||||
CallFlags, FmoveFdFlags, FobtainFdFlags, MunmapFlags, RecvFdFlags, SchemeSocketCall,
|
||||
SendFdFlags, MAP_FIXED_NOREPLACE,
|
||||
SendFdFlags, StdFsCallKind, MAP_FIXED_NOREPLACE,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -27,7 +27,7 @@ use crate::{
|
||||
scheme::SchemeId,
|
||||
sync::{CleanLockToken, LockToken, Mutex, RwLock, WaitQueue, L1},
|
||||
syscall::{
|
||||
data::Map,
|
||||
data::{Map, StdFsCallMeta},
|
||||
error::*,
|
||||
flag::{EventFlags, MapFlags, EVENT_READ, O_NONBLOCK, PROT_READ},
|
||||
usercopy::{UserSlice, UserSliceRo, UserSliceRw, UserSliceWo},
|
||||
@@ -1939,10 +1939,11 @@ impl KernelScheme for UserScheme {
|
||||
fn kstdfscall(
|
||||
&self,
|
||||
id: usize,
|
||||
_kind: StdFsCallKind,
|
||||
desc: Arc<LockedFileDescription>,
|
||||
payload: UserSliceRw,
|
||||
_flags: CallFlags,
|
||||
metadata: &[u64],
|
||||
metadata: StdFsCallMeta,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<usize> {
|
||||
let inner = self.inner.clone();
|
||||
@@ -2080,6 +2081,24 @@ impl KernelScheme for UserScheme {
|
||||
|
||||
Ok(num_fds)
|
||||
}
|
||||
fn translate_std_fs_call(
|
||||
&self,
|
||||
id: usize,
|
||||
desc: Arc<LockedFileDescription>,
|
||||
payload: UserSliceRw,
|
||||
flags: CallFlags,
|
||||
metadata: &[u64],
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<usize> {
|
||||
let &[kind, arg1, arg2, ..] = metadata else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
let Some(kind) = StdFsCallKind::try_from_raw(kind as u8) else {
|
||||
return Err(Error::new(EOPNOTSUPP));
|
||||
};
|
||||
let metadata = StdFsCallMeta::new(kind, arg1, arg2);
|
||||
self.kstdfscall(id, kind, desc, payload, flags, metadata, token)
|
||||
}
|
||||
}
|
||||
|
||||
trait Args: Copy {
|
||||
|
||||
+1
-1
@@ -303,7 +303,7 @@ fn call_normal(
|
||||
let scheme = scheme::get_scheme(token.token(), scheme_id)?;
|
||||
|
||||
if flags.contains(CallFlags::STD_FS) {
|
||||
scheme.kstdfscall(number, file.description, payload, flags, metadata, token)
|
||||
scheme.translate_std_fs_call(number, file.description, payload, flags, metadata, token)
|
||||
} else {
|
||||
scheme.kcall(number, payload, flags, metadata, token)
|
||||
}
|
||||
|
||||
@@ -212,6 +212,12 @@ impl UserSliceRw {
|
||||
pub fn rw(base: usize, size: usize) -> Result<Self> {
|
||||
Self::new(base, size)
|
||||
}
|
||||
pub fn into_ro(self) -> Result<UserSliceRo> {
|
||||
UserSliceRo::ro(self.base, self.len)
|
||||
}
|
||||
pub fn into_wo(self) -> Result<UserSliceWo> {
|
||||
UserSliceWo::wo(self.base, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_kernel_mem(slice: &[u8]) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user