Merge branch 'mksfs' into ucore-fs-enhance

master
Ben Pig Chu 6 years ago
commit 07a4a96b73

@ -3,9 +3,15 @@ name = "simple-filesystem"
version = "0.0.1"
authors = ["WangRunji <wangrunji0408@163.com>"]
[[bin]]
name = "mksfs"
path = "src/bin/mksfs.rs"
required-features = ["std"]
[dependencies]
bit-vec = { default-features = false, git = "https://github.com/AltSysrq/bit-vec.git" } # default-features contains 'std'
static_assertions = "0.2.5"
[features]
debug_print = []
debug_print = []
std = []

@ -0,0 +1,95 @@
extern crate simple_filesystem;
use std::env;
use std::fs;
use std::io::{Read, Write, Result};
use std::path::Path;
use std::mem::uninitialized;
use simple_filesystem::*;
fn main() -> Result<()> {
let args: Vec<_> = env::args().collect();
let cmd = &args[1];
let dir_path = Path::new(&args[2]);
let img_path = Path::new(&args[3]);
match cmd.as_str() {
"zip" => zip(dir_path, img_path),
"unzip" => unzip(dir_path, img_path),
_ => {
println!("USAGE: <zip|unzip> <PATH> <IMG>");
panic!("Invalid command: {}", cmd);
},
}
}
fn zip(path: &Path, img_path: &Path) -> Result<()> {
let img = fs::OpenOptions::new().read(true).write(true).create(true).open(img_path)?;
let sfs = SimpleFileSystem::create(Box::new(img), 0x1000000);
let inode = sfs.root_inode();
zip_dir(path, inode)?;
sfs.sync().expect("Failed to sync");
Ok(())
}
fn zip_dir(path: &Path, inode: INodePtr) -> Result<()> {
let dir = fs::read_dir(path).expect("Failed to open dir");
for entry in dir {
let entry = entry?;
let name_ = entry.file_name();
let name = name_.to_str().unwrap();
let type_ = entry.file_type()?;
if type_.is_file() {
let inode = inode.borrow_mut().create(name, FileType::File).expect("Failed to create INode");
let mut file = fs::File::open(entry.path())?;
inode.borrow_mut().resize(file.metadata().unwrap().len() as usize).expect("Failed to resize INode");
let mut buf: [u8; 4096] = unsafe { uninitialized() };
let mut offset = 0usize;
let mut len = 4096;
while len == 4096 {
len = file.read(&mut buf)?;
inode.borrow().write_at(offset, &buf).expect("Failed to write image");
offset += len;
}
} else if type_.is_dir() {
let inode = inode.borrow_mut().create(name, FileType::Dir).expect("Failed to create INode");
zip_dir(entry.path().as_path(), inode)?;
}
}
Ok(())
}
fn unzip(path: &Path, img_path: &Path) -> Result<()> {
let img = fs::File::open(img_path)?;
let sfs = SimpleFileSystem::open(Box::new(img)).expect("Failed to open sfs");
let inode = sfs.root_inode();
fs::create_dir(&path)?;
unzip_dir(path, inode)
}
fn unzip_dir(path: &Path, inode: INodePtr) -> Result<()> {
let files = inode.borrow().list().expect("Failed to list files from INode");
for name in files.iter().skip(2) {
let inode = inode.borrow().lookup(name.as_str()).expect("Failed to lookup");
let mut path = path.to_path_buf();
path.push(name);
let info = inode.borrow().info().expect("Failed to get file info");
match info.type_ {
FileType::File => {
let mut file = fs::File::create(&path)?;
let mut buf: [u8; 4096] = unsafe { uninitialized() };
let mut offset = 0usize;
let mut len = 4096;
while len == 4096 {
len = inode.borrow().read_at(offset, buf.as_mut()).expect("Failed to read from INode");
file.write(&buf[..len])?;
offset += len;
}
}
FileType::Dir => {
fs::create_dir(&path)?;
unzip_dir(path.as_path(), inode)?;
}
}
}
Ok(())
}

@ -31,3 +31,28 @@ mod tests;
pub use sfs::*;
pub use vfs::*;
pub use blocked_device::BlockedDevice;
#[cfg(any(test, feature = "std"))]
pub mod std_impl {
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use super::Device;
impl Device for File {
fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option<usize> {
let offset = offset as u64;
match self.seek(SeekFrom::Start(offset)) {
Ok(real_offset) if real_offset == offset => self.read(buf).ok(),
_ => None,
}
}
fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option<usize> {
let offset = offset as u64;
match self.seek(SeekFrom::Start(offset)) {
Ok(real_offset) if real_offset == offset => self.write(buf).ok(),
_ => None,
}
}
}
}

@ -9,24 +9,6 @@ use std::rc::Rc;
use std::mem::uninitialized;
use super::structs::{DiskEntry, AsBuf};
impl Device for File {
fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Option<usize> {
let offset = offset as u64;
match self.seek(SeekFrom::Start(offset)) {
Ok(real_offset) if real_offset == offset => self.read(buf).ok(),
_ => None,
}
}
fn write_at(&mut self, offset: usize, buf: &[u8]) -> Option<usize> {
let offset = offset as u64;
match self.seek(SeekFrom::Start(offset)) {
Ok(real_offset) if real_offset == offset => self.write(buf).ok(),
_ => None,
}
}
}
fn _open_sample_file() -> Rc<SimpleFileSystem> {
fs::copy("sfs.img","test.img").expect("failed to open sfs.img");
let file = OpenOptions::new()

Loading…
Cancel
Save