From 513bfaf805b7161128737052be6c56d1cdf51abb Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Sun, 19 Nov 2017 16:15:01 -0700 Subject: [PATCH] Set block size programatically --- src/disk/cache/linked_hash_map.rs | 204 ------------------------------ src/disk/cache/lru_cache.rs | 164 ------------------------ src/disk/cache/mod.rs | 27 ++-- src/disk/file.rs | 5 +- src/ex_node.rs | 9 +- src/extent.rs | 8 +- src/filesystem.rs | 82 ++++++------ src/header.rs | 12 +- src/lib.rs | 2 + src/mount/fuse.rs | 5 +- src/mount/redox/scheme.rs | 3 +- src/node.rs | 9 +- 12 files changed, 87 insertions(+), 443 deletions(-) diff --git a/src/disk/cache/linked_hash_map.rs b/src/disk/cache/linked_hash_map.rs index 845db2f..cc8f620 100644 --- a/src/disk/cache/linked_hash_map.rs +++ b/src/disk/cache/linked_hash_map.rs @@ -9,23 +9,6 @@ // except according to those terms. //! A HashMap wrapper that holds key-value pairs in insertion order. -//! -//! # Examples -//! -//! ``` -//! use linked_hash_map::LinkedHashMap; -//! -//! let mut map = LinkedHashMap::new(); -//! map.insert(2, 20); -//! map.insert(1, 10); -//! map.insert(3, 30); -//! assert_eq!(map[&1], 10); -//! assert_eq!(map[&2], 20); -//! assert_eq!(map[&3], 30); -//! -//! let items: Vec<(i32, i32)> = map.iter().map(|t| (*t.0, *t.1)).collect(); -//! assert_eq!(items, [(2, 20), (1, 10), (3, 30)]); -//! ``` #![forbid(missing_docs)] #![cfg_attr(feature = "nightly", feature(hashmap_public_hasher))] @@ -167,18 +150,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { /// Inserts a key-value pair into the map. If the key already existed, the old value is /// returned. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// - /// map.insert(1, "a"); - /// map.insert(2, "b"); - /// assert_eq!(map[&1], "a"); - /// assert_eq!(map[&2], "b"); - /// ``` pub fn insert(&mut self, k: K, v: V) -> Option<V> { if self.head.is_null() { // allocate the guard node if not present @@ -231,39 +202,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Returns the value corresponding to the key in the map. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// - /// map.insert(1, "a"); - /// map.insert(2, "b"); - /// map.insert(2, "c"); - /// map.insert(3, "d"); - /// - /// assert_eq!(map.get(&1), Some(&"a")); - /// assert_eq!(map.get(&2), Some(&"c")); - /// ``` pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where K: Borrow<Q>, Q: Eq + Hash { self.map.get(Qey::from_ref(k)).map(|e| &e.value) } /// Returns the mutable reference corresponding to the key in the map. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// - /// map.insert(1, "a"); - /// map.insert(2, "b"); - /// - /// *map.get_mut(&1).unwrap() = "c"; - /// assert_eq!(map.get(&1), Some(&"c")); - /// ``` pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Eq + Hash { self.map.get_mut(Qey::from_ref(k)).map(|e| &mut e.value) } @@ -272,21 +215,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { /// /// If value is found, it is moved to the end of the list. /// This operation can be used in implemenation of LRU cache. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// - /// map.insert(1, "a"); - /// map.insert(2, "b"); - /// map.insert(3, "d"); - /// - /// assert_eq!(map.get_refresh(&2), Some(&mut "b")); - /// - /// assert_eq!((&2, &"b"), map.iter().rev().next().unwrap()); - /// ``` pub fn get_refresh<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Eq + Hash { let (value, node_ptr_opt) = match self.map.get_mut(Qey::from_ref(k)) { None => (None, None), @@ -303,20 +231,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Removes and returns the value corresponding to the key from the map. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// - /// map.insert(2, "a"); - /// - /// assert_eq!(map.remove(&1), None); - /// assert_eq!(map.remove(&2), Some("a")); - /// assert_eq!(map.remove(&2), None); - /// assert_eq!(map.len(), 0); - /// ``` pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> where K: Borrow<Q>, Q: Eq + Hash { let removed = self.map.remove(Qey::from_ref(k)); removed.map(|mut node| { @@ -335,14 +249,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Returns the maximum number of key-value pairs the map can hold without reallocating. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map: LinkedHashMap<i32, &str> = LinkedHashMap::new(); - /// let capacity = map.capacity(); - /// ``` pub fn capacity(&self) -> usize { self.map.capacity() } @@ -350,18 +256,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { /// Removes the first entry. /// /// Can be used in implementation of LRU cache. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// map.insert(1, 10); - /// map.insert(2, 20); - /// map.pop_front(); - /// assert_eq!(map.get(&1), None); - /// assert_eq!(map.get(&2), Some(&20)); - /// ``` #[inline] pub fn pop_front(&mut self) -> Option<(K, V)> { if self.len() > 0 { @@ -375,16 +269,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Gets the first entry. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// map.insert(1, 10); - /// map.insert(2, 20); - /// assert_eq!(map.front(), Some((&1, &10))); - /// ``` #[inline] pub fn front(&self) -> Option<(&K, &V)> { if self.len() > 0 { @@ -396,18 +280,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Removes the last entry. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// map.insert(1, 10); - /// map.insert(2, 20); - /// map.pop_back(); - /// assert_eq!(map.get(&1), Some(&10)); - /// assert_eq!(map.get(&2), None); - /// ``` #[inline] pub fn pop_back(&mut self) -> Option<(K, V)> { if self.len() > 0 { @@ -421,16 +293,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Gets the last entry. - /// - /// # Examples - /// - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// let mut map = LinkedHashMap::new(); - /// map.insert(1, 10); - /// map.insert(2, 20); - /// assert_eq!(map.back(), Some((&2, &20))); - /// ``` #[inline] pub fn back(&mut self) -> Option<(&K, &V)> { if self.len() > 0 { @@ -461,22 +323,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { /// Returns a double-ended iterator visiting all key-value pairs in order of insertion. /// Iterator element type is `(&'a K, &'a V)` - /// - /// # Examples - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// - /// let mut map = LinkedHashMap::new(); - /// map.insert("a", 10); - /// map.insert("c", 30); - /// map.insert("b", 20); - /// - /// let mut iter = map.iter(); - /// assert_eq!((&"a", &10), iter.next().unwrap()); - /// assert_eq!((&"c", &30), iter.next().unwrap()); - /// assert_eq!((&"b", &20), iter.next().unwrap()); - /// assert_eq!(None, iter.next()); - /// ``` pub fn iter(&self) -> Iter<K, V> { let head = if ! self.head.is_null() { unsafe { (*self.head).prev } @@ -493,24 +339,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { /// Returns a double-ended iterator visiting all key-value pairs in order of insertion. /// Iterator element type is `(&'a K, &'a mut V)` - /// # Examples - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// - /// let mut map = LinkedHashMap::new(); - /// map.insert("a", 10); - /// map.insert("c", 30); - /// map.insert("b", 20); - /// - /// { - /// let mut iter = map.iter_mut(); - /// let mut entry = iter.next().unwrap(); - /// assert_eq!(&"a", entry.0); - /// *entry.1 = 17; - /// } - /// - /// assert_eq!(&17, map.get(&"a").unwrap()); - /// ``` pub fn iter_mut(&mut self) -> IterMut<K, V> { let head = if ! self.head.is_null() { unsafe { (*self.head).prev } @@ -526,22 +354,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Returns a double-ended iterator visiting all key in order of insertion. - /// - /// # Examples - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// - /// let mut map = LinkedHashMap::new(); - /// map.insert('a', 10); - /// map.insert('c', 30); - /// map.insert('b', 20); - /// - /// let mut keys = map.keys(); - /// assert_eq!(&'a', keys.next().unwrap()); - /// assert_eq!(&'c', keys.next().unwrap()); - /// assert_eq!(&'b', keys.next().unwrap()); - /// assert_eq!(None, keys.next()); - /// ``` pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { fn first<A, B>((a, _): (A, B)) -> A { a } let first: fn((&'a K, &'a V)) -> &'a K = first; // coerce to fn ptr @@ -550,22 +362,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> { } /// Returns a double-ended iterator visiting all values in order of insertion. - /// - /// # Examples - /// ``` - /// use linked_hash_map::LinkedHashMap; - /// - /// let mut map = LinkedHashMap::new(); - /// map.insert('a', 10); - /// map.insert('c', 30); - /// map.insert('b', 20); - /// - /// let mut values = map.values(); - /// assert_eq!(&10, values.next().unwrap()); - /// assert_eq!(&30, values.next().unwrap()); - /// assert_eq!(&20, values.next().unwrap()); - /// assert_eq!(None, values.next()); - /// ``` pub fn values<'a>(&'a self) -> Values<'a, K, V> { fn second<A, B>((_, b): (A, B)) -> B { b } let second: fn((&'a K, &'a V)) -> &'a V = second; // coerce to fn ptr diff --git a/src/disk/cache/lru_cache.rs b/src/disk/cache/lru_cache.rs index 6cdb28d..b5ea5e9 100644 --- a/src/disk/cache/lru_cache.rs +++ b/src/disk/cache/lru_cache.rs @@ -12,30 +12,6 @@ //! capacity of the cache is exceeded, the least-recently-used //! (where "used" means a look-up or putting the pair into the cache) //! pair is automatically removed. -//! -//! # Examples -//! -//! ``` -//! use lru_cache::LruCache; -//! -//! let mut cache = LruCache::new(2); -//! -//! cache.insert(1, 10); -//! cache.insert(2, 20); -//! cache.insert(3, 30); -//! assert!(cache.get_mut(&1).is_none()); -//! assert_eq!(*cache.get_mut(&2).unwrap(), 20); -//! assert_eq!(*cache.get_mut(&3).unwrap(), 30); -//! -//! cache.insert(2, 22); -//! assert_eq!(*cache.get_mut(&2).unwrap(), 22); -//! -//! cache.insert(6, 60); -//! assert!(cache.get_mut(&3).is_none()); -//! -//! cache.set_capacity(1); -//! assert!(cache.get_mut(&2).is_none()); -//! ``` use std::collections::hash_map::RandomState; use std::fmt; @@ -54,13 +30,6 @@ pub struct LruCache<K, V, S = RandomState> where K: Eq + Hash, S: BuildHasher { impl<K: Hash + Eq, V> LruCache<K, V> { /// Creates an empty cache that can hold at most `capacity` items. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// let mut cache: LruCache<i32, &str> = LruCache::new(10); - /// ``` pub fn new(capacity: usize) -> LruCache<K, V> { LruCache { map: LinkedHashMap::new(), @@ -76,17 +45,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher { } /// Checks if the map contains the given key. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(1); - /// - /// cache.insert(1, "a"); - /// assert_eq!(cache.contains_key(&1), true); - /// ``` pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool where K: Borrow<Q>, Q: Hash + Eq @@ -96,19 +54,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher { /// Inserts a key-value pair into the cache. If the key already existed, the old value is /// returned. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1, "a"); - /// cache.insert(2, "b"); - /// assert_eq!(cache.get_mut(&1), Some(&mut "a")); - /// assert_eq!(cache.get_mut(&2), Some(&mut "b")); - /// ``` pub fn insert(&mut self, k: K, v: V) -> Option<V> { let old_val = self.map.insert(k, v); if self.len() > self.capacity() { @@ -119,22 +64,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher { /// Returns a mutable reference to the value corresponding to the given key in the cache, if /// any. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1, "a"); - /// cache.insert(2, "b"); - /// cache.insert(2, "c"); - /// cache.insert(3, "d"); - /// - /// assert_eq!(cache.get_mut(&1), None); - /// assert_eq!(cache.get_mut(&2), Some(&mut "c")); - /// ``` pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Hash + Eq @@ -143,21 +72,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher { } /// Removes the given key from the cache and returns its corresponding value. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(2, "a"); - /// - /// assert_eq!(cache.remove(&1), None); - /// assert_eq!(cache.remove(&2), Some("a")); - /// assert_eq!(cache.remove(&2), None); - /// assert_eq!(cache.len(), 0); - /// ``` pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> where K: Borrow<Q>, Q: Hash + Eq @@ -166,50 +80,12 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher { } /// Returns the maximum number of key-value pairs the cache can hold. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// let mut cache: LruCache<i32, &str> = LruCache::new(2); - /// assert_eq!(cache.capacity(), 2); - /// ``` pub fn capacity(&self) -> usize { self.max_size } /// Sets the number of key-value pairs the cache can hold. Removes /// least-recently-used key-value pairs if necessary. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1, "a"); - /// cache.insert(2, "b"); - /// cache.insert(3, "c"); - /// - /// assert_eq!(cache.get_mut(&1), None); - /// assert_eq!(cache.get_mut(&2), Some(&mut "b")); - /// assert_eq!(cache.get_mut(&3), Some(&mut "c")); - /// - /// cache.set_capacity(3); - /// cache.insert(1, "a"); - /// cache.insert(2, "b"); - /// - /// assert_eq!(cache.get_mut(&1), Some(&mut "a")); - /// assert_eq!(cache.get_mut(&2), Some(&mut "b")); - /// assert_eq!(cache.get_mut(&3), Some(&mut "c")); - /// - /// cache.set_capacity(1); - /// - /// assert_eq!(cache.get_mut(&1), None); - /// assert_eq!(cache.get_mut(&2), None); - /// assert_eq!(cache.get_mut(&3), Some(&mut "c")); - /// ``` pub fn set_capacity(&mut self, capacity: usize) { for _ in capacity..self.len() { self.remove_lru(); @@ -234,52 +110,12 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher { /// Returns an iterator over the cache's key-value pairs in least- to most-recently-used order. /// /// Accessing the cache through the iterator does _not_ affect the cache's LRU state. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1, 10); - /// cache.insert(2, 20); - /// cache.insert(3, 30); - /// - /// let kvs: Vec<_> = cache.iter().collect(); - /// assert_eq!(kvs, [(&2, &20), (&3, &30)]); - /// ``` pub fn iter(&self) -> Iter<K, V> { Iter(self.map.iter()) } /// Returns an iterator over the cache's key-value pairs in least- to most-recently-used order, /// with mutable references to the values. /// /// Accessing the cache through the iterator does _not_ affect the cache's LRU state. - /// - /// # Examples - /// - /// ``` - /// use lru_cache::LruCache; - /// - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1, 10); - /// cache.insert(2, 20); - /// cache.insert(3, 30); - /// - /// let mut n = 2; - /// - /// for (k, v) in cache.iter_mut() { - /// assert_eq!(*k, n); - /// assert_eq!(*v, n * 10); - /// *v *= 10; - /// n += 1; - /// } - /// - /// assert_eq!(n, 4); - /// assert_eq!(cache.get_mut(&2), Some(&mut 200)); - /// assert_eq!(cache.get_mut(&3), Some(&mut 300)); - /// ``` pub fn iter_mut(&mut self) -> IterMut<K, V> { IterMut(self.map.iter_mut()) } } diff --git a/src/disk/cache/mod.rs b/src/disk/cache/mod.rs index a6e5ebe..d20e5ff 100644 --- a/src/disk/cache/mod.rs +++ b/src/disk/cache/mod.rs @@ -1,6 +1,7 @@ use std::{cmp, ptr}; use syscall::error::Result; +use BLOCK_SIZE; use disk::Disk; use self::lru_cache::LruCache; @@ -16,14 +17,14 @@ fn copy_memory(src: &[u8], dest: &mut [u8]) -> usize { pub struct DiskCache<T> { inner: T, - cache: LruCache<u64, [u8; 512]>, + cache: LruCache<u64, [u8; BLOCK_SIZE as usize]>, } impl<T: Disk> DiskCache<T> { pub fn new(inner: T) -> Self { DiskCache { inner: inner, - cache: LruCache::new(65536) // 32 MB cache + cache: LruCache::new((256 * 1024 * 1024 / BLOCK_SIZE) as usize) // 256 MB cache } } } @@ -34,11 +35,11 @@ impl<T: Disk> Disk for DiskCache<T> { let mut read = 0; let mut failed = false; - for i in 0..(buffer.len() + 511)/512 { + for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) { let block_i = block + i as u64; - let buffer_i = i * 512; - let buffer_j = cmp::min(buffer_i + 512, buffer.len()); + let buffer_i = i * BLOCK_SIZE as usize; + let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len()); let buffer_slice = &mut buffer[buffer_i .. buffer_j]; if let Some(cache_buf) = self.cache.get_mut(&block_i) { @@ -53,14 +54,14 @@ impl<T: Disk> Disk for DiskCache<T> { self.inner.read_at(block, buffer)?; read = 0; - for i in 0..(buffer.len() + 511)/512 { + for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) { let block_i = block + i as u64; - let buffer_i = i * 512; - let buffer_j = cmp::min(buffer_i + 512, buffer.len()); + let buffer_i = i * BLOCK_SIZE as usize; + let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len()); let buffer_slice = &buffer[buffer_i .. buffer_j]; - let mut cache_buf = [0; 512]; + let mut cache_buf = [0; BLOCK_SIZE as usize]; read += copy_memory(buffer_slice, &mut cache_buf); self.cache.insert(block_i, cache_buf); } @@ -75,14 +76,14 @@ impl<T: Disk> Disk for DiskCache<T> { self.inner.write_at(block, buffer)?; let mut written = 0; - for i in 0..(buffer.len() + 511)/512 { + for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) { let block_i = block + i as u64; - let buffer_i = i * 512; - let buffer_j = cmp::min(buffer_i + 512, buffer.len()); + let buffer_i = i * BLOCK_SIZE as usize; + let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len()); let buffer_slice = &buffer[buffer_i .. buffer_j]; - let mut cache_buf = [0; 512]; + let mut cache_buf = [0; BLOCK_SIZE as usize]; written += copy_memory(buffer_slice, &mut cache_buf); self.cache.insert(block_i, cache_buf); } diff --git a/src/disk/file.rs b/src/disk/file.rs index a74f64f..578194f 100644 --- a/src/disk/file.rs +++ b/src/disk/file.rs @@ -2,6 +2,7 @@ use std::fs::{File, OpenOptions}; use std::io::{Read, Write, Seek, SeekFrom}; use syscall::error::{Error, Result, EIO}; +use BLOCK_SIZE; use disk::Disk; macro_rules! try_disk { @@ -37,13 +38,13 @@ impl DiskFile { impl Disk for DiskFile { fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> { - try_disk!(self.file.seek(SeekFrom::Start(block * 512))); + try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE))); let count = try_disk!(self.file.read(buffer)); Ok(count) } fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> { - try_disk!(self.file.seek(SeekFrom::Start(block * 512))); + try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE))); let count = try_disk!(self.file.write(buffer)); Ok(count) } diff --git a/src/ex_node.rs b/src/ex_node.rs index ee745e5..0377ee3 100644 --- a/src/ex_node.rs +++ b/src/ex_node.rs @@ -1,13 +1,14 @@ use std::{fmt, mem, ops, slice}; -use super::Extent; +use BLOCK_SIZE; +use Extent; /// An extra node #[repr(packed)] pub struct ExNode { pub prev: u64, pub next: u64, - pub extents: [Extent; 31], + pub extents: [Extent; (BLOCK_SIZE as usize - 16)/16], } impl ExNode { @@ -15,7 +16,7 @@ impl ExNode { ExNode { prev: 0, next: 0, - extents: [Extent::default(); 31], + extents: [Extent::default(); (BLOCK_SIZE as usize - 16)/16], } } @@ -54,5 +55,5 @@ impl ops::DerefMut for ExNode { #[test] fn ex_node_size_test() { - assert_eq!(mem::size_of::<ExNode>(), 512); + assert_eq!(mem::size_of::<ExNode>(), BLOCK_SIZE as usize); } diff --git a/src/extent.rs b/src/extent.rs index ac4718e..773d7ac 100644 --- a/src/extent.rs +++ b/src/extent.rs @@ -1,5 +1,7 @@ use std::cmp::min; +use BLOCK_SIZE; + pub struct BlockIter { block: u64, length: u64, @@ -7,10 +9,10 @@ pub struct BlockIter { } impl Iterator<> for BlockIter { - type Item = (u64, usize); + type Item = (u64, u64); fn next(&mut self) -> Option<Self::Item> { - if self.i < (self.length + 511)/512 { - let ret = Some((self.block + self.i, min(512, self.length - self.i * 512) as usize)); + if self.i < (self.length + BLOCK_SIZE - 1)/BLOCK_SIZE { + let ret = Some((self.block + self.i, min(BLOCK_SIZE, self.length - self.i * BLOCK_SIZE))); self.i += 1; ret } else { diff --git a/src/filesystem.rs b/src/filesystem.rs index 51b0e53..406fed5 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -2,7 +2,7 @@ use std::cmp::min; use syscall::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY}; -use super::{Disk, ExNode, Extent, Header, Node}; +use {BLOCK_SIZE, Disk, ExNode, Extent, Header, Node}; /// A file system pub struct FileSystem<D: Disk> { @@ -45,11 +45,11 @@ impl<D: Disk> FileSystem<D> { /// Reserved data will be zero padded up to the nearest block pub fn create_reserved(mut disk: D, reserved: &[u8], ctime: u64, ctime_nsec: u32) -> Result<Self> { let size = disk.size()?; - let block_offset = (reserved.len() as u64 + 511)/512; + let block_offset = (reserved.len() as u64 + BLOCK_SIZE - 1)/BLOCK_SIZE; - if size >= (block_offset + 4) * 512 { + if size >= (block_offset + 4) * BLOCK_SIZE { let mut free = (2, Node::new(Node::MODE_FILE, "free", 0, ctime, ctime_nsec)); - free.1.extents[0] = Extent::new(4, size - (block_offset + 4) * 512); + free.1.extents[0] = Extent::new(4, size - (block_offset + 4) * BLOCK_SIZE); disk.write_at(block_offset + free.0, &free.1)?; let root = (1, Node::new(Node::MODE_DIR | 0o755, "root", 0, ctime, ctime_nsec)); @@ -59,11 +59,11 @@ impl<D: Disk> FileSystem<D> { disk.write_at(block_offset + header.0, &header.1)?; for block in 0..block_offset as usize { - let mut data = [0; 512]; + let mut data = [0; BLOCK_SIZE as usize]; let mut i = 0; - while i < data.len() && block * 512 + i < reserved.len() { - data[i] = reserved[block * 512 + i]; + while i < data.len() && block * BLOCK_SIZE as usize + i < reserved.len() { + data[i] = reserved[block * BLOCK_SIZE as usize + i]; i += 1; } @@ -94,9 +94,9 @@ impl<D: Disk> FileSystem<D> { let mut free = self.node(free_block)?; let mut block_option = None; for extent in free.1.extents.iter_mut() { - if extent.length/512 >= length { + if extent.length/BLOCK_SIZE >= length { block_option = Some(extent.block); - extent.length -= length * 512; + extent.length -= length * BLOCK_SIZE; extent.block += length; break; } @@ -134,7 +134,7 @@ impl<D: Disk> FileSystem<D> { let parent = self.node(parent_block)?; for extent in parent.1.extents.iter() { for (block, size) in extent.blocks() { - if size >= 512 { + if size >= BLOCK_SIZE { children.push(self.node(block)?); } } @@ -151,7 +151,7 @@ impl<D: Disk> FileSystem<D> { let parent = self.node(parent_block)?; for extent in parent.1.extents.iter() { for (block, size) in extent.blocks() { - if size >= 512 { + if size >= BLOCK_SIZE { let child = self.node(block)?; let mut matches = false; @@ -185,13 +185,13 @@ impl<D: Disk> FileSystem<D> { extent.block = block; extent.length = length; break; - } else if length % 512 == 0 && extent.block == block + length/512 { + } else if length % BLOCK_SIZE == 0 && extent.block == block + length/BLOCK_SIZE { //At beginning inserted = true; extent.block = block; extent.length += length; break; - } else if extent.length % 512 == 0 && extent.block + extent.length/512 == block { + } else if extent.length % BLOCK_SIZE == 0 && extent.block + extent.length/BLOCK_SIZE == block { //At end inserted = true; extent.length += length; @@ -225,7 +225,7 @@ impl<D: Disk> FileSystem<D> { let node = (self.allocate(1)?, Node::new(mode, name, parent_block, ctime, ctime_nsec)); self.write_at(node.0, &node.1)?; - self.insert_blocks(node.0, 512, parent_block)?; + self.insert_blocks(node.0, BLOCK_SIZE, parent_block)?; Ok(node) } @@ -240,12 +240,12 @@ impl<D: Disk> FileSystem<D> { let mut replace_option = None; let mut parent = self.node(parent_block)?; for extent in parent.1.extents.iter_mut() { - if block >= extent.block && block + length <= extent.block + extent.length/512 { + if block >= extent.block && block + length <= extent.block + extent.length/BLOCK_SIZE { //Inside removed = true; - let left = Extent::new(extent.block, (block - extent.block) * 512); - let right = Extent::new(block + length, ((extent.block + extent.length/512) - (block + length)) * 512); + let left = Extent::new(extent.block, (block - extent.block) * BLOCK_SIZE); + let right = Extent::new(block + length, ((extent.block + extent.length/BLOCK_SIZE) - (block + length)) * BLOCK_SIZE); if left.length > 0 { *extent = left; @@ -270,7 +270,7 @@ impl<D: Disk> FileSystem<D> { self.insert_blocks(replace.block, replace.length, parent_block)?; } - self.deallocate(block, 512)?; + self.deallocate(block, BLOCK_SIZE)?; Ok(()) } else { @@ -316,7 +316,7 @@ impl<D: Disk> FileSystem<D> { break; } else { changed = true; - let allocated = ((extent.length + 511)/512) * 512; + let allocated = ((extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE) * BLOCK_SIZE; if allocated >= length { extent.length = length; length = 0; @@ -336,7 +336,7 @@ impl<D: Disk> FileSystem<D> { if node.1.next > 0 { self.node_ensure_len(node.1.next, length) } else { - let new_block = self.allocate((length + 511)/512)?; + let new_block = self.allocate((length + BLOCK_SIZE - 1)/BLOCK_SIZE)?; self.insert_blocks(new_block, length, block)?; Ok(()) } @@ -356,10 +356,10 @@ impl<D: Disk> FileSystem<D> { let mut node = self.node(block)?; for extent in node.1.extents.iter_mut() { if extent.length > length { - let start = (length + 511)/512; - let end = (extent.length + 511)/512; + let start = (length + BLOCK_SIZE - 1)/BLOCK_SIZE; + let end = (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE; if end > start { - self.deallocate(extent.block + start, (end - start) * 512)?; + self.deallocate(extent.block + start, (end - start) * BLOCK_SIZE)?; } extent.length = length; changed = true; @@ -393,9 +393,9 @@ impl<D: Disk> FileSystem<D> { if push_extent.block == 0 { push_extent.block = block; } - if len >= size { - push_extent.length += size as u64; - len -= size; + if len as u64 >= size { + push_extent.length += size; + len -= size as usize; } else if len > 0 { push_extent.length += len as u64; len = 0; @@ -423,8 +423,8 @@ impl<D: Disk> FileSystem<D> { } pub fn read_node(&mut self, block: u64, offset: u64, buf: &mut [u8]) -> Result<usize> { - let block_offset = offset / 512; - let mut byte_offset = (offset % 512) as usize; + let block_offset = offset / BLOCK_SIZE; + let mut byte_offset = (offset % BLOCK_SIZE) as usize; let mut extents = Vec::new(); self.node_extents(block, block_offset, byte_offset + buf.len(), &mut extents)?; @@ -435,7 +435,7 @@ impl<D: Disk> FileSystem<D> { let mut length = extent.length; if byte_offset > 0 && length > 0 { - let mut sector = [0; 512]; + let mut sector = [0; BLOCK_SIZE as usize]; self.read_at(block, &mut sector)?; let sector_size = min(sector.len() as u64, length) as usize; @@ -450,18 +450,18 @@ impl<D: Disk> FileSystem<D> { byte_offset = 0; } - let length_aligned = ((min(length, (buf.len() - i) as u64)/512) * 512) as usize; + let length_aligned = ((min(length, (buf.len() - i) as u64)/BLOCK_SIZE) * BLOCK_SIZE) as usize; if length_aligned > 0 { let extent_buf = &mut buf[i..i + length_aligned]; self.read_at(block, extent_buf)?; i += length_aligned; - block += (length_aligned as u64)/512; + block += (length_aligned as u64)/BLOCK_SIZE; length -= length_aligned as u64; } if length > 0 { - let mut sector = [0; 512]; + let mut sector = [0; BLOCK_SIZE as usize]; self.read_at(block, &mut sector)?; let sector_size = min(sector.len() as u64, length) as usize; @@ -475,17 +475,17 @@ impl<D: Disk> FileSystem<D> { } assert_eq!(length, 0); - assert_eq!(block, extent.block + (extent.length + 511)/512); + assert_eq!(block, extent.block + (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE); } Ok(i) } pub fn write_node(&mut self, block: u64, offset: u64, buf: &[u8], mtime: u64, mtime_nsec: u32) -> Result<usize> { - let block_offset = offset / 512; - let mut byte_offset = (offset % 512) as usize; + let block_offset = offset / BLOCK_SIZE; + let mut byte_offset = (offset % BLOCK_SIZE) as usize; - self.node_ensure_len(block, block_offset as u64 * 512 + (byte_offset + buf.len()) as u64)?; + self.node_ensure_len(block, block_offset as u64 * BLOCK_SIZE + (byte_offset + buf.len()) as u64)?; let mut extents = Vec::new(); self.node_extents(block, block_offset, byte_offset + buf.len(), &mut extents)?; @@ -496,7 +496,7 @@ impl<D: Disk> FileSystem<D> { let mut length = extent.length; if byte_offset > 0 && length > 0 { - let mut sector = [0; 512]; + let mut sector = [0; BLOCK_SIZE as usize]; self.read_at(block, &mut sector)?; let sector_size = min(sector.len() as u64, length) as usize; @@ -513,18 +513,18 @@ impl<D: Disk> FileSystem<D> { byte_offset = 0; } - let length_aligned = ((min(length, (buf.len() - i) as u64)/512) * 512) as usize; + let length_aligned = ((min(length, (buf.len() - i) as u64)/BLOCK_SIZE) * BLOCK_SIZE) as usize; if length_aligned > 0 { let extent_buf = &buf[i..i + length_aligned]; self.write_at(block, extent_buf)?; i += length_aligned; - block += (length_aligned as u64)/512; + block += (length_aligned as u64)/BLOCK_SIZE; length -= length_aligned as u64; } if length > 0 { - let mut sector = [0; 512]; + let mut sector = [0; BLOCK_SIZE as usize]; self.read_at(block, &mut sector)?; let sector_size = min(sector.len() as u64, length) as usize; @@ -540,7 +540,7 @@ impl<D: Disk> FileSystem<D> { } assert_eq!(length, 0); - assert_eq!(block, extent.block + (extent.length + 511)/512); + assert_eq!(block, extent.block + (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE); } if i > 0 { diff --git a/src/header.rs b/src/header.rs index be7b7bb..7d978c5 100644 --- a/src/header.rs +++ b/src/header.rs @@ -3,6 +3,8 @@ use std::ops::{Deref, DerefMut}; use uuid::Uuid; +use BLOCK_SIZE; + /// The header of the filesystem #[repr(packed)] pub struct Header { @@ -12,14 +14,14 @@ pub struct Header { pub version: u64, /// Disk ID, a 128-bit unique identifier pub uuid: [u8; 16], - /// Disk size, in 512-byte sectors + /// Disk size, in number of BLOCK_SIZE sectors pub size: u64, /// Block of root node pub root: u64, /// Block of free space node pub free: u64, /// Padding - pub padding: [u8; 456] + pub padding: [u8; BLOCK_SIZE as usize - 56] } impl Header { @@ -34,7 +36,7 @@ impl Header { size: 0, root: 0, free: 0, - padding: [0; 456] + padding: [0; BLOCK_SIZE as usize - 56] } } @@ -47,7 +49,7 @@ impl Header { size: size, root: root, free: free, - padding: [0; 456] + padding: [0; BLOCK_SIZE as usize - 56] } } @@ -88,5 +90,5 @@ impl DerefMut for Header { #[test] fn header_size_test() { - assert_eq!(mem::size_of::<Header>(), 512); + assert_eq!(mem::size_of::<Header>(), BLOCK_SIZE as usize); } diff --git a/src/lib.rs b/src/lib.rs index 3cde771..47a0bb3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,8 @@ extern crate syscall; extern crate uuid; +pub const BLOCK_SIZE: u64 = 512; + pub use self::disk::{Disk, DiskCache, DiskFile}; pub use self::ex_node::ExNode; pub use self::extent::Extent; diff --git a/src/mount/fuse.rs b/src/mount/fuse.rs index b7bbac1..bdfab5b 100644 --- a/src/mount/fuse.rs +++ b/src/mount/fuse.rs @@ -7,6 +7,7 @@ use std::os::unix::ffi::OsStrExt; use std::path::Path; use std::time::{SystemTime, UNIX_EPOCH}; +use BLOCK_SIZE; use disk::Disk; use filesystem; use node::Node; @@ -36,7 +37,7 @@ fn node_attr(node: &(u64, Node)) -> FileAttr { FileAttr { ino: node.0, size: node.1.extents[0].length, - blocks: (node.1.extents[0].length + 511)/512, + blocks: (node.1.extents[0].length + BLOCK_SIZE - 1)/BLOCK_SIZE, atime: NULL_TIME, mtime: Timespec { sec: node.1.mtime as i64, @@ -297,7 +298,7 @@ impl<D: Disk> Filesystem for Fuse<D> { let free = self.fs.header.1.free; match self.fs.node_len(free) { Ok(free_size) => { - let bsize = 512; + let bsize = BLOCK_SIZE; let blocks = self.fs.header.1.size/bsize; let bfree = free_size/bsize; reply.statfs(blocks, bfree, bfree, 0, 0, bsize as u32, 256, 0); diff --git a/src/mount/redox/scheme.rs b/src/mount/redox/scheme.rs index 2607547..1f4bdb4 100644 --- a/src/mount/redox/scheme.rs +++ b/src/mount/redox/scheme.rs @@ -9,6 +9,7 @@ use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOE use syscall::flag::{O_APPEND, O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM, O_SYMLINK, O_NOFOLLOW}; use syscall::scheme::Scheme; +use BLOCK_SIZE; use disk::Disk; use filesystem::FileSystem; use node::Node; @@ -518,7 +519,7 @@ impl<D: Disk> Scheme for FileScheme<D> { let free = fs.header.1.free; let free_size = fs.node_len(free)?; - stat.f_bsize = 512; + stat.f_bsize = BLOCK_SIZE as u32; stat.f_blocks = fs.header.1.size/(stat.f_bsize as u64); stat.f_bfree = free_size/(stat.f_bsize as u64); stat.f_bavail = stat.f_bfree; diff --git a/src/node.rs b/src/node.rs index ce7cd1d..334344b 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,5 +1,6 @@ use std::{fmt, mem, ops, slice, str}; +use BLOCK_SIZE; use super::Extent; /// A file/folder node @@ -15,7 +16,7 @@ pub struct Node { pub name: [u8; 222], pub parent: u64, pub next: u64, - pub extents: [Extent; 15], + pub extents: [Extent; (BLOCK_SIZE as usize - 272)/16], } impl Node { @@ -41,7 +42,7 @@ impl Node { name: [0; 222], parent: 0, next: 0, - extents: [Extent::default(); 15], + extents: [Extent::default(); (BLOCK_SIZE as usize - 272)/16], } } @@ -62,7 +63,7 @@ impl Node { name: bytes, parent: parent, next: 0, - extents: [Extent::default(); 15], + extents: [Extent::default(); (BLOCK_SIZE as usize - 272)/16], } } @@ -147,5 +148,5 @@ impl ops::DerefMut for Node { #[test] fn node_size_test() { - assert_eq!(mem::size_of::<Node>(), 512); + assert_eq!(mem::size_of::<Node>(), BLOCK_SIZE as usize); } -- GitLab