Create SFS and check magic.

master
WangRunji 7 years ago
parent 7658341eb9
commit 3a45996496

@ -4,4 +4,5 @@ version = "0.1.0"
authors = ["WangRunji <wangrunji0408@163.com>"]
[dependencies]
spin = "0.4"
spin = "0.4"
bit-set = "0.5"

@ -1,10 +1,15 @@
#![feature(alloc)]
#![no_std]
#[cfg(test)]
#[macro_use]
extern crate std;
extern crate spin;
extern crate alloc;
extern crate bit_set;
mod vfs;
mod sfs;
mod structs;
#[cfg(test)]
mod tests;

@ -0,0 +1,69 @@
use spin::Mutex;
use bit_set::BitSet;
use alloc::{boxed::Box, Vec};
use super::structs::*;
use core::mem::{uninitialized, size_of};
use core::slice;
/// Interface for SFS to read & write
/// TODO: use std::io::{Read, Write}
pub trait Device {
fn read_at(&mut self, offset: u64, buf: &mut [u8]) -> Option<usize>;
fn write_at(&mut self, offset: u64, buf: &[u8]) -> Option<usize>;
}
/// inode for sfs
pub struct Inode {
/// on-disk inode
disk_inode: *mut DiskInode,
/// inode number
id: u32,
/// true if inode modified
dirty: bool,
/// kill inode if it hits zero
reclaim_count: u32,
/// semaphore for din
mutex: Mutex<()>,
}
/// filesystem for sfs
pub struct SimpleFileSystem {
/// on-disk superblock
super_block: SuperBlock,
/// blocks in use are mared 0
free_map: BitSet,
/// true if super/freemap modified
super_dirty: bool,
/// buffer for non-block aligned io
// buffer: u8,
/// semaphore for fs
// fs_mutex: Mutex<()>,
/// semaphore for link/unlink and rename
// link_mutex: Mutex<()>,
/// inode list
// inodes: Vec<Inode>,
/// device
device: Mutex<Box<Device>>,
}
impl SimpleFileSystem {
/// Create a new SFS with device
pub fn new(mut device: Box<Device>) -> Option<Self> {
let mut super_block: SuperBlock = unsafe{ uninitialized() };
let slice = unsafe{ slice::from_raw_parts_mut(
&mut super_block as *mut SuperBlock as *mut u8, size_of::<SuperBlock>()) };
if device.read_at(0, slice).is_none() {
return None;
}
if super_block.check() == false {
return None;
}
Some(SimpleFileSystem {
super_block,
free_map: BitSet::new(),
super_dirty: false,
device: Mutex::new(device),
})
}
}

@ -1,81 +1,49 @@
use spin::Mutex;
use alloc::Vec;
//use core::fmt::{Debug, Formatter, Error};
/// On-disk superblock
#[repr(C, packed)]
struct SuperBlock {
pub struct SuperBlock {
/// magic number, should be SFS_MAGIC
magic: u32,
pub magic: u32,
/// number of blocks in fs
blocks: u32,
pub blocks: u32,
/// number of unused blocks in fs
unused_blocks: u32,
pub unused_blocks: u32,
/// infomation for sfs
info: [u8; MAX_INFO_LEN + 1],
pub info: [u8; MAX_INFO_LEN + 1],
}
/// inode (on disk)
#[repr(C, packed)]
#[derive(Debug)]
struct DiskInode {
pub struct DiskInode {
/// size of the file (in bytes)
size: u32,
pub size: u32,
/// one of SYS_TYPE_* above
type_: u16,
pub type_: u16,
/// number of hard links to this file
nlinks: u16,
pub nlinks: u16,
/// number of blocks
blocks: u32,
pub blocks: u32,
/// direct blocks
direct: [u32; NDIRECT],
pub direct: [u32; NDIRECT],
/// indirect blocks
indirect: u32,
pub indirect: u32,
/// double indirect blocks
db_indirect: u32,
pub db_indirect: u32,
}
/// file entry (on disk)
#[repr(C, packed)]
struct DiskEntry {
pub struct DiskEntry {
/// inode number
inode_number: u32,
pub inode_number: u32,
/// file name
name: [u8; MAX_FNAME_LEN + 1],
}
/// inode for sfs
struct Inode {
/// on-disk inode
disk_inode: *mut DiskInode,
/// inode number
id: u32,
/// true if inode modified
dirty: bool,
/// kill inode if it hits zero
reclaim_count: u32,
/// semaphore for din
mutex: Mutex<()>,
pub name: [u8; MAX_FNAME_LEN + 1],
}
/// filesystem for sfs
struct SimpleFileSystem {
/// on-disk superblock
super_block: SuperBlock,
/// blocks in use are mared 0
free_map: [u8; 0],
/// true if super/freemap modified
super_dirty: bool,
/// buffer for non-block aligned io
buffer: [u8; 0],
/// semaphore for fs
fs_mutex: Mutex<()>,
/// semaphore for io
io_mutex: Mutex<()>,
/// semaphore for link/unlink and rename
link_mutex: Mutex<()>,
/// inode list
inodes: Vec<DiskInode>
impl SuperBlock {
pub fn check(&self) -> bool {
self.magic == MAGIC
}
}
/*
@ -83,29 +51,29 @@ struct SimpleFileSystem {
* and is used by tools that work on SFS volumes, such as mksfs.
*/
/// magic number for sfs
const MAGIC: usize = 0x2f8dbe2a;
pub const MAGIC: u32 = 0x2f8dbe2a;
/// size of block
const BLKSIZE: usize = 4096;
pub const BLKSIZE: usize = 4096;
/// number of direct blocks in inode
const NDIRECT: usize = 12;
pub const NDIRECT: usize = 12;
/// max length of infomation
const MAX_INFO_LEN: usize = 31;
pub const MAX_INFO_LEN: usize = 31;
/// max length of filename
const MAX_FNAME_LEN: usize = 255;
pub const MAX_FNAME_LEN: usize = 255;
/// max file size (128M)
const MAX_FILE_SIZE: usize = 1024 * 1024 * 128;
pub const MAX_FILE_SIZE: usize = 1024 * 1024 * 128;
/// block the superblock lives in
const BLKN_SUPER: usize = 0;
pub const BLKN_SUPER: usize = 0;
/// location of the root dir inode
const BLKN_ROOT: usize = 1;
pub const BLKN_ROOT: usize = 1;
/// 1st block of the freemap
const BLKN_FREEMAP: usize = 2;
pub const BLKN_FREEMAP: usize = 2;
/// number of bits in a block
const BLKBITS: usize = BLKSIZE * 8;
pub const BLKBITS: usize = BLKSIZE * 8;
/// number of entries in a block
const BLK_NENTRY: usize = BLKSIZE / 4;
pub const BLK_NENTRY: usize = BLKSIZE / 4;
/// file types
enum FileType {
pub enum FileType {
Invalid = 0, File = 1, Dir = 2, Link = 3,
}

@ -1,4 +1,28 @@
use std::fs::File;
use std::io::{Read, Write, Seek, SeekFrom};
use std::boxed::Box;
use super::sfs::*;
impl Device for File {
fn read_at(&mut self, offset: u64, buf: &mut [u8]) -> Option<usize> {
match self.seek(SeekFrom::Start(offset)) {
Ok(real_offset) if real_offset == offset => self.read(buf).ok(),
_ => None,
}
}
fn write_at(&mut self, offset: u64, buf: &[u8]) -> Option<usize> {
match self.seek(SeekFrom::Start(offset)) {
Ok(real_offset) if real_offset == offset => self.write(buf).ok(),
_ => None,
}
}
}
#[test]
fn test() {
let file = File::open("sfs.img")
.expect("failed to open sfs.img");
let sfs = SimpleFileSystem::new(Box::new(file))
.expect("failed to create SFS");
}
Loading…
Cancel
Save