#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "linux")]
pub use self::linux::*;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
pub use self::macos::*;
#[cfg(target_os = "freebsd")]
mod freebsd;
#[cfg(target_os = "freebsd")]
pub use self::freebsd::*;
use std::cmp::min;
use std::io::{Read, Result, Seek, SeekFrom, Write};
pub trait BlckExt: Seek + Read + Write {
fn is_block_device(&self) -> bool;
fn get_block_device_size(&self) -> Result<u64>;
fn get_size_of_block(&self) -> Result<u64>;
fn get_block_count(&self) -> Result<u64>;
fn block_reread_paritions(&self) -> Result<()>;
fn block_discard_zeros(&self) -> Result<bool>;
fn block_discard(&self, offset: u64, len: u64) -> Result<()>;
fn block_zero_out(&mut self, offset: u64, len: u64) -> Result<()> {
const BUF_SIZE: usize = 1024;
let zeros = [0; BUF_SIZE];
let oldpos = self.seek(SeekFrom::Start(offset))?;
let mut remaining = len;
while remaining > BUF_SIZE as u64 {
self.write_all(&zeros)?;
remaining -= BUF_SIZE as u64;
}
self.write_all(&zeros[0..remaining as usize])?;
self.seek(SeekFrom::Start(oldpos))?;
Ok(())
}
fn block_fast_zero_out(&mut self, offset: u64, len: u64) -> Result<()> {
const BUF_SIZE: usize = 1024;
let test_len = min(BUF_SIZE as u64, len) as usize;
let ones = [255; BUF_SIZE];
self.seek(SeekFrom::Start(offset))?;
self.write_all(&ones[0..test_len])?;
self.seek(SeekFrom::Start(offset))?;
self.sync_data()?;
self.block_discard(offset, len)?;
self.sync_data()?;
let mut buffer = [255; BUF_SIZE];
let read = self.read(&mut buffer)?;
self.seek(SeekFrom::Start(offset))?;
if read < test_len {
return Err(io_error("Fast Zero Block failed"));
}
if buffer[0..test_len].iter().any(|x| *x != 0) {
return Err(io_error("Fast Zero Block failed"));
}
Ok(())
}
fn sync_data(&self) -> Result<()>;
}
fn io_error(str: &str) -> std::io::Error {
std::io::Error::new(std::io::ErrorKind::Other, str)
}
fn to_io(err: nix::Error) -> std::io::Error {
match err {
nix::Error::Sys(errno) => errno.into(),
nix::Error::InvalidPath => io_error("InvalidPath"),
nix::Error::InvalidUtf8 => io_error("InvalidUtf8"),
nix::Error::UnsupportedOperation => io_error("UnsupportedOperation"),
}
}