From 1e537b063cee2f9df615282a47db661ac65e7f37 Mon Sep 17 00:00:00 2001 From: Able Date: Mon, 7 Feb 2022 22:18:39 -0600 Subject: [PATCH] ported to modern rust --- Cargo.toml | 8 ++-- src/error.rs | 6 ++- src/fs/mod.rs | 27 +++++++------ src/fs/sync.rs | 70 ++++++++++++++++++--------------- src/lib.rs | 22 +++++------ src/sector.rs | 26 +++++++++---- src/sys/block_group.rs | 32 ++++++++-------- src/sys/inode.rs | 53 +++++++++++++------------ src/sys/superblock.rs | 87 ++++++++++++++++++++++-------------------- src/volume/mod.rs | 40 ++++++++++--------- src/volume/size.rs | 11 ++++-- 11 files changed, 210 insertions(+), 172 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 190a96d..f72ff11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,14 @@ [package] name = "ext2" -version = "0.1.0" -authors = ["Szymon Walter "] +version = "0.1.1" +authors = ["Szymon Walter ", +"able "] + [dependencies] bitflags = "1.0" rlibc = { version = "1.0", optional = true } -spin = "0.4" +spin = "0.9.2" genfs = "^0.1.4" [features] diff --git a/src/error.rs b/src/error.rs index 161b39d..5092a26 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,7 @@ -use core::fmt::{self, Display}; -use alloc::String; +use { + alloc::string::String, + core::fmt::{self, Display}, +}; #[cfg(any(test, not(feature = "no_std")))] use std::io; diff --git a/src/fs/mod.rs b/src/fs/mod.rs index 8feccfa..7634f5c 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -1,16 +1,18 @@ -use core::mem; - -use alloc::Vec; - -use error::Error; -use sector::{Address, SectorSize}; -use volume::Volume; -use sys::superblock::Superblock; -use sys::block_group::BlockGroupDescriptor; -use sys::inode::Inode as RawInode; +use { + alloc::vec::Vec, + core::mem, + error::Error, + sector::{Address, SectorSize}, + sys::{ + block_group::BlockGroupDescriptor, inode::Inode as RawInode, + superblock::Superblock, + }, + volume::Volume, +}; pub mod sync; +#[allow(dead_code)] pub(crate) struct Struct { pub inner: T, pub offset: Address, @@ -124,8 +126,8 @@ impl> Ext2 { #[cfg(test)] mod tests { - use std::fs::File; use std::cell::RefCell; + use std::fs::File; use sector::{Address, Size512}; use volume::Volume; @@ -145,7 +147,8 @@ mod tests { file.slice_unchecked( Address::::from(1024_u64) ..Address::::from(2048_u64), - ).len() + ) + .len() }, 1024 ); diff --git a/src/fs/sync.rs b/src/fs/sync.rs index 9a864d5..ebcbf7a 100644 --- a/src/fs/sync.rs +++ b/src/fs/sync.rs @@ -1,19 +1,21 @@ -use core::fmt::{self, Debug}; -use core::nonzero::NonZero; -use core::iter::Iterator; - -use alloc::{String, Vec}; -use alloc::arc::Arc; - -use spin::{Mutex, MutexGuard}; -use genfs::*; - -use error::Error; -use sector::{Address, SectorSize}; -use volume::Volume; -use sys::inode::Inode as RawInode; - -use super::Ext2; +use { + super::Ext2, + alloc::{ + sync::Arc, + {string::String, vec::Vec}, + }, + core::{ + fmt::{self, Debug}, + iter::Iterator, + num::NonZeroU32, + }, + error::Error, + genfs::*, + sector::{Address, SectorSize}, + spin::{Mutex, MutexGuard}, + sys::inode::Inode as RawInode, + volume::Volume, +}; pub struct Synced { inner: Arc>, @@ -115,13 +117,16 @@ impl> Fs for Synced> { name: String::from_utf8_lossy(abs_path).into_owned(), })?; - let entry = dir.find(|entry| { - entry.is_err() || entry.as_ref().unwrap().name == name - }).ok_or_else(|| Error::NotFound { - name: String::from_utf8_lossy(abs_path).into_owned(), - })??; + let entry = dir + .find(|entry| { + entry.is_err() || entry.as_ref().unwrap().name == name + }) + .ok_or_else(|| Error::NotFound { + 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 })?; inner(fs, inode, path, abs_path) @@ -345,7 +350,8 @@ impl> Inode { buf.set_len(size); } Ok(size) - }).or_else(|err| { + }) + .or_else(|err| { unsafe { buf.set_len(0); } @@ -381,14 +387,14 @@ impl> Inode { unsafe { self.inner.type_perm.contains(TypePerm::DIRECTORY) } } - pub fn block(&self, index: usize) -> Option> { + pub fn block(&self, index: usize) -> Option { self.try_block(index).ok().and_then(|block| block) } pub fn try_block( &self, mut index: usize, - ) -> Result>, Error> { + ) -> Result, Error> { // number of blocks in direct table: 12 // number of blocks in indirect table: block_size/4 // why? @@ -408,7 +414,7 @@ impl> Inode { block: u32, index: usize, log_block_size: u32, - ) -> Result>, Error> { + ) -> Result, Error> { let offset = (index * 4) as i32; let end = offset + 4; let addr = Address::with_block_size(block, offset, log_block_size); @@ -416,7 +422,7 @@ impl> Inode { let block = volume.slice(addr..end); match block { Ok(block) => unsafe { - Ok(NonZero::new(block.dynamic_cast::().0)) + Ok(NonZeroU32::new(block.dynamic_cast::().0)) }, Err(err) => Err(err.into()), } @@ -428,7 +434,7 @@ impl> Inode { let log_block_size = fs.log_block_size(); if index < 12 { - return Ok(NonZero::new(self.inner.direct_pointer[index])); + return Ok(NonZeroU32::new(self.inner.direct_pointer[index])); } index -= 12; @@ -595,7 +601,8 @@ impl> Iterator for InodeBlocks { let offset = Address::with_block_size(block, 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) .map(|slice| (slice.to_vec(), offset)) .map_err(|err| err.into()); @@ -632,7 +639,8 @@ impl> Iterator for Directory { 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[3] as u32) << 24; if inode == 0 { @@ -688,8 +696,8 @@ impl DirEntry for DirectoryEntry { #[cfg(test)] mod tests { - use std::fs::File; use std::cell::RefCell; + use std::fs::File; use genfs::{File as GenFile, Fs, OpenOptions}; diff --git a/src/lib.rs b/src/lib.rs index 2b6f35c..e38f5fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,9 @@ -#![feature(alloc)] -#![feature(specialization)] -#![feature(swap_with_slice)] -#![feature(macro_lifetime_matcher)] -#![feature(const_fn)] -#![feature(step_trait)] -#![feature(nonzero)] -#![feature(associated_type_defaults)] +#![feature( + min_specialization, + const_fn_trait_bound, + step_trait, + associated_type_defaults +)] #![cfg_attr(all(not(test), feature = "no_std"), no_std)] #[macro_use] @@ -19,16 +17,16 @@ extern crate spin; extern crate core; pub mod error; -pub mod sys; -pub mod sector; -pub mod volume; pub mod fs; +pub mod sector; +pub mod sys; +pub mod volume; #[cfg(test)] mod tests { - use sys::superblock::*; use sys::block_group::*; use sys::inode::*; + use sys::superblock::*; #[test] fn sizes() { diff --git a/src/sector.rs b/src/sector.rs index ee59227..ba29779 100644 --- a/src/sector.rs +++ b/src/sector.rs @@ -1,8 +1,9 @@ -use core::mem; -use core::marker::PhantomData; -use core::ops::{Add, Sub}; -use core::fmt::{self, Debug, Display, LowerHex}; -use core::iter::Step; +use core::{ + fmt::{self, Debug, Display, LowerHex}, + iter::Step, + marker::PhantomData, + ops::{Add, Sub}, +}; pub trait SectorSize: Clone + Copy + PartialEq + PartialOrd + 'static { // log_sector_size = log_2(sector_size) @@ -104,7 +105,7 @@ impl Step for Address { None } } - + /* fn replace_one(&mut self) -> Self { mem::replace(self, Address::new(1, 0)) } @@ -123,8 +124,17 @@ impl Step for Address { fn add_usize(&self, n: usize) -> Option { self.sector - .checked_add(n as u32) - .map(|sector| Address::new(sector, 0)) + .checked_add(n as u32) + .map(|sector| Address::new(sector, 0)) + } + */ + + fn forward_checked(start: Self, count: usize) -> Option { + todo!("forward_checked") + } + + fn backward_checked(start: Self, count: usize) -> Option { + todo!("backward_checked") } } diff --git a/src/sys/block_group.rs b/src/sys/block_group.rs index cb669a5..8c4d4b9 100644 --- a/src/sys/block_group.rs +++ b/src/sys/block_group.rs @@ -1,11 +1,13 @@ -use core::mem; -use core::fmt::{self, Debug}; - -use alloc::Vec; - -use error::Error; -use sector::{Address, SectorSize}; -use volume::Volume; +use { + alloc::vec::Vec, + core::{ + fmt::{self, Debug}, + mem, + }, + error::Error, + sector::{Address, SectorSize}, + volume::Volume, +}; /// 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, @@ -41,12 +43,12 @@ pub struct BlockGroupDescriptor { impl Debug for BlockGroupDescriptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("BlockGroupDescriptor") - .field("block_usage_addr", unsafe { &self.block_usage_addr }) - .field("inode_usage_addr", unsafe { &self.inode_usage_addr }) - .field("inode_table_block", unsafe { &self.inode_table_block }) - .field("free_blocks_count", unsafe { &self.free_blocks_count }) - .field("free_inodes_count", unsafe { &self.free_inodes_count }) - .field("dirs_count", unsafe { &self.dirs_count }) + .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() } } @@ -103,8 +105,8 @@ impl BlockGroupDescriptor { #[cfg(test)] mod tests { - use sector::{Address, Size512}; use super::*; + use sector::{Address, Size512}; #[test] fn find() { diff --git a/src/sys/inode.rs b/src/sys/inode.rs index 40b9288..44e7025 100644 --- a/src/sys/inode.rs +++ b/src/sys/inode.rs @@ -1,9 +1,12 @@ -use core::mem; -use core::fmt::{self, Debug}; - -use error::Error; -use sector::{Address, SectorSize}; -use volume::Volume; +use { + core::{ + fmt::{self, Debug}, + mem, + }, + error::Error, + sector::{Address, SectorSize}, + volume::Volume, +}; /// 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 / @@ -71,26 +74,26 @@ pub struct Inode { impl Debug for Inode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Inode") - .field("type_perm", unsafe { &self.type_perm }) - .field("uid", unsafe { &self.uid }) - .field("size_low", unsafe { &self.size_low }) - .field("atime", unsafe { &self.atime }) - .field("ctime", unsafe { &self.ctime }) - .field("mtime", unsafe { &self.mtime }) - .field("dtime", unsafe { &self.dtime }) - .field("gid", unsafe { &self.gid }) - .field("hard_links", unsafe { &self.hard_links }) - .field("sectors_count", unsafe { &self.sectors_count }) - .field("flags", unsafe { &self.flags }) + .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", unsafe { &self.direct_pointer }) - .field("indirect_pointer", unsafe { &self.indirect_pointer }) - .field("doubly_indirect", unsafe { &self.doubly_indirect }) - .field("triply_indirect", unsafe { &self.triply_indirect }) - .field("gen_number", unsafe { &self.gen_number }) - .field("ext_attribute_block", unsafe { &self.ext_attribute_block }) - .field("size_high", unsafe { &self.size_high }) - .field("frag_block_addr", unsafe { &self.frag_block_addr }) + .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() } diff --git a/src/sys/superblock.rs b/src/sys/superblock.rs index c81a776..8e04519 100644 --- a/src/sys/superblock.rs +++ b/src/sys/superblock.rs @@ -1,9 +1,12 @@ -use core::mem; -use core::fmt::{self, Debug}; - -use error::Error; -use sector::{Address, SectorSize}; -use volume::Volume; +use { + core::{ + fmt::{self, Debug}, + mem, + }, + error::Error, + sector::{Address, SectorSize}, + volume::Volume, +}; /// Ext2 signature (0xef53), used to help confirm the presence of Ext2 on a /// volume @@ -149,47 +152,47 @@ pub struct Superblock { impl Debug for Superblock { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Superblock") - .field("inodes_count", unsafe { &self.inodes_count }) - .field("blocks_count", unsafe { &self.blocks_count }) - .field("r_blocks_count", unsafe { &self.r_blocks_count }) - .field("free_blocks_count", unsafe { &self.free_blocks_count }) - .field("free_inodes_count", unsafe { &self.free_inodes_count }) - .field("first_data_block", unsafe { &self.first_data_block }) - .field("log_block_size", unsafe { &self.log_block_size }) - .field("log_frag_size", unsafe { &self.log_frag_size }) - .field("blocks_per_group", unsafe { &self.blocks_per_group }) - .field("frags_per_group", unsafe { &self.frags_per_group }) - .field("inodes_per_group", unsafe { &self.inodes_per_group }) - .field("mtime", unsafe { &self.mtime }) - .field("wtime", unsafe { &self.wtime }) - .field("mnt_count", unsafe { &self.mnt_count }) - .field("max_mnt_count", unsafe { &self.max_mnt_count }) - .field("magic", unsafe { &self.magic }) - .field("state", unsafe { &self.state }) - .field("errors", unsafe { &self.errors }) - .field("rev_minor", unsafe { &self.rev_minor }) - .field("lastcheck", unsafe { &self.lastcheck }) - .field("checkinterval", unsafe { &self.checkinterval }) - .field("creator_os", unsafe { &self.creator_os }) - .field("rev_major", unsafe { &self.rev_major }) - .field("block_uid", unsafe { &self.block_uid }) - .field("block_gid", unsafe { &self.block_gid }) - .field("first_inode", unsafe { &self.first_inode }) - .field("inode_size", unsafe { &self.inode_size }) - .field("block_group", unsafe { &self.block_group }) - .field("features_opt", unsafe { &self.features_opt }) - .field("features_req", unsafe { &self.features_req }) - .field("features_ronly", unsafe { &self.features_ronly }) + .field("inodes_count", &self.inodes_count) + .field("blocks_count", &self.blocks_count) + .field("r_blocks_count", &self.r_blocks_count) + .field("free_blocks_count", &self.free_blocks_count) + .field("free_inodes_count", &self.free_inodes_count) + .field("first_data_block", &self.first_data_block) + .field("log_block_size", &self.log_block_size) + .field("log_frag_size", &self.log_frag_size) + .field("blocks_per_group", &self.blocks_per_group) + .field("frags_per_group", &self.frags_per_group) + .field("inodes_per_group", &self.inodes_per_group) + .field("mtime", &self.mtime) + .field("wtime", &self.wtime) + .field("mnt_count", &self.mnt_count) + .field("max_mnt_count", &self.max_mnt_count) + .field("magic", &self.magic) + .field("state", &self.state) + .field("errors", &self.errors) + .field("rev_minor", &self.rev_minor) + .field("lastcheck", &self.lastcheck) + .field("checkinterval", &self.checkinterval) + .field("creator_os", &self.creator_os) + .field("rev_major", &self.rev_major) + .field("block_uid", &self.block_uid) + .field("block_gid", &self.block_gid) + .field("first_inode", &self.first_inode) + .field("inode_size", &self.inode_size) + .field("block_group", &self.block_group) + .field("features_opt", &self.features_opt) + .field("features_req", &self.features_req) + .field("features_ronly", &self.features_ronly) .field("fs_id", &self.fs_id) .field("volume_name", &self.volume_name) .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_dirs", &self.prealloc_blocks_dirs) .field("journal_id", &self.journal_id) - .field("journal_inode", unsafe { &self.journal_inode }) - .field("journal_dev", unsafe { &self.journal_dev }) - .field("journal_orphan_head", unsafe { &self.journal_orphan_head }) + .field("journal_inode", &self.journal_inode) + .field("journal_dev", &self.journal_dev) + .field("journal_orphan_head", &self.journal_orphan_head) .finish() } } @@ -295,8 +298,8 @@ bitflags! { #[cfg(test)] mod tests { - use sector::Size512; use super::*; + use sector::Size512; #[test] fn find() { diff --git a/src/volume/mod.rs b/src/volume/mod.rs index f1b08e3..e8fc605 100644 --- a/src/volume/mod.rs +++ b/src/volume/mod.rs @@ -1,13 +1,17 @@ -use core::mem; -use core::slice; -use core::ops::{Deref, DerefMut, Range}; - -use alloc::Vec; -use alloc::boxed::Box; -use alloc::borrow::{Cow, ToOwned}; - -use error::Error; -use sector::{Address, SectorSize}; +use { + alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + vec::Vec, + }, + core::{ + mem, + ops::{Deref, DerefMut, Range}, + slice, + }, + error::Error, + sector::{Address, SectorSize}, +}; pub mod size; use self::size::Size; @@ -257,15 +261,15 @@ impl_slice!(Box<[T]>); #[cfg(any(test, not(feature = "no_std")))] mod file { - use std::ops::Range; - use std::io::{self, Read, Seek, SeekFrom, Write}; - use std::fs::File; 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 super::{Volume, VolumeCommit, VolumeSlice}; use super::size::Size; + use super::{Volume, VolumeCommit, VolumeSlice}; impl Volume for RefCell { type Error = io::Error; @@ -318,9 +322,9 @@ mod file { range: Range>, ) -> Result, Self::Error> { let index = range.start; - let mut vec = Vec::with_capacity((range.end - range.start) - .into_index() - as usize); + let mut vec = Vec::with_capacity( + (range.end - range.start).into_index() as usize, + ); unsafe { vec.set_len((range.end - range.start).into_index() as usize); } @@ -335,8 +339,8 @@ mod file { #[cfg(test)] mod tests { - use sector::{Address, Size512}; use super::*; + use sector::{Address, Size512}; #[test] fn volume() { diff --git a/src/volume/size.rs b/src/volume/size.rs index 3c6b4d0..61da531 100644 --- a/src/volume/size.rs +++ b/src/volume/size.rs @@ -1,7 +1,10 @@ -use core::fmt::{self, Display}; -use core::cmp::Ordering; - -use sector::{Address, SectorSize}; +use { + core::{ + cmp::Ordering, + fmt::{self, Display}, + }, + sector::{Address, SectorSize}, +}; #[derive(Clone, Copy, Debug, Hash)] pub enum Size {