1 Commits

Author SHA1 Message Date
Cutieguwu
71675d0771 Update io.rs 2026-01-01 14:40:51 -05:00
5 changed files with 28 additions and 30 deletions

View File

@@ -20,12 +20,33 @@ pub fn get_stream_length<S: Seek>(stream: &mut S) -> io::Result<u64> {
len
}
/*
* IO Error Poisoning:
*
* Attempt 2:
*
* Return to using safe-on-the-surface Rust, but attempt to execute the reads
* via a separate thread, hoping that the observed poisoning goes away with the
* thread being closed and doesn't affect the main thread.
*
* May need `mpsc` to transfer data without spawning a thread on every read.
*/
pub fn load_input() -> anyhow::Result<File> {
OpenOptions::new()
.read(true)
.custom_flags(libc::O_DIRECT)
.open(&CONFIG.input)
.with_context(|| format!("Failed to open input file: {}", &CONFIG.input.display()))
/*
use std::ffi::CString;
use std::os::fd::FromRawFd;
let path = CString::new(CONFIG.input.to_str().unwrap().to_owned()).unwrap();
let flags = libc::O_DIRECT | libc::O_RDONLY;
let f = unsafe { File::from_raw_fd(libc::open(path.as_ptr(), flags)) };
*/
}
pub fn load_output() -> anyhow::Result<File> {
@@ -61,18 +82,3 @@ pub fn load_map_write() -> anyhow::Result<File> {
)
})
}
#[repr(C, align(512))]
pub struct DirectIOBuffer(pub [u8; crate::MAX_BUFFER_SIZE]);
impl Default for DirectIOBuffer {
fn default() -> Self {
Self([crate::FB_NULL_VALUE; _])
}
}
impl From<[u8; crate::MAX_BUFFER_SIZE]> for DirectIOBuffer {
fn from(value: [u8; crate::MAX_BUFFER_SIZE]) -> Self {
Self(value)
}
}

View File

@@ -11,8 +11,6 @@ use anyhow;
const FB_SECTOR_SIZE: usize = 2048;
const FB_NULL_VALUE: u8 = 0;
const MAX_BUFFER_SIZE: usize = FB_SECTOR_SIZE * 16;
fn main() -> anyhow::Result<()> {
let mut recover_tool = Recover::new()?;
recover_tool.run()?;

View File

@@ -21,7 +21,6 @@ impl Default for Cluster {
impl Cluster {
/// Breaks apart into a vec of clusters,
/// each of cluster_size, excepting last.
#[allow(dead_code)]
pub fn subdivide(&mut self, cluster_len: usize) -> Vec<Cluster> {
let domain_len = self.domain.len();
let mut start = self.domain.start;
@@ -50,8 +49,6 @@ impl Cluster {
clusters
}
// This is used in unit tests at present. Ideally it probably shouldn't exist.
#[allow(dead_code)]
pub fn set_stage(&mut self, stage: Stage) -> &mut Self {
self.stage = stage;
self

View File

@@ -16,7 +16,6 @@ impl Default for Domain {
impl Domain {
/// Return length of domain in sectors.
#[allow(dead_code)]
pub fn len(self) -> usize {
self.end - self.start
}

View File

@@ -2,13 +2,13 @@ use std::fs::File;
use std::io::{BufWriter, Read, Seek, SeekFrom, Write};
use std::usize;
use anyhow::Context;
use anyhow::{Context, anyhow};
use crate::cli::CONFIG;
use crate::io::DirectIOBuffer;
use crate::mapping::prelude::*;
#[derive(Debug)]
#[allow(dead_code)]
pub struct Recover {
input: File,
output: BufWriter<File>,
@@ -90,12 +90,11 @@ impl Recover {
/// Attempt to copy all untested blocks.
fn copy_untested(&mut self) -> anyhow::Result<()> {
let mut buf = DirectIOBuffer::default();
for untested in self.map.get_clusters(Stage::Untested) {
// Caching.
let mut read_position: usize;
let mut cluster: Cluster;
let mut buf: Vec<u8>;
let mut buf_capacity = self.get_buf_capacity() as usize;
dbg!(untested.domain);
@@ -105,6 +104,7 @@ impl Recover {
dbg!(read_position);
buf_capacity = buf_capacity.min(untested.domain.end - read_position);
buf = vec![crate::FB_NULL_VALUE; buf_capacity];
cluster = Cluster {
domain: Domain {
@@ -114,7 +114,7 @@ impl Recover {
stage: Stage::Intact,
};
if let Err(err) = self.input.read_exact(&mut buf.0) {
if let Err(err) = self.input.read_exact(&mut buf) {
// If buf were zeroed out before every read, one could theoretically recover
// part of that read given the assumption that all null values from the end to
// the first non-null value are unread, and some further padding from the last
@@ -141,7 +141,7 @@ impl Recover {
if cluster.stage == Stage::Intact {
self.output
.write_all(&buf.0[0..buf_capacity])
.write_all(&buf[0..buf_capacity])
.context("Failed to write data to output file")?;
}
@@ -151,8 +151,6 @@ impl Recover {
}
}
drop(buf);
self.map.write_to(&mut crate::io::load_map_write()?)?;
Ok(())
@@ -161,7 +159,7 @@ impl Recover {
/// Set buffer capacity as cluster length in bytes.
/// Varies depending on the recovery stage.
fn get_buf_capacity(&mut self) -> u64 {
crate::MAX_BUFFER_SIZE.min(CONFIG.sector_size * CONFIG.cluster_length) as u64
CONFIG.sector_size as u64 * CONFIG.cluster_length as u64
}
/// Reloads the input and restores the seek position.