From 0d39ec0428c64018ec908dc377d70773261bd40d Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 23 May 2018 23:50:17 +0800 Subject: [PATCH 1/7] BlockedDevice --- src/blocked_device.rs | 141 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 + src/sfs.rs | 56 ++--------------- src/structs.rs | 4 +- src/util.rs | 60 ++++++++++++++++++ 5 files changed, 212 insertions(+), 52 deletions(-) create mode 100644 src/blocked_device.rs create mode 100644 src/util.rs diff --git a/src/blocked_device.rs b/src/blocked_device.rs new file mode 100644 index 0000000..be05aaf --- /dev/null +++ b/src/blocked_device.rs @@ -0,0 +1,141 @@ +use util::*; +use vfs::Device; + +/// Device which can only R/W in blocks +pub trait BlockedDevice { + fn block_size_log2(&self) -> u8; + fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool; + fn write_at(&mut self, block_id: usize, buf: &[u8]) -> bool; +} + +macro_rules! try0 { + ($len:expr, $res:expr) => { + if(!$res) {return Some($len);} + }; +} + +/// Helper functions to R/W BlockedDevice in bytes +impl Device for T { + fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option { + let iter = BlockIter { + begin: offset, + end: offset + buf.len(), + block_size_log2: self.block_size_log2(), + }; + + // For each block + for mut range in iter { + let len = range.origin_begin() - offset; + 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)); + } 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)); + // Copy to target buf then + buf.copy_from_slice(&mut block_buf[range.begin..range.end]); + } + } + Some(buf.len()) + } + + fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option { + let iter = BlockIter { + begin: offset, + end: offset + buf.len(), + block_size_log2: self.block_size_log2(), + }; + + // For each block + for mut range in iter { + let len = range.origin_begin() - offset; + 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)); + } 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)); + // 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)); + } + } + Some(buf.len()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + impl BlockedDevice for [u8; 16] { + fn block_size_log2(&self) -> u8 { 2 } + fn read_at(&mut 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]); + true + } + fn write_at(&mut 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]); + 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 mut res: [u8; 6] = [0; 6]; + + // all inside + let ret = Device::read_at(&mut 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); + 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); + 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 mut res: [u8; 6] = [3, 4, 5, 6, 7, 8]; + + // all inside + let ret = Device::write_at(&mut 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); + 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); + assert_eq!(ret, Some(0)); + assert_eq!(buf, [0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 3, 4, 5, 6, 7]); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ffef679..e9d0141 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,8 @@ macro_rules! eprintln { } mod dirty; +mod util; +mod blocked_device; mod vfs; mod sfs; mod structs; @@ -34,6 +36,7 @@ mod tests; pub use sfs::*; pub use vfs::*; +pub use blocked_device::BlockedDevice; #[cfg(feature = "ucore")] #[global_allocator] diff --git a/src/sfs.rs b/src/sfs.rs index cbf7c89..aa1bced 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -2,12 +2,13 @@ use spin::Mutex; use bit_set::BitSet; use alloc::{boxed::Box, Vec, BTreeMap, rc::{Rc, Weak}, String}; use core::cell::{RefCell, RefMut}; -use dirty::Dirty; -use super::structs::*; -use super::vfs::{self, Device}; use core::mem::{uninitialized, size_of}; use core::slice; use core::fmt::{Debug, Formatter, Error}; +use dirty::Dirty; +use structs::*; +use vfs::{self, Device}; +use util::*; trait DeviceExt: Device { fn read_block(&mut self, id: BlockId, offset: usize, buf: &mut [u8]) -> vfs::Result<()> { @@ -180,6 +181,7 @@ impl INode { let iter = BlockIter { begin: size.min(begin), end: size.min(end), + block_size_log2: BLKSIZE_LOG2, }; // For each block @@ -319,40 +321,6 @@ impl Drop for INode { } } -/// Given a range and iterate sub-range for each block -struct BlockIter { - begin: usize, - end: usize, -} - -#[derive(Debug, Eq, PartialEq)] -struct BlockRange { - block: BlockId, - begin: usize, - end: usize, -} - -impl BlockRange { - fn len(&self) -> usize { - self.end - self.begin - } -} - -impl Iterator for BlockIter { - type Item = BlockRange; - - fn next(&mut self) -> Option<::Item> { - if self.begin >= self.end { - return None; - } - let block = self.begin / BLKSIZE; - let begin = self.begin % BLKSIZE; - let end = if block == self.end / BLKSIZE { self.end % BLKSIZE } else { BLKSIZE }; - self.begin += end - begin; - Some(BlockRange { block, begin, end }) - } -} - /// filesystem for sfs /// @@ -576,17 +544,3 @@ impl From for vfs::FileType { } } } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn block_iter() { - let mut iter = BlockIter { begin: 0x123, end: 0x2018 }; - assert_eq!(iter.next(), Some(BlockRange { block: 0, begin: 0x123, end: 0x1000 })); - assert_eq!(iter.next(), Some(BlockRange { block: 1, begin: 0, end: 0x1000 })); - assert_eq!(iter.next(), Some(BlockRange { block: 2, begin: 0, end: 0x18 })); - assert_eq!(iter.next(), None); - } -} \ No newline at end of file diff --git a/src/structs.rs b/src/structs.rs index 3bd7caf..2b07667 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -153,7 +153,9 @@ pub type INodeId = BlockId; /// magic number for sfs pub const MAGIC: u32 = 0x2f8dbe2a; /// size of block -pub const BLKSIZE: usize = 4096; +pub const BLKSIZE: usize = 1usize << BLKSIZE_LOG2; +/// log2( size of block ) +pub const BLKSIZE_LOG2: u8 = 12; /// number of direct blocks in inode pub const NDIRECT: usize = 12; /// max length of infomation diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..507630d --- /dev/null +++ b/src/util.rs @@ -0,0 +1,60 @@ +/// Given a range and iterate sub-range for each block +pub struct BlockIter { + pub begin: usize, + pub end: usize, + pub block_size_log2: u8, +} + +#[derive(Debug, Eq, PartialEq)] +pub struct BlockRange { + pub block: usize, + pub begin: usize, + pub end: usize, + pub block_size_log2: u8, +} + +impl BlockRange { + pub fn len(&self) -> usize { + self.end - self.begin + } + pub fn is_full(&self) -> bool { + self.len() == (1usize << self.block_size_log2) + } + pub fn origin_begin(&self) -> usize { + (self.block << self.block_size_log2) + self.begin + } + pub fn origin_end(&self) -> usize { + (self.block << self.block_size_log2) + self.end + } +} + +impl Iterator for BlockIter { + type Item = BlockRange; + + fn next(&mut self) -> Option<::Item> { + if self.begin >= self.end { + return None; + } + let block_size_log2 = self.block_size_log2; + let block_size = 1usize << self.block_size_log2; + let block = self.begin / block_size; + let begin = self.begin % block_size; + let end = if block == self.end / block_size { self.end % block_size } else { block_size }; + self.begin += end - begin; + Some(BlockRange { block, begin, end, block_size_log2 }) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn block_iter() { + let mut iter = BlockIter { begin: 0x123, end: 0x2018, block_size_log2: 12 }; + assert_eq!(iter.next(), Some(BlockRange { block: 0, begin: 0x123, end: 0x1000, block_size_log2: 12 })); + assert_eq!(iter.next(), Some(BlockRange { block: 1, begin: 0, end: 0x1000, block_size_log2: 12 })); + assert_eq!(iter.next(), Some(BlockRange { block: 2, begin: 0, end: 0x18, block_size_log2: 12 })); + assert_eq!(iter.next(), None); + } +} \ No newline at end of file From e56b22fa74c842e68dcbee2275663cb58c975174 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 24 May 2018 00:01:33 +0800 Subject: [PATCH 2/7] impl BlockedDevice for ucore::Device --- src/c_interface.rs | 47 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/src/c_interface.rs b/src/c_interface.rs index d4ef86e..a942f70 100644 --- a/src/c_interface.rs +++ b/src/c_interface.rs @@ -12,6 +12,7 @@ use alloc::heap::{Alloc, AllocErr, Layout}; use core::mem::{size_of, self}; use core::ptr; use vfs; +use blocked_device::BlockedDevice; /// Lang items for bare lib mod lang { @@ -330,56 +331,40 @@ impl IoBuf { } } -impl vfs::Device for Device { - fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option { +impl BlockedDevice for Device { + fn block_size_log2(&self) -> u8 { if self.blocksize != 4096 { unimplemented!("block_size != 4096 is not supported yet"); } - let begin_block = offset / 4096; - let end_block = (offset + buf.len() - 1) / 4096; // inclusive - let begin_offset = offset % 4096; - let end_offset = (offset + buf.len() - 1) % 4096; - assert_eq!(begin_block, end_block, "more than 1 block is not supported yet"); - - use core::mem::uninitialized; - let mut block_buf: [u8; 4096] = unsafe{ uninitialized() }; + 12 + } + + fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool { + assert!(buf.len() >= 4096); let mut io_buf = IoBuf { - base: block_buf.as_mut_ptr(), - offset: (begin_block * 4096) as i32, + base: buf.as_mut_ptr(), + offset: (block_id * 4096) as i32, len: 4096, resident: 4096, }; let ret = (self.io)(self, &mut io_buf, false); assert_eq!(ret, ErrorCode::Ok); assert_eq!(io_buf.resident, 0); - buf.copy_from_slice(&block_buf[begin_offset .. end_offset+1]); - Some(buf.len()) + true } - fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option { - if self.blocksize != 4096 { - unimplemented!("block_size != 4096 is not supported yet"); - } - let begin_block = offset / 4096; - let end_block = (offset + buf.len() - 1) / 4096; // inclusive - let begin_offset = offset % 4096; - let end_offset = (offset + buf.len() - 1) % 4096; - assert_eq!(begin_block, end_block, "more than 1 block is not supported yet"); - - use core::mem::uninitialized; - let mut block_buf: [u8; 4096] = unsafe{ uninitialized() }; + fn write_at(&mut self, block_id: usize, buf: &[u8]) -> bool { + assert!(buf.len() >= 4096); let mut io_buf = IoBuf { - base: block_buf.as_mut_ptr(), - offset: (begin_block * 4096) as i32, + base: buf.as_ptr() as *mut _, + offset: (block_id * 4096) as i32, len: 4096, resident: 4096, }; - block_buf[begin_offset .. end_offset+1].copy_from_slice(&buf); - let ret = (self.io)(self, &mut io_buf, true); assert_eq!(ret, ErrorCode::Ok); assert_eq!(io_buf.resident, 0); - Some(buf.len()) + true } } From 4aac6474f190423c2cd68b518e9577c04a919202 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sun, 27 May 2018 23:21:58 +0800 Subject: [PATCH 3/7] Split C-interface to a new crate --- Cargo.toml | 13 +------------ Xargo.toml | 2 -- Makefile => sfs-c/Makefile | 2 +- sfs-c/Xargo.toml | 2 ++ src/c_interface.rs => sfs-c/src/lib.rs | 21 ++++++++++++++++++--- ucore.json => sfs-c/ucore.json | 0 src/lib.rs | 13 +------------ src/sfs.rs | 1 - 8 files changed, 23 insertions(+), 31 deletions(-) delete mode 100644 Xargo.toml rename Makefile => sfs-c/Makefile (65%) create mode 100644 sfs-c/Xargo.toml rename src/c_interface.rs => sfs-c/src/lib.rs (97%) rename ucore.json => sfs-c/ucore.json (100%) diff --git a/Cargo.toml b/Cargo.toml index c64817d..c6e07e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,20 +3,9 @@ name = "simple-filesystem" version = "0.0.1" authors = ["WangRunji "] -[lib] -#crate-type = ["staticlib"] - -[profile.dev] -panic = 'abort' # prevent `_Unwind_Resume` link error - [dependencies] -spin = "0.4" bit-set = { default-features = false, version = "0.5" } # default-features contains 'std' static_assertions = "0.2.5" -[target.ucore.dependencies] -bitflags = "1.0" - [features] -debug_print = [] -ucore = [] \ No newline at end of file +debug_print = [] \ No newline at end of file diff --git a/Xargo.toml b/Xargo.toml deleted file mode 100644 index 10e8f71..0000000 --- a/Xargo.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.ucore.dependencies] -alloc = {} \ No newline at end of file diff --git a/Makefile b/sfs-c/Makefile similarity index 65% rename from Makefile rename to sfs-c/Makefile index be19a06..3b65f15 100644 --- a/Makefile +++ b/sfs-c/Makefile @@ -1,6 +1,6 @@ ucore: rustup override set nightly-2018-04-01 - RUST_TARGET_PATH=$(shell pwd) xargo build --target ucore --features ucore + RUST_TARGET_PATH=$(shell pwd) xargo build --target ucore --release install-rust: which cargo || ( curl https://sh.rustup.rs -sSf | sh ) diff --git a/sfs-c/Xargo.toml b/sfs-c/Xargo.toml new file mode 100644 index 0000000..85b3939 --- /dev/null +++ b/sfs-c/Xargo.toml @@ -0,0 +1,2 @@ +[dependencies] +alloc = {} \ No newline at end of file diff --git a/src/c_interface.rs b/sfs-c/src/lib.rs similarity index 97% rename from src/c_interface.rs rename to sfs-c/src/lib.rs index a942f70..5fe193f 100644 --- a/src/c_interface.rs +++ b/sfs-c/src/lib.rs @@ -3,6 +3,18 @@ //! NOTE: Must link these sections: //! `*.got.*` `*.data.*` `*.rodata.*` +#![feature(allocator_api, global_allocator, lang_items)] +#![feature(alloc)] +#![no_std] + +#[macro_use] +extern crate alloc; +extern crate simple_filesystem; +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate static_assertions; + use alloc::{rc::Rc, boxed::Box, BTreeMap}; use core::cell::RefCell; use core::slice; @@ -11,8 +23,8 @@ use core::cmp::Ordering; use alloc::heap::{Alloc, AllocErr, Layout}; use core::mem::{size_of, self}; use core::ptr; -use vfs; -use blocked_device::BlockedDevice; +use simple_filesystem as sfs; +use simple_filesystem as vfs; /// Lang items for bare lib mod lang { @@ -331,7 +343,7 @@ impl IoBuf { } } -impl BlockedDevice for Device { +impl vfs::BlockedDevice for Device { fn block_size_log2(&self) -> u8 { if self.blocksize != 4096 { unimplemented!("block_size != 4096 is not supported yet"); @@ -562,6 +574,9 @@ static FS_OPS: FsOps = { /// Allocator supported by ucore functions pub struct UcoreAllocator; +#[global_allocator] +pub static UCORE_ALLOCATOR: UcoreAllocator = UcoreAllocator; + unsafe impl<'a> Alloc for &'a UcoreAllocator { unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { // cprintf!("alloc %d\n", layout.size()); diff --git a/ucore.json b/sfs-c/ucore.json similarity index 100% rename from ucore.json rename to sfs-c/ucore.json diff --git a/src/lib.rs b/src/lib.rs index e9d0141..12c3624 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,18 +1,13 @@ #![feature(alloc)] #![feature(const_fn)] -#![cfg_attr(feature = "ucore", feature(allocator_api, global_allocator, lang_items))] #![no_std] -#[cfg(test)] +#[cfg(any(test, feature = "std"))] #[macro_use] extern crate std; -extern crate spin; #[macro_use] extern crate alloc; extern crate bit_set; -#[cfg(feature = "ucore")] -#[macro_use] -extern crate bitflags; #[macro_use] extern crate static_assertions; @@ -29,15 +24,9 @@ mod blocked_device; mod vfs; mod sfs; mod structs; -#[cfg(feature = "ucore")] -pub mod c_interface; #[cfg(test)] mod tests; pub use sfs::*; pub use vfs::*; pub use blocked_device::BlockedDevice; - -#[cfg(feature = "ucore")] -#[global_allocator] -pub static UCORE_ALLOCATOR: c_interface::UcoreAllocator = c_interface::UcoreAllocator{}; \ No newline at end of file diff --git a/src/sfs.rs b/src/sfs.rs index aa1bced..3dd7787 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -1,4 +1,3 @@ -use spin::Mutex; use bit_set::BitSet; use alloc::{boxed::Box, Vec, BTreeMap, rc::{Rc, Weak}, String}; use core::cell::{RefCell, RefMut}; From 25e7f8e0a7a4a91c0f0cffb5bfd3d63604c6c41a Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sun, 27 May 2018 23:31:23 +0800 Subject: [PATCH 4/7] Fix cargo.toml --- sfs-c/Cargo.toml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 sfs-c/Cargo.toml diff --git a/sfs-c/Cargo.toml b/sfs-c/Cargo.toml new file mode 100644 index 0000000..8d23380 --- /dev/null +++ b/sfs-c/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "sfs-c" +version = "0.0.1" +authors = ["WangRunji "] + +[lib] +crate-type = ["staticlib"] + +[profile.dev] +panic = 'abort' # prevent `_Unwind_Resume` link error + +[dependencies] +bitflags = "1.0" +static_assertions = "0.2.5" +simple-filesystem = { path = ".." } From e283c50866203d12f95494b3b2d09e5ef7b3bf8b Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 14 Jul 2018 17:34:11 +0800 Subject: [PATCH 5/7] Fix compile for RV32 --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 12c3624..b406fd2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![feature(alloc)] #![feature(const_fn)] +#![cfg_attr(target_arch = "riscv", feature(match_default_bindings))] #![no_std] #[cfg(any(test, feature = "std"))] From 7251ab7fb70f88172b31e3f38322b5ab81bca74b Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sun, 15 Jul 2018 16:36:26 +0800 Subject: [PATCH 6/7] Make `block_size_log2` a constant --- src/blocked_device.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/blocked_device.rs b/src/blocked_device.rs index be05aaf..f8802fe 100644 --- a/src/blocked_device.rs +++ b/src/blocked_device.rs @@ -3,7 +3,7 @@ use vfs::Device; /// Device which can only R/W in blocks pub trait BlockedDevice { - fn block_size_log2(&self) -> u8; + 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; } @@ -20,7 +20,7 @@ impl Device for T { let iter = BlockIter { begin: offset, end: offset + buf.len(), - block_size_log2: self.block_size_log2(), + block_size_log2: Self::BLOCK_SIZE_LOG2, }; // For each block @@ -33,7 +33,7 @@ impl Device for T { } else { use core::mem::uninitialized; let mut block_buf: [u8; 4096] = unsafe { uninitialized() }; - assert!(self.block_size_log2() <= 12); + assert!(Self::BLOCK_SIZE_LOG2 <= 12); // Read to local buf first try0!(len, BlockedDevice::read_at(self, range.block, &mut block_buf)); // Copy to target buf then @@ -47,7 +47,7 @@ impl Device for T { let iter = BlockIter { begin: offset, end: offset + buf.len(), - block_size_log2: self.block_size_log2(), + block_size_log2: Self::BLOCK_SIZE_LOG2, }; // For each block @@ -60,7 +60,7 @@ impl Device for T { } else { use core::mem::uninitialized; let mut block_buf: [u8; 4096] = unsafe { uninitialized() }; - assert!(self.block_size_log2() <= 12); + assert!(Self::BLOCK_SIZE_LOG2 <= 12); // Read to local buf first try0!(len, BlockedDevice::read_at(self, range.block, &mut block_buf)); // Write to local buf @@ -78,7 +78,7 @@ mod test { use super::*; impl BlockedDevice for [u8; 16] { - fn block_size_log2(&self) -> u8 { 2 } + const BLOCK_SIZE_LOG2: u8 = 2; fn read_at(&mut self, block_id: usize, buf: &mut [u8]) -> bool { if block_id >= 4 { return false; From ca10d11264c85932e95e6c7c29e8b10c91ae0720 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 4 Aug 2018 14:09:37 +0800 Subject: [PATCH 7/7] Fit for newest Rust nightly. BitSet -> BitVec. --- .travis.yml | 2 +- Cargo.toml | 2 +- src/lib.rs | 2 +- src/sfs.rs | 30 +++++++++++++++--------------- src/vfs.rs | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b2fc9c..0f33674 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: rust rust: - - nightly-2018-04-01 \ No newline at end of file + - nightly \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index c6e07e9..8f342a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.1" authors = ["WangRunji "] [dependencies] -bit-set = { default-features = false, version = "0.5" } # default-features contains 'std' +bit-vec = { default-features = false, git = "https://github.com/AltSysrq/bit-vec.git" } # default-features contains 'std' static_assertions = "0.2.5" [features] diff --git a/src/lib.rs b/src/lib.rs index b406fd2..eeaab74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ extern crate std; #[macro_use] extern crate alloc; -extern crate bit_set; +extern crate bit_vec; #[macro_use] extern crate static_assertions; diff --git a/src/sfs.rs b/src/sfs.rs index 3dd7787..3e47564 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -1,5 +1,5 @@ -use bit_set::BitSet; -use alloc::{boxed::Box, Vec, BTreeMap, rc::{Rc, Weak}, String}; +use bit_vec::BitVec; +use alloc::{boxed::Box, vec::Vec, collections::BTreeMap, rc::{Rc, Weak}, string::String}; use core::cell::{RefCell, RefMut}; use core::mem::{uninitialized, size_of}; use core::slice; @@ -331,7 +331,7 @@ pub struct SimpleFileSystem { /// on-disk superblock super_block: RefCell>, /// blocks in use are mared 0 - free_map: RefCell>, + free_map: RefCell>, /// inode list inodes: RefCell>>, /// device @@ -351,7 +351,7 @@ impl SimpleFileSystem { Some(SimpleFileSystem { super_block: RefCell::new(Dirty::new(super_block)), - free_map: RefCell::new(Dirty::new(BitSet::from_bytes(&free_map))), + free_map: RefCell::new(Dirty::new(BitVec::from_bytes(&free_map))), inodes: RefCell::new(BTreeMap::>::new()), device: RefCell::new(device), self_ptr: Weak::default(), @@ -369,9 +369,9 @@ impl SimpleFileSystem { info: Str32::from("simple file system"), }; let free_map = { - let mut bitset = BitSet::with_capacity(BLKBITS); + let mut bitset = BitVec::from_elem(BLKBITS, false); for i in 3..blocks { - bitset.insert(i); + bitset.set(i, true); } bitset }; @@ -417,8 +417,8 @@ impl SimpleFileSystem { /// Free a block fn free_block(&self, block_id: usize) { let mut free_map = self.free_map.borrow_mut(); - assert!(!free_map.contains(block_id)); - free_map.insert(block_id); + assert!(!free_map[block_id]); + free_map.set(block_id, true); self.super_block.borrow_mut().unused_blocks += 1; } @@ -436,7 +436,7 @@ impl SimpleFileSystem { /// Get inode by id. Load if not in memory. /// ** Must ensure it's a valid INode ** fn get_inode(&self, id: INodeId) -> Ptr { - assert!(!self.free_map.borrow().contains(id)); + assert!(!self.free_map.borrow()[id]); // Load if not in memory. if !self.inodes.borrow().contains_key(&id) { @@ -510,24 +510,24 @@ trait BitsetAlloc { fn alloc(&mut self) -> Option; } -impl BitsetAlloc for BitSet { +impl BitsetAlloc for BitVec { fn alloc(&mut self) -> Option { // TODO: more efficient - let id = (0..self.len()).find(|&i| self.contains(i)); + let id = (0..self.len()).find(|&i| self[i]); if let Some(id) = id { - self.remove(id); + self.set(id, false); } id } } -impl AsBuf for BitSet { +impl AsBuf for BitVec { fn as_buf(&self) -> &[u8] { - let slice = self.get_ref().storage(); + let slice = self.storage(); unsafe { slice::from_raw_parts(slice as *const _ as *const u8, slice.len() * 4) } } fn as_buf_mut(&mut self) -> &mut [u8] { - let slice = self.get_ref().storage(); + let slice = self.storage(); unsafe { slice::from_raw_parts_mut(slice as *const _ as *mut u8, slice.len() * 4) } } } diff --git a/src/vfs.rs b/src/vfs.rs index fa85633..ad2b560 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -1,4 +1,4 @@ -use alloc::{Vec, String, rc::{Rc, Weak}}; +use alloc::{vec::Vec, string::String, rc::{Rc, Weak}}; use core::cell::RefCell; use core::mem::size_of; use core;