Switch ided to v2 scheme protocol.
This commit is contained in:
Generated
+2
@@ -591,6 +591,8 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox-scheme",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "ided"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../../common" }
|
||||
@@ -11,4 +11,6 @@ log = "0.4"
|
||||
pcid = { path = "../../pcid" }
|
||||
redox-daemon = "0.1"
|
||||
redox-log = "0.1"
|
||||
redox_syscall = "0.5"
|
||||
redox_syscall = { version = "0.5", features = ["std"] }
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
redox_event = "0.4"
|
||||
|
||||
+48
-66
@@ -1,8 +1,10 @@
|
||||
use driver_block::Disk;
|
||||
use event::{EventFlags, RawEventQueue};
|
||||
use libredox::flag;
|
||||
use log::{error, info};
|
||||
use pcid_interface::{PciBar, PcidServerHandle};
|
||||
use redox_log::{OutputBuilder, RedoxLogger};
|
||||
use redox_scheme::{RequestKind, Response, SignalBehavior, Socket, V2};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{ErrorKind, Read, Write},
|
||||
@@ -12,11 +14,7 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
use syscall::{
|
||||
data::{Event, Packet},
|
||||
error::{Error, ENODEV},
|
||||
flag::{EVENT_READ},
|
||||
io::Io,
|
||||
scheme::SchemeBlockMut,
|
||||
data::{Event, Packet}, error::{Error, ENODEV}, flag::EVENT_READ, io::Io, scheme::SchemeBlockMut, EAGAIN, EINTR, EWOULDBLOCK
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -236,12 +234,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
}
|
||||
|
||||
let scheme_name = format!("disk.{}", name);
|
||||
let socket_fd = libredox::call::open(
|
||||
&format!(":{}", scheme_name),
|
||||
flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK,
|
||||
0,
|
||||
).expect("ided: failed to create disk scheme");
|
||||
let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) };
|
||||
let socket_fd = Socket::<V2>::nonblock(&scheme_name)
|
||||
.expect("ided: failed to create disk scheme");
|
||||
|
||||
let primary_irq_fd = libredox::call::open(
|
||||
&format!("irq:{}", primary_irq),
|
||||
@@ -257,63 +251,59 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
).expect("ided: failed to open irq file");
|
||||
let mut secondary_irq_file = unsafe { File::from_raw_fd(secondary_irq_fd as RawFd) };
|
||||
|
||||
let mut event_file = File::open("event:").expect("ided: failed to open event file");
|
||||
let mut event_queue = RawEventQueue::new().expect("ided: failed to open event file");
|
||||
|
||||
libredox::call::setrens(0, 0).expect("ided: failed to enter null namespace");
|
||||
|
||||
daemon.ready().expect("ided: failed to notify parent");
|
||||
|
||||
event_file.write(&Event {
|
||||
id: socket_fd,
|
||||
flags: EVENT_READ,
|
||||
data: 0
|
||||
}).expect("ided: failed to event disk scheme");
|
||||
event_queue.subscribe(
|
||||
socket_fd.inner().raw(),
|
||||
0,
|
||||
EventFlags::READ,
|
||||
).expect("ided: failed to event disk scheme");
|
||||
|
||||
event_file.write(&Event {
|
||||
id: primary_irq_fd,
|
||||
flags: EVENT_READ,
|
||||
data: 0
|
||||
}).expect("ided: failed to event irq scheme");
|
||||
event_queue.subscribe(
|
||||
primary_irq_fd,
|
||||
0,
|
||||
EventFlags::READ,
|
||||
).expect("ided: failed to event irq scheme");
|
||||
|
||||
event_file.write(&Event {
|
||||
id: secondary_irq_fd,
|
||||
flags: EVENT_READ,
|
||||
data: 0
|
||||
}).expect("ided: failed to event irq scheme");
|
||||
event_queue.subscribe(
|
||||
secondary_irq_fd,
|
||||
0,
|
||||
EventFlags::READ,
|
||||
).expect("ided: failed to event irq scheme");
|
||||
|
||||
let mut scheme = DiskScheme::new(scheme_name, chans, disks);
|
||||
|
||||
let mut mounted = true;
|
||||
let mut todo = Vec::new();
|
||||
while mounted {
|
||||
let mut event = Event::default();
|
||||
if event_file.read(&mut event).expect("ided: failed to read event file") == 0 {
|
||||
'outer: loop {
|
||||
let Some(event) = event_queue.next().transpose().expect("ided: failed to read event file") else {
|
||||
break;
|
||||
}
|
||||
if event.id == socket_fd {
|
||||
};
|
||||
if event.fd == socket_fd.inner().raw() {
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
match socket.read(&mut packet) {
|
||||
Ok(0) => {
|
||||
mounted = false;
|
||||
break;
|
||||
let req = match socket_fd.next_request(SignalBehavior::Interrupt) {
|
||||
Ok(None) => break 'outer,
|
||||
Ok(Some(r)) => if let RequestKind::Call(c) = r.kind() {
|
||||
c
|
||||
} else {
|
||||
continue;
|
||||
},
|
||||
Ok(_) => (),
|
||||
Err(err) => if err.kind() == ErrorKind::WouldBlock {
|
||||
Err(err) => if matches!(err.errno, EAGAIN | EWOULDBLOCK | EINTR) {
|
||||
break;
|
||||
} else {
|
||||
panic!("ided: failed to read disk scheme: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(a) = scheme.handle(&packet) {
|
||||
packet.a = a;
|
||||
socket.write(&mut packet).expect("ided: failed to write disk scheme");
|
||||
};
|
||||
if let Some(resp) = req.handle_scheme_block_mut(&mut scheme) {
|
||||
socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme");
|
||||
} else {
|
||||
todo.push(packet);
|
||||
todo.push(req);
|
||||
}
|
||||
}
|
||||
} else if event.id == primary_irq_fd {
|
||||
} else if event.fd == primary_irq_fd {
|
||||
let mut irq = [0; 8];
|
||||
if primary_irq_file.read(&mut irq).expect("ided: failed to read irq file") >= irq.len() {
|
||||
if scheme.irq(0) {
|
||||
@@ -322,17 +312,15 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
// Handle todos in order to finish previous packets if possible
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
if let Some(a) = scheme.handle(&todo[i]) {
|
||||
let mut packet = todo.remove(i);
|
||||
packet.a = a;
|
||||
socket.write(&mut packet).expect("ided: failed to write disk scheme");
|
||||
if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) {
|
||||
socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if event.id == secondary_irq_fd {
|
||||
} else if event.fd == secondary_irq_fd {
|
||||
let mut irq = [0; 8];
|
||||
if secondary_irq_file.read(&mut irq).expect("ided: failed to read irq file") >= irq.len() {
|
||||
if scheme.irq(1) {
|
||||
@@ -341,10 +329,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
// Handle todos in order to finish previous packets if possible
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
if let Some(a) = scheme.handle(&todo[i]) {
|
||||
let mut packet = todo.remove(i);
|
||||
packet.a = a;
|
||||
socket.write(&mut packet).expect("ided: failed to write disk scheme");
|
||||
if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) {
|
||||
socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
@@ -352,26 +338,22 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("Unknown event {}", event.id);
|
||||
error!("Unknown event {}", event.fd);
|
||||
}
|
||||
|
||||
// Handle todos to start new packets if possible
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
if let Some(a) = scheme.handle(&todo[i]) {
|
||||
let mut packet = todo.remove(i);
|
||||
packet.a = a;
|
||||
socket.write(&packet).expect("ided: failed to write disk scheme");
|
||||
if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) {
|
||||
socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ! mounted {
|
||||
for mut packet in todo.drain(..) {
|
||||
packet.a = Error::mux(Err(Error::new(ENODEV)));
|
||||
socket.write(&packet).expect("ided: failed to write disk scheme");
|
||||
}
|
||||
for req in todo.drain(..) {
|
||||
socket_fd.write_response(Response::new(&req, Err(Error::new(ENODEV))), SignalBehavior::Restart)
|
||||
.expect("ided: failed to write disk scheme");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-95
@@ -1,23 +1,23 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::{cmp, str};
|
||||
use std::convert::{TryFrom};
|
||||
use std::str;
|
||||
use std::fmt::Write;
|
||||
use std::io::prelude::*;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use driver_block::{Disk, DiskWrapper};
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
use syscall::{
|
||||
Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result,
|
||||
Io, SchemeBlockMut, Stat, MODE_DIR, MODE_FILE, O_DIRECTORY,
|
||||
O_STAT, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Stat, MODE_DIR,
|
||||
MODE_FILE, O_DIRECTORY, O_STAT,
|
||||
};
|
||||
|
||||
use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut};
|
||||
use crate::ide::Channel;
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Handle {
|
||||
List(Vec<u8>, usize), // Dir contents buffer, position
|
||||
Disk(usize, usize), // Disk index, position
|
||||
Partition(usize, u32, usize), // Disk index, partition index, position
|
||||
List(Vec<u8>), // Dir contents buffer
|
||||
Disk(usize), // Disk index
|
||||
Partition(usize, u32), // Disk index, partition index
|
||||
}
|
||||
|
||||
pub struct DiskScheme {
|
||||
@@ -31,7 +31,7 @@ pub struct DiskScheme {
|
||||
impl DiskScheme {
|
||||
pub fn new(scheme_name: String, chans: Vec<Arc<Mutex<Channel>>>, disks: Vec<Box<dyn Disk>>) -> DiskScheme {
|
||||
DiskScheme {
|
||||
scheme_name: scheme_name,
|
||||
scheme_name,
|
||||
chans: chans.into_boxed_slice(),
|
||||
disks: disks.into_iter().map(DiskWrapper::new).collect::<Vec<_>>().into_boxed_slice(),
|
||||
handles: BTreeMap::new(),
|
||||
@@ -40,7 +40,7 @@ impl DiskScheme {
|
||||
}
|
||||
|
||||
pub fn irq(&mut self, chan_i: usize) -> bool {
|
||||
let mut chan = self.chans[chan_i].lock().unwrap();
|
||||
let _chan = self.chans[chan_i].lock().unwrap();
|
||||
//TODO: check chan for irq
|
||||
true
|
||||
}
|
||||
@@ -49,10 +49,10 @@ impl DiskScheme {
|
||||
fn check_locks(&self, disk_i: usize, part_i_opt: Option<u32>) -> 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));
|
||||
@@ -70,8 +70,8 @@ impl DiskScheme {
|
||||
}
|
||||
|
||||
impl SchemeBlockMut for DiskScheme {
|
||||
fn open(&mut self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<Option<usize>> {
|
||||
if uid == 0 {
|
||||
fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<Option<OpenResult>> {
|
||||
if ctx.uid == 0 {
|
||||
let path_str = path.trim_matches('/');
|
||||
if path_str.is_empty() {
|
||||
if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT {
|
||||
@@ -90,8 +90,8 @@ impl SchemeBlockMut for DiskScheme {
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::List(list.into_bytes(), 0));
|
||||
Ok(Some(id))
|
||||
self.handles.insert(id, Handle::List(list.into_bytes()));
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
} else {
|
||||
Err(Error::new(EISDIR))
|
||||
}
|
||||
@@ -113,8 +113,8 @@ impl SchemeBlockMut for DiskScheme {
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::Partition(i, p, 0));
|
||||
Ok(Some(id))
|
||||
self.handles.insert(id, Handle::Partition(i, p));
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
@@ -126,8 +126,8 @@ impl SchemeBlockMut for DiskScheme {
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::Disk(i, 0));
|
||||
Ok(Some(id))
|
||||
self.handles.insert(id, Handle::Disk(i));
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
@@ -155,19 +155,19 @@ impl SchemeBlockMut for DiskScheme {
|
||||
|
||||
fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result<Option<usize>> {
|
||||
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))?;
|
||||
@@ -203,8 +203,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;
|
||||
@@ -214,7 +214,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;
|
||||
@@ -229,29 +229,25 @@ impl SchemeBlockMut for DiskScheme {
|
||||
Ok(Some(i))
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||
fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _flags: u32) -> Result<Option<usize>> {
|
||||
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 bytes = src.len().min(buf.len());
|
||||
buf[..bytes].copy_from_slice(&src[..bytes]);
|
||||
Ok(Some(bytes))
|
||||
},
|
||||
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))?;
|
||||
@@ -264,36 +260,27 @@ impl SchemeBlockMut for DiskScheme {
|
||||
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<Option<usize>> {
|
||||
fn write(&mut self, id: usize, buf: &[u8], offset: u64, _flags: u32) -> Result<Option<usize>> {
|
||||
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 as u64);
|
||||
|
||||
let abs_block = {
|
||||
let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?;
|
||||
@@ -306,54 +293,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<Option<isize>> {
|
||||
let pos = pos as usize;
|
||||
|
||||
fn fsize(&mut self, id: usize) -> Result<Option<u64>> {
|
||||
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::List(ref mut handle) => {
|
||||
Ok(Some(handle.len() as u64))
|
||||
},
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
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))
|
||||
Ok(Some(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))
|
||||
Ok(Some(u64::from(disk.block_length()?) * block_count))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user