[all (rust)] Pull out structures for intermediate representation
Also fix the data type for thin timestamp
This commit is contained in:
parent
6d31d4def2
commit
7002a8ae8d
11
src/cache/dump.rs
vendored
11
src/cache/dump.rs
vendored
@ -7,9 +7,10 @@ use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::cache::hint::Hint;
|
||||
use crate::cache::ir::{self, MetadataVisitor};
|
||||
use crate::cache::mapping::Mapping;
|
||||
use crate::cache::superblock::*;
|
||||
use crate::cache::xml::{self, MetadataVisitor};
|
||||
use crate::cache::xml;
|
||||
use crate::io_engine::{AsyncIoEngine, IoEngine, SyncIoEngine};
|
||||
use crate::pdata::array::{self, ArrayBlock};
|
||||
use crate::pdata::array_walker::*;
|
||||
@ -58,7 +59,7 @@ mod format1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let m = xml::Map {
|
||||
let m = ir::Map {
|
||||
cblock,
|
||||
oblock: map.oblock,
|
||||
dirty: map.is_dirty(),
|
||||
@ -133,7 +134,7 @@ mod format2 {
|
||||
// default to dirty if the bitset is damaged
|
||||
dirty = true;
|
||||
}
|
||||
let m = xml::Map {
|
||||
let m = ir::Map {
|
||||
cblock,
|
||||
oblock: map.oblock,
|
||||
dirty,
|
||||
@ -175,7 +176,7 @@ impl<'a> ArrayVisitor<Hint> for HintEmitter<'a> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let h = xml::Hint {
|
||||
let h = ir::Hint {
|
||||
cblock,
|
||||
data: hint.hint.to_vec(),
|
||||
};
|
||||
@ -226,7 +227,7 @@ fn dump_metadata(
|
||||
let engine = &ctx.engine;
|
||||
|
||||
let mut out = xml::XmlWriter::new(w);
|
||||
let xml_sb = xml::Superblock {
|
||||
let xml_sb = ir::Superblock {
|
||||
uuid: "".to_string(),
|
||||
block_size: sb.data_block_size,
|
||||
nr_cache_blocks: sb.cache_blocks,
|
||||
|
60
src/cache/ir.rs
vendored
Normal file
60
src/cache/ir.rs
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
use anyhow::Result;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Superblock {
|
||||
pub uuid: String,
|
||||
pub block_size: u32,
|
||||
pub nr_cache_blocks: u32,
|
||||
pub policy: String,
|
||||
pub hint_width: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Map {
|
||||
pub cblock: u32,
|
||||
pub oblock: u64,
|
||||
pub dirty: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Hint {
|
||||
pub cblock: u32,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Discard {
|
||||
pub begin: u64,
|
||||
pub end: u64,
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Visit {
|
||||
Continue,
|
||||
Stop,
|
||||
}
|
||||
|
||||
pub trait MetadataVisitor {
|
||||
fn superblock_b(&mut self, sb: &Superblock) -> Result<Visit>;
|
||||
fn superblock_e(&mut self) -> Result<Visit>;
|
||||
|
||||
fn mappings_b(&mut self) -> Result<Visit>;
|
||||
fn mappings_e(&mut self) -> Result<Visit>;
|
||||
fn mapping(&mut self, m: &Map) -> Result<Visit>;
|
||||
|
||||
fn hints_b(&mut self) -> Result<Visit>;
|
||||
fn hints_e(&mut self) -> Result<Visit>;
|
||||
fn hint(&mut self, h: &Hint) -> Result<Visit>;
|
||||
|
||||
fn discards_b(&mut self) -> Result<Visit>;
|
||||
fn discards_e(&mut self) -> Result<Visit>;
|
||||
fn discard(&mut self, d: &Discard) -> Result<Visit>;
|
||||
|
||||
fn eof(&mut self) -> Result<Visit>;
|
||||
}
|
||||
|
||||
//------------------------------------------
|
1
src/cache/mod.rs
vendored
1
src/cache/mod.rs
vendored
@ -1,6 +1,7 @@
|
||||
pub mod check;
|
||||
pub mod dump;
|
||||
pub mod hint;
|
||||
pub mod ir;
|
||||
pub mod mapping;
|
||||
pub mod restore;
|
||||
pub mod superblock;
|
||||
|
15
src/cache/restore.rs
vendored
15
src/cache/restore.rs
vendored
@ -7,9 +7,10 @@ use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cache::hint::Hint;
|
||||
use crate::cache::ir::{self, MetadataVisitor, Visit};
|
||||
use crate::cache::mapping::{Mapping, MappingFlags};
|
||||
use crate::cache::superblock::*;
|
||||
use crate::cache::xml::{self, MetadataVisitor, Visit};
|
||||
use crate::cache::xml;
|
||||
use crate::io_engine::*;
|
||||
use crate::math::*;
|
||||
use crate::pdata::array_builder::*;
|
||||
@ -56,7 +57,7 @@ fn mk_context(opts: &CacheRestoreOptions) -> anyhow::Result<Context> {
|
||||
//------------------------------------------
|
||||
|
||||
struct RestoreResult {
|
||||
sb: xml::Superblock,
|
||||
sb: ir::Superblock,
|
||||
mapping_root: u64,
|
||||
dirty_root: Option<u64>,
|
||||
hint_root: u64,
|
||||
@ -65,7 +66,7 @@ struct RestoreResult {
|
||||
|
||||
struct Restorer<'a> {
|
||||
write_batcher: &'a mut WriteBatcher,
|
||||
sb: Option<xml::Superblock>,
|
||||
sb: Option<ir::Superblock>,
|
||||
mapping_builder: Option<ArrayBuilder<Mapping>>,
|
||||
dirty_builder: Option<ArrayBuilder<u64>>,
|
||||
hint_builder: Option<ArrayBuilder<Hint>>,
|
||||
@ -112,7 +113,7 @@ impl<'a> Restorer<'a> {
|
||||
}
|
||||
|
||||
impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
fn superblock_b(&mut self, sb: &xml::Superblock) -> Result<Visit> {
|
||||
fn superblock_b(&mut self, sb: &ir::Superblock) -> Result<Visit> {
|
||||
self.sb = Some(sb.clone());
|
||||
self.write_batcher.alloc()?;
|
||||
self.mapping_builder = Some(ArrayBuilder::new(sb.nr_cache_blocks as u64));
|
||||
@ -157,7 +158,7 @@ impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
fn mapping(&mut self, m: &xml::Map) -> Result<Visit> {
|
||||
fn mapping(&mut self, m: &ir::Map) -> Result<Visit> {
|
||||
let map = Mapping {
|
||||
oblock: m.oblock,
|
||||
flags: MappingFlags::Valid as u32,
|
||||
@ -198,7 +199,7 @@ impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
fn hint(&mut self, h: &xml::Hint) -> Result<Visit> {
|
||||
fn hint(&mut self, h: &ir::Hint) -> Result<Visit> {
|
||||
let hint = Hint {
|
||||
hint: h.data[..].try_into().unwrap(),
|
||||
};
|
||||
@ -215,7 +216,7 @@ impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
fn discard(&mut self, _d: &xml::Discard) -> Result<Visit> {
|
||||
fn discard(&mut self, _d: &ir::Discard) -> Result<Visit> {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
|
54
src/cache/xml.rs
vendored
54
src/cache/xml.rs
vendored
@ -6,63 +6,11 @@ use std::io::{Read, Write};
|
||||
use quick_xml::events::{BytesEnd, BytesStart, Event};
|
||||
use quick_xml::{Reader, Writer};
|
||||
|
||||
use crate::cache::ir::*;
|
||||
use crate::xml::*;
|
||||
|
||||
//---------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Superblock {
|
||||
pub uuid: String,
|
||||
pub block_size: u32,
|
||||
pub nr_cache_blocks: u32,
|
||||
pub policy: String,
|
||||
pub hint_width: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Map {
|
||||
pub cblock: u32,
|
||||
pub oblock: u64,
|
||||
pub dirty: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Hint {
|
||||
pub cblock: u32,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Discard {
|
||||
pub begin: u64,
|
||||
pub end: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Visit {
|
||||
Continue,
|
||||
Stop,
|
||||
}
|
||||
|
||||
pub trait MetadataVisitor {
|
||||
fn superblock_b(&mut self, sb: &Superblock) -> Result<Visit>;
|
||||
fn superblock_e(&mut self) -> Result<Visit>;
|
||||
|
||||
fn mappings_b(&mut self) -> Result<Visit>;
|
||||
fn mappings_e(&mut self) -> Result<Visit>;
|
||||
fn mapping(&mut self, m: &Map) -> Result<Visit>;
|
||||
|
||||
fn hints_b(&mut self) -> Result<Visit>;
|
||||
fn hints_e(&mut self) -> Result<Visit>;
|
||||
fn hint(&mut self, h: &Hint) -> Result<Visit>;
|
||||
|
||||
fn discards_b(&mut self) -> Result<Visit>;
|
||||
fn discards_e(&mut self) -> Result<Visit>;
|
||||
fn discard(&mut self, d: &Discard) -> Result<Visit>;
|
||||
|
||||
fn eof(&mut self) -> Result<Visit>;
|
||||
}
|
||||
|
||||
pub struct XmlWriter<W: Write> {
|
||||
w: Writer<W>,
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::shrink::copier::{self, Region};
|
||||
use crate::thin::xml::{self, Visit};
|
||||
use crate::thin::ir::{self, MetadataVisitor, Visit};
|
||||
use crate::thin::xml;
|
||||
|
||||
//---------------------------------------
|
||||
|
||||
@ -34,8 +35,8 @@ impl Pass1 {
|
||||
}
|
||||
}
|
||||
|
||||
impl xml::MetadataVisitor for Pass1 {
|
||||
fn superblock_b(&mut self, sb: &xml::Superblock) -> Result<Visit> {
|
||||
impl MetadataVisitor for Pass1 {
|
||||
fn superblock_b(&mut self, sb: &ir::Superblock) -> Result<Visit> {
|
||||
self.allocated_blocks.grow(sb.nr_data_blocks as usize);
|
||||
self.block_size = Some(sb.data_block_size as u64);
|
||||
Ok(Visit::Continue)
|
||||
@ -53,7 +54,7 @@ impl xml::MetadataVisitor for Pass1 {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn device_b(&mut self, _d: &xml::Device) -> Result<Visit> {
|
||||
fn device_b(&mut self, _d: &ir::Device) -> Result<Visit> {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
@ -61,7 +62,7 @@ impl xml::MetadataVisitor for Pass1 {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
fn map(&mut self, m: &xml::Map) -> Result<Visit> {
|
||||
fn map(&mut self, m: &ir::Map) -> Result<Visit> {
|
||||
for i in m.data_begin..(m.data_begin + m.len) {
|
||||
if i > self.nr_blocks {
|
||||
self.nr_high_blocks += 1;
|
||||
@ -99,8 +100,8 @@ impl<W: Write> Pass2<W> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> xml::MetadataVisitor for Pass2<W> {
|
||||
fn superblock_b(&mut self, sb: &xml::Superblock) -> Result<Visit> {
|
||||
impl<W: Write> MetadataVisitor for Pass2<W> {
|
||||
fn superblock_b(&mut self, sb: &ir::Superblock) -> Result<Visit> {
|
||||
self.writer.superblock_b(sb)
|
||||
}
|
||||
|
||||
@ -116,7 +117,7 @@ impl<W: Write> xml::MetadataVisitor for Pass2<W> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn device_b(&mut self, d: &xml::Device) -> Result<Visit> {
|
||||
fn device_b(&mut self, d: &ir::Device) -> Result<Visit> {
|
||||
self.writer.device_b(d)
|
||||
}
|
||||
|
||||
@ -124,7 +125,7 @@ impl<W: Write> xml::MetadataVisitor for Pass2<W> {
|
||||
self.writer.device_e()
|
||||
}
|
||||
|
||||
fn map(&mut self, m: &xml::Map) -> Result<Visit> {
|
||||
fn map(&mut self, m: &ir::Map) -> Result<Visit> {
|
||||
if m.data_begin + m.len < self.nr_blocks {
|
||||
// no remapping needed.
|
||||
self.writer.map(m)?;
|
||||
@ -134,7 +135,7 @@ impl<W: Write> xml::MetadataVisitor for Pass2<W> {
|
||||
let mut written = 0;
|
||||
|
||||
for r in remaps {
|
||||
self.writer.map(&xml::Map {
|
||||
self.writer.map(&ir::Map {
|
||||
thin_begin: m.thin_begin + written,
|
||||
data_begin: r.start,
|
||||
time: m.time,
|
||||
@ -493,7 +494,7 @@ fn build_copy_regions(remaps: &[(BlockRange, BlockRange)], block_size: u64) -> V
|
||||
rs
|
||||
}
|
||||
|
||||
fn process_xml<MV: xml::MetadataVisitor>(input_path: &Path, pass: &mut MV) -> Result<()> {
|
||||
fn process_xml<MV: MetadataVisitor>(input_path: &Path, pass: &mut MV) -> Result<()> {
|
||||
let input = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(false)
|
||||
|
@ -18,14 +18,15 @@ use crate::pdata::unpack::*;
|
||||
use crate::report::*;
|
||||
use crate::thin::block_time::*;
|
||||
use crate::thin::device_detail::*;
|
||||
use crate::thin::ir::{self, MetadataVisitor};
|
||||
use crate::thin::runs::*;
|
||||
use crate::thin::superblock::*;
|
||||
use crate::thin::xml::{self, MetadataVisitor};
|
||||
use crate::thin::xml;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
struct RunBuilder {
|
||||
run: Option<xml::Map>,
|
||||
run: Option<ir::Map>,
|
||||
}
|
||||
|
||||
impl RunBuilder {
|
||||
@ -33,12 +34,12 @@ impl RunBuilder {
|
||||
RunBuilder { run: None }
|
||||
}
|
||||
|
||||
fn next(&mut self, thin_block: u64, data_block: u64, time: u32) -> Option<xml::Map> {
|
||||
use xml::Map;
|
||||
fn next(&mut self, thin_block: u64, data_block: u64, time: u32) -> Option<ir::Map> {
|
||||
use ir::Map;
|
||||
|
||||
match self.run {
|
||||
None => {
|
||||
self.run = Some(xml::Map {
|
||||
self.run = Some(ir::Map {
|
||||
thin_begin: thin_block,
|
||||
data_begin: data_block,
|
||||
time,
|
||||
@ -46,7 +47,7 @@ impl RunBuilder {
|
||||
});
|
||||
None
|
||||
}
|
||||
Some(xml::Map {
|
||||
Some(ir::Map {
|
||||
thin_begin,
|
||||
data_begin,
|
||||
time: mtime,
|
||||
@ -70,7 +71,7 @@ impl RunBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn complete(&mut self) -> Option<xml::Map> {
|
||||
fn complete(&mut self) -> Option<ir::Map> {
|
||||
self.run.take()
|
||||
}
|
||||
}
|
||||
@ -78,7 +79,7 @@ impl RunBuilder {
|
||||
//------------------------------------------
|
||||
|
||||
struct MVInner<'a> {
|
||||
md_out: &'a mut dyn xml::MetadataVisitor,
|
||||
md_out: &'a mut dyn MetadataVisitor,
|
||||
builder: RunBuilder,
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ struct MappingVisitor<'a> {
|
||||
//------------------------------------------
|
||||
|
||||
impl<'a> MappingVisitor<'a> {
|
||||
fn new(md_out: &'a mut dyn xml::MetadataVisitor) -> MappingVisitor<'a> {
|
||||
fn new(md_out: &'a mut dyn MetadataVisitor) -> MappingVisitor<'a> {
|
||||
MappingVisitor {
|
||||
inner: Mutex::new(MVInner {
|
||||
md_out,
|
||||
@ -516,7 +517,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn emit_leaves(ctx: &Context, out: &mut dyn xml::MetadataVisitor, ls: &[u64]) -> Result<()> {
|
||||
fn emit_leaves(ctx: &Context, out: &mut dyn MetadataVisitor, ls: &[u64]) -> Result<()> {
|
||||
let mut v = MappingVisitor::new(out);
|
||||
let proc = |b| {
|
||||
emit_leaf(&mut v, &b)?;
|
||||
@ -560,9 +561,9 @@ fn emit_entries<W: Write>(
|
||||
fn dump_metadata(ctx: &Context, w: &mut dyn Write, sb: &Superblock, md: &Metadata) -> Result<()> {
|
||||
let data_root = unpack::<SMRoot>(&sb.data_sm_root[0..])?;
|
||||
let mut out = xml::XmlWriter::new(w);
|
||||
let xml_sb = xml::Superblock {
|
||||
let xml_sb = ir::Superblock {
|
||||
uuid: "".to_string(),
|
||||
time: sb.time as u64,
|
||||
time: sb.time,
|
||||
transaction: sb.transaction_id,
|
||||
flags: None,
|
||||
version: Some(2),
|
||||
@ -581,12 +582,12 @@ fn dump_metadata(ctx: &Context, w: &mut dyn Write, sb: &Superblock, md: &Metadat
|
||||
|
||||
ctx.report.set_title("Dumping devices");
|
||||
for dev in &md.devs {
|
||||
let device = xml::Device {
|
||||
let device = ir::Device {
|
||||
dev_id: dev.thin_id,
|
||||
mapped_blocks: dev.detail.mapped_blocks,
|
||||
transaction: dev.detail.transaction_id,
|
||||
creation_time: dev.detail.creation_time as u64,
|
||||
snap_time: dev.detail.snapshotted_time as u64,
|
||||
creation_time: dev.detail.creation_time,
|
||||
snap_time: dev.detail.snapshotted_time,
|
||||
};
|
||||
out.device_b(&device)?;
|
||||
emit_entries(ctx, &mut out, &dev.map.entries)?;
|
||||
|
60
src/thin/ir.rs
Normal file
60
src/thin/ir.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use anyhow::Result;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Superblock {
|
||||
pub uuid: String,
|
||||
pub time: u32,
|
||||
pub transaction: u64,
|
||||
pub flags: Option<u32>,
|
||||
pub version: Option<u32>,
|
||||
pub data_block_size: u32,
|
||||
pub nr_data_blocks: u64,
|
||||
pub metadata_snap: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Device {
|
||||
pub dev_id: u32,
|
||||
pub mapped_blocks: u64,
|
||||
pub transaction: u64,
|
||||
pub creation_time: u32,
|
||||
pub snap_time: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Map {
|
||||
pub thin_begin: u64,
|
||||
pub data_begin: u64,
|
||||
pub time: u32,
|
||||
pub len: u64,
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Visit {
|
||||
Continue,
|
||||
Stop,
|
||||
}
|
||||
|
||||
pub trait MetadataVisitor {
|
||||
fn superblock_b(&mut self, sb: &Superblock) -> Result<Visit>;
|
||||
fn superblock_e(&mut self) -> Result<Visit>;
|
||||
|
||||
// Defines a shared sub tree. May only contain a 'map' (no 'ref' allowed).
|
||||
fn def_shared_b(&mut self, name: &str) -> Result<Visit>;
|
||||
fn def_shared_e(&mut self) -> Result<Visit>;
|
||||
|
||||
// A device contains a number of 'map' or 'ref' items.
|
||||
fn device_b(&mut self, d: &Device) -> Result<Visit>;
|
||||
fn device_e(&mut self) -> Result<Visit>;
|
||||
|
||||
fn map(&mut self, m: &Map) -> Result<Visit>;
|
||||
fn ref_shared(&mut self, name: &str) -> Result<Visit>;
|
||||
|
||||
fn eof(&mut self) -> Result<Visit>;
|
||||
}
|
||||
|
||||
//------------------------------------------
|
@ -2,6 +2,7 @@ pub mod block_time;
|
||||
pub mod check;
|
||||
pub mod device_detail;
|
||||
pub mod dump;
|
||||
pub mod ir;
|
||||
pub mod restore;
|
||||
pub mod runs;
|
||||
pub mod superblock;
|
||||
|
@ -16,8 +16,9 @@ use crate::pdata::unpack::Pack;
|
||||
use crate::report::*;
|
||||
use crate::thin::block_time::*;
|
||||
use crate::thin::device_detail::*;
|
||||
use crate::thin::ir::{self, MetadataVisitor, Visit};
|
||||
use crate::thin::superblock::{self, *};
|
||||
use crate::thin::xml::{self, *};
|
||||
use crate::thin::xml;
|
||||
use crate::write_batcher::*;
|
||||
|
||||
//------------------------------------------
|
||||
@ -58,7 +59,7 @@ impl std::fmt::Display for MappedSection {
|
||||
//------------------------------------------
|
||||
|
||||
struct RestoreResult {
|
||||
sb: xml::Superblock,
|
||||
sb: ir::Superblock,
|
||||
devices: BTreeMap<u32, (DeviceDetail, u64)>,
|
||||
data_sm: Arc<Mutex<dyn SpaceMap>>,
|
||||
}
|
||||
@ -74,7 +75,7 @@ struct Restorer<'a> {
|
||||
current_map: Option<(MappedSection, NodeBuilder<BlockTime>)>,
|
||||
current_dev: Option<DeviceDetail>,
|
||||
|
||||
sb: Option<xml::Superblock>,
|
||||
sb: Option<ir::Superblock>,
|
||||
devices: BTreeMap<u32, (DeviceDetail, u64)>,
|
||||
data_sm: Option<Arc<Mutex<dyn SpaceMap>>>,
|
||||
}
|
||||
@ -136,7 +137,7 @@ impl<'a> Restorer<'a> {
|
||||
}
|
||||
|
||||
impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
fn superblock_b(&mut self, sb: &xml::Superblock) -> Result<Visit> {
|
||||
fn superblock_b(&mut self, sb: &ir::Superblock) -> Result<Visit> {
|
||||
self.sb = Some(sb.clone());
|
||||
self.data_sm = Some(core_sm(sb.nr_data_blocks, u32::MAX));
|
||||
self.w.alloc()?;
|
||||
@ -160,7 +161,7 @@ impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn device_b(&mut self, d: &Device) -> Result<Visit> {
|
||||
fn device_b(&mut self, d: &ir::Device) -> Result<Visit> {
|
||||
self.report
|
||||
.info(&format!("building btree for device {}", d.dev_id));
|
||||
self.current_dev = Some(DeviceDetail {
|
||||
@ -186,7 +187,7 @@ impl<'a> MetadataVisitor for Restorer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn map(&mut self, m: &Map) -> Result<Visit> {
|
||||
fn map(&mut self, m: &ir::Map) -> Result<Visit> {
|
||||
if let Some((_, builder)) = self.current_map.as_mut() {
|
||||
for i in 0..m.len {
|
||||
let bt = BlockTime {
|
||||
|
@ -4,63 +4,11 @@ use std::{io::prelude::*, io::BufReader, io::Write};
|
||||
use quick_xml::events::{BytesEnd, BytesStart, Event};
|
||||
use quick_xml::{Reader, Writer};
|
||||
|
||||
use crate::thin::ir::*;
|
||||
use crate::xml::*;
|
||||
|
||||
//---------------------------------------
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Superblock {
|
||||
pub uuid: String,
|
||||
pub time: u64,
|
||||
pub transaction: u64,
|
||||
pub flags: Option<u32>,
|
||||
pub version: Option<u32>,
|
||||
pub data_block_size: u32,
|
||||
pub nr_data_blocks: u64,
|
||||
pub metadata_snap: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Device {
|
||||
pub dev_id: u32,
|
||||
pub mapped_blocks: u64,
|
||||
pub transaction: u64,
|
||||
pub creation_time: u64,
|
||||
pub snap_time: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Map {
|
||||
pub thin_begin: u64,
|
||||
pub data_begin: u64,
|
||||
pub time: u32,
|
||||
pub len: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Visit {
|
||||
Continue,
|
||||
Stop,
|
||||
}
|
||||
|
||||
pub trait MetadataVisitor {
|
||||
fn superblock_b(&mut self, sb: &Superblock) -> Result<Visit>;
|
||||
fn superblock_e(&mut self) -> Result<Visit>;
|
||||
|
||||
// Defines a shared sub tree. May only contain a 'map' (no 'ref' allowed).
|
||||
fn def_shared_b(&mut self, name: &str) -> Result<Visit>;
|
||||
fn def_shared_e(&mut self) -> Result<Visit>;
|
||||
|
||||
// A device contains a number of 'map' or 'ref' items.
|
||||
fn device_b(&mut self, d: &Device) -> Result<Visit>;
|
||||
fn device_e(&mut self) -> Result<Visit>;
|
||||
|
||||
fn map(&mut self, m: &Map) -> Result<Visit>;
|
||||
fn ref_shared(&mut self, name: &str) -> Result<Visit>;
|
||||
|
||||
fn eof(&mut self) -> Result<Visit>;
|
||||
}
|
||||
|
||||
pub struct XmlWriter<W: Write> {
|
||||
w: Writer<W>,
|
||||
}
|
||||
@ -178,7 +126,7 @@ impl<W: Write> MetadataVisitor for XmlWriter<W> {
|
||||
|
||||
fn parse_superblock(e: &BytesStart) -> Result<Superblock> {
|
||||
let mut uuid: Option<String> = None;
|
||||
let mut time: Option<u64> = None;
|
||||
let mut time: Option<u32> = None;
|
||||
let mut transaction: Option<u64> = None;
|
||||
let mut flags: Option<u32> = None;
|
||||
let mut version: Option<u32> = None;
|
||||
@ -190,7 +138,7 @@ fn parse_superblock(e: &BytesStart) -> Result<Superblock> {
|
||||
let kv = a.unwrap();
|
||||
match kv.key {
|
||||
b"uuid" => uuid = Some(string_val(&kv)),
|
||||
b"time" => time = Some(u64_val(&kv)?),
|
||||
b"time" => time = Some(u32_val(&kv)?),
|
||||
b"transaction" => transaction = Some(u64_val(&kv)?),
|
||||
b"flags" => flags = Some(u32_val(&kv)?),
|
||||
b"version" => version = Some(u32_val(&kv)?),
|
||||
@ -235,8 +183,8 @@ fn parse_device(e: &BytesStart) -> Result<Device> {
|
||||
let mut dev_id: Option<u32> = None;
|
||||
let mut mapped_blocks: Option<u64> = None;
|
||||
let mut transaction: Option<u64> = None;
|
||||
let mut creation_time: Option<u64> = None;
|
||||
let mut snap_time: Option<u64> = None;
|
||||
let mut creation_time: Option<u32> = None;
|
||||
let mut snap_time: Option<u32> = None;
|
||||
|
||||
for a in e.attributes() {
|
||||
let kv = a.unwrap();
|
||||
@ -244,8 +192,8 @@ fn parse_device(e: &BytesStart) -> Result<Device> {
|
||||
b"dev_id" => dev_id = Some(u32_val(&kv)?),
|
||||
b"mapped_blocks" => mapped_blocks = Some(u64_val(&kv)?),
|
||||
b"transaction" => transaction = Some(u64_val(&kv)?),
|
||||
b"creation_time" => creation_time = Some(u64_val(&kv)?),
|
||||
b"snap_time" => snap_time = Some(u64_val(&kv)?),
|
||||
b"creation_time" => creation_time = Some(u32_val(&kv)?),
|
||||
b"snap_time" => snap_time = Some(u32_val(&kv)?),
|
||||
_ => return bad_attr("device", kv.key),
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,13 @@ use rand::prelude::*;
|
||||
use std::collections::HashSet;
|
||||
use std::fs::OpenOptions;
|
||||
use std::path::Path;
|
||||
use thinp::cache::ir::{self, MetadataVisitor};
|
||||
use thinp::cache::xml;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
pub trait XmlGen {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()>;
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()>;
|
||||
}
|
||||
|
||||
pub fn write_xml(path: &Path, g: &mut dyn XmlGen) -> Result<()> {
|
||||
@ -50,8 +51,8 @@ impl CacheGen {
|
||||
}
|
||||
|
||||
impl XmlGen for CacheGen {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
|
||||
v.superblock_b(&xml::Superblock {
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
||||
v.superblock_b(&ir::Superblock {
|
||||
uuid: "".to_string(),
|
||||
block_size: self.block_size,
|
||||
nr_cache_blocks: self.nr_cache_blocks,
|
||||
@ -77,7 +78,7 @@ impl XmlGen for CacheGen {
|
||||
|
||||
used.insert(oblock);
|
||||
// FIXME: dirty should vary
|
||||
v.mapping(&xml::Map {
|
||||
v.mapping(&ir::Map {
|
||||
cblock: cblocks[n as usize],
|
||||
oblock,
|
||||
dirty: false,
|
||||
|
@ -4,12 +4,13 @@ use std::collections::VecDeque;
|
||||
use std::fs::OpenOptions;
|
||||
use std::ops::Range;
|
||||
use std::path::Path;
|
||||
use thinp::thin::ir::{self, MetadataVisitor};
|
||||
use thinp::thin::xml;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
pub trait XmlGen {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()>;
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()>;
|
||||
}
|
||||
|
||||
pub fn write_xml(path: &Path, g: &mut dyn XmlGen) -> Result<()> {
|
||||
@ -24,8 +25,8 @@ pub fn write_xml(path: &Path, g: &mut dyn XmlGen) -> Result<()> {
|
||||
g.generate_xml(&mut w)
|
||||
}
|
||||
|
||||
fn common_sb(nr_blocks: u64) -> xml::Superblock {
|
||||
xml::Superblock {
|
||||
fn common_sb(nr_blocks: u64) -> ir::Superblock {
|
||||
ir::Superblock {
|
||||
uuid: "".to_string(),
|
||||
time: 0,
|
||||
transaction: 0,
|
||||
@ -42,7 +43,7 @@ fn common_sb(nr_blocks: u64) -> xml::Superblock {
|
||||
pub struct EmptyPoolS {}
|
||||
|
||||
impl XmlGen for EmptyPoolS {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
||||
v.superblock_b(&common_sb(1024))?;
|
||||
v.superblock_e()?;
|
||||
Ok(())
|
||||
@ -70,16 +71,16 @@ impl SingleThinS {
|
||||
}
|
||||
|
||||
impl XmlGen for SingleThinS {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
||||
v.superblock_b(&common_sb(self.old_nr_data_blocks))?;
|
||||
v.device_b(&xml::Device {
|
||||
v.device_b(&ir::Device {
|
||||
dev_id: 0,
|
||||
mapped_blocks: self.len,
|
||||
transaction: 0,
|
||||
creation_time: 0,
|
||||
snap_time: 0,
|
||||
})?;
|
||||
v.map(&xml::Map {
|
||||
v.map(&ir::Map {
|
||||
thin_begin: 0,
|
||||
data_begin: self.offset,
|
||||
time: 0,
|
||||
@ -146,7 +147,7 @@ fn mk_runs(thin_id: u32, total_len: u64, run_len: std::ops::Range<u64>) -> Vec<T
|
||||
}
|
||||
|
||||
impl XmlGen for FragmentedS {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
||||
// Allocate each thin fully, in runs between 1 and 16.
|
||||
let mut runs = Vec::new();
|
||||
for thin in 0..self.nr_thins {
|
||||
@ -188,7 +189,7 @@ impl XmlGen for FragmentedS {
|
||||
// write the xml
|
||||
v.superblock_b(&common_sb(self.old_nr_data_blocks))?;
|
||||
for thin in 0..self.nr_thins {
|
||||
v.device_b(&xml::Device {
|
||||
v.device_b(&ir::Device {
|
||||
dev_id: thin,
|
||||
mapped_blocks: self.thin_size,
|
||||
transaction: 0,
|
||||
@ -201,7 +202,7 @@ impl XmlGen for FragmentedS {
|
||||
continue;
|
||||
}
|
||||
|
||||
v.map(&xml::Map {
|
||||
v.map(&ir::Map {
|
||||
thin_begin: m.thin_begin,
|
||||
data_begin: m.data_begin,
|
||||
time: 0,
|
||||
@ -329,8 +330,8 @@ struct ThinDev {
|
||||
}
|
||||
|
||||
impl ThinDev {
|
||||
fn emit(&self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
|
||||
v.device_b(&xml::Device {
|
||||
fn emit(&self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
||||
v.device_b(&ir::Device {
|
||||
dev_id: self.thin_id,
|
||||
mapped_blocks: self.dev_size,
|
||||
transaction: 0,
|
||||
@ -342,7 +343,7 @@ impl ThinDev {
|
||||
for r in &self.runs {
|
||||
match r {
|
||||
Run::Mapped { data_begin, len } => {
|
||||
v.map(&xml::Map {
|
||||
v.map(&ir::Map {
|
||||
thin_begin: b,
|
||||
data_begin: *data_begin,
|
||||
time: 0,
|
||||
@ -522,7 +523,7 @@ impl SnapS {
|
||||
}
|
||||
|
||||
impl XmlGen for SnapS {
|
||||
fn generate_xml(&mut self, v: &mut dyn xml::MetadataVisitor) -> Result<()> {
|
||||
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
||||
let mut allocator = Allocator::new_shuffled(self.old_nr_data_blocks, 64..512);
|
||||
let origin = mk_origin(0, self.len, &mut allocator)?;
|
||||
|
||||
|
@ -6,7 +6,8 @@ use std::io::{Cursor, Read, Seek, SeekFrom, Write};
|
||||
use std::path::Path;
|
||||
|
||||
use thinp::file_utils;
|
||||
use thinp::thin::xml::{self, Visit};
|
||||
use thinp::thin::ir::{self, MetadataVisitor, Visit};
|
||||
use thinp::thin::xml;
|
||||
|
||||
mod common;
|
||||
use common::test_dir::*;
|
||||
@ -91,8 +92,8 @@ struct ThinXmlVisitor<'a, V: ThinVisitor> {
|
||||
thin_id: Option<u32>,
|
||||
}
|
||||
|
||||
impl<'a, V: ThinVisitor> xml::MetadataVisitor for ThinXmlVisitor<'a, V> {
|
||||
fn superblock_b(&mut self, sb: &xml::Superblock) -> Result<Visit> {
|
||||
impl<'a, V: ThinVisitor> MetadataVisitor for ThinXmlVisitor<'a, V> {
|
||||
fn superblock_b(&mut self, sb: &ir::Superblock) -> Result<Visit> {
|
||||
self.block_size = Some(sb.data_block_size);
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
@ -109,7 +110,7 @@ impl<'a, V: ThinVisitor> xml::MetadataVisitor for ThinXmlVisitor<'a, V> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn device_b(&mut self, d: &xml::Device) -> Result<Visit> {
|
||||
fn device_b(&mut self, d: &ir::Device) -> Result<Visit> {
|
||||
self.thin_id = Some(d.dev_id);
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
@ -118,7 +119,7 @@ impl<'a, V: ThinVisitor> xml::MetadataVisitor for ThinXmlVisitor<'a, V> {
|
||||
Ok(Visit::Continue)
|
||||
}
|
||||
|
||||
fn map(&mut self, m: &xml::Map) -> Result<Visit> {
|
||||
fn map(&mut self, m: &ir::Map) -> Result<Visit> {
|
||||
for i in 0..m.len {
|
||||
let block = ThinBlock {
|
||||
thin_id: self.thin_id.unwrap(),
|
||||
|
Loading…
Reference in New Issue
Block a user