Files
rust-based-os-comp2022/ci-user/overwrite/easy-fs-fuse.rs
2022-06-28 09:27:28 +08:00

83 lines
2.7 KiB
Rust

use clap::{App, Arg};
use easy_fs::{BlockDevice, EasyFileSystem};
use std::fs::{read_dir, File, OpenOptions};
use std::io::{Read, Seek, SeekFrom, Write};
use std::sync::Arc;
use std::sync::Mutex;
const BLOCK_SZ: usize = 512;
struct BlockFile(Mutex<File>);
impl BlockDevice for BlockFile {
fn read_block(&self, block_id: usize, buf: &mut [u8]) {
let mut file = self.0.lock().unwrap();
file.seek(SeekFrom::Start((block_id * BLOCK_SZ) as u64))
.expect("Error when seeking!");
assert_eq!(file.read(buf).unwrap(), BLOCK_SZ, "Not a complete block!");
}
fn write_block(&self, block_id: usize, buf: &[u8]) {
let mut file = self.0.lock().unwrap();
file.seek(SeekFrom::Start((block_id * BLOCK_SZ) as u64))
.expect("Error when seeking!");
assert_eq!(file.write(buf).unwrap(), BLOCK_SZ, "Not a complete block!");
}
}
fn main() {
easy_fs_pack().expect("Error when packing easy-fs!");
}
fn easy_fs_pack() -> std::io::Result<()> {
let matches = App::new("EasyFileSystem packer")
.arg(
Arg::with_name("source")
.short("s")
.long("source")
.takes_value(true)
.help("Executable source dir"),
)
.arg(
Arg::with_name("output")
.short("o")
.long("output")
.takes_value(true)
.help("Output file path"),
)
.get_matches();
let src_path = matches.value_of("source").unwrap();
let output_path = matches.value_of("output").unwrap();
println!("src_path = {}\noutput_path = {}", src_path, output_path);
let block_file = Arc::new(BlockFile(Mutex::new({
let f = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(output_path)?;
f.set_len(14000 * 512).unwrap();
f
})));
// 4MiB, at most 4095 files
let efs = EasyFileSystem::create(block_file.clone(), 14000, 1);
let root_inode = Arc::new(EasyFileSystem::root_inode(&efs));
for dir_entry in read_dir(src_path).unwrap() {
let dir_entry = dir_entry.unwrap();
let path = dir_entry.path();
// load app data from host file system
let mut host_file = File::open(&path).unwrap();
let mut all_data: Vec<u8> = Vec::new();
host_file.read_to_end(&mut all_data).unwrap();
// create a file in easy-fs
let name = path.file_stem().unwrap().to_str().unwrap();
let inode = root_inode.create(name).unwrap();
// write data to easy-fs
inode.write_at(0, all_data.as_slice());
}
// list apps
for app in root_inode.ls() {
println!("{}", app);
}
Ok(())
}