diff --git a/src/bin/mkfs.rs b/src/bin/mkfs.rs index 3abdd70bb92bb9bfdbf89232c2bb8e149e4a7230..327aeb61e388076e48919346590aca81ea3c531c 100644 --- a/src/bin/mkfs.rs +++ b/src/bin/mkfs.rs @@ -2,34 +2,57 @@ extern crate redoxfs; -use std::{env, process, time}; +use std::{env, fs, process, time}; +use std::io::Read; use redoxfs::{FileSystem, DiskFile}; fn main() { - let mut args = env::args(); - if let Some(path) = args.nth(1) { - let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); - - //Open an existing image - match DiskFile::open(&path) { - Ok(disk) => match FileSystem::create(disk, ctime.as_secs(), ctime.subsec_nanos()) { - Ok(filesystem) => { - println!("redoxfs-mkfs: created filesystem on {}, size {} MB", path, filesystem.header.1.size/1024/1024); - }, + let mut args = env::args().skip(1); + + let disk_path = if let Some(path) = args.next() { + path + } else { + println!("redoxfs-mkfs: no disk image provided"); + println!("redoxfs-mkfs DISK [BOOTLOADER]"); + process::exit(1); + }; + + let bootloader_path_opt = args.next(); + + let disk = match DiskFile::open(&disk_path) { + Ok(disk) => disk, + Err(err) => { + println!("redoxfs-mkfs: failed to open image {}: {}", disk_path, err); + process::exit(1); + } + }; + + let mut bootloader = vec![]; + if let Some(bootloader_path) = bootloader_path_opt { + match fs::File::open(&bootloader_path) { + Ok(mut file) => match file.read_to_end(&mut bootloader) { + Ok(_) => (), Err(err) => { - println!("redoxfs-mkfs: failed to create filesystem on {}: {}", path, err); + println!("redoxfs-mkfs: failed to read bootloader {}: {}", bootloader_path, err); process::exit(1); } }, Err(err) => { - println!("redoxfs-mkfs: failed to open image {}: {}", path, err); + println!("redoxfs-mkfs: failed to open bootloader {}: {}", bootloader_path, err); process::exit(1); } } - } else { - println!("redoxfs-mkfs: no disk image provided"); - println!("redoxfs-mkfs [disk]"); - process::exit(1); + }; + + let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); + match FileSystem::create_reserved(disk, &bootloader, ctime.as_secs(), ctime.subsec_nanos()) { + Ok(filesystem) => { + println!("redoxfs-mkfs: created filesystem on {}, reserved {} blocks, size {} MB", disk_path, filesystem.block, filesystem.header.1.size/1000/1000); + }, + Err(err) => { + println!("redoxfs-mkfs: failed to create filesystem on {}: {}", disk_path, err); + process::exit(1); + } } } diff --git a/src/filesystem.rs b/src/filesystem.rs index 41516ef698687a84c9e87a56b4a5c3236df661ce..fa2bd246be9285a683ce91d9893763bb85d1a889 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -37,23 +37,42 @@ impl<D: Disk> FileSystem<D> { } /// Create a file system on a disk - pub fn create(mut disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> { + pub fn create(disk: D, ctime: u64, ctime_nsec: u32) -> Result<Self> { + Self::create_reserved(disk, &[], ctime, ctime_nsec) + } + + /// Create a file system on a disk, with reserved data at the beginning + /// Reserved data will be zero padded up to the nearest block + pub fn create_reserved(mut disk: D, reserved: &[u8], ctime: u64, ctime_nsec: u32) -> Result<Self> { let size = disk.size()?; + let block_offset = (reserved.len() as u64 + 511)/512; - if size >= 4 * 512 { - let mut free = (2, Node::new(Node::MODE_FILE, "free", 0, ctime, ctime_nsec)); - free.1.extents[0] = Extent::new(4, size - 4 * 512); + if size >= (block_offset + 4) * 512 { + let mut free = (block_offset + 2, Node::new(Node::MODE_FILE, "free", 0, ctime, ctime_nsec)); + free.1.extents[0] = Extent::new(block_offset + 4, size - (block_offset + 4) * 512); disk.write_at(free.0, &free.1)?; - let root = (1, Node::new(Node::MODE_DIR | 0o755, "root", 0, ctime, ctime_nsec)); + let root = (block_offset + 1, Node::new(Node::MODE_DIR | 0o755, "root", 0, ctime, ctime_nsec)); disk.write_at(root.0, &root.1)?; - let header = (0, Header::new(size, root.0, free.0)); + let header = (block_offset + 0, Header::new(size, root.0, free.0)); disk.write_at(header.0, &header.1)?; + for block in 0..block_offset as usize { + let mut data = [0; 512]; + + let mut i = 0; + while i < data.len() && block * 512 + i < reserved.len() { + data[i] = reserved[block * 512 + i]; + i += 1; + } + + disk.write_at(block as u64, &data)?; + } + Ok(FileSystem { disk: disk, - block: 0, + block: block_offset, header: header }) } else {