improve Device trait. fix some warnings.

master
WangRunji 6 years ago
parent 6f282baf2f
commit 09382c21b8

@ -5,7 +5,6 @@ use rcore_fs::vfs::FsError;
#[cfg(any(test, feature = "std"))] #[cfg(any(test, feature = "std"))]
pub use self::std_impl::*; pub use self::std_impl::*;
pub mod sgx_impl;
pub mod std_impl; pub mod std_impl;
/// A file stores a normal file or directory. /// A file stores a normal file or directory.

@ -1,115 +0,0 @@
#![cfg(feature = "sgx")]
use std::boxed::Box;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::sgxfs::{remove, OpenOptions, SgxFile as File};
use std::sync::SgxMutex as Mutex;
use std::time::{SystemTime, UNIX_EPOCH};
use std::untrusted::time::SystemTimeEx; // FIXME: use trusted ime
use rcore_fs::dev::TimeProvider;
use rcore_fs::vfs::Timespec;
use super::{DevResult, DeviceError};
pub struct SgxStorage {
path: PathBuf,
}
impl SgxStorage {
pub fn new(path: impl AsRef<Path>) -> Self {
// assert!(path.as_ref().is_dir());
SgxStorage {
path: path.as_ref().to_path_buf(),
}
}
}
impl super::Storage for SgxStorage {
fn open(&self, file_id: usize) -> DevResult<Box<super::File>> {
let mut path = self.path.to_path_buf();
path.push(format!("{}", file_id));
// TODO: key
let key = [0u8; 16];
let file = OpenOptions::new()
.read(true)
.update(true)
.open_ex(path, &key)?;
Ok(Box::new(LockedFile(Mutex::new(file))))
}
fn create(&self, file_id: usize) -> DevResult<Box<super::File>> {
let mut path = self.path.to_path_buf();
path.push(format!("{}", file_id));
// TODO: key
let key = [0u8; 16];
let file = OpenOptions::new()
.write(true)
.update(true)
.open_ex(path, &key)?;
Ok(Box::new(LockedFile(Mutex::new(file))))
}
fn remove(&self, file_id: usize) -> DevResult<()> {
let mut path = self.path.to_path_buf();
path.push(format!("{}", file_id));
remove(path)?;
Ok(())
}
}
impl From<std::io::Error> for DeviceError {
fn from(e: std::io::Error) -> Self {
println!("{:?}", e);
panic!("{:?}", e);
DeviceError
}
}
pub struct LockedFile(Mutex<File>);
// `sgx_tstd::sgxfs::SgxFile` not impl Send ...
unsafe impl Send for LockedFile {}
unsafe impl Sync for LockedFile {}
impl super::File for LockedFile {
fn read_at(&self, buf: &mut [u8], offset: usize) -> DevResult<usize> {
let mut file = self.0.lock().unwrap();
let offset = offset as u64;
file.seek(SeekFrom::Start(offset))?;
let len = file.read(buf)?;
Ok(len)
}
fn write_at(&self, buf: &[u8], offset: usize) -> DevResult<usize> {
let mut file = self.0.lock().unwrap();
let offset = offset as u64;
file.seek(SeekFrom::Start(offset))?;
let len = file.write(buf)?;
Ok(len)
}
fn set_len(&self, len: usize) -> DevResult<()> {
// NOTE: do nothing ??
Ok(())
}
fn flush(&self) -> DevResult<()> {
let mut file = self.0.lock().unwrap();
file.flush()?;
Ok(())
}
}
pub struct SgxTimeProvider;
impl TimeProvider for SgxTimeProvider {
fn current_time(&self) -> Timespec {
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
Timespec {
sec: duration.as_secs() as i64,
nsec: duration.subsec_nanos() as i32,
}
}
}

@ -77,13 +77,13 @@ impl super::File for Mutex<File> {
} }
fn set_len(&self, len: usize) -> DevResult<()> { fn set_len(&self, len: usize) -> DevResult<()> {
let mut file = self.lock(); let file = self.lock();
file.set_len(len as u64)?; file.set_len(len as u64)?;
Ok(()) Ok(())
} }
fn flush(&self) -> DevResult<()> { fn flush(&self) -> DevResult<()> {
let mut file = self.lock(); let file = self.lock();
file.sync_all()?; file.sync_all()?;
Ok(()) Ok(())
} }

@ -113,8 +113,6 @@ pub const MAGIC: u32 = 0x2f8dbe2a;
pub const BLKSIZE: usize = 1usize << BLKSIZE_LOG2; pub const BLKSIZE: usize = 1usize << BLKSIZE_LOG2;
/// log2( size of block ) /// log2( size of block )
pub const BLKSIZE_LOG2: u8 = 7; pub const BLKSIZE_LOG2: u8 = 7;
/// max length of information
pub const MAX_INFO_LEN: usize = 31;
/// max length of filename /// max length of filename
pub const MAX_FNAME_LEN: usize = 255; pub const MAX_FNAME_LEN: usize = 255;
/// block the superblock lives in /// block the superblock lives in
@ -125,10 +123,6 @@ pub const BLKN_ROOT: BlockId = 2;
pub const BLKN_FREEMAP: BlockId = 1; pub const BLKN_FREEMAP: BlockId = 1;
/// number of bits in a block /// number of bits in a block
pub const BLKBITS: usize = BLKSIZE * 8; pub const BLKBITS: usize = BLKSIZE * 8;
/// size of one entry
pub const ENTRY_SIZE: usize = 4;
/// number of entries in a block
pub const BLK_NENTRY: usize = BLKSIZE / ENTRY_SIZE;
/// size of a dirent used in the size field /// size of a dirent used in the size field
pub const DIRENT_SIZE: usize = 260; pub const DIRENT_SIZE: usize = 260;

@ -35,14 +35,14 @@ trait DeviceExt: Device {
fn read_block(&self, id: BlockId, offset: usize, buf: &mut [u8]) -> vfs::Result<()> { fn read_block(&self, id: BlockId, offset: usize, buf: &mut [u8]) -> vfs::Result<()> {
debug_assert!(offset + buf.len() <= BLKSIZE); debug_assert!(offset + buf.len() <= BLKSIZE);
match self.read_at(id * BLKSIZE + offset, buf) { match self.read_at(id * BLKSIZE + offset, buf) {
Some(len) if len == buf.len() => Ok(()), Ok(len) if len == buf.len() => Ok(()),
_ => panic!("cannot read block {} offset {} from device", id, offset), _ => panic!("cannot read block {} offset {} from device", id, offset),
} }
} }
fn write_block(&self, id: BlockId, offset: usize, buf: &[u8]) -> vfs::Result<()> { fn write_block(&self, id: BlockId, offset: usize, buf: &[u8]) -> vfs::Result<()> {
debug_assert!(offset + buf.len() <= BLKSIZE); debug_assert!(offset + buf.len() <= BLKSIZE);
match self.write_at(id * BLKSIZE + offset, buf) { match self.write_at(id * BLKSIZE + offset, buf) {
Some(len) if len == buf.len() => Ok(()), Ok(len) if len == buf.len() => Ok(()),
_ => panic!("cannot write block {} offset {} to device", id, offset), _ => panic!("cannot write block {} offset {} to device", id, offset),
} }
} }
@ -213,7 +213,7 @@ impl INodeImpl {
if blocks > MAX_NBLOCK_DOUBLE_INDIRECT as u32 { if blocks > MAX_NBLOCK_DOUBLE_INDIRECT as u32 {
return Err(FsError::InvalidParam); return Err(FsError::InvalidParam);
} }
use core::cmp::{Ord, Ordering}; use core::cmp::Ordering;
let old_blocks = self.disk_inode.read().blocks; let old_blocks = self.disk_inode.read().blocks;
match blocks.cmp(&old_blocks) { match blocks.cmp(&old_blocks) {
Ordering::Equal => {} // Do nothing Ordering::Equal => {} // Do nothing

@ -9,30 +9,40 @@ pub trait TimeProvider: Send + Sync {
} }
/// Interface for FS to read & write /// Interface for FS to read & write
/// TODO: use std::io::{Read, Write}
pub trait Device: Send + Sync { pub trait Device: Send + Sync {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option<usize>; fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize>;
fn write_at(&self, offset: usize, buf: &[u8]) -> Option<usize>; fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize>;
fn sync(&self) -> Result<()>;
} }
/// Device which can only R/W in blocks /// Device which can only R/W in blocks
pub trait BlockDevice: Send + Sync { pub trait BlockDevice: Send + Sync {
const BLOCK_SIZE_LOG2: u8; const BLOCK_SIZE_LOG2: u8;
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool; fn read_at(&self, block_id: BlockId, buf: &mut [u8]) -> Result<()>;
fn write_at(&self, block_id: usize, buf: &[u8]) -> bool; fn write_at(&self, block_id: BlockId, buf: &[u8]) -> Result<()>;
fn sync(&self) -> Result<()>;
} }
/// The error type for device.
#[derive(Debug, PartialEq, Eq)]
pub struct DevError;
/// A specialized `Result` type for device.
pub type Result<T> = core::result::Result<T, DevError>;
pub type BlockId = usize;
macro_rules! try0 { macro_rules! try0 {
($len:expr, $res:expr) => { ($len:expr, $res:expr) => {
if !$res { if $res.is_err() {
return Some($len); return Ok($len);
} }
}; };
} }
/// Helper functions to R/W BlockDevice in bytes /// Helper functions to R/W BlockDevice in bytes
impl<T: BlockDevice> Device for T { impl<T: BlockDevice> Device for T {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option<usize> { fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
let iter = BlockIter { let iter = BlockIter {
begin: offset, begin: offset,
end: offset + buf.len(), end: offset + buf.len(),
@ -48,18 +58,18 @@ impl<T: BlockDevice> Device for T {
try0!(len, BlockDevice::read_at(self, range.block, buf)); try0!(len, BlockDevice::read_at(self, range.block, buf));
} else { } else {
use core::mem::uninitialized; use core::mem::uninitialized;
let mut block_buf: [u8; 4096] = unsafe { uninitialized() }; let mut block_buf: [u8; 1 << 10] = unsafe { uninitialized() };
assert!(Self::BLOCK_SIZE_LOG2 <= 12); assert!(Self::BLOCK_SIZE_LOG2 <= 10);
// Read to local buf first // Read to local buf first
try0!(len, BlockDevice::read_at(self, range.block, &mut block_buf)); try0!(len, BlockDevice::read_at(self, range.block, &mut block_buf));
// Copy to target buf then // Copy to target buf then
buf.copy_from_slice(&mut block_buf[range.begin..range.end]); buf.copy_from_slice(&mut block_buf[range.begin..range.end]);
} }
} }
Some(buf.len()) Ok(buf.len())
} }
fn write_at(&self, offset: usize, buf: &[u8]) -> Option<usize> { fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
let iter = BlockIter { let iter = BlockIter {
begin: offset, begin: offset,
end: offset + buf.len(), end: offset + buf.len(),
@ -75,8 +85,8 @@ impl<T: BlockDevice> Device for T {
try0!(len, BlockDevice::write_at(self, range.block, buf)); try0!(len, BlockDevice::write_at(self, range.block, buf));
} else { } else {
use core::mem::uninitialized; use core::mem::uninitialized;
let mut block_buf: [u8; 4096] = unsafe { uninitialized() }; let mut block_buf: [u8; 1 << 10] = unsafe { uninitialized() };
assert!(Self::BLOCK_SIZE_LOG2 <= 12); assert!(Self::BLOCK_SIZE_LOG2 <= 10);
// Read to local buf first // Read to local buf first
try0!(len, BlockDevice::read_at(self, range.block, &mut block_buf)); try0!(len, BlockDevice::read_at(self, range.block, &mut block_buf));
// Write to local buf // Write to local buf
@ -85,7 +95,11 @@ impl<T: BlockDevice> Device for T {
try0!(len, BlockDevice::write_at(self, range.block, &block_buf)); try0!(len, BlockDevice::write_at(self, range.block, &block_buf));
} }
} }
Some(buf.len()) Ok(buf.len())
}
fn sync(&self) -> Result<()> {
BlockDevice::sync(self)
} }
} }
@ -96,21 +110,24 @@ mod test {
impl BlockDevice for Mutex<[u8; 16]> { impl BlockDevice for Mutex<[u8; 16]> {
const BLOCK_SIZE_LOG2: u8 = 2; const BLOCK_SIZE_LOG2: u8 = 2;
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { fn read_at(&self, block_id: BlockId, buf: &mut [u8]) -> Result<()> {
if block_id >= 4 { if block_id >= 4 {
return false; return Err(DevError);
} }
let begin = block_id << 2; let begin = block_id << 2;
buf[..4].copy_from_slice(&mut self.lock().unwrap()[begin..begin + 4]); buf[..4].copy_from_slice(&mut self.lock().unwrap()[begin..begin + 4]);
true Ok(())
} }
fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { fn write_at(&self, block_id: BlockId, buf: &[u8]) -> Result<()> {
if block_id >= 4 { if block_id >= 4 {
return false; return Err(DevError);
} }
let begin = block_id << 2; let begin = block_id << 2;
self.lock().unwrap()[begin..begin + 4].copy_from_slice(&buf[..4]); self.lock().unwrap()[begin..begin + 4].copy_from_slice(&buf[..4]);
true Ok(())
}
fn sync(&self) -> Result<()> {
Ok(())
} }
} }
@ -122,17 +139,17 @@ mod test {
// all inside // all inside
let ret = Device::read_at(&buf, 3, &mut res); let ret = Device::read_at(&buf, 3, &mut res);
assert_eq!(ret, Some(6)); assert_eq!(ret, Ok(6));
assert_eq!(res, [3, 4, 5, 6, 7, 8]); assert_eq!(res, [3, 4, 5, 6, 7, 8]);
// partly inside // partly inside
let ret = Device::read_at(&buf, 11, &mut res); let ret = Device::read_at(&buf, 11, &mut res);
assert_eq!(ret, Some(5)); assert_eq!(ret, Ok(5));
assert_eq!(res, [11, 12, 13, 14, 15, 8]); assert_eq!(res, [11, 12, 13, 14, 15, 8]);
// all outside // all outside
let ret = Device::read_at(&buf, 16, &mut res); let ret = Device::read_at(&buf, 16, &mut res);
assert_eq!(ret, Some(0)); assert_eq!(ret, Ok(0));
assert_eq!(res, [11, 12, 13, 14, 15, 8]); assert_eq!(res, [11, 12, 13, 14, 15, 8]);
} }
@ -143,7 +160,7 @@ mod test {
// all inside // all inside
let ret = Device::write_at(&buf, 3, &res); let ret = Device::write_at(&buf, 3, &res);
assert_eq!(ret, Some(6)); assert_eq!(ret, Ok(6));
assert_eq!( assert_eq!(
*buf.lock().unwrap(), *buf.lock().unwrap(),
[0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0]
@ -151,7 +168,7 @@ mod test {
// partly inside // partly inside
let ret = Device::write_at(&buf, 11, &res); let ret = Device::write_at(&buf, 11, &res);
assert_eq!(ret, Some(5)); assert_eq!(ret, Ok(5));
assert_eq!( assert_eq!(
*buf.lock().unwrap(), *buf.lock().unwrap(),
[0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7] [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7]
@ -159,7 +176,7 @@ mod test {
// all outside // all outside
let ret = Device::write_at(&buf, 16, &res); let ret = Device::write_at(&buf, 16, &res);
assert_eq!(ret, Some(0)); assert_eq!(ret, Ok(0));
assert_eq!( assert_eq!(
*buf.lock().unwrap(), *buf.lock().unwrap(),
[0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7] [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7]

@ -1,29 +1,33 @@
#![cfg(any(test, feature = "std"))] #![cfg(any(test, feature = "std"))]
use std::fs::File; use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write, Error};
use std::sync::Mutex; use std::sync::Mutex;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use super::*; use super::*;
impl Device for Mutex<File> { impl Device for Mutex<File> {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option<usize> { fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
let offset = offset as u64; let offset = offset as u64;
let mut file = self.lock().unwrap(); let mut file = self.lock().unwrap();
match file.seek(SeekFrom::Start(offset)) { file.seek(SeekFrom::Start(offset))?;
Ok(real_offset) if real_offset == offset => file.read(buf).ok(), let len = file.read(buf)?;
_ => None, Ok(len)
}
} }
fn write_at(&self, offset: usize, buf: &[u8]) -> Option<usize> { fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
let offset = offset as u64; let offset = offset as u64;
let mut file = self.lock().unwrap(); let mut file = self.lock().unwrap();
match file.seek(SeekFrom::Start(offset)) { file.seek(SeekFrom::Start(offset))?;
Ok(real_offset) if real_offset == offset => file.write(buf).ok(), let len = file.write(buf)?;
_ => None, Ok(len)
} }
fn sync(&self) -> Result<()> {
let file = self.lock().unwrap();
file.sync_all()?;
Ok(())
} }
} }
@ -38,3 +42,9 @@ impl TimeProvider for StdTimeProvider {
} }
} }
} }
impl From<Error> for DevError {
fn from(e: Error) -> Self {
DevError
}
}

Loading…
Cancel
Save