Add sparse disk file to not require image to be sized initially.
This commit is contained in:
+5
-4
@@ -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 {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user