|
|
@ -1,5 +1,5 @@
|
|
|
|
use bit_set::BitSet;
|
|
|
|
use bit_vec::BitVec;
|
|
|
|
use alloc::{boxed::Box, Vec, BTreeMap, rc::{Rc, Weak}, String};
|
|
|
|
use alloc::{boxed::Box, vec::Vec, collections::BTreeMap, rc::{Rc, Weak}, string::String};
|
|
|
|
use core::cell::{RefCell, RefMut};
|
|
|
|
use core::cell::{RefCell, RefMut};
|
|
|
|
use core::mem::{uninitialized, size_of};
|
|
|
|
use core::mem::{uninitialized, size_of};
|
|
|
|
use core::slice;
|
|
|
|
use core::slice;
|
|
|
@ -331,7 +331,7 @@ pub struct SimpleFileSystem {
|
|
|
|
/// on-disk superblock
|
|
|
|
/// on-disk superblock
|
|
|
|
super_block: RefCell<Dirty<SuperBlock>>,
|
|
|
|
super_block: RefCell<Dirty<SuperBlock>>,
|
|
|
|
/// blocks in use are mared 0
|
|
|
|
/// blocks in use are mared 0
|
|
|
|
free_map: RefCell<Dirty<BitSet>>,
|
|
|
|
free_map: RefCell<Dirty<BitVec>>,
|
|
|
|
/// inode list
|
|
|
|
/// inode list
|
|
|
|
inodes: RefCell<BTreeMap<INodeId, Ptr<INode>>>,
|
|
|
|
inodes: RefCell<BTreeMap<INodeId, Ptr<INode>>>,
|
|
|
|
/// device
|
|
|
|
/// device
|
|
|
@ -351,7 +351,7 @@ impl SimpleFileSystem {
|
|
|
|
|
|
|
|
|
|
|
|
Some(SimpleFileSystem {
|
|
|
|
Some(SimpleFileSystem {
|
|
|
|
super_block: RefCell::new(Dirty::new(super_block)),
|
|
|
|
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::<INodeId, Ptr<INode>>::new()),
|
|
|
|
inodes: RefCell::new(BTreeMap::<INodeId, Ptr<INode>>::new()),
|
|
|
|
device: RefCell::new(device),
|
|
|
|
device: RefCell::new(device),
|
|
|
|
self_ptr: Weak::default(),
|
|
|
|
self_ptr: Weak::default(),
|
|
|
@ -369,9 +369,9 @@ impl SimpleFileSystem {
|
|
|
|
info: Str32::from("simple file system"),
|
|
|
|
info: Str32::from("simple file system"),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let free_map = {
|
|
|
|
let free_map = {
|
|
|
|
let mut bitset = BitSet::with_capacity(BLKBITS);
|
|
|
|
let mut bitset = BitVec::from_elem(BLKBITS, false);
|
|
|
|
for i in 3..blocks {
|
|
|
|
for i in 3..blocks {
|
|
|
|
bitset.insert(i);
|
|
|
|
bitset.set(i, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bitset
|
|
|
|
bitset
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -417,8 +417,8 @@ impl SimpleFileSystem {
|
|
|
|
/// Free a block
|
|
|
|
/// Free a block
|
|
|
|
fn free_block(&self, block_id: usize) {
|
|
|
|
fn free_block(&self, block_id: usize) {
|
|
|
|
let mut free_map = self.free_map.borrow_mut();
|
|
|
|
let mut free_map = self.free_map.borrow_mut();
|
|
|
|
assert!(!free_map.contains(block_id));
|
|
|
|
assert!(!free_map[block_id]);
|
|
|
|
free_map.insert(block_id);
|
|
|
|
free_map.set(block_id, true);
|
|
|
|
self.super_block.borrow_mut().unused_blocks += 1;
|
|
|
|
self.super_block.borrow_mut().unused_blocks += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -436,7 +436,7 @@ impl SimpleFileSystem {
|
|
|
|
/// Get inode by id. Load if not in memory.
|
|
|
|
/// Get inode by id. Load if not in memory.
|
|
|
|
/// ** Must ensure it's a valid INode **
|
|
|
|
/// ** Must ensure it's a valid INode **
|
|
|
|
fn get_inode(&self, id: INodeId) -> Ptr<INode> {
|
|
|
|
fn get_inode(&self, id: INodeId) -> Ptr<INode> {
|
|
|
|
assert!(!self.free_map.borrow().contains(id));
|
|
|
|
assert!(!self.free_map.borrow()[id]);
|
|
|
|
|
|
|
|
|
|
|
|
// Load if not in memory.
|
|
|
|
// Load if not in memory.
|
|
|
|
if !self.inodes.borrow().contains_key(&id) {
|
|
|
|
if !self.inodes.borrow().contains_key(&id) {
|
|
|
@ -510,24 +510,24 @@ trait BitsetAlloc {
|
|
|
|
fn alloc(&mut self) -> Option<usize>;
|
|
|
|
fn alloc(&mut self) -> Option<usize>;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl BitsetAlloc for BitSet {
|
|
|
|
impl BitsetAlloc for BitVec {
|
|
|
|
fn alloc(&mut self) -> Option<usize> {
|
|
|
|
fn alloc(&mut self) -> Option<usize> {
|
|
|
|
// TODO: more efficient
|
|
|
|
// 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 {
|
|
|
|
if let Some(id) = id {
|
|
|
|
self.remove(id);
|
|
|
|
self.set(id, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
id
|
|
|
|
id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl AsBuf for BitSet {
|
|
|
|
impl AsBuf for BitVec {
|
|
|
|
fn as_buf(&self) -> &[u8] {
|
|
|
|
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) }
|
|
|
|
unsafe { slice::from_raw_parts(slice as *const _ as *const u8, slice.len() * 4) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn as_buf_mut(&mut self) -> &mut [u8] {
|
|
|
|
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) }
|
|
|
|
unsafe { slice::from_raw_parts_mut(slice as *const _ as *mut u8, slice.len() * 4) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|