[thin_check (rust)] Factor out pdata/unpack
This commit is contained in:
parent
55ee4bfad8
commit
50bde693a1
@ -1,31 +1,17 @@
|
|||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use fixedbitset::FixedBitSet;
|
use fixedbitset::FixedBitSet;
|
||||||
use nom::{number::complete::*, IResult};
|
use nom::{number::complete::*, IResult};
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::checksum;
|
use crate::checksum;
|
||||||
use crate::io_engine::*;
|
use crate::io_engine::*;
|
||||||
|
use crate::pdata::unpack::*;
|
||||||
|
|
||||||
// FIXME: check that keys are in ascending order between nodes.
|
// FIXME: check that keys are in ascending order between nodes.
|
||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
pub trait Unpack {
|
|
||||||
// The size of the value when on disk.
|
|
||||||
fn disk_size() -> u32;
|
|
||||||
fn unpack(data: &[u8]) -> IResult<&[u8], Self>
|
|
||||||
where
|
|
||||||
Self: std::marker::Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unpack<U: Unpack>(data: &[u8]) -> Result<U> {
|
|
||||||
match U::unpack(data) {
|
|
||||||
Err(_e) => Err(anyhow!("couldn't parse SMRoot")),
|
|
||||||
Ok((_i, v)) => Ok(v),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const NODE_HEADER_SIZE: usize = 32;
|
const NODE_HEADER_SIZE: usize = 32;
|
||||||
|
|
||||||
pub struct NodeHeader {
|
pub struct NodeHeader {
|
||||||
@ -160,28 +146,6 @@ pub fn unpack_node<V: Unpack>(
|
|||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
impl Unpack for u64 {
|
|
||||||
fn disk_size() -> u32 {
|
|
||||||
8
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unpack(i: &[u8]) -> IResult<&[u8], u64> {
|
|
||||||
le_u64(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Unpack for u32 {
|
|
||||||
fn disk_size() -> u32 {
|
|
||||||
4
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unpack(i: &[u8]) -> IResult<&[u8], u32> {
|
|
||||||
le_u32(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------
|
|
||||||
|
|
||||||
pub trait NodeVisitor<V: Unpack> {
|
pub trait NodeVisitor<V: Unpack> {
|
||||||
fn visit(&mut self, w: &BTreeWalker, b: &Block, node: &Node<V>) -> Result<()>;
|
fn visit(&mut self, w: &BTreeWalker, b: &Block, node: &Node<V>) -> Result<()>;
|
||||||
}
|
}
|
||||||
@ -315,7 +279,9 @@ struct ValueCollector<V> {
|
|||||||
|
|
||||||
impl<V> ValueCollector<V> {
|
impl<V> ValueCollector<V> {
|
||||||
fn new() -> ValueCollector<V> {
|
fn new() -> ValueCollector<V> {
|
||||||
ValueCollector { values: BTreeMap::new() }
|
ValueCollector {
|
||||||
|
values: BTreeMap::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,9 +304,11 @@ impl<V: Unpack + Clone> NodeVisitor<V> for ValueCollector<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn btree_to_map<V: Unpack + Clone>(engine: Arc<dyn IoEngine + Send + Sync>,
|
pub fn btree_to_map<V: Unpack + Clone>(
|
||||||
ignore_non_fatal: bool,
|
engine: Arc<dyn IoEngine + Send + Sync>,
|
||||||
root: u64) -> Result<BTreeMap<u64, V>> {
|
ignore_non_fatal: bool,
|
||||||
|
root: u64,
|
||||||
|
) -> Result<BTreeMap<u64, V>> {
|
||||||
let mut walker = BTreeWalker::new(engine, ignore_non_fatal);
|
let mut walker = BTreeWalker::new(engine, ignore_non_fatal);
|
||||||
let mut visitor = ValueCollector::<V>::new();
|
let mut visitor = ValueCollector::<V>::new();
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
pub mod btree;
|
pub mod btree;
|
||||||
pub mod space_map;
|
pub mod space_map;
|
||||||
|
pub mod unpack;
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use nom::{number::complete::*, IResult};
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::io_engine::*;
|
use crate::io_engine::*;
|
||||||
use crate::pdata::btree::Unpack;
|
use crate::pdata::unpack::Unpack;
|
||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
|
43
src/pdata/unpack.rs
Normal file
43
src/pdata/unpack.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use nom::{number::complete::*, IResult};
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
pub trait Unpack {
|
||||||
|
// The size of the value when on disk.
|
||||||
|
fn disk_size() -> u32;
|
||||||
|
fn unpack(data: &[u8]) -> IResult<&[u8], Self>
|
||||||
|
where
|
||||||
|
Self: std::marker::Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack<U: Unpack>(data: &[u8]) -> Result<U> {
|
||||||
|
match U::unpack(data) {
|
||||||
|
Err(_e) => Err(anyhow!("couldn't parse SMRoot")),
|
||||||
|
Ok((_i, v)) => Ok(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
impl Unpack for u64 {
|
||||||
|
fn disk_size() -> u32 {
|
||||||
|
8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack(i: &[u8]) -> IResult<&[u8], u64> {
|
||||||
|
le_u64(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unpack for u32 {
|
||||||
|
fn disk_size() -> u32 {
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack(i: &[u8]) -> IResult<&[u8], u32> {
|
||||||
|
le_u32(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------
|
@ -8,7 +8,8 @@ use threadpool::ThreadPool;
|
|||||||
|
|
||||||
use crate::checksum;
|
use crate::checksum;
|
||||||
use crate::io_engine::{AsyncIoEngine, Block, IoEngine, SyncIoEngine};
|
use crate::io_engine::{AsyncIoEngine, Block, IoEngine, SyncIoEngine};
|
||||||
use crate::pdata::btree::{btree_to_map, unpack, BTreeWalker, Node, NodeVisitor, Unpack};
|
use crate::pdata::unpack::*;
|
||||||
|
use crate::pdata::btree::{btree_to_map, BTreeWalker, Node, NodeVisitor};
|
||||||
use crate::pdata::space_map::*;
|
use crate::pdata::space_map::*;
|
||||||
use crate::thin::superblock::*;
|
use crate::thin::superblock::*;
|
||||||
|
|
||||||
@ -207,7 +208,7 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> {
|
|||||||
// mapping top level
|
// mapping top level
|
||||||
let roots = btree_to_map::<u64>(engine.clone(), false, sb.mapping_root)?;
|
let roots = btree_to_map::<u64>(engine.clone(), false, sb.mapping_root)?;
|
||||||
|
|
||||||
// mapping bottom level
|
// Check the mappings filling in the data_sm as we go.
|
||||||
let data_sm;
|
let data_sm;
|
||||||
{
|
{
|
||||||
// FIXME: with a thread pool we need to return errors another way.
|
// FIXME: with a thread pool we need to return errors another way.
|
||||||
@ -242,7 +243,7 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> {
|
|||||||
pool.join();
|
pool.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
// data space map
|
// Check the data space map.
|
||||||
{
|
{
|
||||||
let data_sm = data_sm.lock().unwrap();
|
let data_sm = data_sm.lock().unwrap();
|
||||||
let root = unpack::<SMRoot>(&sb.data_sm_root[0..])?;
|
let root = unpack::<SMRoot>(&sb.data_sm_root[0..])?;
|
||||||
@ -265,6 +266,7 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> {
|
|||||||
blocks.push(Block::new(i.blocknr));
|
blocks.push(Block::new(i.blocknr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: we should do this in batches
|
||||||
engine.read_many(&mut blocks)?;
|
engine.read_many(&mut blocks)?;
|
||||||
|
|
||||||
let mut leaks = 0;
|
let mut leaks = 0;
|
||||||
@ -322,6 +324,9 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the metadata space map.
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user