Commit 946efa2f authored by Jeremy Soller's avatar Jeremy Soller

Add sparse disk file to not require image to be sized initially.

parent 07540199
Pipeline #4110 passed with stages
in 1 minute and 47 seconds
......@@ -7,7 +7,7 @@ use std::io::{self, Read};
use std::path::Path;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use redoxfs::{BLOCK_SIZE, Disk, DiskFile, Extent, FileSystem, Node};
use redoxfs::{BLOCK_SIZE, Disk, DiskSparse, Extent, FileSystem, Node};
use uuid::Uuid;
fn syscall_err(err: syscall::Error) -> io::Error {
......@@ -72,14 +72,15 @@ fn archive<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path: P, ctim
let free_block = fs.header.1.free;
let mut free = fs.node(free_block).map_err(syscall_err)?;
let end_block = free.1.extents[0].block;
let end_size = end_block * BLOCK_SIZE;
free.1.extents[0] = Extent::default();
fs.write_at(free.0, &free.1).map_err(syscall_err)?;
fs.header.1.size = end_block;
fs.header.1.size = end_size;
let header = fs.header;
fs.write_at(header.0, &header.1).map_err(syscall_err)?;
Ok(end_block * BLOCK_SIZE)
Ok(end_size)
}
fn main() {
......@@ -103,7 +104,7 @@ fn main() {
let bootloader_path_opt = args.next();
let disk = match DiskFile::open(&disk_path) {
let disk = match DiskSparse::create(&disk_path) {
Ok(disk) => disk,
Err(err) => {
println!("redoxfs-ar: failed to open image {}: {}", disk_path, err);
......
......@@ -2,9 +2,11 @@ use syscall::error::Result;
pub use self::cache::DiskCache;
pub use self::file::DiskFile;
pub use self::sparse::DiskSparse;
mod cache;
mod file;
mod sparse;
/// A disk
pub trait Disk {
......
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use std::u64;
use syscall::error::{Error, Result, EIO};
use BLOCK_SIZE;
use disk::Disk;
macro_rules! try_disk {
($expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
eprintln!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
}
})
}
pub struct DiskSparse {
pub file: File,
}
impl DiskSparse {
pub fn create(path: &str) -> Result<DiskSparse> {
let file = try_disk!(OpenOptions::new().read(true).write(true).create(true).open(path));
Ok(DiskSparse {
file
})
}
}
impl Disk for DiskSparse {
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE)));
let count = try_disk!(self.file.read(buffer));
Ok(count)
}
fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE)));
let count = try_disk!(self.file.write(buffer));
Ok(count)
}
fn size(&mut self) -> Result<u64> {
Ok(u64::MAX)
}
}
......@@ -11,7 +11,7 @@ pub const SIGNATURE: &'static [u8; 8] = b"RedoxFS\0";
pub const VERSION: u64 = 3;
pub static IS_UMT: AtomicUsize = AtomicUsize::new(0);
pub use self::disk::{Disk, DiskCache, DiskFile};
pub use self::disk::{Disk, DiskCache, DiskFile, DiskSparse};
pub use self::ex_node::ExNode;
pub use self::extent::Extent;
pub use self::filesystem::FileSystem;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment