-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
### Rust template | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "easy-fs-fuse" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
clap = "3.0.14" | ||
rand = "0.8.4" | ||
easy-fs = {path = "../easy-fs"} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
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 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(with backslash)"), | ||
) | ||
.arg( | ||
Arg::with_name("target") | ||
.short('t') | ||
.long("target") | ||
.takes_value(true) | ||
.help("Executable target dir(with backslash)"), | ||
) | ||
.get_matches(); | ||
let src_path = matches.value_of("source").unwrap(); | ||
let target_path = matches.value_of("target").unwrap(); | ||
println!("src_path = {}\ntarget_path = {}", src_path, target_path); | ||
let block_file = Arc::new(BlockFile(Mutex::new({ | ||
let f = OpenOptions::new() | ||
.read(true) | ||
.write(true) | ||
.create(true) | ||
.open(format!("{}{}", target_path, "fs.img"))?; | ||
f.set_len(16 * 2048 * 512).unwrap(); | ||
f | ||
}))); | ||
// 16MiB, at most 4095 files | ||
let efs = EasyFileSystem::create(block_file, 16 * 2048, 1); | ||
let root_inode = Arc::new(EasyFileSystem::root_inode(&efs)); | ||
let apps: Vec<_> = read_dir(src_path) | ||
.unwrap() | ||
.into_iter() | ||
.map(|dir_entry| { | ||
let mut name_with_ext = dir_entry.unwrap().file_name().into_string().unwrap(); | ||
name_with_ext.drain(name_with_ext.find('.').unwrap()..name_with_ext.len()); | ||
name_with_ext | ||
}) | ||
.collect(); | ||
for app in apps { | ||
// load app data from host file system | ||
let mut host_file = File::open(format!("{}{}", target_path, app)).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 inode = root_inode.create(app.as_str()).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(()) | ||
} | ||
|
||
#[test] | ||
fn efs_test() -> std::io::Result<()> { | ||
let block_file = Arc::new(BlockFile(Mutex::new({ | ||
let f = OpenOptions::new() | ||
.read(true) | ||
.write(true) | ||
.create(true) | ||
.open("target/fs.img")?; | ||
f.set_len(8192 * 512).unwrap(); | ||
f | ||
}))); | ||
EasyFileSystem::create(block_file.clone(), 4096, 1); | ||
let efs = EasyFileSystem::open(block_file.clone()); | ||
let root_inode = EasyFileSystem::root_inode(&efs); | ||
root_inode.create("filea"); | ||
root_inode.create("fileb"); | ||
for name in root_inode.ls() { | ||
println!("{}", name); | ||
} | ||
let filea = root_inode.find("filea").unwrap(); | ||
let greet_str = "Hello, world!"; | ||
filea.write_at(0, greet_str.as_bytes()); | ||
//let mut buffer = [0u8; 512]; | ||
let mut buffer = [0u8; 233]; | ||
let len = filea.read_at(0, &mut buffer); | ||
assert_eq!(greet_str, core::str::from_utf8(&buffer[..len]).unwrap(),); | ||
|
||
let mut random_str_test = |len: usize| { | ||
filea.clear(); | ||
assert_eq!(filea.read_at(0, &mut buffer), 0,); | ||
let mut str = String::new(); | ||
use rand; | ||
// random digit | ||
for _ in 0..len { | ||
str.push(char::from('0' as u8 + rand::random::<u8>() % 10)); | ||
} | ||
filea.write_at(0, str.as_bytes()); | ||
let mut read_buffer = [0u8; 127]; | ||
let mut offset = 0usize; | ||
let mut read_str = String::new(); | ||
loop { | ||
let len = filea.read_at(offset, &mut read_buffer); | ||
if len == 0 { | ||
break; | ||
} | ||
offset += len; | ||
read_str.push_str(core::str::from_utf8(&read_buffer[..len]).unwrap()); | ||
} | ||
assert_eq!(str, read_str); | ||
}; | ||
|
||
random_str_test(4 * BLOCK_SZ); | ||
random_str_test(8 * BLOCK_SZ + BLOCK_SZ / 2); | ||
random_str_test(100 * BLOCK_SZ); | ||
random_str_test(70 * BLOCK_SZ + BLOCK_SZ / 7); | ||
random_str_test((12 + 128) * BLOCK_SZ); | ||
random_str_test(400 * BLOCK_SZ); | ||
random_str_test(1000 * BLOCK_SZ); | ||
random_str_test(2000 * BLOCK_SZ); | ||
|
||
Ok(()) | ||
} | ||
|
||
fn main() { | ||
easy_fs_pack().expect("Error when packing easy-fs!"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
### Rust template | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "easy-fs" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
spin = "0.9.2" | ||
lazy_static = {version = "1.4.0", features = ["spin_no_std"]} | ||
|
||
|
||
[profile.release] | ||
debug = true |