Improve debugging and image creation
This commit is contained in:
@@ -10,3 +10,6 @@
|
||||
# Generated by Cargo
|
||||
Cargo.lock
|
||||
/target/
|
||||
|
||||
# Images
|
||||
*.bin
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
pub trait Disk<E> {
|
||||
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize, E>;
|
||||
fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize, E>;
|
||||
fn size(&mut self) -> Result<u64, E>;
|
||||
}
|
||||
|
||||
@@ -5,3 +5,12 @@ pub struct Extent {
|
||||
pub block: u64,
|
||||
pub length: u64,
|
||||
}
|
||||
|
||||
impl Extent {
|
||||
pub fn new(block: u64, length: u64) -> Extent {
|
||||
Extent {
|
||||
block: block,
|
||||
length: length
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
-7
@@ -1,22 +1,33 @@
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use super::{Disk, Header, Node};
|
||||
use super::{Disk, Extent, Header, Node};
|
||||
|
||||
/// A file system
|
||||
pub struct FileSystem<E> {
|
||||
pub disk: Box<Disk<E>>,
|
||||
pub header: Header,
|
||||
pub header: (u64, Header),
|
||||
pub root: (u64, Node),
|
||||
pub free: (u64, Node)
|
||||
}
|
||||
|
||||
impl<E> FileSystem<E> {
|
||||
/// Open a file system on a disk
|
||||
pub fn open(mut disk: Box<Disk<E>>) -> Result<Option<Self>, E> {
|
||||
let mut header = Header::default();
|
||||
try!(disk.read_at(1, &mut header));
|
||||
if header.valid() {
|
||||
let mut header = (1, Header::default());
|
||||
try!(disk.read_at(header.0, &mut header.1));
|
||||
|
||||
if header.1.valid() {
|
||||
let mut root = (header.1.root, Node::default());
|
||||
try!(disk.read_at(root.0, &mut root.1));
|
||||
|
||||
let mut free = (header.1.free, Node::default());
|
||||
try!(disk.read_at(free.0, &mut free.1));
|
||||
|
||||
Ok(Some(FileSystem {
|
||||
disk: disk,
|
||||
header: header,
|
||||
root: root,
|
||||
free: free
|
||||
}))
|
||||
}else{
|
||||
Ok(None)
|
||||
@@ -25,11 +36,25 @@ impl<E> FileSystem<E> {
|
||||
|
||||
/// Create a file system on a disk
|
||||
pub fn create(mut disk: Box<Disk<E>>) -> Result<Self, E> {
|
||||
let header = Header::new();
|
||||
try!(disk.write_at(1, &header));
|
||||
let size = try!(disk.size());
|
||||
|
||||
assert!(size > 4);
|
||||
|
||||
let mut free = (3, Node::new("free", Node::MODE_DIR));
|
||||
free.1.extents[0] = Extent::new(4, (size - 4 * 512));
|
||||
try!(disk.write_at(free.0, &free.1));
|
||||
|
||||
let root = (2, Node::new("root", Node::MODE_DIR));
|
||||
try!(disk.write_at(root.0, &root.1));
|
||||
|
||||
let header = (1, Header::new(size, root.0, free.0));
|
||||
try!(disk.write_at(header.0, &header.1));
|
||||
|
||||
Ok(FileSystem {
|
||||
disk: disk,
|
||||
header: header,
|
||||
root: root,
|
||||
free: free
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -16,7 +16,7 @@ pub struct Header {
|
||||
/// Block of root node
|
||||
pub root: u64,
|
||||
/// Block of free space node
|
||||
pub free_space: u64,
|
||||
pub free: u64,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
@@ -27,18 +27,18 @@ impl Header {
|
||||
uuid: [0; 16],
|
||||
size: 0,
|
||||
root: 0,
|
||||
free_space: 0,
|
||||
free: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Header {
|
||||
pub fn new(size: u64, root: u64, free: u64) -> Header {
|
||||
Header {
|
||||
signature: *b"REDOXFS\0",
|
||||
version: 1,
|
||||
uuid: [0; 16],
|
||||
size: 0,
|
||||
root: 0,
|
||||
free_space: 0,
|
||||
size: size,
|
||||
root: root,
|
||||
free: free,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![crate_name="redoxfs"]
|
||||
#![crate_type="lib"]
|
||||
#![feature(alloc)]
|
||||
#![feature(associated_consts)]
|
||||
#![feature(collections)]
|
||||
#![no_std]
|
||||
|
||||
|
||||
+31
-1
@@ -1,3 +1,5 @@
|
||||
use collections::Vec;
|
||||
|
||||
use core::{fmt, mem, ops, slice, str};
|
||||
|
||||
use super::Extent;
|
||||
@@ -12,6 +14,10 @@ pub struct Node {
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub const MODE_MASK: u64 = 0xF000;
|
||||
pub const MODE_FILE: u64 = 0x8000;
|
||||
pub const MODE_DIR: u64 = 0x4000;
|
||||
|
||||
pub fn default() -> Node {
|
||||
Node {
|
||||
name: [0; 256],
|
||||
@@ -21,6 +27,20 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(name: &str, mode: u64) -> Node {
|
||||
let mut bytes = [0; 256];
|
||||
for (mut b, c) in bytes.iter_mut().zip(name.bytes()) {
|
||||
*b = c;
|
||||
}
|
||||
|
||||
Node {
|
||||
name: bytes,
|
||||
mode: mode,
|
||||
next: 0,
|
||||
extents: [Extent::default(); 15]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Result<&str, str::Utf8Error> {
|
||||
let mut len = 0;
|
||||
|
||||
@@ -33,11 +53,21 @@ impl Node {
|
||||
|
||||
str::from_utf8(&self.name[..len])
|
||||
}
|
||||
|
||||
pub fn size(&self) -> u64 {
|
||||
self.extents.iter().fold(0, |size, extent| size + extent.length)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Node {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Node {{ name: {:?}, mode: {:?}, next: {:?}, extents: {:?} }}", self.name(), self.mode, self.next, self.extents)
|
||||
let extents: Vec<&Extent> = self.extents.iter().filter(|extent| -> bool { extent.length > 0 }).collect();
|
||||
f.debug_struct("Node")
|
||||
.field("name", &self.name())
|
||||
.field("mode", &self.mode)
|
||||
.field("next", &self.next)
|
||||
.field("extents", &extents)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-4
@@ -1,4 +1,4 @@
|
||||
use std::fs::File;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Error, Read, Write, Seek, SeekFrom};
|
||||
|
||||
use redoxfs::Disk;
|
||||
@@ -9,14 +9,15 @@ pub struct Image {
|
||||
|
||||
impl Image {
|
||||
pub fn open(path: &str) -> Result<Image, Error> {
|
||||
let file = try!(File::open(path));
|
||||
let file = try!(OpenOptions::new().read(true).write(true).open(path));
|
||||
Ok(Image {
|
||||
file: file
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create(path: &str) -> Result<Image, Error> {
|
||||
let file = try!(File::create(path));
|
||||
pub fn create(path: &str, size: u64) -> Result<Image, Error> {
|
||||
let file = try!(OpenOptions::new().read(true).write(true).create(true).open(path));
|
||||
try!(file.set_len(size));
|
||||
Ok(Image {
|
||||
file: file
|
||||
})
|
||||
@@ -33,4 +34,8 @@ impl Disk<Error> for Image {
|
||||
try!(self.file.seek(SeekFrom::Start(block * 512)));
|
||||
self.file.write(buffer)
|
||||
}
|
||||
|
||||
fn size(&mut self) -> Result<u64, Error> {
|
||||
self.file.seek(SeekFrom::End(0))
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -29,9 +29,7 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
|
||||
match command {
|
||||
"" => (),
|
||||
"exit" => break,
|
||||
"header" => {
|
||||
println!("{:#?}", fs.header);
|
||||
},
|
||||
"header" => println!("{:#?}", fs.header),
|
||||
"node" => {
|
||||
if let Some(arg) = args.next() {
|
||||
match arg.parse::<u64>() {
|
||||
@@ -76,6 +74,7 @@ fn main() {
|
||||
let mut args = env::args();
|
||||
if let Some(path) = args.nth(1) {
|
||||
if Path::new(&path).exists() {
|
||||
//Open an existing image
|
||||
match Image::open(&path) {
|
||||
Ok(disk) => match FileSystem::open(Box::new(disk)) {
|
||||
Ok(filesystem_option) => match filesystem_option {
|
||||
@@ -90,7 +89,8 @@ fn main() {
|
||||
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
|
||||
}
|
||||
}else{
|
||||
match Image::create(&path) {
|
||||
//Create a 1 GB disk image
|
||||
match Image::create(&path, 1024 * 1024 * 1024) {
|
||||
Ok(disk) => match FileSystem::create(Box::new(disk)) {
|
||||
Ok(filesystem) => {
|
||||
println!("redoxfs: created filesystem {}", path);
|
||||
|
||||
Reference in New Issue
Block a user