ported to modern rust
This commit is contained in:
parent
abcf7c5c84
commit
1e537b063c
|
@ -1,12 +1,14 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ext2"
|
name = "ext2"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
authors = ["Szymon Walter <walter.szymon.98@gmail.com>"]
|
authors = ["Szymon Walter <walter.szymon.98@gmail.com>",
|
||||||
|
"able <abl3theabove@gmail.com>"]
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
rlibc = { version = "1.0", optional = true }
|
rlibc = { version = "1.0", optional = true }
|
||||||
spin = "0.4"
|
spin = "0.9.2"
|
||||||
genfs = "^0.1.4"
|
genfs = "^0.1.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use core::fmt::{self, Display};
|
use {
|
||||||
use alloc::String;
|
alloc::string::String,
|
||||||
|
core::fmt::{self, Display},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(any(test, not(feature = "no_std")))]
|
#[cfg(any(test, not(feature = "no_std")))]
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
use core::mem;
|
use {
|
||||||
|
alloc::vec::Vec,
|
||||||
use alloc::Vec;
|
core::mem,
|
||||||
|
error::Error,
|
||||||
use error::Error;
|
sector::{Address, SectorSize},
|
||||||
use sector::{Address, SectorSize};
|
sys::{
|
||||||
use volume::Volume;
|
block_group::BlockGroupDescriptor, inode::Inode as RawInode,
|
||||||
use sys::superblock::Superblock;
|
superblock::Superblock,
|
||||||
use sys::block_group::BlockGroupDescriptor;
|
},
|
||||||
use sys::inode::Inode as RawInode;
|
volume::Volume,
|
||||||
|
};
|
||||||
|
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) struct Struct<T, S: SectorSize> {
|
pub(crate) struct Struct<T, S: SectorSize> {
|
||||||
pub inner: T,
|
pub inner: T,
|
||||||
pub offset: Address<S>,
|
pub offset: Address<S>,
|
||||||
|
@ -124,8 +126,8 @@ impl<S: SectorSize, V: Volume<u8, S>> Ext2<S, V> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::fs::File;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
use sector::{Address, Size512};
|
use sector::{Address, Size512};
|
||||||
use volume::Volume;
|
use volume::Volume;
|
||||||
|
@ -145,7 +147,8 @@ mod tests {
|
||||||
file.slice_unchecked(
|
file.slice_unchecked(
|
||||||
Address::<Size512>::from(1024_u64)
|
Address::<Size512>::from(1024_u64)
|
||||||
..Address::<Size512>::from(2048_u64),
|
..Address::<Size512>::from(2048_u64),
|
||||||
).len()
|
)
|
||||||
|
.len()
|
||||||
},
|
},
|
||||||
1024
|
1024
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
use core::fmt::{self, Debug};
|
use {
|
||||||
use core::nonzero::NonZero;
|
super::Ext2,
|
||||||
use core::iter::Iterator;
|
alloc::{
|
||||||
|
sync::Arc,
|
||||||
use alloc::{String, Vec};
|
{string::String, vec::Vec},
|
||||||
use alloc::arc::Arc;
|
},
|
||||||
|
core::{
|
||||||
use spin::{Mutex, MutexGuard};
|
fmt::{self, Debug},
|
||||||
use genfs::*;
|
iter::Iterator,
|
||||||
|
num::NonZeroU32,
|
||||||
use error::Error;
|
},
|
||||||
use sector::{Address, SectorSize};
|
error::Error,
|
||||||
use volume::Volume;
|
genfs::*,
|
||||||
use sys::inode::Inode as RawInode;
|
sector::{Address, SectorSize},
|
||||||
|
spin::{Mutex, MutexGuard},
|
||||||
use super::Ext2;
|
sys::inode::Inode as RawInode,
|
||||||
|
volume::Volume,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Synced<T> {
|
pub struct Synced<T> {
|
||||||
inner: Arc<Mutex<T>>,
|
inner: Arc<Mutex<T>>,
|
||||||
|
@ -115,13 +117,16 @@ impl<S: SectorSize, V: Volume<u8, S>> Fs for Synced<Ext2<S, V>> {
|
||||||
name: String::from_utf8_lossy(abs_path).into_owned(),
|
name: String::from_utf8_lossy(abs_path).into_owned(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let entry = dir.find(|entry| {
|
let entry = dir
|
||||||
|
.find(|entry| {
|
||||||
entry.is_err() || entry.as_ref().unwrap().name == name
|
entry.is_err() || entry.as_ref().unwrap().name == name
|
||||||
}).ok_or_else(|| Error::NotFound {
|
})
|
||||||
|
.ok_or_else(|| Error::NotFound {
|
||||||
name: String::from_utf8_lossy(abs_path).into_owned(),
|
name: String::from_utf8_lossy(abs_path).into_owned(),
|
||||||
})??;
|
})??;
|
||||||
|
|
||||||
let inode = fs.inode_nth(entry.inode)
|
let inode = fs
|
||||||
|
.inode_nth(entry.inode)
|
||||||
.ok_or(Error::InodeNotFound { inode: inode.num })?;
|
.ok_or(Error::InodeNotFound { inode: inode.num })?;
|
||||||
|
|
||||||
inner(fs, inode, path, abs_path)
|
inner(fs, inode, path, abs_path)
|
||||||
|
@ -345,7 +350,8 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
buf.set_len(size);
|
buf.set_len(size);
|
||||||
}
|
}
|
||||||
Ok(size)
|
Ok(size)
|
||||||
}).or_else(|err| {
|
})
|
||||||
|
.or_else(|err| {
|
||||||
unsafe {
|
unsafe {
|
||||||
buf.set_len(0);
|
buf.set_len(0);
|
||||||
}
|
}
|
||||||
|
@ -381,14 +387,14 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
unsafe { self.inner.type_perm.contains(TypePerm::DIRECTORY) }
|
unsafe { self.inner.type_perm.contains(TypePerm::DIRECTORY) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block(&self, index: usize) -> Option<NonZero<u32>> {
|
pub fn block(&self, index: usize) -> Option<NonZeroU32> {
|
||||||
self.try_block(index).ok().and_then(|block| block)
|
self.try_block(index).ok().and_then(|block| block)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_block(
|
pub fn try_block(
|
||||||
&self,
|
&self,
|
||||||
mut index: usize,
|
mut index: usize,
|
||||||
) -> Result<Option<NonZero<u32>>, Error> {
|
) -> Result<Option<NonZeroU32>, Error> {
|
||||||
// number of blocks in direct table: 12
|
// number of blocks in direct table: 12
|
||||||
// number of blocks in indirect table: block_size/4
|
// number of blocks in indirect table: block_size/4
|
||||||
// why?
|
// why?
|
||||||
|
@ -408,7 +414,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
block: u32,
|
block: u32,
|
||||||
index: usize,
|
index: usize,
|
||||||
log_block_size: u32,
|
log_block_size: u32,
|
||||||
) -> Result<Option<NonZero<u32>>, Error> {
|
) -> Result<Option<NonZeroU32>, Error> {
|
||||||
let offset = (index * 4) as i32;
|
let offset = (index * 4) as i32;
|
||||||
let end = offset + 4;
|
let end = offset + 4;
|
||||||
let addr = Address::with_block_size(block, offset, log_block_size);
|
let addr = Address::with_block_size(block, offset, log_block_size);
|
||||||
|
@ -416,7 +422,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
let block = volume.slice(addr..end);
|
let block = volume.slice(addr..end);
|
||||||
match block {
|
match block {
|
||||||
Ok(block) => unsafe {
|
Ok(block) => unsafe {
|
||||||
Ok(NonZero::new(block.dynamic_cast::<u32>().0))
|
Ok(NonZeroU32::new(block.dynamic_cast::<u32>().0))
|
||||||
},
|
},
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(err.into()),
|
||||||
}
|
}
|
||||||
|
@ -428,7 +434,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
let log_block_size = fs.log_block_size();
|
let log_block_size = fs.log_block_size();
|
||||||
|
|
||||||
if index < 12 {
|
if index < 12 {
|
||||||
return Ok(NonZero::new(self.inner.direct_pointer[index]));
|
return Ok(NonZeroU32::new(self.inner.direct_pointer[index]));
|
||||||
}
|
}
|
||||||
|
|
||||||
index -= 12;
|
index -= 12;
|
||||||
|
@ -595,7 +601,8 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for InodeBlocks<S, V> {
|
||||||
let offset = Address::with_block_size(block, 0, log_block_size);
|
let offset = Address::with_block_size(block, 0, log_block_size);
|
||||||
let end = Address::with_block_size(block + 1, 0, log_block_size);
|
let end = Address::with_block_size(block + 1, 0, log_block_size);
|
||||||
|
|
||||||
let slice = fs.volume
|
let slice = fs
|
||||||
|
.volume
|
||||||
.slice(offset..end)
|
.slice(offset..end)
|
||||||
.map(|slice| (slice.to_vec(), offset))
|
.map(|slice| (slice.to_vec(), offset))
|
||||||
.map_err(|err| err.into());
|
.map_err(|err| err.into());
|
||||||
|
@ -632,7 +639,8 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for Directory<S, V> {
|
||||||
|
|
||||||
let buffer = &self.buffer.as_ref().unwrap()[self.offset..];
|
let buffer = &self.buffer.as_ref().unwrap()[self.offset..];
|
||||||
|
|
||||||
let inode = buffer[0] as u32 | (buffer[1] as u32) << 8
|
let inode = buffer[0] as u32
|
||||||
|
| (buffer[1] as u32) << 8
|
||||||
| (buffer[2] as u32) << 16
|
| (buffer[2] as u32) << 16
|
||||||
| (buffer[3] as u32) << 24;
|
| (buffer[3] as u32) << 24;
|
||||||
if inode == 0 {
|
if inode == 0 {
|
||||||
|
@ -688,8 +696,8 @@ impl DirEntry for DirectoryEntry {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::fs::File;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
use genfs::{File as GenFile, Fs, OpenOptions};
|
use genfs::{File as GenFile, Fs, OpenOptions};
|
||||||
|
|
||||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -1,11 +1,9 @@
|
||||||
#![feature(alloc)]
|
#![feature(
|
||||||
#![feature(specialization)]
|
min_specialization,
|
||||||
#![feature(swap_with_slice)]
|
const_fn_trait_bound,
|
||||||
#![feature(macro_lifetime_matcher)]
|
step_trait,
|
||||||
#![feature(const_fn)]
|
associated_type_defaults
|
||||||
#![feature(step_trait)]
|
)]
|
||||||
#![feature(nonzero)]
|
|
||||||
#![feature(associated_type_defaults)]
|
|
||||||
#![cfg_attr(all(not(test), feature = "no_std"), no_std)]
|
#![cfg_attr(all(not(test), feature = "no_std"), no_std)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -19,16 +17,16 @@ extern crate spin;
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod sys;
|
|
||||||
pub mod sector;
|
|
||||||
pub mod volume;
|
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
pub mod sector;
|
||||||
|
pub mod sys;
|
||||||
|
pub mod volume;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use sys::superblock::*;
|
|
||||||
use sys::block_group::*;
|
use sys::block_group::*;
|
||||||
use sys::inode::*;
|
use sys::inode::*;
|
||||||
|
use sys::superblock::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sizes() {
|
fn sizes() {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use core::mem;
|
use core::{
|
||||||
use core::marker::PhantomData;
|
fmt::{self, Debug, Display, LowerHex},
|
||||||
use core::ops::{Add, Sub};
|
iter::Step,
|
||||||
use core::fmt::{self, Debug, Display, LowerHex};
|
marker::PhantomData,
|
||||||
use core::iter::Step;
|
ops::{Add, Sub},
|
||||||
|
};
|
||||||
|
|
||||||
pub trait SectorSize: Clone + Copy + PartialEq + PartialOrd + 'static {
|
pub trait SectorSize: Clone + Copy + PartialEq + PartialOrd + 'static {
|
||||||
// log_sector_size = log_2(sector_size)
|
// log_sector_size = log_2(sector_size)
|
||||||
|
@ -104,7 +105,7 @@ impl<S: SectorSize> Step for Address<S> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
fn replace_one(&mut self) -> Self {
|
fn replace_one(&mut self) -> Self {
|
||||||
mem::replace(self, Address::new(1, 0))
|
mem::replace(self, Address::new(1, 0))
|
||||||
}
|
}
|
||||||
|
@ -126,6 +127,15 @@ impl<S: SectorSize> Step for Address<S> {
|
||||||
.checked_add(n as u32)
|
.checked_add(n as u32)
|
||||||
.map(|sector| Address::new(sector, 0))
|
.map(|sector| Address::new(sector, 0))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fn forward_checked(start: Self, count: usize) -> Option<Self> {
|
||||||
|
todo!("forward_checked")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn backward_checked(start: Self, count: usize) -> Option<Self> {
|
||||||
|
todo!("backward_checked")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SectorSize> Debug for Address<S> {
|
impl<S: SectorSize> Debug for Address<S> {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use core::mem;
|
use {
|
||||||
use core::fmt::{self, Debug};
|
alloc::vec::Vec,
|
||||||
|
core::{
|
||||||
use alloc::Vec;
|
fmt::{self, Debug},
|
||||||
|
mem,
|
||||||
use error::Error;
|
},
|
||||||
use sector::{Address, SectorSize};
|
error::Error,
|
||||||
use volume::Volume;
|
sector::{Address, SectorSize},
|
||||||
|
volume::Volume,
|
||||||
|
};
|
||||||
|
|
||||||
/// The Block Group Descriptor Table contains a descriptor for each block group
|
/// The Block Group Descriptor Table contains a descriptor for each block group
|
||||||
/// within the file system. The number of block groups within the file system,
|
/// within the file system. The number of block groups within the file system,
|
||||||
|
@ -41,12 +43,12 @@ pub struct BlockGroupDescriptor {
|
||||||
impl Debug for BlockGroupDescriptor {
|
impl Debug for BlockGroupDescriptor {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("BlockGroupDescriptor")
|
f.debug_struct("BlockGroupDescriptor")
|
||||||
.field("block_usage_addr", unsafe { &self.block_usage_addr })
|
.field("block_usage_addr", &self.block_usage_addr)
|
||||||
.field("inode_usage_addr", unsafe { &self.inode_usage_addr })
|
.field("inode_usage_addr", &self.inode_usage_addr)
|
||||||
.field("inode_table_block", unsafe { &self.inode_table_block })
|
.field("inode_table_block", &self.inode_table_block)
|
||||||
.field("free_blocks_count", unsafe { &self.free_blocks_count })
|
.field("free_blocks_count", &self.free_blocks_count)
|
||||||
.field("free_inodes_count", unsafe { &self.free_inodes_count })
|
.field("free_inodes_count", &self.free_inodes_count)
|
||||||
.field("dirs_count", unsafe { &self.dirs_count })
|
.field("dirs_count", &self.dirs_count)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,8 +105,8 @@ impl BlockGroupDescriptor {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use sector::{Address, Size512};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use sector::{Address, Size512};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find() {
|
fn find() {
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use core::mem;
|
use {
|
||||||
use core::fmt::{self, Debug};
|
core::{
|
||||||
|
fmt::{self, Debug},
|
||||||
use error::Error;
|
mem,
|
||||||
use sector::{Address, SectorSize};
|
},
|
||||||
use volume::Volume;
|
error::Error,
|
||||||
|
sector::{Address, SectorSize},
|
||||||
|
volume::Volume,
|
||||||
|
};
|
||||||
|
|
||||||
/// An inode is a structure on the disk that represents a file, directory,
|
/// An inode is a structure on the disk that represents a file, directory,
|
||||||
/// symbolic link, etc. Inodes do not contain the data of the file / directory /
|
/// symbolic link, etc. Inodes do not contain the data of the file / directory /
|
||||||
|
@ -71,26 +74,26 @@ pub struct Inode {
|
||||||
impl Debug for Inode {
|
impl Debug for Inode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("Inode")
|
f.debug_struct("Inode")
|
||||||
.field("type_perm", unsafe { &self.type_perm })
|
.field("type_perm", &self.type_perm)
|
||||||
.field("uid", unsafe { &self.uid })
|
.field("uid", &self.uid)
|
||||||
.field("size_low", unsafe { &self.size_low })
|
.field("size_low", &self.size_low)
|
||||||
.field("atime", unsafe { &self.atime })
|
.field("atime", &self.atime)
|
||||||
.field("ctime", unsafe { &self.ctime })
|
.field("ctime", &self.ctime)
|
||||||
.field("mtime", unsafe { &self.mtime })
|
.field("mtime", &self.mtime)
|
||||||
.field("dtime", unsafe { &self.dtime })
|
.field("dtime", &self.dtime)
|
||||||
.field("gid", unsafe { &self.gid })
|
.field("gid", &self.gid)
|
||||||
.field("hard_links", unsafe { &self.hard_links })
|
.field("hard_links", &self.hard_links)
|
||||||
.field("sectors_count", unsafe { &self.sectors_count })
|
.field("sectors_count", &self.sectors_count)
|
||||||
.field("flags", unsafe { &self.flags })
|
.field("flags", &self.flags)
|
||||||
.field("os_specific_1", &self._os_specific_1)
|
.field("os_specific_1", &self._os_specific_1)
|
||||||
.field("direct_pointer", unsafe { &self.direct_pointer })
|
.field("direct_pointer", &self.direct_pointer)
|
||||||
.field("indirect_pointer", unsafe { &self.indirect_pointer })
|
.field("indirect_pointer", &self.indirect_pointer)
|
||||||
.field("doubly_indirect", unsafe { &self.doubly_indirect })
|
.field("doubly_indirect", &self.doubly_indirect)
|
||||||
.field("triply_indirect", unsafe { &self.triply_indirect })
|
.field("triply_indirect", &self.triply_indirect)
|
||||||
.field("gen_number", unsafe { &self.gen_number })
|
.field("gen_number", &self.gen_number)
|
||||||
.field("ext_attribute_block", unsafe { &self.ext_attribute_block })
|
.field("ext_attribute_block", &self.ext_attribute_block)
|
||||||
.field("size_high", unsafe { &self.size_high })
|
.field("size_high", &self.size_high)
|
||||||
.field("frag_block_addr", unsafe { &self.frag_block_addr })
|
.field("frag_block_addr", &self.frag_block_addr)
|
||||||
.field("os_specific_2", &self._os_specific_2)
|
.field("os_specific_2", &self._os_specific_2)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use core::mem;
|
use {
|
||||||
use core::fmt::{self, Debug};
|
core::{
|
||||||
|
fmt::{self, Debug},
|
||||||
use error::Error;
|
mem,
|
||||||
use sector::{Address, SectorSize};
|
},
|
||||||
use volume::Volume;
|
error::Error,
|
||||||
|
sector::{Address, SectorSize},
|
||||||
|
volume::Volume,
|
||||||
|
};
|
||||||
|
|
||||||
/// Ext2 signature (0xef53), used to help confirm the presence of Ext2 on a
|
/// Ext2 signature (0xef53), used to help confirm the presence of Ext2 on a
|
||||||
/// volume
|
/// volume
|
||||||
|
@ -149,47 +152,47 @@ pub struct Superblock {
|
||||||
impl Debug for Superblock {
|
impl Debug for Superblock {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("Superblock")
|
f.debug_struct("Superblock")
|
||||||
.field("inodes_count", unsafe { &self.inodes_count })
|
.field("inodes_count", &self.inodes_count)
|
||||||
.field("blocks_count", unsafe { &self.blocks_count })
|
.field("blocks_count", &self.blocks_count)
|
||||||
.field("r_blocks_count", unsafe { &self.r_blocks_count })
|
.field("r_blocks_count", &self.r_blocks_count)
|
||||||
.field("free_blocks_count", unsafe { &self.free_blocks_count })
|
.field("free_blocks_count", &self.free_blocks_count)
|
||||||
.field("free_inodes_count", unsafe { &self.free_inodes_count })
|
.field("free_inodes_count", &self.free_inodes_count)
|
||||||
.field("first_data_block", unsafe { &self.first_data_block })
|
.field("first_data_block", &self.first_data_block)
|
||||||
.field("log_block_size", unsafe { &self.log_block_size })
|
.field("log_block_size", &self.log_block_size)
|
||||||
.field("log_frag_size", unsafe { &self.log_frag_size })
|
.field("log_frag_size", &self.log_frag_size)
|
||||||
.field("blocks_per_group", unsafe { &self.blocks_per_group })
|
.field("blocks_per_group", &self.blocks_per_group)
|
||||||
.field("frags_per_group", unsafe { &self.frags_per_group })
|
.field("frags_per_group", &self.frags_per_group)
|
||||||
.field("inodes_per_group", unsafe { &self.inodes_per_group })
|
.field("inodes_per_group", &self.inodes_per_group)
|
||||||
.field("mtime", unsafe { &self.mtime })
|
.field("mtime", &self.mtime)
|
||||||
.field("wtime", unsafe { &self.wtime })
|
.field("wtime", &self.wtime)
|
||||||
.field("mnt_count", unsafe { &self.mnt_count })
|
.field("mnt_count", &self.mnt_count)
|
||||||
.field("max_mnt_count", unsafe { &self.max_mnt_count })
|
.field("max_mnt_count", &self.max_mnt_count)
|
||||||
.field("magic", unsafe { &self.magic })
|
.field("magic", &self.magic)
|
||||||
.field("state", unsafe { &self.state })
|
.field("state", &self.state)
|
||||||
.field("errors", unsafe { &self.errors })
|
.field("errors", &self.errors)
|
||||||
.field("rev_minor", unsafe { &self.rev_minor })
|
.field("rev_minor", &self.rev_minor)
|
||||||
.field("lastcheck", unsafe { &self.lastcheck })
|
.field("lastcheck", &self.lastcheck)
|
||||||
.field("checkinterval", unsafe { &self.checkinterval })
|
.field("checkinterval", &self.checkinterval)
|
||||||
.field("creator_os", unsafe { &self.creator_os })
|
.field("creator_os", &self.creator_os)
|
||||||
.field("rev_major", unsafe { &self.rev_major })
|
.field("rev_major", &self.rev_major)
|
||||||
.field("block_uid", unsafe { &self.block_uid })
|
.field("block_uid", &self.block_uid)
|
||||||
.field("block_gid", unsafe { &self.block_gid })
|
.field("block_gid", &self.block_gid)
|
||||||
.field("first_inode", unsafe { &self.first_inode })
|
.field("first_inode", &self.first_inode)
|
||||||
.field("inode_size", unsafe { &self.inode_size })
|
.field("inode_size", &self.inode_size)
|
||||||
.field("block_group", unsafe { &self.block_group })
|
.field("block_group", &self.block_group)
|
||||||
.field("features_opt", unsafe { &self.features_opt })
|
.field("features_opt", &self.features_opt)
|
||||||
.field("features_req", unsafe { &self.features_req })
|
.field("features_req", &self.features_req)
|
||||||
.field("features_ronly", unsafe { &self.features_ronly })
|
.field("features_ronly", &self.features_ronly)
|
||||||
.field("fs_id", &self.fs_id)
|
.field("fs_id", &self.fs_id)
|
||||||
.field("volume_name", &self.volume_name)
|
.field("volume_name", &self.volume_name)
|
||||||
.field("last_mnt_path", &self.last_mnt_path.as_ref())
|
.field("last_mnt_path", &self.last_mnt_path.as_ref())
|
||||||
.field("compression", unsafe { &self.compression })
|
.field("compression", &self.compression)
|
||||||
.field("prealloc_blocks_files", &self.prealloc_blocks_files)
|
.field("prealloc_blocks_files", &self.prealloc_blocks_files)
|
||||||
.field("prealloc_blocks_dirs", &self.prealloc_blocks_dirs)
|
.field("prealloc_blocks_dirs", &self.prealloc_blocks_dirs)
|
||||||
.field("journal_id", &self.journal_id)
|
.field("journal_id", &self.journal_id)
|
||||||
.field("journal_inode", unsafe { &self.journal_inode })
|
.field("journal_inode", &self.journal_inode)
|
||||||
.field("journal_dev", unsafe { &self.journal_dev })
|
.field("journal_dev", &self.journal_dev)
|
||||||
.field("journal_orphan_head", unsafe { &self.journal_orphan_head })
|
.field("journal_orphan_head", &self.journal_orphan_head)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,8 +298,8 @@ bitflags! {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use sector::Size512;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use sector::Size512;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find() {
|
fn find() {
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
use core::mem;
|
use {
|
||||||
use core::slice;
|
alloc::{
|
||||||
use core::ops::{Deref, DerefMut, Range};
|
borrow::{Cow, ToOwned},
|
||||||
|
boxed::Box,
|
||||||
use alloc::Vec;
|
vec::Vec,
|
||||||
use alloc::boxed::Box;
|
},
|
||||||
use alloc::borrow::{Cow, ToOwned};
|
core::{
|
||||||
|
mem,
|
||||||
use error::Error;
|
ops::{Deref, DerefMut, Range},
|
||||||
use sector::{Address, SectorSize};
|
slice,
|
||||||
|
},
|
||||||
|
error::Error,
|
||||||
|
sector::{Address, SectorSize},
|
||||||
|
};
|
||||||
|
|
||||||
pub mod size;
|
pub mod size;
|
||||||
use self::size::Size;
|
use self::size::Size;
|
||||||
|
@ -257,15 +261,15 @@ impl_slice!(Box<[T]>);
|
||||||
|
|
||||||
#[cfg(any(test, not(feature = "no_std")))]
|
#[cfg(any(test, not(feature = "no_std")))]
|
||||||
mod file {
|
mod file {
|
||||||
use std::ops::Range;
|
|
||||||
use std::io::{self, Read, Seek, SeekFrom, Write};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{self, Read, Seek, SeekFrom, Write};
|
||||||
|
use std::ops::Range;
|
||||||
|
|
||||||
use sector::{Address, SectorSize};
|
use sector::{Address, SectorSize};
|
||||||
|
|
||||||
use super::{Volume, VolumeCommit, VolumeSlice};
|
|
||||||
use super::size::Size;
|
use super::size::Size;
|
||||||
|
use super::{Volume, VolumeCommit, VolumeSlice};
|
||||||
|
|
||||||
impl<S: SectorSize> Volume<u8, S> for RefCell<File> {
|
impl<S: SectorSize> Volume<u8, S> for RefCell<File> {
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
@ -318,9 +322,9 @@ mod file {
|
||||||
range: Range<Address<S>>,
|
range: Range<Address<S>>,
|
||||||
) -> Result<VolumeSlice<'a, u8, S>, Self::Error> {
|
) -> Result<VolumeSlice<'a, u8, S>, Self::Error> {
|
||||||
let index = range.start;
|
let index = range.start;
|
||||||
let mut vec = Vec::with_capacity((range.end - range.start)
|
let mut vec = Vec::with_capacity(
|
||||||
.into_index()
|
(range.end - range.start).into_index() as usize,
|
||||||
as usize);
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
vec.set_len((range.end - range.start).into_index() as usize);
|
vec.set_len((range.end - range.start).into_index() as usize);
|
||||||
}
|
}
|
||||||
|
@ -335,8 +339,8 @@ mod file {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use sector::{Address, Size512};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use sector::{Address, Size512};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn volume() {
|
fn volume() {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use core::fmt::{self, Display};
|
use {
|
||||||
use core::cmp::Ordering;
|
core::{
|
||||||
|
cmp::Ordering,
|
||||||
use sector::{Address, SectorSize};
|
fmt::{self, Display},
|
||||||
|
},
|
||||||
|
sector::{Address, SectorSize},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash)]
|
#[derive(Clone, Copy, Debug, Hash)]
|
||||||
pub enum Size<S: SectorSize> {
|
pub enum Size<S: SectorSize> {
|
||||||
|
|
Reference in a new issue