diff --git a/Cargo.toml b/Cargo.toml index d22438a..f71ba8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [workspace] members = [ "rcore-fs", + "rcore-fs-sfs", + "rcore-fs-sefs", "rcore-fs-fuse" ] \ No newline at end of file diff --git a/rcore-fs-fuse/Cargo.toml b/rcore-fs-fuse/Cargo.toml index 23ba98f..870fe3f 100644 --- a/rcore-fs-fuse/Cargo.toml +++ b/rcore-fs-fuse/Cargo.toml @@ -12,3 +12,5 @@ fuse = "0.3" structopt = "0.2" env_logger = "0.3" rcore-fs = { path = "../rcore-fs", features = ["std"] } +rcore-fs-sfs = { path = "../rcore-fs-sfs", features = ["std"] } +rcore-fs-sefs = { path = "../rcore-fs-sefs", features = ["std"] } diff --git a/rcore-fs-fuse/src/main.rs b/rcore-fs-fuse/src/main.rs index 5f373a0..765680f 100644 --- a/rcore-fs-fuse/src/main.rs +++ b/rcore-fs-fuse/src/main.rs @@ -9,7 +9,9 @@ use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, use structopt::StructOpt; use time::Timespec; -use rcore_fs::{sfs, sefs, vfs}; +use rcore_fs::vfs; +use rcore_fs_sfs as sfs; +use rcore_fs_sefs as sefs; const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second @@ -230,12 +232,12 @@ fn main() { // let img = OpenOptions::new().read(true).write(true).open(&opt.image) // .expect("failed to open image"); let sfs = if opt.image.is_dir() { - let img = sefs::std_impl::StdStorage::new(&opt.image); + let img = sefs::dev::StdStorage::new(&opt.image); sefs::SEFS::open(Box::new(img)) .expect("failed to open sefs") } else { std::fs::create_dir_all(&opt.image).unwrap(); - let img = sefs::std_impl::StdStorage::new(&opt.image); + let img = sefs::dev::StdStorage::new(&opt.image); sefs::SEFS::create(Box::new(img)) .expect("failed to create sefs") }; diff --git a/rcore-fs-sefs/Cargo.toml b/rcore-fs-sefs/Cargo.toml new file mode 100644 index 0000000..e5d74c8 --- /dev/null +++ b/rcore-fs-sefs/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "rcore-fs-sefs" +version = "0.1.0" +authors = ["WangRunji "] +edition = "2018" + +[dependencies] +rcore-fs = { path = "../rcore-fs" } +static_assertions = "0.3" +spin = "0.4" +log = "0.4" + +[dependencies.bitvec] +version = "0.9" +default-features = false +features = ["alloc"] + +[features] +std = ["rcore-fs/std"] diff --git a/rcore-fs-sefs/src/dev/mod.rs b/rcore-fs-sefs/src/dev/mod.rs new file mode 100644 index 0000000..8cd51e7 --- /dev/null +++ b/rcore-fs-sefs/src/dev/mod.rs @@ -0,0 +1,44 @@ +use alloc::boxed::Box; + +use rcore_fs::vfs::FsError; + +pub use self::std_impl::*; + +mod std_impl; + +/// A file stores a normal file or directory. +/// +/// The interface is same as `std::fs::File`. +pub trait File: Send + Sync { + fn read_at(&self, buf: &mut [u8], offset: usize) -> DevResult; + fn write_at(&self, buf: &[u8], offset: usize) -> DevResult; + fn set_len(&self, len: usize) -> DevResult<()>; + fn flush(&self) -> DevResult<()>; + + fn read_exact_at(&self, buf: &mut [u8], offset: usize) -> DevResult<()> { + let len = self.read_at(buf, offset)?; + if len == buf.len() { Ok(()) } else { Err(DeviceError) } + } + fn write_all_at(&self, buf: &[u8], offset: usize) -> DevResult<()> { + let len = self.write_at(buf, offset)?; + if len == buf.len() { Ok(()) } else { Err(DeviceError) } + } +} + +/// The collection of all files in the FS. +pub trait Storage: Send + Sync { + fn open(&self, file_id: usize) -> DevResult>; + fn create(&self, file_id: usize) -> DevResult>; + fn remove(&self, file_id: usize) -> DevResult<()>; +} + +#[derive(Debug)] +pub struct DeviceError; + +pub type DevResult = Result; + +impl From for FsError { + fn from(_: DeviceError) -> Self { + FsError::DeviceError + } +} diff --git a/rcore-fs/src/sefs/std_impl.rs b/rcore-fs-sefs/src/dev/std_impl.rs similarity index 100% rename from rcore-fs/src/sefs/std_impl.rs rename to rcore-fs-sefs/src/dev/std_impl.rs diff --git a/rcore-fs/src/sefs/mod.rs b/rcore-fs-sefs/src/lib.rs similarity index 93% rename from rcore-fs/src/sefs/mod.rs rename to rcore-fs-sefs/src/lib.rs index ef1c09e..74f4f0c 100644 --- a/rcore-fs/src/sefs/mod.rs +++ b/rcore-fs-sefs/src/lib.rs @@ -1,56 +1,25 @@ +#![cfg_attr(not(any(test, feature = "std")), no_std)] +#![feature(alloc)] + +extern crate alloc; + use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::{Arc, Weak}, vec::Vec}; use core::any::Any; use core::fmt::{Debug, Error, Formatter}; use core::mem::uninitialized; use bitvec::BitVec; -use log::*; -use spin::{Mutex, RwLock}; +//use log::*; +use spin::RwLock; -use crate::dirty::Dirty; -use crate::vfs::{self, FileSystem, FsError, INode, Timespec}; +use rcore_fs::dirty::Dirty; +use rcore_fs::vfs::{self, FileSystem, FsError, INode, Timespec}; +use self::dev::*; use self::structs::*; mod structs; -pub mod std_impl; - -/// A file stores a normal file or directory. -/// -/// The interface is same as `std::fs::File`. -pub trait File: Send + Sync { - fn read_at(&self, buf: &mut [u8], offset: usize) -> DevResult; - fn write_at(&self, buf: &[u8], offset: usize) -> DevResult; - fn set_len(&self, len: usize) -> DevResult<()>; - fn flush(&self) -> DevResult<()>; - - fn read_exact_at(&self, buf: &mut [u8], offset: usize) -> DevResult<()> { - let len = self.read_at(buf, offset)?; - if len == buf.len() { Ok(()) } else { Err(DeviceError) } - } - fn write_all_at(&self, buf: &[u8], offset: usize) -> DevResult<()> { - let len = self.write_at(buf, offset)?; - if len == buf.len() { Ok(()) } else { Err(DeviceError) } - } -} - -/// The collection of all files in the FS. -pub trait Storage: Send + Sync { - fn open(&self, file_id: usize) -> DevResult>; - fn create(&self, file_id: usize) -> DevResult>; - fn remove(&self, file_id: usize) -> DevResult<()>; -} - -#[derive(Debug)] -pub struct DeviceError; - -pub type DevResult = Result; - -impl From for FsError { - fn from(_: DeviceError) -> Self { - FsError::DeviceError - } -} +pub mod dev; /// Helper methods for `File` impl File { @@ -413,7 +382,7 @@ impl Drop for INodeImpl { if self.disk_inode.read().nlinks <= 0 { self.disk_inode.write().sync(); self.fs.free_block(self.id); - self.fs.device.remove(self.id); + self.fs.device.remove(self.id).unwrap(); } } } diff --git a/rcore-fs/src/sefs/structs.rs b/rcore-fs-sefs/src/structs.rs similarity index 100% rename from rcore-fs/src/sefs/structs.rs rename to rcore-fs-sefs/src/structs.rs diff --git a/rcore-fs-sfs/Cargo.toml b/rcore-fs-sfs/Cargo.toml new file mode 100644 index 0000000..eefe8bf --- /dev/null +++ b/rcore-fs-sfs/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "rcore-fs-sfs" +version = "0.1.0" +authors = ["WangRunji "] +edition = "2018" + +[[bin]] +name = "mksfs" +path = "src/bin/mksfs.rs" +required-features = ["std"] + +[dependencies] +rcore-fs = { path = "../rcore-fs" } +static_assertions = "0.3" +spin = "0.4" +log = "0.4" + +[dependencies.bitvec] +version = "0.9" +default-features = false +features = ["alloc"] + +[features] +std = ["rcore-fs/std"] diff --git a/rcore-fs/src/bin/mksfs.rs b/rcore-fs-sfs/src/bin/mksfs.rs similarity index 95% rename from rcore-fs/src/bin/mksfs.rs rename to rcore-fs-sfs/src/bin/mksfs.rs index ec8910e..60f7bd5 100644 --- a/rcore-fs/src/bin/mksfs.rs +++ b/rcore-fs-sfs/src/bin/mksfs.rs @@ -3,8 +3,10 @@ use std::fs; use std::io::{Read, Write, Result}; use std::path::Path; use std::mem::uninitialized; -use std::sync::Arc; -use rcore_fs::{sfs::SimpleFileSystem, vfs::*}; +use std::sync::{Arc, Mutex}; + +use rcore_fs::vfs::*; +use rcore_fs_sfs::SimpleFileSystem; fn main() -> Result<()> { let args: Vec<_> = env::args().collect(); @@ -23,6 +25,7 @@ fn main() -> Result<()> { fn zip(path: &Path, img_path: &Path) -> Result<()> { let img = fs::OpenOptions::new().read(true).write(true).create(true).open(img_path)?; + let img = Mutex::new(img); let sfs = SimpleFileSystem::create(Box::new(img), 0x1000000); let inode = sfs.root_inode(); zip_dir(path, inode)?; @@ -59,6 +62,7 @@ fn zip_dir(path: &Path, inode: Arc) -> Result<()> { fn unzip(path: &Path, img_path: &Path) -> Result<()> { let img = fs::File::open(img_path)?; + let img = Mutex::new(img); let sfs = SimpleFileSystem::open(Box::new(img)).expect("Failed to open sfs"); let inode = sfs.root_inode(); fs::create_dir(&path)?; diff --git a/rcore-fs/src/sfs/mod.rs b/rcore-fs-sfs/src/lib.rs similarity index 94% rename from rcore-fs/src/sfs/mod.rs rename to rcore-fs-sfs/src/lib.rs index 511f787..4ebef13 100644 --- a/rcore-fs/src/sfs/mod.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -1,3 +1,9 @@ +#![cfg_attr(not(any(test, feature = "std")), no_std)] +#![feature(alloc)] +#![feature(const_str_len)] + +extern crate alloc; + use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::{Arc, Weak}, vec::Vec}; use core::any::Any; use core::fmt::{Debug, Error, Formatter}; @@ -5,34 +11,26 @@ use core::mem::uninitialized; use bitvec::BitVec; use log::*; -use spin::{Mutex, RwLock}; +use spin::RwLock; -use crate::dirty::Dirty; -use crate::util::*; -use crate::vfs::{self, FileSystem, FsError, INode, Timespec}; +use rcore_fs::dev::Device; +use rcore_fs::dirty::Dirty; +use rcore_fs::util::*; +use rcore_fs::vfs::{self, FileSystem, FsError, INode, Timespec}; use self::structs::*; mod structs; -mod std_impl; -mod blocked_device; - -/// Interface for FS to read & write -/// TODO: use std::io::{Read, Write} -pub trait Device: Send { - fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option; - fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option; -} -impl Device { - fn read_block(&mut self, id: BlockId, offset: usize, buf: &mut [u8]) -> vfs::Result<()> { +trait DeviceExt: Device { + fn read_block(&self, id: BlockId, offset: usize, buf: &mut [u8]) -> vfs::Result<()> { debug_assert!(offset + buf.len() <= BLKSIZE); match self.read_at(id * BLKSIZE + offset, buf) { Some(len) if len == buf.len() => Ok(()), _ => panic!(), } } - fn write_block(&mut 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); match self.write_at(id * BLKSIZE + offset, buf) { Some(len) if len == buf.len() => Ok(()), @@ -40,12 +38,14 @@ impl Device { } } /// Load struct `T` from given block in device - fn load_struct(&mut self, id: BlockId) -> vfs::Result { + fn load_struct(&self, id: BlockId) -> vfs::Result { let mut s: T = unsafe { uninitialized() }; self.read_block(id, 0, s.as_buf_mut()).map(|_|{s}) } } +impl DeviceExt for Device {} + /// inode for sfs pub struct INodeImpl { /// inode number @@ -73,7 +73,7 @@ impl INodeImpl { Ok(disk_inode.direct[id] as BlockId), id if id < NDIRECT + BLK_NENTRY => { let mut disk_block_id: u32 = 0; - self.fs.device.lock().read_block( + self.fs.device.read_block( disk_inode.indirect as usize, ENTRY_SIZE * (id - NDIRECT), disk_block_id.as_buf_mut(), @@ -93,7 +93,7 @@ impl INodeImpl { } id if id < NDIRECT + BLK_NENTRY => { let disk_block_id = disk_block_id as u32; - self.fs.device.lock().write_block( + self.fs.device.write_block( self.disk_inode.read().indirect as usize, ENTRY_SIZE * (id - NDIRECT), disk_block_id.as_buf(), @@ -215,7 +215,7 @@ impl INodeImpl { // Note: the _\w*_at method always return begin>size?0:begin(&self, begin: usize, end: usize, mut f: F) -> vfs::Result - where F: FnMut(&mut Box, &BlockRange, usize) -> vfs::Result<()> + where F: FnMut(&Box, &BlockRange, usize) -> vfs::Result<()> { let size = self._size(); let iter = BlockIter { @@ -228,7 +228,7 @@ impl INodeImpl { let mut buf_offset = 0usize; for mut range in iter { range.block = self.get_disk_block_id(range.block)?; - f(&mut *self.fs.device.lock(), &range, buf_offset)?; + f(&self.fs.device, &range, buf_offset)?; buf_offset += range.len(); } Ok(buf_offset) @@ -299,7 +299,7 @@ impl vfs::INode for INodeImpl { fn sync(&self) -> vfs::Result<()> { let mut disk_inode = self.disk_inode.write(); if disk_inode.dirty() { - self.fs.device.lock().write_block(self.id, 0, disk_inode.as_buf())?; + self.fs.device.write_block(self.id, 0, disk_inode.as_buf())?; disk_inode.sync(); } Ok(()) @@ -543,14 +543,14 @@ pub struct SimpleFileSystem { /// inode list inodes: RwLock>>, /// device - device: Mutex>, + device: Box, /// Pointer to self, used by INodes self_ptr: Weak, } impl SimpleFileSystem { /// Load SFS from device - pub fn open(mut device: Box) -> vfs::Result> { + pub fn open(device: Box) -> vfs::Result> { let super_block = device.load_struct::(BLKN_SUPER).unwrap(); if !super_block.check() { return Err(FsError::WrongFs); @@ -561,7 +561,7 @@ impl SimpleFileSystem { super_block: RwLock::new(Dirty::new(super_block)), free_map: RwLock::new(Dirty::new(BitVec::from(free_map.as_ref()))), inodes: RwLock::new(BTreeMap::new()), - device: Mutex::new(device), + device, self_ptr: Weak::default(), }.wrap()) } @@ -589,7 +589,7 @@ impl SimpleFileSystem { super_block: RwLock::new(Dirty::new_dirty(super_block)), free_map: RwLock::new(Dirty::new_dirty(free_map)), inodes: RwLock::new(BTreeMap::new()), - device: Mutex::new(device), + device, self_ptr: Weak::default(), }.wrap(); @@ -661,7 +661,7 @@ impl SimpleFileSystem { } } // Load if not in set, or is weak ref. - let disk_inode = Dirty::new(self.device.lock().load_struct::(id).unwrap()); + let disk_inode = Dirty::new(self.device.load_struct::(id).unwrap()); self._new_inode(id, disk_inode) } /// Create a new INode file @@ -694,12 +694,12 @@ impl vfs::FileSystem for SimpleFileSystem { fn sync(&self) -> vfs::Result<()> { let mut super_block = self.super_block.write(); if super_block.dirty() { - self.device.lock().write_at(BLKSIZE * BLKN_SUPER, super_block.as_buf()).unwrap(); + self.device.write_at(BLKSIZE * BLKN_SUPER, super_block.as_buf()).unwrap(); super_block.sync(); } let mut free_map = self.free_map.write(); if free_map.dirty() { - self.device.lock().write_at(BLKSIZE * BLKN_FREEMAP, free_map.as_buf()).unwrap(); + self.device.write_at(BLKSIZE * BLKN_FREEMAP, free_map.as_buf()).unwrap(); free_map.sync(); } self.flush_weak_inodes(); diff --git a/rcore-fs/src/sfs/structs.rs b/rcore-fs-sfs/src/structs.rs similarity index 100% rename from rcore-fs/src/sfs/structs.rs rename to rcore-fs-sfs/src/structs.rs diff --git a/rcore-fs/Cargo.toml b/rcore-fs/Cargo.toml index 63b98a7..1b47bb5 100644 --- a/rcore-fs/Cargo.toml +++ b/rcore-fs/Cargo.toml @@ -4,21 +4,6 @@ version = "0.1.0" authors = ["WangRunji ", "Ben Pig Chu "] edition = "2018" -[[bin]] -name = "mksfs" -path = "src/bin/mksfs.rs" -required-features = ["std"] - -[dependencies] -static_assertions = "0.3" -spin = "0.4" -log = "0.4" - -[dependencies.bitvec] -version = "0.9" -default-features = false -features = ["alloc"] - [dev-dependencies] tempfile = "3" diff --git a/rcore-fs/src/sfs/blocked_device.rs b/rcore-fs/src/dev/mod.rs similarity index 62% rename from rcore-fs/src/sfs/blocked_device.rs rename to rcore-fs/src/dev/mod.rs index 472b326..a871423 100644 --- a/rcore-fs/src/sfs/blocked_device.rs +++ b/rcore-fs/src/dev/mod.rs @@ -1,11 +1,19 @@ use crate::util::*; -use super::Device; + +mod std_impl; + +/// Interface for FS to read & write +/// TODO: use std::io::{Read, Write} +pub trait Device: Send + Sync { + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option; + fn write_at(&self, offset: usize, buf: &[u8]) -> Option; +} /// Device which can only R/W in blocks -pub trait BlockedDevice: Send { +pub trait BlockDevice: Send + Sync { const BLOCK_SIZE_LOG2: u8; - fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool; - fn write_at(&mut self, block_id: usize, buf: &[u8]) -> bool; + fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool; + fn write_at(&self, block_id: usize, buf: &[u8]) -> bool; } macro_rules! try0 { @@ -14,9 +22,9 @@ macro_rules! try0 { }; } -/// Helper functions to R/W BlockedDevice in bytes -impl Device for T { - fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option { +/// Helper functions to R/W BlockDevice in bytes +impl Device for T { + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option { let iter = BlockIter { begin: offset, end: offset + buf.len(), @@ -29,13 +37,13 @@ impl Device for T { let buf = &mut buf[range.origin_begin() - offset..range.origin_end() - offset]; if range.is_full() { // Read to target buf directly - try0!(len, BlockedDevice::read_at(self, range.block, buf)); + try0!(len, BlockDevice::read_at(self, range.block, buf)); } else { use core::mem::uninitialized; let mut block_buf: [u8; 4096] = unsafe { uninitialized() }; assert!(Self::BLOCK_SIZE_LOG2 <= 12); // Read to local buf first - try0!(len, BlockedDevice::read_at(self, range.block, &mut block_buf)); + try0!(len, BlockDevice::read_at(self, range.block, &mut block_buf)); // Copy to target buf then buf.copy_from_slice(&mut block_buf[range.begin..range.end]); } @@ -43,7 +51,7 @@ impl Device for T { Some(buf.len()) } - fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option { + fn write_at(&self, offset: usize, buf: &[u8]) -> Option { let iter = BlockIter { begin: offset, end: offset + buf.len(), @@ -56,17 +64,17 @@ impl Device for T { let buf = &buf[range.origin_begin() - offset..range.origin_end() - offset]; if range.is_full() { // Write to target buf directly - try0!(len, BlockedDevice::write_at(self, range.block, buf)); + try0!(len, BlockDevice::write_at(self, range.block, buf)); } else { use core::mem::uninitialized; let mut block_buf: [u8; 4096] = unsafe { uninitialized() }; assert!(Self::BLOCK_SIZE_LOG2 <= 12); // Read to local buf first - try0!(len, BlockedDevice::read_at(self, range.block, &mut block_buf)); + try0!(len, BlockDevice::read_at(self, range.block, &mut block_buf)); // Write to local buf block_buf[range.begin..range.end].copy_from_slice(buf); // Write back to target buf - try0!(len, BlockedDevice::write_at(self, range.block, &block_buf)); + try0!(len, BlockDevice::write_at(self, range.block, &block_buf)); } } Some(buf.len()) @@ -76,65 +84,66 @@ impl Device for T { #[cfg(test)] mod test { use super::*; + use std::sync::Mutex; - impl BlockedDevice for [u8; 16] { + impl BlockDevice for Mutex<[u8; 16]> { const BLOCK_SIZE_LOG2: u8 = 2; - fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool { + fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { if block_id >= 4 { return false; } let begin = block_id << 2; - buf[..4].copy_from_slice(&mut self[begin..begin + 4]); + buf[..4].copy_from_slice(&mut self.lock()[begin..begin + 4]); true } - fn write_at(&mut self, block_id: usize, buf: &[u8]) -> bool { + fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { if block_id >= 4 { return false; } let begin = block_id << 2; - self[begin..begin + 4].copy_from_slice(&buf[..4]); + self.lock()[begin..begin + 4].copy_from_slice(&buf[..4]); true } } #[test] fn read() { - let mut buf: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + let buf: Mutex<[u8; 16]> = Mutex::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); let mut res: [u8; 6] = [0; 6]; // all inside - let ret = Device::read_at(&mut buf, 3, &mut res); + let ret = Device::read_at(&buf, 3, &mut res); assert_eq!(ret, Some(6)); assert_eq!(res, [3, 4, 5, 6, 7, 8]); // partly inside - let ret = Device::read_at(&mut buf, 11, &mut res); + let ret = Device::read_at(&buf, 11, &mut res); assert_eq!(ret, Some(5)); assert_eq!(res, [11, 12, 13, 14, 15, 8]); // all outside - let ret = Device::read_at(&mut buf, 16, &mut res); + let ret = Device::read_at(&buf, 16, &mut res); assert_eq!(ret, Some(0)); assert_eq!(res, [11, 12, 13, 14, 15, 8]); } #[test] fn write() { - let mut buf: [u8; 16] = [0; 16]; + let buf: Mutex<[u8; 16]> = Mutex::new([0; 16]); let res: [u8; 6] = [3, 4, 5, 6, 7, 8]; // all inside - let ret = Device::write_at(&mut buf, 3, &res); + let ret = Device::write_at(&buf, 3, &res); assert_eq!(ret, Some(6)); assert_eq!(buf, [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0]); // partly inside - let ret = Device::write_at(&mut buf, 11, &res); + let ret = Device::write_at(&buf, 11, &res); assert_eq!(ret, Some(5)); assert_eq!(buf, [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7]); // all outside - let ret = Device::write_at(&mut buf, 16, &res); + let ret = Device::write_at(&buf, 16, &res); assert_eq!(ret, Some(0)); assert_eq!(buf, [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7]); } diff --git a/rcore-fs/src/dev/std_impl.rs b/rcore-fs/src/dev/std_impl.rs new file mode 100644 index 0000000..d58e628 --- /dev/null +++ b/rcore-fs/src/dev/std_impl.rs @@ -0,0 +1,27 @@ +#![cfg(any(test, feature = "std"))] + +use std::fs::File; +use std::io::{Read, Seek, SeekFrom, Write}; +use std::sync::Mutex; + +use super::Device; + +impl Device for Mutex { + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option { + let offset = offset as u64; + let mut file = self.lock().unwrap(); + match file.seek(SeekFrom::Start(offset)) { + Ok(real_offset) if real_offset == offset => file.read(buf).ok(), + _ => None, + } + } + + fn write_at(&self, offset: usize, buf: &[u8]) -> Option { + let offset = offset as u64; + let mut file = self.lock().unwrap(); + match file.seek(SeekFrom::Start(offset)) { + Ok(real_offset) if real_offset == offset => file.write(buf).ok(), + _ => None, + } + } +} \ No newline at end of file diff --git a/rcore-fs/src/lib.rs b/rcore-fs/src/lib.rs index e8938fc..1da365c 100644 --- a/rcore-fs/src/lib.rs +++ b/rcore-fs/src/lib.rs @@ -4,11 +4,10 @@ extern crate alloc; -mod dirty; -mod util; +pub mod dirty; +pub mod util; pub mod vfs; -pub mod sfs; -pub mod sefs; +pub mod dev; pub mod file; #[cfg(test)] mod tests; diff --git a/rcore-fs/src/sfs/std_impl.rs b/rcore-fs/src/sfs/std_impl.rs deleted file mode 100644 index 0025ff9..0000000 --- a/rcore-fs/src/sfs/std_impl.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![cfg(any(test, feature = "std"))] - -use std::fs::File; -use std::io::{Read, Write, Seek, SeekFrom}; -use super::Device; - -impl Device for File { - fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option { - let offset = offset as u64; - match self.seek(SeekFrom::Start(offset)) { - Ok(real_offset) if real_offset == offset => self.read(buf).ok(), - _ => None, - } - } - - fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option { - let offset = offset as u64; - match self.seek(SeekFrom::Start(offset)) { - Ok(real_offset) if real_offset == offset => self.write(buf).ok(), - _ => None, - } - } -} \ No newline at end of file