diff --git a/Cargo.lock b/Cargo.lock index 7f3e5cc940..4fc06669d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1100,7 +1100,7 @@ dependencies = [ [[package]] name = "redox-scheme" version = "0.2.0" -source = "git+https://gitlab.redox-os.org/4lDO2/redox-scheme.git?branch=schemev2#aeff1a7ef5d456679437551a910e5b22a213d8a7" +source = "git+https://gitlab.redox-os.org/4lDO2/redox-scheme.git?branch=schemev2plus#ca239589c873374a17715b637be1f9385345721c" dependencies = [ "libredox 0.1.3", "redox_syscall 0.5.1", @@ -1137,7 +1137,7 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.5.1" -source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=schemev2#ef3273b17114fe02848eaccf102119fc7fdd6056" +source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=schemev2plus#b4f9a8952cec870ed7f457e3c15652d09aa0c9c7" dependencies = [ "bitflags 2.5.0", ] diff --git a/Cargo.toml b/Cargo.toml index 98a246a883..7637bcbedd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,4 +47,4 @@ lto = "fat" mio = { git = "https://gitlab.redox-os.org/redox-os/mio.git", branch = "redox-unix" } orbclient = { git = "https://gitlab.redox-os.org/redox-os/orbclient.git", version = "0.3.44" } redox-daemon = { git = "https://gitlab.redox-os.org/redox-os/redox-daemon.git" } -redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "schemev2", features = ["std"] } +redox_syscall = { git = "https://gitlab.redox-os.org/4lDO2/syscall.git", branch = "schemev2plus", features = ["std"] } diff --git a/storage/ahcid/Cargo.toml b/storage/ahcid/Cargo.toml index 661f28e2c4..d845d95533 100644 --- a/storage/ahcid/Cargo.toml +++ b/storage/ahcid/Cargo.toml @@ -15,5 +15,5 @@ common = { path = "../../common" } driver-block = { path = "../driver-block" } pcid = { path = "../../pcid" } libredox = "0.1.3" -redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2" } +redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2plus" } redox_event = "0.4" diff --git a/storage/ahcid/src/scheme.rs b/storage/ahcid/src/scheme.rs index 9f6635fa27..224fdb3d97 100644 --- a/storage/ahcid/src/scheme.rs +++ b/storage/ahcid/src/scheme.rs @@ -1,12 +1,11 @@ use std::collections::BTreeMap; -use std::{cmp, str}; +use std::str; use std::fmt::Write; -use std::io::prelude::*; use driver_block::{Disk, DiskWrapper}; use syscall::{ Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Io, Stat, MODE_DIR, - MODE_FILE, O_DIRECTORY, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET, + MODE_FILE, O_DIRECTORY, O_STAT, }; use redox_scheme::SchemeBlockMut; @@ -14,9 +13,9 @@ use crate::ahci::hba::HbaMem; #[derive(Clone)] enum Handle { - List(Vec, usize), // Dir contents buffer, position - Disk(usize, usize), // Disk index, position - Partition(usize, u32, usize), // Disk index, partition index, position + List(Vec), // Dir contents buffer + Disk(usize), // Disk index + Partition(usize, u32), // Disk index, partition index } pub struct DiskScheme { @@ -61,10 +60,10 @@ impl DiskScheme { fn check_locks(&self, disk_i: usize, part_i_opt: Option) -> Result<()> { for (_, handle) in self.handles.iter() { match handle { - Handle::Disk(i, _) => if disk_i == *i { + Handle::Disk(i) => if disk_i == *i { return Err(Error::new(ENOLCK)); }, - Handle::Partition(i, p, _) => if disk_i == *i { + Handle::Partition(i, p) => if disk_i == *i { match part_i_opt { Some(part_i) => if part_i == *p { return Err(Error::new(ENOLCK)); @@ -102,7 +101,7 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; - self.handles.insert(id, Handle::List(list.into_bytes(), 0)); + self.handles.insert(id, Handle::List(list.into_bytes())); Ok(Some(id)) } else { Err(Error::new(EISDIR)) @@ -125,7 +124,7 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; - self.handles.insert(id, Handle::Partition(i, p, 0)); + self.handles.insert(id, Handle::Partition(i, p)); Ok(Some(id)) } else { Err(Error::new(ENOENT)) @@ -138,7 +137,7 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; - self.handles.insert(id, Handle::Disk(i, 0)); + self.handles.insert(id, Handle::Disk(i)); Ok(Some(id)) } else { Err(Error::new(ENOENT)) @@ -167,19 +166,19 @@ impl SchemeBlockMut for DiskScheme { fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { match *self.handles.get(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref data, _) => { + Handle::List(ref data) => { stat.st_mode = MODE_DIR; stat.st_size = data.len() as u64; Ok(Some(0)) }, - Handle::Disk(number, _) => { + Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; stat.st_mode = MODE_FILE; stat.st_size = disk.size(); stat.st_blksize = disk.block_length()?; Ok(Some(0)) } - Handle::Partition(disk_id, part_num, _) => { + Handle::Partition(disk_id, part_num) => { let disk = self.disks.get_mut(disk_id).ok_or(Error::new(EBADF))?; let size = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; @@ -215,8 +214,8 @@ impl SchemeBlockMut for DiskScheme { } match *handle { - Handle::List(_, _) => (), - Handle::Disk(number, _) => { + Handle::List(_) => (), + Handle::Disk(number) => { let number_str = format!("{}", number); let number_bytes = number_str.as_bytes(); j = 0; @@ -226,7 +225,7 @@ impl SchemeBlockMut for DiskScheme { j += 1; } } - Handle::Partition(disk_num, part_num, _) => { + Handle::Partition(disk_num, part_num) => { let path = format!("{}p{}", disk_num, part_num); let path_bytes = path.as_bytes(); j = 0; @@ -241,71 +240,60 @@ impl SchemeBlockMut for DiskScheme { Ok(Some(i)) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref handle, ref mut size) => { - let count = (&handle[*size..]).read(buf).unwrap(); - *size += count; - Ok(Some(count)) + Handle::List(ref handle) => { + let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]); + + let byte_count = core::cmp::min(src.len(), buf.len()); + buf[..byte_count].copy_from_slice(&src[..byte_count]); + Ok(Some(byte_count)) }, - Handle::Disk(number, ref mut size) => { + Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; - if let Some(count) = disk.read((*size as u64)/(blk_len as u64), buf)? { - *size += count; - Ok(Some(count)) - } else { - Ok(None) - } + disk.read(offset / u64::from(blk_len), buf) } - Handle::Partition(disk_num, part_num, ref mut position) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; let blksize = disk.block_length()?; // validate that we're actually reading within the bounds of the partition - let rel_block = *position as u64 / blksize as u64; + let rel_block = offset / u64::from(blksize); let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; + // TODO: This shouldn't return EOVERFLOW? if rel_block >= partition.size { return Err(Error::new(EOVERFLOW)); } abs_block }; - if let Some(count) = disk.read(abs_block, buf)? { - Ok(Some(count)) - } else { - Ok(None) - } + disk.read(abs_block, buf) } } } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(_, _) => { + Handle::List(_) => { Err(Error::new(EBADF)) }, - Handle::Disk(number, ref mut size) => { + Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; - if let Some(count) = disk.write((*size as u64)/(blk_len as u64), buf)? { - *size += count; - Ok(Some(count)) - } else { - Ok(None) - } + disk.write(offset / u64::from(blk_len), buf) } - Handle::Partition(disk_num, part_num, ref mut position) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; let blksize = disk.block_length()?; // validate that we're actually reading within the bounds of the partition - let rel_block = *position as u64 / blksize as u64; + let rel_block = offset / u64::from(blksize); let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; @@ -318,56 +306,24 @@ impl SchemeBlockMut for DiskScheme { abs_block }; - if let Some(count) = disk.write(abs_block, buf)? { - Ok(Some(count)) - } else { - Ok(None) - } + disk.write(abs_block, buf) } } } - fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result> { - let pos = pos as usize; - - match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle, ref mut size) => { - let len = handle.len() as usize; - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(Some(*size as isize)) - }, - Handle::Disk(number, ref mut size) => { + fn fsize(&mut self, id: usize) -> Result> { + Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::List(ref mut handle) => handle.len() as u64, + Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; - let len = disk.size() as usize; - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(Some(*size as isize)) + disk.size() } - Handle::Partition(disk_num, part_num, ref mut position) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; let block_count = disk.pt.as_ref().ok_or(Error::new(EBADF))?.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?.size; - let len = u64::from(disk.block_length()?) * block_count; - - *position = match whence { - SEEK_SET => cmp::min(len as usize, pos) as usize, // Why isn't pos u64? - SEEK_CUR => cmp::max(0, cmp::min(len as isize, *position as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)), - }; - Ok(Some(*position as isize)) + u64::from(disk.block_length()?) * block_count } - } + })) } fn close(&mut self, id: usize) -> Result> { diff --git a/storage/nvmed/Cargo.toml b/storage/nvmed/Cargo.toml index 9b8eed9cec..46c6947593 100644 --- a/storage/nvmed/Cargo.toml +++ b/storage/nvmed/Cargo.toml @@ -12,7 +12,7 @@ log = "0.4" redox-daemon = "0.1" redox-log = "0.1" redox_syscall = { version = "0.5", features = ["std"] } -redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2" } +redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2plus" } redox_event = "0.4" partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" } smallvec = "1" diff --git a/storage/nvmed/src/scheme.rs b/storage/nvmed/src/scheme.rs index 71944e9712..6b852f887d 100644 --- a/storage/nvmed/src/scheme.rs +++ b/storage/nvmed/src/scheme.rs @@ -18,9 +18,9 @@ use partitionlib::{LogicalBlockSize, PartitionTable}; #[derive(Clone)] enum Handle { - List(Vec, usize), // entries, offset - Disk(u32, usize), // disk num, offset - Partition(u32, u32, usize), // disk num, part num, offset + List(Vec), // entries + Disk(u32), // disk num + Partition(u32, u32), // disk num, part num } pub struct DiskWrapper { @@ -163,10 +163,10 @@ impl DiskScheme { fn check_locks(&self, disk_i: u32, part_i_opt: Option) -> Result<()> { for (_, handle) in self.handles.iter() { match handle { - Handle::Disk(i, _) => if disk_i == *i { + Handle::Disk(i) => if disk_i == *i { return Err(Error::new(ENOLCK)); }, - Handle::Partition(i, p, _) => if disk_i == *i { + Handle::Partition(i, p) => if disk_i == *i { match part_i_opt { Some(part_i) => if part_i == *p { return Err(Error::new(ENOLCK)); @@ -205,7 +205,7 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; - self.handles.insert(id, Handle::List(list.into_bytes(), 0)); + self.handles.insert(id, Handle::List(list.into_bytes())); Ok(Some(id)) } else { Err(Error::new(EISDIR)) @@ -235,7 +235,7 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles - .insert(id, Handle::Partition(nsid, part_num, 0)); + .insert(id, Handle::Partition(nsid, part_num)); Ok(Some(id)) } else { Err(Error::new(ENOENT)) @@ -251,7 +251,7 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; - self.handles.insert(id, Handle::Disk(nsid, 0)); + self.handles.insert(id, Handle::Disk(nsid)); Ok(Some(id)) } else { Err(Error::new(ENOENT)) @@ -280,12 +280,12 @@ impl SchemeBlockMut for DiskScheme { fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { match *self.handles.get(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref data, _) => { + Handle::List(ref data) => { stat.st_mode = MODE_DIR; stat.st_size = data.len() as u64; Ok(Some(0)) } - Handle::Disk(number, _) => { + Handle::Disk(number) => { let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; stat.st_mode = MODE_FILE; stat.st_blocks = disk.as_ref().blocks; @@ -297,7 +297,7 @@ impl SchemeBlockMut for DiskScheme { stat.st_size = disk.as_ref().blocks * disk.as_ref().block_size; Ok(Some(0)) } - Handle::Partition(disk_num, part_num, _) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; let part = disk .pt @@ -338,8 +338,8 @@ impl SchemeBlockMut for DiskScheme { } match *handle { - Handle::List(_, _) => (), - Handle::Disk(number, _) => { + Handle::List(_) => (), + Handle::Disk(number) => { let number_str = format!("{}", number); let number_bytes = number_str.as_bytes(); j = 0; @@ -349,7 +349,7 @@ impl SchemeBlockMut for DiskScheme { j += 1; } } - Handle::Partition(disk_num, part_num, _) => { + Handle::Partition(disk_num, part_num) => { let number_str = format!("{}p{}", disk_num, part_num); let number_bytes = number_str.as_bytes(); j = 0; @@ -364,24 +364,20 @@ impl SchemeBlockMut for DiskScheme { Ok(Some(i)) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle, ref mut size) => { - let count = (&handle[*size..]).read(buf).unwrap(); - *size += count; + Handle::List(ref handle) => { + let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]); + let count = core::cmp::min(src.len(), buf.len()); + buf[..count].copy_from_slice(&src[..count]); Ok(Some(count)) } - Handle::Disk(number, ref mut size) => { + Handle::Disk(number) => { let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; let block_size = disk.as_ref().block_size; - if let Some(count) = self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, (*size as u64) / block_size, buf)? { - *size += count; - Ok(Some(count)) - } else { - Ok(None) - } + self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, offset / block_size, buf) } - Handle::Partition(disk_num, part_num, ref mut offset) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; let part = disk .pt @@ -392,38 +388,27 @@ impl SchemeBlockMut for DiskScheme { .ok_or(Error::new(EBADF))?; let block_size = disk.as_ref().block_size; - let rel_block = (*offset as u64) / block_size; + let rel_block = offset / block_size; if rel_block >= part.size { return Err(Error::new(EOVERFLOW)); } let abs_block = part.start_lba + rel_block; - if let Some(count) = self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, abs_block, buf)? { - *offset += count; - Ok(Some(count)) - } else { - Ok(None) - } + self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, abs_block, buf) } } } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(_, _) => Err(Error::new(EBADF)), - Handle::Disk(number, ref mut size) => { + Handle::List(_) => Err(Error::new(EBADF)), + Handle::Disk(number) => { let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; let block_size = disk.as_ref().block_size; - if let Some(count) = self.nvme - .namespace_write(disk.as_ref(), disk.as_ref().id, (*size as u64) / block_size, buf)? { - *size += count; - Ok(Some(count)) - } else { - Ok(None) - } + self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, offset / block_size, buf) } - Handle::Partition(disk_num, part_num, ref mut offset) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; let part = disk .pt @@ -434,57 +419,26 @@ impl SchemeBlockMut for DiskScheme { .ok_or(Error::new(EBADF))?; let block_size = disk.as_ref().block_size; - let rel_block = (*offset as u64) / block_size; + let rel_block = offset / block_size; if rel_block >= part.size { return Err(Error::new(EOVERFLOW)); } let abs_block = part.start_lba + rel_block; - if let Some(count) = self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, abs_block, buf)? { - *offset += count; - Ok(Some(count)) - } else { - Ok(None) - } + self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, abs_block, buf) } } } - fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result> { - match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle, ref mut size) => { - let len = handle.len() as isize; - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => { - cmp::max(0, cmp::min(len, *size as isize + pos)) - } - SEEK_END => { - cmp::max(0, cmp::min(len, len + pos)) - } - _ => return Err(Error::new(EINVAL)), - } as usize; - - Ok(Some(*size as isize)) - } - Handle::Disk(number, ref mut size) => { + fn fsize(&mut self, id: usize) -> Result> { + Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::List(ref handle) => handle.len() as u64, + Handle::Disk(number) => { let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; - let len = (disk.as_ref().blocks * disk.as_ref().block_size) as isize; - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => { - cmp::max(0, cmp::min(len, *size as isize + pos)) - } - SEEK_END => { - cmp::max(0, cmp::min(len, len + pos)) - } - _ => return Err(Error::new(EINVAL)), - } as usize; - - Ok(Some(*size as isize)) + disk.as_ref().blocks * disk.as_ref().block_size } - Handle::Partition(disk_num, part_num, ref mut size) => { + Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; let part = disk .pt @@ -494,22 +448,9 @@ impl SchemeBlockMut for DiskScheme { .get(part_num as usize) .ok_or(Error::new(EBADF))?; - let len = (part.size * disk.as_ref().block_size) as isize; - - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => { - cmp::max(0, cmp::min(len, *size as isize + pos)) - } - SEEK_END => { - cmp::max(0, cmp::min(len, len + pos)) - } - _ => return Err(Error::new(EINVAL)), - } as usize; - - Ok(Some(*size as isize)) + part.size * disk.as_ref().block_size } - } + })) } fn close(&mut self, id: usize) -> Result> { diff --git a/storage/usbscsid/Cargo.toml b/storage/usbscsid/Cargo.toml index 4bcf696cad..80df55b2da 100644 --- a/storage/usbscsid/Cargo.toml +++ b/storage/usbscsid/Cargo.toml @@ -2,7 +2,7 @@ name = "usbscsid" version = "0.1.0" authors = ["4lDO2 <4lDO2@protonmail.com>"] -edition = "2018" +edition = "2021" license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -13,6 +13,6 @@ libredox = "0.1.3" plain = "0.2" redox-daemon = "0.1" redox_syscall = { version = "0.5", features = ["std"] } -redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2" } +redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2plus" } thiserror = "1" xhcid = { path = "../../xhcid" } diff --git a/storage/usbscsid/src/scheme.rs b/storage/usbscsid/src/scheme.rs index c0defdca0d..41fc0a5d82 100644 --- a/storage/usbscsid/src/scheme.rs +++ b/storage/usbscsid/src/scheme.rs @@ -15,9 +15,9 @@ use syscall::flag::{SEEK_CUR, SEEK_END, SEEK_SET}; const LIST_CONTENTS: &'static [u8] = b"0\n"; enum Handle { - List(usize), - Disk(usize), - //Partition(usize, u32, usize), + List, + Disk, + //Partition(usize, u32), } pub struct ScsiScheme<'a> { @@ -50,12 +50,12 @@ impl SchemeMut for ScsiScheme<'_> { .trim_start_matches('/'); let handle = if path_str.is_empty() { // List - Handle::List(0) + Handle::List } else if let Some(_p_pos) = path_str.chars().position(|c| c == 'p') { // TODO: Partitions. return Err(Error::new(ENOSYS)); } else { - Handle::Disk(0) + Handle::Disk }; self.next_fd += 1; self.handles.insert(self.next_fd, handle); @@ -63,13 +63,13 @@ impl SchemeMut for ScsiScheme<'_> { } fn fstat(&mut self, fd: usize, stat: &mut syscall::Stat) -> Result { match self.handles.get(&fd).ok_or(Error::new(EBADF))? { - Handle::Disk(_) => { + Handle::Disk => { stat.st_mode = MODE_CHR; stat.st_size = self.scsi.get_disk_size(); stat.st_blksize = self.scsi.block_size; stat.st_blocks = self.scsi.block_count; } - Handle::List(_) => { + Handle::List => { stat.st_mode = MODE_DIR; stat.st_size = LIST_CONTENTS.len() as u64; } @@ -78,84 +78,64 @@ impl SchemeMut for ScsiScheme<'_> { } fn fpath(&mut self, fd: usize, buf: &mut [u8]) -> Result { let path = match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? { - Handle::Disk(_) => "0", - Handle::List(_) => "", + Handle::Disk => "0", + Handle::List => "", } .as_bytes(); let min = std::cmp::min(path.len(), buf.len()); buf[..min].copy_from_slice(&path[..min]); Ok(min) } - fn seek(&mut self, fd: usize, pos: isize, whence: usize) -> Result { - match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? { - Handle::Disk(ref mut offset) => { - let len = self.scsi.get_disk_size() as isize; - *offset = match whence { - SEEK_SET => cmp::max(0, cmp::min(pos, len)), - SEEK_CUR => cmp::max(0, cmp::min(*offset as isize + pos, len)), - SEEK_END => cmp::max(0, cmp::min(len + pos, len)), - _ => return Err(Error::new(EINVAL)), - } as usize; - Ok(*offset as isize) - } - Handle::List(ref mut offset) => { - let len = LIST_CONTENTS.len() as isize; - *offset = match whence { - SEEK_SET => cmp::max(0, cmp::min(pos, len)), - SEEK_CUR => cmp::max(0, cmp::min(*offset as isize + pos, len)), - SEEK_END => cmp::max(0, cmp::min(len + pos, len)), - _ => return Err(Error::new(EINVAL)), - } as usize; - Ok(*offset as isize) - } - } + fn fsize(&mut self, fd: usize) -> Result { + Ok(match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? { + Handle::Disk => self.scsi.get_disk_size(), + Handle::List => LIST_CONTENTS.len() as u64, + }) } - fn read(&mut self, fd: usize, buf: &mut [u8]) -> Result { + fn read(&mut self, fd: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result { match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? { - Handle::Disk(ref mut offset) => { - if *offset as u64 % u64::from(self.scsi.block_size) != 0 + Handle::Disk => { + if offset % u64::from(self.scsi.block_size) != 0 || buf.len() as u64 % u64::from(self.scsi.block_size) != 0 { return Err(Error::new(EINVAL)); } - let lba = *offset as u64 / u64::from(self.scsi.block_size); - let bytes_read = self - .scsi - .read(self.protocol, lba, buf) - .map_err(|err| dbg!(err)) - .or(Err(Error::new(EIO)))?; - *offset += bytes_read as usize; - Ok(bytes_read as usize) + let lba = offset / u64::from(self.scsi.block_size); + match self.scsi.read(self.protocol, lba, buf) { + Ok(bytes_read) => Ok(bytes_read as usize), + Err(err) => { + eprintln!("usbscsid: READ IO ERROR: {err}"); + Err(Error::new(EIO)) + } + } } - Handle::List(ref mut offset) => { - let max_bytes_to_read = cmp::min(LIST_CONTENTS.len(), buf.len()); - let bytes_to_read = cmp::max(max_bytes_to_read, *offset) - *offset; + Handle::List => { + let src = usize::try_from(offset).ok().and_then(|o| LIST_CONTENTS.get(o..)).unwrap_or(&[]); + let min = core::cmp::min(src.len(), buf.len()); + buf[..min].copy_from_slice(&src[..min]); - buf[..bytes_to_read].copy_from_slice(&LIST_CONTENTS[..bytes_to_read]); - *offset += bytes_to_read; - - Ok(bytes_to_read) + Ok(min) } } } - fn write(&mut self, fd: usize, buf: &[u8]) -> Result { + fn write(&mut self, fd: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result { match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? { - Handle::Disk(ref mut offset) => { - if *offset as u64 % u64::from(self.scsi.block_size) != 0 + Handle::Disk => { + if offset % u64::from(self.scsi.block_size) != 0 || buf.len() as u64 % u64::from(self.scsi.block_size) != 0 { return Err(Error::new(EINVAL)); } - let lba = *offset as u64 / u64::from(self.scsi.block_size); - let bytes_written = self - .scsi - .write(self.protocol, lba, buf) - .map_err(|err| dbg!(err)) - .or(Err(Error::new(EIO)))?; - *offset += bytes_written as usize; - Ok(bytes_written as usize) + let lba = offset / u64::from(self.scsi.block_size); + match self.scsi.write(self.protocol, lba, buf) { + Ok(bytes_written) => Ok(bytes_written as usize), + Err(err) => { + eprintln!("usbscsid: WRITE IO ERROR: {err}"); + Err(Error::new(EIO)) + } + } } - Handle::List(_) => Err(Error::new(EBADF)), + Handle::List => Err(Error::new(EBADF)), } } } diff --git a/storage/virtio-blkd/Cargo.toml b/storage/virtio-blkd/Cargo.toml index 9e05406e61..f67de06320 100644 --- a/storage/virtio-blkd/Cargo.toml +++ b/storage/virtio-blkd/Cargo.toml @@ -15,7 +15,7 @@ spin = "*" redox-daemon = "0.1" redox-log = "0.1" redox_syscall = { version = "0.5", features = ["std"] } -redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2" } +redox-scheme = { git = "https://gitlab.redox-os.org/4lDO2/redox-scheme.git", branch = "schemev2plus" } partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" } common = { path = "../../common" } diff --git a/storage/virtio-blkd/src/scheme.rs b/storage/virtio-blkd/src/scheme.rs index 84d9e23a39..c0cd7a0575 100644 --- a/storage/virtio-blkd/src/scheme.rs +++ b/storage/virtio-blkd/src/scheme.rs @@ -84,18 +84,13 @@ pub enum Handle { Partition { /// Partition Number number: u32, - /// Offset in bytes - offset: usize, }, List { entries: Vec, - offset: usize, }, - Disk { - offset: usize, - }, + Disk, } pub struct DiskScheme<'a> { @@ -224,7 +219,6 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { id, Handle::List { entries: list.into_bytes(), - offset: 0, }, ); @@ -250,7 +244,6 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { id, Handle::Partition { number: part_num, - offset: 0, }, ); @@ -261,25 +254,24 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { let id = self.next_id; self.next_id += 1; - self.handles.insert(id, Handle::Disk { offset: 0 }); + self.handles.insert(id, Handle::Disk); Ok(Some(id)) } } - fn read(&mut self, id: usize, buf: &mut [u8]) -> syscall::Result> { - match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> syscall::Result> { + Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List { ref mut entries, - ref mut offset, } => { - let count = (&entries[*offset..]).read(buf).unwrap(); - *offset += count; - Ok(Some(count)) + let src = usize::try_from(offset).ok().and_then(|o| entries.get(o..)).unwrap_or(&[]); + let count = core::cmp::min(src.len(), buf.len()); + buf[..count].copy_from_slice(&src[..count]); + count } Handle::Partition { number, - ref mut offset, } => { let part_table = self.part_table.as_ref().unwrap(); let part = part_table @@ -288,68 +280,52 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { .ok_or(Error::new(EBADF))?; // Get the offset in sectors. - let rel_block = (*offset as u64) / BLK_SIZE; + let rel_block = offset / BLK_SIZE; // if rel_block >= part.size { // return Err(Error::new(EOVERFLOW)); // } let abs_block = part.start_lba + rel_block; - let count = futures::executor::block_on(self.queue.read(abs_block, buf)); - *offset += count; - Ok(Some(count)) + futures::executor::block_on(self.queue.read(abs_block, buf)) } - Handle::Disk { ref mut offset } => { + Handle::Disk => { let block_size = self.cfg.block_size(); - let count = futures::executor::block_on( - self.queue.read((*offset as u64) / block_size as u64, buf), - ); - *offset += count; - Ok(Some(count)) + futures::executor::block_on( + self.queue.read(offset / u64::from(block_size), buf), + ) } - } + })) } - fn write(&mut self, id: usize, buf: &[u8]) -> syscall::Result> { - match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::Disk { ref mut offset } => { + fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> syscall::Result> { + Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::Disk => { let block_size = self.cfg.block_size(); - let count = futures::executor::block_on( - self.queue.write((*offset as u64) / block_size as u64, buf), - ); - - *offset += count; - Ok(Some(count)) + futures::executor::block_on( + self.queue.write(offset / u64::from(block_size), buf), + ) } - _ => unimplemented!(), - } + _ => todo!(), + })) } - fn seek(&mut self, id: usize, pos: isize, whence: usize) -> syscall::Result> { - match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + fn fsize(&mut self, id: usize) -> syscall::Result> { + Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List { ref entries, - ref mut offset, } => { - let len = entries.len() as isize; - log::debug!("list: whence={whence:?} pos={pos:?} part_len={len:?}"); + let len = entries.len() as u64; + log::debug!("list: part_len={len:?}"); - *offset = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len, *offset as isize + pos)), - SEEK_END => cmp::max(0, cmp::min(len, len + pos)), - _ => return Err(Error::new(EINVAL)), - } as usize; - - Ok(Some(*offset as isize)) + len } Handle::Partition { number, - ref mut offset, } => { let part_table = self.part_table.as_ref().unwrap(); let part = part_table @@ -358,33 +334,15 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { .ok_or(Error::new(EBADF))?; // Partition size in bytes. - let len = (part.size * BLK_SIZE) as isize; + let len = part.size * BLK_SIZE; - log::debug!("part: whence={whence:?} pos={pos:?} part_len={len:?}"); + log::debug!("part: part_len={len:?}"); - *offset = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len, *offset as isize + pos)), - SEEK_END => cmp::max(0, cmp::min(len, len + pos)), - _ => return Err(Error::new(EINVAL)), - } as usize; - - Ok(Some(*offset as isize)) + len } - Handle::Disk { ref mut offset } => { - let len = (self.cfg.capacity() * self.cfg.block_size() as u64) as isize; - - *offset = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len, *offset as isize + pos)), - SEEK_END => cmp::max(0, cmp::min(len, len + pos)), - _ => return Err(Error::new(EINVAL)), - } as usize; - - Ok(Some(*offset as isize)) - } - } + Handle::Disk => self.cfg.capacity() * u64::from(self.cfg.block_size()), + })) } fn fpath(&mut self, _id: usize, _buf: &mut [u8]) -> syscall::Result> {