sparse.rs 1.22 KB
Newer Older
1 2
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
3
use std::path::Path;
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
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 {
25
    pub fn create<P: AsRef<Path>>(path: P) -> Result<DiskSparse> {
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
        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)
    }
}