feat: Implement translation of std_fs_call to each function

This commit is contained in:
Ibuki.O
2026-03-14 11:37:07 +09:00
parent 8f468ec106
commit 3934ea454d
5 changed files with 74 additions and 37 deletions
+2 -30
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}
+6
View File
@@ -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 {