From c089667ade76acfcd9d2d18abab88b6d30fee5bb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 13 Dec 2025 15:39:19 +0100 Subject: [PATCH] Remove support for the legacy packet user schemes --- src/scheme/mod.rs | 9 -- src/scheme/root.rs | 6 +- src/scheme/user.rs | 307 ++++----------------------------------------- src/syscall/fs.rs | 24 +--- 4 files changed, 30 insertions(+), 316 deletions(-) diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs index 6bb2625b89..eabc78a729 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs @@ -512,15 +512,6 @@ pub trait KernelScheme: Send + Sync + 'static { fn fsize(&self, id: usize, token: &mut CleanLockToken) -> Result { Err(Error::new(ESPIPE)) } - fn legacy_seek( - &self, - id: usize, - pos: isize, - whence: usize, - token: &mut CleanLockToken, - ) -> Option> { - None - } fn fchmod(&self, id: usize, new_mode: u16, token: &mut CleanLockToken) -> Result<()> { Err(Error::new(EBADF)) } diff --git a/src/scheme/root.rs b/src/scheme/root.rs index 19ab9db6d5..a74d95e572 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -81,7 +81,8 @@ impl KernelScheme for RootScheme { let new_close = flags & O_EXLOCK == O_EXLOCK; if !v2 { - warn!("Context {} opened a v1 scheme", context::current().read(token.token()).name); + error!("Context {} tried to open a v1 scheme", context::current().read(token.token()).name); + return Err(Error::new(EINVAL)); } if !new_close { warn!( @@ -98,9 +99,6 @@ impl KernelScheme for RootScheme { let inner = Arc::new(UserInner::new( self.scheme_id, scheme_id, - // TODO: This is a hack, but eventually the legacy interface will be - // removed. - v2, new_close, id, path_box, diff --git a/src/scheme/user.rs b/src/scheme/user.rs index d2d404e068..e28f260d30 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -14,8 +14,7 @@ use spin::{Mutex, RwLock}; use syscall::{ schemev2::{Cqe, CqeOpcode, Opcode, Sqe, SqeFlags}, CallFlags, FmoveFdFlags, FobtainFdFlags, MunmapFlags, RecvFdFlags, SchemeSocketCall, - SendFdFlags, F_SETFL, KSMSG_CANCEL, MAP_FIXED_NOREPLACE, SKMSG_FOBTAINFD, SKMSG_FRETURNFD, - SKMSG_PROVIDE_MMAP, + SendFdFlags, MAP_FIXED_NOREPLACE, }; use crate::{ @@ -35,10 +34,9 @@ use crate::{ scheme::SchemeId, sync::{CleanLockToken, WaitQueue}, syscall::{ - data::{Map, Packet}, + data::Map, error::*, flag::{EventFlags, MapFlags, EVENT_READ, O_NONBLOCK, PROT_READ}, - number::*, usercopy::{UserSlice, UserSliceRo, UserSliceRw, UserSliceWo}, }, }; @@ -50,7 +48,6 @@ pub struct UserInner { handle_id: usize, pub name: Box, pub scheme_id: SchemeId, - v2: bool, supports_on_close: bool, context: Weak, todo: WaitQueue, @@ -114,61 +111,8 @@ enum ParsedCqe { base_addr: VirtualAddress, page_count: usize, }, - NoOp, // TODO: remove } impl ParsedCqe { - fn parse_packet(packet: &Packet, token: &mut CleanLockToken) -> Result { - Ok(if packet.id == 0 { - match packet.a { - SYS_FEVENT => Self::TriggerFevent { - number: packet.b, - flags: EventFlags::from_bits_truncate(packet.c), - }, - _ => { - warn!( - "Unknown scheme -> kernel message {} from {}", - packet.a, - context::current().read(token.token()).name - ); - - // Some schemes don't implement cancellation properly yet, so we temporarily - // ignore their responses to the cancellation message, rather than EINVAL. - if packet.a == Error::mux(Err(Error::new(ENOSYS))) { - return Ok(Self::NoOp); - } - - return Err(Error::new(EINVAL)); - } - } - } else if Error::demux(packet.a) == Err(Error::new(ESKMSG)) { - // The reason why the new ESKMSG mechanism was introduced, is that passing packet IDs - // in packet.id is much cleaner than having to convert it into 1 or 2 usizes etc. - match packet.b { - SKMSG_FRETURNFD => Self::ResponseWithFd { - tag: (packet.id - 1) as u32, - fd: packet.d, - }, - SKMSG_FOBTAINFD => Self::ObtainFd { - tag: (packet.id - 1) as u32, - flags: FobtainFdFlags::from_bits(packet.d).ok_or(Error::new(EINVAL))?, - dst_fd_or_ptr: packet.c, - }, - SKMSG_PROVIDE_MMAP => Self::ProvideMmap { - tag: (packet.id - 1) as u32, - offset: u64::from(packet.uid) | (u64::from(packet.gid) << 32), - base_addr: VirtualAddress::new(packet.c), - page_count: packet.d, - }, - _ => return Err(Error::new(EINVAL)), - } - } else { - ParsedCqe::RegularResponse { - tag: (packet.id - 1) as u32, - code: packet.a, - extra0: 0, - } - }) - } fn parse_cqe(cqe: &Cqe) -> Result { Ok( match CqeOpcode::try_from_raw(cqe.flags & 0b111).ok_or(Error::new(EINVAL))? { @@ -204,7 +148,6 @@ impl UserInner { pub fn new( root_id: SchemeId, scheme_id: SchemeId, - v2: bool, new_close: bool, handle_id: usize, name: Box, @@ -215,7 +158,6 @@ impl UserInner { root_id, handle_id, name, - v2, supports_on_close: new_close, scheme_id, context, @@ -779,171 +721,29 @@ impl UserInner { // If unmounting, do not block so that EOF can be returned immediately let block = !(nonblock || self.unmounting.load(Ordering::SeqCst)); - if self.v2 { - match self - .todo - .receive_into_user(buf, block, "UserInner::read (v2)", token) - { - // If we received requests, return them to the scheme handler - Ok(byte_count) => Ok(byte_count), - // If there were no requests and we were unmounting, return EOF - Err(Error { errno: EAGAIN }) if self.unmounting.load(Ordering::SeqCst) => Ok(0), - // If there were no requests and O_NONBLOCK was used (EAGAIN), or some other error - // occurred, return that. - Err(error) => Err(error), - } - } else { - let mut bytes_read = 0; - - for dst in buf.in_exact_chunks(size_of::()) { - match self - .todo - .receive(block && bytes_read == 0, "UserInner::read (legacy)", token) - { - Ok(sqe) => { - dst.copy_exactly(&self.translate_sqe_to_packet(&sqe)?)?; - bytes_read += size_of::(); - } - Err(_) if bytes_read > 0 => return Ok(bytes_read), - Err(Error { errno: EAGAIN }) if self.unmounting.load(Ordering::SeqCst) => { - return Ok(bytes_read) - } - Err(error) => return Err(error), - } - } - Ok(bytes_read) + match self + .todo + .receive_into_user(buf, block, "UserInner::read (v2)", token) + { + // If we received requests, return them to the scheme handler + Ok(byte_count) => Ok(byte_count), + // If there were no requests and we were unmounting, return EOF + Err(Error { errno: EAGAIN }) if self.unmounting.load(Ordering::SeqCst) => Ok(0), + // If there were no requests and O_NONBLOCK was used (EAGAIN), or some other error + // occurred, return that. + Err(error) => Err(error), } } - fn translate_sqe_to_packet(&self, sqe: &Sqe) -> Result { - let opc = Opcode::try_from_raw(sqe.opcode) - .expect("passed scheme opcode not internally recognized by kernel"); - - let uid = sqe.args[5] as u32; - let gid = (sqe.args[5] >> 32) as u32; - - Ok(Packet { - id: u64::from(sqe.tag) + 1, - pid: sqe.caller as usize, - a: match opc { - Opcode::Open => SYS_OPEN, - Opcode::Rmdir => SYS_RMDIR, - Opcode::Unlink => SYS_UNLINK, - Opcode::Close => SYS_CLOSE, - Opcode::Dup => SYS_DUP, - Opcode::Read => SYS_READ, - Opcode::Write => SYS_WRITE, - Opcode::Fsize => SYS_LSEEK, // lseek reuses the fsize "opcode", must be !v2 - Opcode::Fchmod => SYS_FCHMOD, - Opcode::Fchown => SYS_FCHOWN, - Opcode::Fcntl => SYS_FCNTL, - Opcode::Fevent => SYS_FEVENT, - Opcode::Sendfd => SYS_SENDFD, - Opcode::Flink => SYS_FLINK, - Opcode::Fpath => SYS_FPATH, - Opcode::Frename => SYS_FRENAME, - Opcode::Fstat => SYS_FSTAT, - Opcode::Fstatvfs => SYS_FSTATVFS, - Opcode::Fsync => SYS_FSYNC, - Opcode::Ftruncate => SYS_FTRUNCATE, - Opcode::Futimens => SYS_FUTIMENS, - - Opcode::MmapPrep => { - return Ok(Packet { - id: u64::from(sqe.tag) + 1, - pid: sqe.caller as usize, - a: KSMSG_MMAP_PREP, - b: sqe.args[0] as usize, - c: sqe.args[1] as usize, - d: sqe.args[2] as usize, - uid: sqe.args[3] as u32, - gid: (sqe.args[3] >> 32) as u32, - }) - } - Opcode::RequestMmap => { - return Ok(Packet { - id: u64::from(sqe.tag) + 1, - pid: sqe.caller as usize, - a: KSMSG_MMAP, - b: sqe.args[0] as usize, - c: sqe.args[1] as usize, - d: sqe.args[2] as usize, - uid: sqe.args[3] as u32, - gid: (sqe.args[3] >> 32) as u32, - }) - } - Opcode::Munmap => { - return Ok(Packet { - id: u64::from(sqe.tag) + 1, - pid: sqe.caller as usize, - a: KSMSG_MUNMAP, - b: sqe.args[0] as usize, // fd - c: sqe.args[1] as usize, // size - d: sqe.args[2] as usize, // flags - uid: sqe.args[3] as u32, // offset lo - gid: (sqe.args[3] >> 32) as u32, // offset hi - }); - } - Opcode::Getdents => { - return Ok(Packet { - id: u64::from(sqe.tag) + 1, - pid: sqe.caller as usize, - a: SYS_GETDENTS, - b: sqe.args[0] as usize, - c: sqe.args[1] as usize, - d: sqe.args[2] as usize, - uid: sqe.args[3] as u32, - gid: (sqe.args[3] >> 32) as u32, - }); - } - - Opcode::Mremap => SYS_MREMAP, - Opcode::Msync => KSMSG_MSYNC, - - Opcode::Cancel => { - return Ok(Packet { - id: 0, - a: KSMSG_CANCEL, - b: sqe.tag as usize + 1, - c: 0, - d: 0, - pid: sqe.caller as usize, - uid, - gid, - }) - } - - _ => return Err(Error::new(EOPNOTSUPP)), - }, - b: sqe.args[0] as usize, - c: sqe.args[1] as usize, - d: sqe.args[2] as usize, - - uid, - gid, - }) - } pub fn write(&self, buf: UserSliceRo, token: &mut CleanLockToken) -> Result { let mut bytes_read = 0; - if self.v2 { - for chunk in buf.in_exact_chunks(size_of::()) { - match ParsedCqe::parse_cqe(&unsafe { chunk.read_exact::()? }) - .and_then(|p| self.handle_parsed(&p, token)) - { - Ok(()) => bytes_read += size_of::(), - Err(_) if bytes_read > 0 => break, - Err(error) => return Err(error), - } - } - } else { - for chunk in buf.in_exact_chunks(size_of::()) { - match ParsedCqe::parse_packet(&unsafe { chunk.read_exact::()? }, token) - .and_then(|p| self.handle_parsed(&p, token)) - { - Ok(()) => bytes_read += size_of::(), - Err(_) if bytes_read > 0 => break, - Err(error) => return Err(error), - } + for chunk in buf.in_exact_chunks(size_of::()) { + match ParsedCqe::parse_cqe(&unsafe { chunk.read_exact::()? }) + .and_then(|p| self.handle_parsed(&p, token)) + { + Ok(()) => bytes_read += size_of::(), + Err(_) if bytes_read > 0 => break, + Err(error) => return Err(error), } } Ok(bytes_read) @@ -964,16 +764,6 @@ impl UserInner { states[tag as usize] = State::Fmap(Arc::downgrade(&context::current())); } - /*self.todo.send(Packet { - id: packet_id, - pid: context::context_id().into(), - a: KSMSG_MMAP, - b: id, - c: flags.bits(), - d: required_page_count, - uid: offset as u32, - gid: (offset >> 32) as u32, - });*/ self.todo.send( Sqe { opcode: Opcode::RequestMmap as u8, @@ -1122,7 +912,6 @@ impl UserInner { ParsedCqe::TriggerFevent { number, flags } => { event::trigger(self.scheme_id, number, flags) } - ParsedCqe::NoOp => (), } Ok(()) } @@ -1266,22 +1055,6 @@ impl UserInner { let response = self.call_extended_inner( None, - /* - Packet { - id: self.next_id(), - pid: pid.into(), - a: KSMSG_MMAP_PREP, - b: file, - c: unaligned_size, - d: map.flags.bits(), - // The uid and gid can be obtained by the proc scheme anyway, if the pid is provided. - uid: map.offset as u32, - #[cfg(target_pointer_width = "64")] - gid: (map.offset >> 32) as u32, - #[cfg(target_pointer_width = "32")] - gid: 0, - }, - */ Sqe { opcode: Opcode::MmapPrep as u8, sqe_flags: SqeFlags::empty(), @@ -1750,9 +1523,6 @@ impl KernelScheme for UserScheme { fn fsize(&self, file: usize, token: &mut CleanLockToken) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - if !inner.v2 { - return Err(Error::new(ESPIPE)); - } inner .call(Opcode::Fsize, [file], &mut PageSpan::empty(), token) .map(|o| o as u64) @@ -1949,15 +1719,11 @@ impl KernelScheme for UserScheme { buf: UserSliceWo, offset: u64, call_flags: u32, - stored_flags: u32, + _stored_flags: u32, token: &mut CleanLockToken, ) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - if call_flags != stored_flags && !inner.v2 { - self.fcntl(file, F_SETFL, call_flags as usize, token)?; - } - let mut address = inner.capture_user(buf, token)?; let result = inner.call( Opcode::Read, @@ -1973,10 +1739,6 @@ impl KernelScheme for UserScheme { ); address.release()?; - if call_flags != stored_flags && !inner.v2 { - self.fcntl(file, F_SETFL, stored_flags as usize, token)?; - } - result } @@ -1986,13 +1748,10 @@ impl KernelScheme for UserScheme { buf: UserSliceRo, offset: u64, call_flags: u32, - stored_flags: u32, + _stored_flags: u32, token: &mut CleanLockToken, ) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - if call_flags != stored_flags && !inner.v2 { - self.fcntl(file, F_SETFL, call_flags as usize, token)?; - } let mut address = inner.capture_user(buf, token)?; let result = inner.call( @@ -2009,30 +1768,8 @@ impl KernelScheme for UserScheme { ); address.release()?; - if call_flags != stored_flags && !inner.v2 { - self.fcntl(file, F_SETFL, stored_flags as usize, token)?; - } - result } - fn legacy_seek( - &self, - id: usize, - pos: isize, - whence: usize, - token: &mut CleanLockToken, - ) -> Option> { - let inner = self.inner.upgrade()?; - if inner.v2 { - return None; - } - Some(inner.call( - Opcode::Fsize, - [id, pos as usize, whence], - &mut PageSpan::empty(), - token, - )) - } fn kfutimens( &self, file: usize, diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 6fc449852f..1a4306e2ce 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -796,25 +796,13 @@ pub fn mremap( } pub fn lseek(fd: FileHandle, pos: i64, whence: usize, token: &mut CleanLockToken) -> Result { - enum Ret { - Legacy(usize), - Fsize((Option, Arc>)), - } - let fsize_or_legacy = file_op_generic_ext(fd, token, |scheme, desc_arc, desc, token| { - Ok( - if let Some(new_off) = scheme.legacy_seek(desc.number, pos as isize, whence, token) { - Ret::Legacy(new_off?) - } else if whence == SEEK_END { - Ret::Fsize((Some(scheme.fsize(desc.number, token)?), desc_arc)) - } else { - Ret::Fsize((None, desc_arc)) - }, - ) + let (fsize, desc) = file_op_generic_ext(fd, token, |scheme, desc_arc, desc, token| { + Ok(if whence == SEEK_END { + (Some(scheme.fsize(desc.number, token)?), desc_arc) + } else { + (None, desc_arc) + }) })?; - let (fsize, desc) = match fsize_or_legacy { - Ret::Fsize(fsize) => fsize, - Ret::Legacy(new_pos) => return Ok(new_pos), - }; let mut guard = desc.write();