From 50bde693a144b4e819f8421a939112193d6911ee Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 10 Aug 2020 15:42:10 +0100 Subject: [PATCH] [thin_check (rust)] Factor out pdata/unpack --- src/pdata/btree.rs | 52 ++++++++---------------------------------- src/pdata/mod.rs | 1 + src/pdata/space_map.rs | 2 +- src/pdata/unpack.rs | 43 ++++++++++++++++++++++++++++++++++ src/thin/check.rs | 11 ++++++--- 5 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 src/pdata/unpack.rs diff --git a/src/pdata/btree.rs b/src/pdata/btree.rs index 21b6ce2..2706bb6 100644 --- a/src/pdata/btree.rs +++ b/src/pdata/btree.rs @@ -1,31 +1,17 @@ use anyhow::{anyhow, Result}; use fixedbitset::FixedBitSet; use nom::{number::complete::*, IResult}; -use std::sync::{Arc, Mutex}; use std::collections::BTreeMap; +use std::sync::{Arc, Mutex}; use crate::checksum; use crate::io_engine::*; +use crate::pdata::unpack::*; // 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(data: &[u8]) -> Result { - match U::unpack(data) { - Err(_e) => Err(anyhow!("couldn't parse SMRoot")), - Ok((_i, v)) => Ok(v), - } -} - const NODE_HEADER_SIZE: usize = 32; pub struct NodeHeader { @@ -160,28 +146,6 @@ pub fn unpack_node( //------------------------------------------ -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 { fn visit(&mut self, w: &BTreeWalker, b: &Block, node: &Node) -> Result<()>; } @@ -315,7 +279,9 @@ struct ValueCollector { impl ValueCollector { fn new() -> ValueCollector { - ValueCollector { values: BTreeMap::new() } + ValueCollector { + values: BTreeMap::new(), + } } } @@ -338,9 +304,11 @@ impl NodeVisitor for ValueCollector { } } -pub fn btree_to_map(engine: Arc, - ignore_non_fatal: bool, - root: u64) -> Result> { +pub fn btree_to_map( + engine: Arc, + ignore_non_fatal: bool, + root: u64, +) -> Result> { let mut walker = BTreeWalker::new(engine, ignore_non_fatal); let mut visitor = ValueCollector::::new(); diff --git a/src/pdata/mod.rs b/src/pdata/mod.rs index 3e36813..6e473e2 100644 --- a/src/pdata/mod.rs +++ b/src/pdata/mod.rs @@ -1,3 +1,4 @@ pub mod btree; pub mod space_map; +pub mod unpack; diff --git a/src/pdata/space_map.rs b/src/pdata/space_map.rs index 9d46b32..91ac606 100644 --- a/src/pdata/space_map.rs +++ b/src/pdata/space_map.rs @@ -3,7 +3,7 @@ use nom::{number::complete::*, IResult}; use std::sync::{Arc, Mutex}; use crate::io_engine::*; -use crate::pdata::btree::Unpack; +use crate::pdata::unpack::Unpack; //------------------------------------------ diff --git a/src/pdata/unpack.rs b/src/pdata/unpack.rs new file mode 100644 index 0000000..c2a80b5 --- /dev/null +++ b/src/pdata/unpack.rs @@ -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(data: &[u8]) -> Result { + 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) + } +} + +//------------------------------------------ diff --git a/src/thin/check.rs b/src/thin/check.rs index 73094c9..e7110c2 100644 --- a/src/thin/check.rs +++ b/src/thin/check.rs @@ -8,7 +8,8 @@ use threadpool::ThreadPool; use crate::checksum; 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::thin::superblock::*; @@ -207,7 +208,7 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> { // mapping top level let roots = btree_to_map::(engine.clone(), false, sb.mapping_root)?; - // mapping bottom level + // Check the mappings filling in the data_sm as we go. let data_sm; { // FIXME: with a thread pool we need to return errors another way. @@ -242,7 +243,7 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> { pool.join(); } - // data space map + // Check the data space map. { let data_sm = data_sm.lock().unwrap(); let root = unpack::(&sb.data_sm_root[0..])?; @@ -265,6 +266,7 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> { blocks.push(Block::new(i.blocknr)); } + // FIXME: we should do this in batches engine.read_many(&mut blocks)?; let mut leaks = 0; @@ -322,6 +324,9 @@ pub fn check(opts: &ThinCheckOptions) -> Result<()> { } } + // Check the metadata space map. + + Ok(()) }