Add initial support for ext2

master
Jiajie Chen 6 years ago
parent 41ccb1675c
commit 17aea0d930

@ -3,6 +3,7 @@ members = [
"rcore-fs",
"rcore-fs-sfs",
"rcore-fs-sefs",
"rcore-fs-fuse"
"rcore-fs-fuse",
"rcore-fs-ext2"
]
exclude = ["sefs-fuse"]
exclude = ["sefs-fuse"]

@ -0,0 +1 @@
test.img

@ -0,0 +1,9 @@
[package]
name = "rcore-fs-ext2"
version = "0.1.0"
authors = ["Jiajie Chen <noc@jiegec.ac.cn>"]
edition = "2018"
[dependencies]
ext2 = { git = "https://github.com/rcore-os/ext2-rs" }
rcore-fs = { path = "../rcore-fs" }

Binary file not shown.

@ -0,0 +1,91 @@
#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![feature(alloc)]
extern crate alloc;
extern crate ext2;
#[cfg(test)]
mod tests;
use alloc::sync::Arc;
use ext2::fs::sync::Synced;
use ext2::fs::Ext2;
use ext2::error::Error;
use ext2::sector::{Size512, Address};
use ext2::volume::size::Size;
use ext2::volume::{Volume, VolumeCommit, VolumeSlice};
use core::ops::Range;
use rcore_fs::dev::Device;
use rcore_fs::vfs;
#[derive(Clone)]
struct Ext2Volume {
inner: Arc<Device>,
}
#[derive(Clone)]
pub struct Ext2FileSystem {
inner: Synced<Ext2<Size512, Ext2Volume>>,
volume: Ext2Volume,
}
/// A conversion between vfs::FsError and ext2::Error
#[derive(Debug)]
struct Ext2Error {
inner: Error
}
impl core::convert::From<Ext2Error> for vfs::FsError {
fn from(err: Ext2Error) -> Self {
match err.inner {
_ => vfs::FsError::DeviceError
}
}
}
impl core::convert::From<Error> for Ext2Error {
fn from(err: Error) -> Self {
Ext2Error {
inner: err
}
}
}
impl Ext2FileSystem {
pub fn open(device: Arc<Device>) -> vfs::Result<Arc<Self>> {
Ok(Self::open_internal(device)?)
}
fn open_internal(device: Arc<Device>) -> Result<Arc<Self>, Ext2Error> {
let volume = Ext2Volume {
inner: device
};
let fs = Synced::new(volume.clone())?;
Ok(Arc::new(Ext2FileSystem {
inner: fs,
volume,
}))
}
}
impl Volume<u8, Size512> for Ext2Volume {
type Error = Error;
fn size(&self) -> Size<Size512> {
Size::Unbounded
}
fn commit(&mut self, slice: Option<VolumeCommit<u8, Size512>>) -> Result<(), Self::Error> {
unimplemented!()
}
unsafe fn slice_unchecked<'a>(&'a self, range: Range<Address<Size512>>) -> VolumeSlice<'a, u8, Size512> {
unimplemented!()
}
fn slice<'a>(&'a self, range: Range<Address<Size512>>) -> Result<VolumeSlice<'a, u8, Size512>, Self::Error> {
unimplemented!()
}
}

@ -0,0 +1,21 @@
extern crate std;
use crate::*;
use std::fs::{self, OpenOptions};
use std::sync::Arc;
use std::sync::Mutex;
fn open_sample_file() -> Arc<Ext2FileSystem> {
fs::copy("ext2.img", "test.img").expect("failed to open ext2.img");
let file = OpenOptions::new()
.read(true)
.write(true)
.open("test.img")
.expect("failed to open test.img");
Ext2FileSystem::open(Arc::new(Mutex::new(file))).expect("failed to open Ext2")
}
#[test]
fn test_open() {
let fs = open_sample_file();
}

@ -15,10 +15,10 @@ use core::fmt::{Debug, Error, Formatter};
use core::mem::uninitialized;
use bitvec::BitVec;
use log::*;
use rcore_fs::dev::TimeProvider;
use rcore_fs::dirty::Dirty;
use rcore_fs::vfs::{self, FileSystem, FsError, INode, Timespec};
use log::*;
use spin::RwLock;
use self::dev::*;
@ -162,7 +162,7 @@ impl vfs::INode for INodeImpl {
Ok(vfs::PollStatus {
read: true,
write: true,
error: false
error: false,
})
}
/// the size returned here is logical size(entry num for directory), not the disk space used.
@ -471,10 +471,15 @@ impl SEFS {
// load free map
let mut free_map = BitVec::with_capacity(BLKBITS * super_block.groups as usize);
unsafe { free_map.set_len(BLKBITS * super_block.groups as usize); }
unsafe {
free_map.set_len(BLKBITS * super_block.groups as usize);
}
for i in 0..super_block.groups as usize {
let block_id = Self::get_freemap_block_id_of_group(i);
meta_file.read_block(block_id, &mut free_map.as_mut()[BLKSIZE * i..BLKSIZE * (i+1)])?;
meta_file.read_block(
block_id,
&mut free_map.as_mut()[BLKSIZE * i..BLKSIZE * (i + 1)],
)?;
}
Ok(SEFS {
@ -557,7 +562,8 @@ impl SEFS {
super_block.groups += 1;
super_block.blocks += BLKBITS as u32;
super_block.unused_blocks += BLKBITS as u32 - 1;
self.meta_file.set_len(super_block.groups as usize * BLKBITS * BLKSIZE)
self.meta_file
.set_len(super_block.groups as usize * BLKBITS * BLKSIZE)
.expect("failed to extend meta file");
free_map.extend(core::iter::repeat(true).take(BLKBITS));
free_map.set(Self::get_freemap_block_id_of_group(new_group_id), false);
@ -659,7 +665,7 @@ impl vfs::FileSystem for SEFS {
let mut free_map = self.free_map.write();
if free_map.dirty() {
for i in 0..super_block.groups as usize {
let slice = &free_map.as_ref()[BLKSIZE * i..BLKSIZE * (i+1)];
let slice = &free_map.as_ref()[BLKSIZE * i..BLKSIZE * (i + 1)];
self.meta_file
.write_all_at(slice, BLKSIZE * Self::get_freemap_block_id_of_group(i))?;
}
@ -698,8 +704,7 @@ impl vfs::FileSystem for SEFS {
impl Drop for SEFS {
/// Auto sync when drop
fn drop(&mut self) {
self.sync()
.expect("Failed to sync when dropping the SEFS");
self.sync().expect("Failed to sync when dropping the SEFS");
}
}

@ -1,7 +1,7 @@
#![cfg(any(test, feature = "std"))]
use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write, Error};
use std::io::{Error, Read, Seek, SeekFrom, Write};
use std::sync::Mutex;
use std::time::{SystemTime, UNIX_EPOCH};

Loading…
Cancel
Save