From 2b146f87789baebcbf5c880082ba9c3e3ea0507a Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Wed, 12 Jun 2024 17:45:24 +0200 Subject: [PATCH] Properly pass POSITIONED new fd flag. --- storage/ahcid/src/scheme.rs | 113 ++++++++++++-------------- storage/nvmed/src/scheme.rs | 128 ++++++++++++++---------------- storage/usbscsid/src/scheme.rs | 9 ++- storage/virtio-blkd/src/scheme.rs | 16 ++-- 4 files changed, 127 insertions(+), 139 deletions(-) diff --git a/storage/ahcid/src/scheme.rs b/storage/ahcid/src/scheme.rs index 224fdb3d97..8a6cc89480 100644 --- a/storage/ahcid/src/scheme.rs +++ b/storage/ahcid/src/scheme.rs @@ -3,11 +3,12 @@ use std::str; use std::fmt::Write; use driver_block::{Disk, DiskWrapper}; +use syscall::schemev2::NewFdFlags; use syscall::{ Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Io, Stat, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, }; -use redox_scheme::SchemeBlockMut; +use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use crate::ahci::hba::HbaMem; @@ -81,74 +82,64 @@ impl DiskScheme { } impl SchemeBlockMut for DiskScheme { - fn open(&mut self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result> { - if uid == 0 { - let path_str = path.trim_matches('/'); - if path_str.is_empty() { - if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT { - let mut list = String::new(); + fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result> { + if ctx.uid != 0 { + return Err(Error::new(EACCES)); + } + let path_str = path.trim_matches('/'); - for (disk_index, disk) in self.disks.iter().enumerate() { - write!(list, "{}\n", disk_index).unwrap(); + let handle = if path_str.is_empty() { + if flags & O_DIRECTORY != O_DIRECTORY && flags & O_STAT != O_STAT { + return Err(Error::new(EISDIR)); + } + let mut list = String::new(); - if disk.pt.is_none() { - continue - } - for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() { - write!(list, "{}p{}\n", disk_index, part_index).unwrap(); - } - } + for (disk_index, disk) in self.disks.iter().enumerate() { + write!(list, "{}\n", disk_index).unwrap(); - let id = self.next_id; - self.next_id += 1; - self.handles.insert(id, Handle::List(list.into_bytes())); - Ok(Some(id)) - } else { - Err(Error::new(EISDIR)) + if disk.pt.is_none() { + continue } - } else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') { - let disk_id_str = &path_str[..p_pos]; - if p_pos + 1 >= path_str.len() { - return Err(Error::new(ENOENT)); - } - let part_id_str = &path_str[p_pos + 1..]; - let i = disk_id_str.parse::().or(Err(Error::new(ENOENT)))?; - let p = part_id_str.parse::().or(Err(Error::new(ENOENT)))?; - - if let Some(disk) = self.disks.get(i) { - if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() { - return Err(Error::new(ENOENT)); - } - - self.check_locks(i, Some(p))?; - - let id = self.next_id; - self.next_id += 1; - self.handles.insert(id, Handle::Partition(i, p)); - Ok(Some(id)) - } else { - Err(Error::new(ENOENT)) - } - } else { - let i = path_str.parse::().or(Err(Error::new(ENOENT)))?; - - if self.disks.get(i).is_some() { - self.check_locks(i, None)?; - - let id = self.next_id; - self.next_id += 1; - self.handles.insert(id, Handle::Disk(i)); - Ok(Some(id)) - } else { - Err(Error::new(ENOENT)) + for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() { + write!(list, "{}p{}\n", disk_index, part_index).unwrap(); } } + + Handle::List(list.into_bytes()) + } else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') { + let disk_id_str = &path_str[..p_pos]; + if p_pos + 1 >= path_str.len() { + return Err(Error::new(ENOENT)); + } + let part_id_str = &path_str[p_pos + 1..]; + let i = disk_id_str.parse::().or(Err(Error::new(ENOENT)))?; + let p = part_id_str.parse::().or(Err(Error::new(ENOENT)))?; + + let disk = self.disks.get(i).ok_or(Error::new(ENOENT))?; + if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() { + return Err(Error::new(ENOENT)); + } + + self.check_locks(i, Some(p))?; + + Handle::Partition(i, p) } else { - Err(Error::new(EACCES)) - } + let i = path_str.parse::().or(Err(Error::new(ENOENT)))?; + + if self.disks.get(i).is_none() { + return Err(Error::new(ENOENT)); + } + self.check_locks(i, None)?; + + Handle::Disk(i) + }; + let id = self.next_id; + self.next_id += 1; + self.handles.insert(id, handle); + Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) } - fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { + fn xdup(&mut self, id: usize, buf: &[u8], _: &CallerCtx) -> Result> { if ! buf.is_empty() { return Err(Error::new(EINVAL)); } @@ -161,7 +152,7 @@ impl SchemeBlockMut for DiskScheme { let new_id = self.next_id; self.next_id += 1; self.handles.insert(new_id, new_handle); - Ok(Some(new_id)) + Ok(Some(OpenResult::ThisScheme { number: new_id, flags: NewFdFlags::POSITIONED })) } fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { diff --git a/storage/nvmed/src/scheme.rs b/storage/nvmed/src/scheme.rs index 6b852f887d..a301a7fa98 100644 --- a/storage/nvmed/src/scheme.rs +++ b/storage/nvmed/src/scheme.rs @@ -6,11 +6,12 @@ use std::io::prelude::*; use std::sync::Arc; use std::{cmp, str}; +use syscall::schemev2::NewFdFlags; use syscall::{ Error, Io, Result, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET, }; -use redox_scheme::SchemeBlockMut; +use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use crate::nvme::{Nvme, NvmeNamespace}; @@ -184,82 +185,75 @@ impl DiskScheme { } impl SchemeBlockMut for DiskScheme { - fn open(&mut self, path_str: &str, flags: usize, uid: u32, _gid: u32) -> Result> { - if uid == 0 { - let path_str = path_str - .trim_matches('/'); - if path_str.is_empty() { - if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT { - let mut list = String::new(); + fn xopen(&mut self, path_str: &str, flags: usize, ctx: &CallerCtx) -> Result> { + if ctx.uid != 0 { + return Err(Error::new(EACCES)); + } + let path_str = path_str + .trim_matches('/'); - for (nsid, disk) in self.disks.iter() { - write!(list, "{}\n", nsid).unwrap(); + let handle = if path_str.is_empty() { + if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT { + let mut list = String::new(); - if disk.pt.is_none() { - continue; - } - for part_num in 0..disk.pt.as_ref().unwrap().partitions.len() { - write!(list, "{}p{}\n", nsid, part_num).unwrap(); - } + for (nsid, disk) in self.disks.iter() { + write!(list, "{}\n", nsid).unwrap(); + + if disk.pt.is_none() { + continue; + } + for part_num in 0..disk.pt.as_ref().unwrap().partitions.len() { + write!(list, "{}p{}\n", nsid, part_num).unwrap(); } - - let id = self.next_id; - self.next_id += 1; - self.handles.insert(id, Handle::List(list.into_bytes())); - Ok(Some(id)) - } else { - Err(Error::new(EISDIR)) } - } else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') { - let nsid_str = &path_str[..p_pos]; - if p_pos + 1 >= path_str.len() { + Handle::List(list.into_bytes()) + } else { + return Err(Error::new(EISDIR)); + } + } else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') { + let nsid_str = &path_str[..p_pos]; + + if p_pos + 1 >= path_str.len() { + return Err(Error::new(ENOENT)); + } + let part_num_str = &path_str[p_pos + 1..]; + + let nsid = nsid_str.parse::().or(Err(Error::new(ENOENT)))?; + let part_num = part_num_str.parse::().or(Err(Error::new(ENOENT)))?; + + if let Some(disk) = self.disks.get(&nsid) { + if disk + .pt + .as_ref() + .ok_or(Error::new(ENOENT))? + .partitions + .get(part_num as usize) + .is_some() + { + self.check_locks(nsid, Some(part_num))?; + + Handle::Partition(nsid, part_num) + } else { return Err(Error::new(ENOENT)); } - let part_num_str = &path_str[p_pos + 1..]; - - let nsid = nsid_str.parse::().or(Err(Error::new(ENOENT)))?; - let part_num = part_num_str.parse::().or(Err(Error::new(ENOENT)))?; - - if let Some(disk) = self.disks.get(&nsid) { - if disk - .pt - .as_ref() - .ok_or(Error::new(ENOENT))? - .partitions - .get(part_num as usize) - .is_some() - { - self.check_locks(nsid, Some(part_num))?; - - let id = self.next_id; - self.next_id += 1; - self.handles - .insert(id, Handle::Partition(nsid, part_num)); - Ok(Some(id)) - } else { - Err(Error::new(ENOENT)) - } - } else { - Err(Error::new(ENOENT)) - } } else { - let nsid = path_str.parse::().or(Err(Error::new(ENOENT)))?; - - if self.disks.contains_key(&nsid) { - self.check_locks(nsid, None)?; - - let id = self.next_id; - self.next_id += 1; - self.handles.insert(id, Handle::Disk(nsid)); - Ok(Some(id)) - } else { - Err(Error::new(ENOENT)) - } + return Err(Error::new(ENOENT)); } } else { - Err(Error::new(EACCES)) - } + let nsid = path_str.parse::().or(Err(Error::new(ENOENT)))?; + + if self.disks.contains_key(&nsid) { + self.check_locks(nsid, None)?; + Handle::Disk(nsid) + } else { + return Err(Error::new(ENOENT)); + } + }; + let id = self.next_id; + self.next_id += 1; + self.handles.insert(id, handle); + Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) } fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { diff --git a/storage/usbscsid/src/scheme.rs b/storage/usbscsid/src/scheme.rs index 41fc0a5d82..a175780958 100644 --- a/storage/usbscsid/src/scheme.rs +++ b/storage/usbscsid/src/scheme.rs @@ -4,12 +4,13 @@ use std::{cmp, str}; use crate::protocol::Protocol; use crate::scsi::Scsi; -use redox_scheme::SchemeMut; +use redox_scheme::{CallerCtx, OpenResult, SchemeMut}; use syscall::error::{Error, Result}; use syscall::error::{EACCES, EBADF, EINVAL, EIO, ENOENT, ENOSYS}; use syscall::flag::{MODE_CHR, MODE_DIR}; use syscall::flag::{O_DIRECTORY, O_STAT}; use syscall::flag::{SEEK_CUR, SEEK_END, SEEK_SET}; +use syscall::schemev2::NewFdFlags; // TODO: Only one disk, right? const LIST_CONTENTS: &'static [u8] = b"0\n"; @@ -39,8 +40,8 @@ impl<'a> ScsiScheme<'a> { } impl SchemeMut for ScsiScheme<'_> { - fn open(&mut self, path_str: &str, flags: usize, uid: u32, _gid: u32) -> Result { - if uid != 0 { + fn xopen(&mut self, path_str: &str, flags: usize, ctx: &CallerCtx) -> Result { + if ctx.uid != 0 { return Err(Error::new(EACCES)); } if flags & O_DIRECTORY != 0 && flags & O_STAT == 0 { @@ -59,7 +60,7 @@ impl SchemeMut for ScsiScheme<'_> { }; self.next_fd += 1; self.handles.insert(self.next_fd, handle); - Ok(self.next_fd) + Ok(OpenResult::ThisScheme { number: self.next_fd, flags: NewFdFlags::POSITIONED }) } fn fstat(&mut self, fd: usize, stat: &mut syscall::Stat) -> Result { match self.handles.get(&fd).ok_or(Error::new(EBADF))? { diff --git a/storage/virtio-blkd/src/scheme.rs b/storage/virtio-blkd/src/scheme.rs index c0cd7a0575..fe24c5b813 100644 --- a/storage/virtio-blkd/src/scheme.rs +++ b/storage/virtio-blkd/src/scheme.rs @@ -11,9 +11,12 @@ use common::dma::Dma; use partitionlib::LogicalBlockSize; use partitionlib::PartitionTable; +use redox_scheme::CallerCtx; +use redox_scheme::OpenResult; use redox_scheme::SchemeBlockMut; use syscall::flag::*; use syscall::error::*; +use syscall::schemev2::NewFdFlags; use virtio_core::spec::{Buffer, ChainBuilder, DescriptorFlags}; use virtio_core::transport::Queue; @@ -190,13 +193,12 @@ impl<'a> DiskScheme<'a> { } impl<'a> SchemeBlockMut for DiskScheme<'a> { - fn open( + fn xopen( &mut self, path: &str, flags: usize, - _uid: u32, - _gid: u32, - ) -> syscall::Result> { + _ctx: &CallerCtx, + ) -> syscall::Result> { log::info!("virtiod: open: {}", path); let path_str = path.trim_matches('/'); @@ -222,7 +224,7 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { }, ); - Ok(Some(id)) + Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) } else { return Err(syscall::Error::new(EISDIR)); } @@ -247,7 +249,7 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { }, ); - Ok(Some(id)) + Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) } else { let nsid = path_str.parse::().unwrap(); assert_eq!(nsid, 0); @@ -255,7 +257,7 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::Disk); - Ok(Some(id)) + Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) } }