documentation
This commit is contained in:
parent
1e537b063c
commit
8f7155dcff
29
src/error.rs
29
src/error.rs
|
@ -1,3 +1,4 @@
|
|||
//! Errors
|
||||
use {
|
||||
alloc::string::String,
|
||||
core::fmt::{self, Display},
|
||||
|
@ -9,39 +10,60 @@ use std::io;
|
|||
/// The set of all possible errors
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Generic error
|
||||
Other(String),
|
||||
/// Bad magic number
|
||||
BadMagic {
|
||||
/// The magic number
|
||||
magic: u16,
|
||||
},
|
||||
/// Out of bounds error
|
||||
OutOfBounds {
|
||||
/// index
|
||||
index: usize,
|
||||
},
|
||||
/// Address out of bounds
|
||||
AddressOutOfBounds {
|
||||
///
|
||||
sector: u32,
|
||||
///
|
||||
offset: u32,
|
||||
|
||||
///
|
||||
size: usize,
|
||||
},
|
||||
/// Bad block group count
|
||||
BadBlockGroupCount {
|
||||
///
|
||||
by_blocks: u32,
|
||||
///
|
||||
by_inodes: u32,
|
||||
},
|
||||
/// Inode Not Found
|
||||
InodeNotFound {
|
||||
/// inode number
|
||||
inode: u32,
|
||||
},
|
||||
/// Inode is not a directory
|
||||
NotADirectory {
|
||||
/// inode number
|
||||
inode: u32,
|
||||
/// inode name
|
||||
name: String,
|
||||
},
|
||||
/// Not Absolute Path
|
||||
NotAbsolute {
|
||||
/// path name
|
||||
name: String,
|
||||
},
|
||||
|
||||
/// Not Found
|
||||
NotFound {
|
||||
/// inode name
|
||||
name: String,
|
||||
},
|
||||
#[cfg(any(test, not(feature = "no_std")))]
|
||||
Io {
|
||||
inner: io::Error,
|
||||
},
|
||||
Io { inner: io::Error },
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
|
@ -98,4 +120,5 @@ impl From<io::Error> for Error {
|
|||
}
|
||||
}
|
||||
|
||||
/// Infalliable
|
||||
pub enum Infallible {}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//!
|
||||
|
||||
use {
|
||||
alloc::vec::Vec,
|
||||
core::mem,
|
||||
|
@ -34,6 +36,7 @@ pub struct Ext2<S: SectorSize, V: Volume<u8, S>> {
|
|||
}
|
||||
|
||||
impl<S: SectorSize, V: Volume<u8, S>> Ext2<S, V> {
|
||||
///
|
||||
pub fn new(volume: V) -> Result<Ext2<S, V>, Error> {
|
||||
let superblock = unsafe { Struct::from(Superblock::find(&volume)?) };
|
||||
let block_groups_offset = Address::with_block_size(
|
||||
|
@ -63,14 +66,14 @@ impl<S: SectorSize, V: Volume<u8, S>> Ext2<S, V> {
|
|||
block_groups,
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the version of the filesystem
|
||||
pub fn version(&self) -> (u32, u16) {
|
||||
(
|
||||
self.superblock.inner.rev_major,
|
||||
self.superblock.inner.rev_minor,
|
||||
)
|
||||
}
|
||||
|
||||
/// Return inode size
|
||||
pub fn inode_size(&self) -> usize {
|
||||
if self.version().0 == 0 {
|
||||
mem::size_of::<RawInode>()
|
||||
|
@ -79,15 +82,15 @@ impl<S: SectorSize, V: Volume<u8, S>> Ext2<S, V> {
|
|||
self.superblock.inner.inode_size as usize
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn inodes_count(&self) -> usize {
|
||||
self.superblock.inner.inodes_per_group as _
|
||||
}
|
||||
|
||||
///
|
||||
pub fn total_inodes_count(&self) -> usize {
|
||||
self.superblock.inner.inodes_count as _
|
||||
}
|
||||
|
||||
///
|
||||
pub fn block_group_count(&self) -> Result<usize, Error> {
|
||||
self.superblock
|
||||
.inner
|
||||
|
@ -98,27 +101,27 @@ impl<S: SectorSize, V: Volume<u8, S>> Ext2<S, V> {
|
|||
by_inodes: b,
|
||||
})
|
||||
}
|
||||
|
||||
///
|
||||
pub fn total_block_count(&self) -> usize {
|
||||
self.superblock.inner.blocks_count as _
|
||||
}
|
||||
|
||||
///
|
||||
pub fn free_block_count(&self) -> usize {
|
||||
self.superblock.inner.free_blocks_count as _
|
||||
}
|
||||
|
||||
///
|
||||
pub fn block_size(&self) -> usize {
|
||||
self.superblock.inner.block_size()
|
||||
}
|
||||
|
||||
///
|
||||
pub fn log_block_size(&self) -> u32 {
|
||||
self.superblock.inner.log_block_size + 10
|
||||
}
|
||||
|
||||
///
|
||||
pub fn sector_size(&self) -> usize {
|
||||
S::SIZE
|
||||
}
|
||||
|
||||
///
|
||||
pub fn log_sector_size(&self) -> u32 {
|
||||
S::LOG_SIZE
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//!
|
||||
|
||||
use {
|
||||
super::Ext2,
|
||||
alloc::{
|
||||
|
@ -16,18 +18,20 @@ use {
|
|||
sys::inode::Inode as RawInode,
|
||||
volume::Volume,
|
||||
};
|
||||
|
||||
/// DOCME: what is this?
|
||||
pub struct Synced<T> {
|
||||
inner: Arc<Mutex<T>>,
|
||||
}
|
||||
|
||||
impl<T> Synced<T> {
|
||||
/// DOCME: what is this?
|
||||
pub fn with_inner(inner: T) -> Synced<T> {
|
||||
Synced {
|
||||
inner: Arc::new(Mutex::new(inner)),
|
||||
}
|
||||
}
|
||||
|
||||
/// DOCME: what is this?
|
||||
pub fn inner<'a>(&'a self) -> MutexGuard<'a, T> {
|
||||
self.inner.lock()
|
||||
}
|
||||
|
@ -42,22 +46,23 @@ impl<T> Clone for Synced<T> {
|
|||
}
|
||||
|
||||
impl<S: SectorSize, V: Volume<u8, S>> Synced<Ext2<S, V>> {
|
||||
/// DOCME: what is this?
|
||||
pub fn new(volume: V) -> Result<Synced<Ext2<S, V>>, Error> {
|
||||
Ext2::new(volume).map(|inner| Synced::with_inner(inner))
|
||||
}
|
||||
|
||||
/// Get the root inode.
|
||||
pub fn root_inode(&self) -> Inode<S, V> {
|
||||
self.inode_nth(2).unwrap()
|
||||
}
|
||||
|
||||
/// Get the inode at the given index.
|
||||
pub fn inode_nth(&self, index: usize) -> Option<Inode<S, V>> {
|
||||
self.inodes_nth(index).next()
|
||||
}
|
||||
|
||||
/// DOCME: what is this?
|
||||
pub fn inodes(&self) -> Inodes<S, V> {
|
||||
self.inodes_nth(1)
|
||||
}
|
||||
|
||||
/// DOCME: what is this?
|
||||
pub fn inodes_nth(&self, index: usize) -> Inodes<S, V> {
|
||||
assert!(index > 0, "inodes are 1-indexed");
|
||||
let inner = self.inner();
|
||||
|
@ -70,11 +75,11 @@ impl<S: SectorSize, V: Volume<u8, S>> Synced<Ext2<S, V>> {
|
|||
index,
|
||||
}
|
||||
}
|
||||
|
||||
/// DOCME: what is this?
|
||||
pub fn sector_size(&self) -> usize {
|
||||
S::SIZE
|
||||
}
|
||||
|
||||
/// DOCME: what is this?
|
||||
pub fn log_sector_size(&self) -> u32 {
|
||||
S::LOG_SIZE
|
||||
}
|
||||
|
@ -256,6 +261,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Debug for Synced<Ext2<S, V>> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// A collection of inodes.
|
||||
pub struct Inodes<S: SectorSize, V: Volume<u8, S>> {
|
||||
fs: Synced<Ext2<S, V>>,
|
||||
log_block_size: u32,
|
||||
|
@ -302,6 +308,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for Inodes<S, V> {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// A single inode in an ext2 filesystem.
|
||||
pub struct Inode<S: SectorSize, V: Volume<u8, S>> {
|
||||
fs: Synced<Ext2<S, V>>,
|
||||
inner: RawInode,
|
||||
|
@ -321,6 +328,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Clone for Inode<S, V> {
|
|||
}
|
||||
|
||||
impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||
///
|
||||
pub fn new(
|
||||
fs: Synced<Ext2<S, V>>,
|
||||
inner: RawInode,
|
||||
|
@ -334,7 +342,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
|||
num,
|
||||
}
|
||||
}
|
||||
|
||||
/// Read to the end of a buffer.
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize, Error> {
|
||||
let total_size = self.size();
|
||||
let capacity = buf.capacity();
|
||||
|
@ -358,14 +366,14 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
|||
Err(err)
|
||||
})
|
||||
}
|
||||
|
||||
/// Return blocks on a sector
|
||||
pub fn blocks(&self) -> InodeBlocks<S, V> {
|
||||
InodeBlocks {
|
||||
inode: self.clone(),
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// return a directory iterator
|
||||
pub fn directory(&self) -> Option<Directory<S, V>> {
|
||||
if self.is_dir() {
|
||||
Some(Directory {
|
||||
|
@ -381,16 +389,16 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine if an inode is a directory
|
||||
pub fn is_dir(&self) -> bool {
|
||||
use sys::inode::TypePerm;
|
||||
unsafe { self.inner.type_perm.contains(TypePerm::DIRECTORY) }
|
||||
self.inner.type_perm.contains(TypePerm::DIRECTORY)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn block(&self, index: usize) -> Option<NonZeroU32> {
|
||||
self.try_block(index).ok().and_then(|block| block)
|
||||
}
|
||||
|
||||
/// Try to get a block
|
||||
pub fn try_block(
|
||||
&self,
|
||||
mut index: usize,
|
||||
|
@ -501,27 +509,27 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
|||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn in_use(&self) -> bool {
|
||||
self.inner.hard_links > 0
|
||||
}
|
||||
|
||||
/// return the uid
|
||||
pub fn uid(&self) -> u16 {
|
||||
self.inner.uid
|
||||
}
|
||||
|
||||
///
|
||||
pub fn sectors(&self) -> usize {
|
||||
self.inner.sectors_count as usize
|
||||
}
|
||||
|
||||
///
|
||||
pub fn size32(&self) -> u32 {
|
||||
self.inner.size_low
|
||||
}
|
||||
|
||||
///
|
||||
pub fn size64(&self) -> u64 {
|
||||
self.inner.size_low as u64 | (self.inner.size_high as u64) << 32
|
||||
}
|
||||
|
||||
///
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[inline]
|
||||
pub fn size(&self) -> usize {
|
||||
|
@ -576,6 +584,7 @@ impl<S: SectorSize, V: Volume<u8, S>> File for Inode<S, V> {
|
|||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InodeBlocks<S: SectorSize, V: Volume<u8, S>> {
|
||||
inode: Inode<S, V>,
|
||||
|
@ -611,6 +620,7 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for InodeBlocks<S, V> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// A directory structure
|
||||
pub struct Directory<S: SectorSize, V: Volume<u8, S>> {
|
||||
blocks: InodeBlocks<S, V>,
|
||||
offset: usize,
|
||||
|
@ -664,9 +674,13 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for Directory<S, V> {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
/// A directory entry
|
||||
pub struct DirectoryEntry {
|
||||
/// The name of the entry
|
||||
pub name: Vec<u8>,
|
||||
/// The inode of the entry
|
||||
pub inode: usize,
|
||||
///
|
||||
pub ty: u8,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
//! Ext2 crate for ableOS
|
||||
|
||||
#![deny(missing_docs)]
|
||||
#![feature(
|
||||
min_specialization,
|
||||
const_fn_trait_bound,
|
||||
|
@ -6,8 +9,8 @@
|
|||
)]
|
||||
#![cfg_attr(all(not(test), feature = "no_std"), no_std)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate genfs;
|
||||
|
|
|
@ -1,29 +1,35 @@
|
|||
//! Sector data.
|
||||
|
||||
use core::{
|
||||
fmt::{self, Debug, Display, LowerHex},
|
||||
iter::Step,
|
||||
marker::PhantomData,
|
||||
ops::{Add, Sub},
|
||||
};
|
||||
|
||||
/// Size of a sector in bytes
|
||||
pub trait SectorSize: Clone + Copy + PartialEq + PartialOrd + 'static {
|
||||
// log_sector_size = log_2(sector_size)
|
||||
/// DOCME: What is this?
|
||||
const LOG_SIZE: u32;
|
||||
/// DOCME: What is this?
|
||||
const SIZE: usize = 1 << Self::LOG_SIZE;
|
||||
/// DOCME: What is this?
|
||||
const OFFSET_MASK: u32 = (Self::SIZE - 1) as u32;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
/// DOCME: What is this?
|
||||
pub struct Size512;
|
||||
impl SectorSize for Size512 {
|
||||
const LOG_SIZE: u32 = 9;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
/// DOCME: What is this?
|
||||
pub struct Size1024;
|
||||
impl SectorSize for Size1024 {
|
||||
const LOG_SIZE: u32 = 10;
|
||||
}
|
||||
|
||||
/// DOCME: What is this?
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct Size2048;
|
||||
impl SectorSize for Size2048 {
|
||||
|
@ -31,13 +37,14 @@ impl SectorSize for Size2048 {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
/// DOCME: What is this?
|
||||
pub struct Size4096;
|
||||
impl SectorSize for Size4096 {
|
||||
const LOG_SIZE: u32 = 12;
|
||||
}
|
||||
|
||||
/// Address in a physical sector
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct Address<S: SectorSize> {
|
||||
sector: u32,
|
||||
offset: u32,
|
||||
|
@ -45,6 +52,7 @@ pub struct Address<S: SectorSize> {
|
|||
}
|
||||
|
||||
impl<S: SectorSize> Address<S> {
|
||||
///
|
||||
pub unsafe fn new_unchecked(sector: u32, offset: u32) -> Address<S> {
|
||||
assert!((offset as usize) < S::SIZE, "offset out of sector bounds");
|
||||
let _phantom = PhantomData;
|
||||
|
@ -54,13 +62,13 @@ impl<S: SectorSize> Address<S> {
|
|||
_phantom,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn new(sector: u32, offset: i32) -> Address<S> {
|
||||
let sector = (sector as i32 + (offset >> S::LOG_SIZE)) as u32;
|
||||
let offset = offset.abs() as u32 & S::OFFSET_MASK;
|
||||
unsafe { Address::new_unchecked(sector, offset) }
|
||||
}
|
||||
|
||||
///
|
||||
pub fn with_block_size(
|
||||
block: u32,
|
||||
offset: i32,
|
||||
|
@ -75,23 +83,23 @@ impl<S: SectorSize> Address<S> {
|
|||
let sector = block << log_diff | top_offset;
|
||||
unsafe { Address::new_unchecked(sector, offset) }
|
||||
}
|
||||
|
||||
///
|
||||
pub fn into_index(&self) -> u64 {
|
||||
((self.sector as u64) << S::LOG_SIZE) + self.offset as u64
|
||||
}
|
||||
|
||||
/// Get the size of the sector
|
||||
pub const fn sector_size(&self) -> usize {
|
||||
S::SIZE
|
||||
}
|
||||
|
||||
/// DOCME: What is this?
|
||||
pub const fn log_sector_size(&self) -> u32 {
|
||||
S::LOG_SIZE
|
||||
}
|
||||
|
||||
/// Return the sector number
|
||||
pub fn sector(&self) -> u32 {
|
||||
self.sector
|
||||
}
|
||||
|
||||
/// Return the offset in the sector
|
||||
pub fn offset(&self) -> u32 {
|
||||
self.offset
|
||||
}
|
||||
|
@ -105,6 +113,7 @@ impl<S: SectorSize> Step for Address<S> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn replace_one(&mut self) -> Self {
|
||||
mem::replace(self, Address::new(1, 0))
|
||||
|
@ -129,22 +138,12 @@ impl<S: SectorSize> Step for Address<S> {
|
|||
}
|
||||
*/
|
||||
|
||||
fn forward_checked(start: Self, count: usize) -> Option<Self> {
|
||||
todo!("forward_checked")
|
||||
fn forward_checked(_start: Self, count: usize) -> Option<Self> {
|
||||
todo!("forward_checked: count: {}", count);
|
||||
}
|
||||
|
||||
fn backward_checked(start: Self, count: usize) -> Option<Self> {
|
||||
todo!("backward_checked")
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: SectorSize> Debug for Address<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let name = format!("Address<{}>", S::SIZE);
|
||||
f.debug_struct(&name)
|
||||
.field("sector", &self.sector)
|
||||
.field("offset", &self.offset)
|
||||
.finish()
|
||||
fn backward_checked(_start: Self, count: usize) -> Option<Self> {
|
||||
todo!("backward_checked count: {}", count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
//!
|
||||
|
||||
use {
|
||||
alloc::vec::Vec,
|
||||
core::{
|
||||
fmt::{self, Debug},
|
||||
mem,
|
||||
},
|
||||
core::{fmt::Debug, mem},
|
||||
error::Error,
|
||||
sector::{Address, SectorSize},
|
||||
volume::Volume,
|
||||
|
@ -22,7 +21,7 @@ use {
|
|||
/// Remember that blocks are numbered starting at 0, and that block numbers
|
||||
/// don't usually correspond to physical block addresses.
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub struct BlockGroupDescriptor {
|
||||
/// Block address of block usage bitmap
|
||||
pub block_usage_addr: u32,
|
||||
|
@ -40,20 +39,8 @@ pub struct BlockGroupDescriptor {
|
|||
_reserved: [u8; 14],
|
||||
}
|
||||
|
||||
impl Debug for BlockGroupDescriptor {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("BlockGroupDescriptor")
|
||||
.field("block_usage_addr", &self.block_usage_addr)
|
||||
.field("inode_usage_addr", &self.inode_usage_addr)
|
||||
.field("inode_table_block", &self.inode_table_block)
|
||||
.field("free_blocks_count", &self.free_blocks_count)
|
||||
.field("free_inodes_count", &self.free_inodes_count)
|
||||
.field("dirs_count", &self.dirs_count)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockGroupDescriptor {
|
||||
/// Find a descriptor in a descriptor table
|
||||
pub unsafe fn find_descriptor<S: SectorSize, V: Volume<u8, S>>(
|
||||
haystack: &V,
|
||||
offset: Address<S>,
|
||||
|
@ -74,7 +61,7 @@ impl BlockGroupDescriptor {
|
|||
|
||||
Ok(descr)
|
||||
}
|
||||
|
||||
/// find a descriptor table
|
||||
pub unsafe fn find_descriptor_table<S: SectorSize, V: Volume<u8, S>>(
|
||||
haystack: &V,
|
||||
offset: Address<S>,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
//!
|
||||
|
||||
use {
|
||||
core::{
|
||||
fmt::{self, Debug},
|
||||
mem,
|
||||
},
|
||||
core::{fmt::Debug, mem},
|
||||
error::Error,
|
||||
sector::{Address, SectorSize},
|
||||
volume::Volume,
|
||||
|
@ -16,7 +15,7 @@ use {
|
|||
/// array of inodes it is responsible for, and conversely every inode within a
|
||||
/// file system belongs to one of such tables (and one of such block groups).
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub struct Inode {
|
||||
/// Type and Permissions (see below)
|
||||
pub type_perm: TypePerm,
|
||||
|
@ -71,35 +70,8 @@ pub struct Inode {
|
|||
pub _os_specific_2: [u8; 12],
|
||||
}
|
||||
|
||||
impl Debug for Inode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Inode")
|
||||
.field("type_perm", &self.type_perm)
|
||||
.field("uid", &self.uid)
|
||||
.field("size_low", &self.size_low)
|
||||
.field("atime", &self.atime)
|
||||
.field("ctime", &self.ctime)
|
||||
.field("mtime", &self.mtime)
|
||||
.field("dtime", &self.dtime)
|
||||
.field("gid", &self.gid)
|
||||
.field("hard_links", &self.hard_links)
|
||||
.field("sectors_count", &self.sectors_count)
|
||||
.field("flags", &self.flags)
|
||||
.field("os_specific_1", &self._os_specific_1)
|
||||
.field("direct_pointer", &self.direct_pointer)
|
||||
.field("indirect_pointer", &self.indirect_pointer)
|
||||
.field("doubly_indirect", &self.doubly_indirect)
|
||||
.field("triply_indirect", &self.triply_indirect)
|
||||
.field("gen_number", &self.gen_number)
|
||||
.field("ext_attribute_block", &self.ext_attribute_block)
|
||||
.field("size_high", &self.size_high)
|
||||
.field("frag_block_addr", &self.frag_block_addr)
|
||||
.field("os_specific_2", &self._os_specific_2)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Inode {
|
||||
/// Discover the inode location on the disk.
|
||||
pub unsafe fn find_inode<S: SectorSize, V: Volume<u8, S>>(
|
||||
haystack: &V,
|
||||
offset: Address<S>,
|
||||
|
@ -127,6 +99,7 @@ impl Inode {
|
|||
}
|
||||
|
||||
bitflags! {
|
||||
///
|
||||
pub struct TypePerm: u16 {
|
||||
/// FIFO
|
||||
const FIFO = 0x1000;
|
||||
|
@ -170,6 +143,7 @@ bitflags! {
|
|||
}
|
||||
|
||||
bitflags! {
|
||||
/// Flags
|
||||
pub struct Flags: u32 {
|
||||
/// Secure deletion (not used)
|
||||
const SECURE_DEL = 0x00000001;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
pub mod superblock;
|
||||
//!
|
||||
|
||||
pub mod block_group;
|
||||
pub mod inode;
|
||||
pub mod superblock;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
//! Superblock information
|
||||
|
||||
use {
|
||||
core::{
|
||||
fmt::{self, Debug},
|
||||
mem,
|
||||
},
|
||||
core::{fmt::Debug, mem},
|
||||
error::Error,
|
||||
sector::{Address, SectorSize},
|
||||
volume::Volume,
|
||||
|
@ -44,7 +43,7 @@ pub const OS_LITE: u32 = 4;
|
|||
/// 512 byte sectors, the Superblock will begin at LBA 2 and will occupy all of
|
||||
/// sector 2 and 3.
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub struct Superblock {
|
||||
// taken from https://wiki.osdev.org/Ext2
|
||||
/// Total number of inodes in file system
|
||||
|
@ -148,7 +147,7 @@ pub struct Superblock {
|
|||
#[doc(hidden)]
|
||||
_reserved: [u8; 788],
|
||||
}
|
||||
|
||||
/*
|
||||
impl Debug for Superblock {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Superblock")
|
||||
|
@ -196,8 +195,9 @@ impl Debug for Superblock {
|
|||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
impl Superblock {
|
||||
/// Discover the location of the superblock in the given block device.
|
||||
pub unsafe fn find<S: SectorSize, V: Volume<u8, S>>(
|
||||
haystack: &V,
|
||||
) -> Result<(Superblock, Address<S>), Error> {
|
||||
|
@ -227,15 +227,17 @@ impl Superblock {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
/// Return the block size
|
||||
pub fn block_size(&self) -> usize {
|
||||
1024 << self.log_block_size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Return the fragment size
|
||||
pub fn frag_size(&self) -> usize {
|
||||
1024 << self.log_frag_size
|
||||
}
|
||||
|
||||
/// Return the number of blocks per group
|
||||
pub fn block_group_count(&self) -> Result<u32, (u32, u32)> {
|
||||
let blocks_mod = self.blocks_count % self.blocks_per_group;
|
||||
let inodes_mod = self.inodes_count % self.inodes_per_group;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(missing_docs)]
|
||||
use {
|
||||
alloc::{
|
||||
borrow::{Cow, ToOwned},
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//!
|
||||
|
||||
use {
|
||||
core::{
|
||||
cmp::Ordering,
|
||||
|
@ -7,19 +9,28 @@ use {
|
|||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash)]
|
||||
/// A size
|
||||
pub enum Size<S: SectorSize> {
|
||||
/// An unbounded size
|
||||
Unbounded,
|
||||
/// A bounded size
|
||||
Bounded(Address<S>),
|
||||
}
|
||||
|
||||
impl<S: SectorSize> Size<S> {
|
||||
/// Try to get the length of the sector
|
||||
pub fn try_len(&self) -> Option<Address<S>> {
|
||||
match *self {
|
||||
Size::Unbounded => None,
|
||||
Size::Bounded(n) => Some(n),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the length of the sector unsafely
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is unsafe because it does not check that the size is
|
||||
/// bounded.
|
||||
pub unsafe fn len(&self) -> Address<S> {
|
||||
match *self {
|
||||
Size::Unbounded => panic!(
|
||||
|
@ -31,6 +42,7 @@ impl<S: SectorSize> Size<S> {
|
|||
}
|
||||
|
||||
impl<S: SectorSize> Size<S> {
|
||||
/// Check if the size is unbounded
|
||||
pub fn is_bounded(&self) -> bool {
|
||||
match *self {
|
||||
Size::Unbounded => false,
|
||||
|
|
Reference in a new issue