Create SFS and check magic.

master
WangRunji 7 years ago
parent 7658341eb9
commit 3a45996496

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

@ -1,10 +1,15 @@
#![feature(alloc)] #![feature(alloc)]
#![no_std] #![no_std]
#[cfg(test)]
#[macro_use]
extern crate std;
extern crate spin; extern crate spin;
extern crate alloc; extern crate alloc;
extern crate bit_set;
mod vfs; mod sfs;
mod structs; mod structs;
#[cfg(test)] #[cfg(test)]
mod tests; 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 /// On-disk superblock
#[repr(C, packed)] #[repr(C, packed)]
struct SuperBlock { pub struct SuperBlock {
/// magic number, should be SFS_MAGIC /// magic number, should be SFS_MAGIC
magic: u32, pub magic: u32,
/// number of blocks in fs /// number of blocks in fs
blocks: u32, pub blocks: u32,
/// number of unused blocks in fs /// number of unused blocks in fs
unused_blocks: u32, pub unused_blocks: u32,
/// infomation for sfs /// infomation for sfs
info: [u8; MAX_INFO_LEN + 1], pub info: [u8; MAX_INFO_LEN + 1],
} }
/// inode (on disk) /// inode (on disk)
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Debug)] #[derive(Debug)]
struct DiskInode { pub struct DiskInode {
/// size of the file (in bytes) /// size of the file (in bytes)
size: u32, pub size: u32,
/// one of SYS_TYPE_* above /// one of SYS_TYPE_* above
type_: u16, pub type_: u16,
/// number of hard links to this file /// number of hard links to this file
nlinks: u16, pub nlinks: u16,
/// number of blocks /// number of blocks
blocks: u32, pub blocks: u32,
/// direct blocks /// direct blocks
direct: [u32; NDIRECT], pub direct: [u32; NDIRECT],
/// indirect blocks /// indirect blocks
indirect: u32, pub indirect: u32,
/// double indirect blocks /// double indirect blocks
db_indirect: u32, pub db_indirect: u32,
} }
/// file entry (on disk) /// file entry (on disk)
#[repr(C, packed)] #[repr(C, packed)]
struct DiskEntry { pub struct DiskEntry {
/// inode number /// inode number
inode_number: u32, pub inode_number: u32,
/// file name /// file name
name: [u8; MAX_FNAME_LEN + 1], pub name: [u8; MAX_FNAME_LEN + 1],
} }
/// inode for sfs impl SuperBlock {
struct Inode { pub fn check(&self) -> bool {
/// on-disk inode self.magic == MAGIC
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
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>
} }
/* /*
@ -83,29 +51,29 @@ struct SimpleFileSystem {
* and is used by tools that work on SFS volumes, such as mksfs. * and is used by tools that work on SFS volumes, such as mksfs.
*/ */
/// magic number for sfs /// magic number for sfs
const MAGIC: usize = 0x2f8dbe2a; pub const MAGIC: u32 = 0x2f8dbe2a;
/// size of block /// size of block
const BLKSIZE: usize = 4096; pub const BLKSIZE: usize = 4096;
/// number of direct blocks in inode /// number of direct blocks in inode
const NDIRECT: usize = 12; pub const NDIRECT: usize = 12;
/// max length of infomation /// max length of infomation
const MAX_INFO_LEN: usize = 31; pub const MAX_INFO_LEN: usize = 31;
/// max length of filename /// max length of filename
const MAX_FNAME_LEN: usize = 255; pub const MAX_FNAME_LEN: usize = 255;
/// max file size (128M) /// 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 /// block the superblock lives in
const BLKN_SUPER: usize = 0; pub const BLKN_SUPER: usize = 0;
/// location of the root dir inode /// location of the root dir inode
const BLKN_ROOT: usize = 1; pub const BLKN_ROOT: usize = 1;
/// 1st block of the freemap /// 1st block of the freemap
const BLKN_FREEMAP: usize = 2; pub const BLKN_FREEMAP: usize = 2;
/// number of bits in a block /// number of bits in a block
const BLKBITS: usize = BLKSIZE * 8; pub const BLKBITS: usize = BLKSIZE * 8;
/// number of entries in a block /// number of entries in a block
const BLK_NENTRY: usize = BLKSIZE / 4; pub const BLK_NENTRY: usize = BLKSIZE / 4;
/// file types /// file types
enum FileType { pub enum FileType {
Invalid = 0, File = 1, Dir = 2, Link = 3, 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] #[test]
fn 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