mirror of
https://github.com/LearningOS/rust-based-os-comp2022.git
synced 2026-05-08 23:01:31 +08:00
83 lines
2.7 KiB
Rust
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(())
|
|
}
|