From 3a653eaa5fe9af9215664ca7d75f6e82ceb56577 Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Wed, 26 May 2021 21:18:53 +0800 Subject: [PATCH] [thin_restore (rust)] Build metadata and data space maps --- src/thin/restore.rs | 67 ++++++++++++++++++++++++++++++++++++------ src/thin/superblock.rs | 4 +-- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/thin/restore.rs b/src/thin/restore.rs index d435250..7f1bfa7 100644 --- a/src/thin/restore.rs +++ b/src/thin/restore.rs @@ -2,12 +2,17 @@ use anyhow::{anyhow, Result}; use std::collections::BTreeMap; use std::fs::OpenOptions; +use std::io::Cursor; +use std::ops::Deref; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use crate::io_engine::*; use crate::pdata::btree_builder::*; use crate::pdata::space_map::*; +use crate::pdata::space_map_disk::*; +use crate::pdata::space_map_metadata::*; +use crate::pdata::unpack::Pack; use crate::report::*; use crate::thin::block_time::*; use crate::thin::device_detail::*; @@ -17,6 +22,25 @@ use crate::write_batcher::*; //------------------------------------------ +struct MappingRC { + sm: Arc>, +} + +impl RefCounter for MappingRC { + fn get(&self, v: &BlockTime) -> Result { + return self.sm.lock().unwrap().get(v.block); + } + fn inc(&mut self, v: &BlockTime) -> Result<()> { + self.sm.lock().unwrap().inc(v.block, 1) + } + fn dec(&mut self, v: &BlockTime) -> Result<()> { + self.sm.lock().unwrap().dec(v.block)?; + Ok(()) + } +} + +//------------------------------------------ + enum MappedSection { Def(String), Dev(u32), @@ -31,9 +55,12 @@ impl std::fmt::Display for MappedSection { } } +//------------------------------------------ + struct Pass1Result { sb: xml::Superblock, devices: BTreeMap)>, + data_sm: Arc>, } struct Pass1<'a> { @@ -47,6 +74,7 @@ struct Pass1<'a> { sb: Option, devices: BTreeMap)>, + data_sm: Option>>, } impl<'a> Pass1<'a> { @@ -58,6 +86,7 @@ impl<'a> Pass1<'a> { map: None, sb: None, devices: BTreeMap::new(), + data_sm: None, } } @@ -68,6 +97,7 @@ impl<'a> Pass1<'a> { Ok(Pass1Result { sb: self.sb.unwrap(), devices: self.devices, + data_sm: self.data_sm.unwrap(), }) } @@ -80,7 +110,9 @@ impl<'a> Pass1<'a> { return Err(anyhow!(msg)); } - let value_rc = Box::new(NoopRC {}); + let value_rc = Box::new(MappingRC { + sm: self.data_sm.as_ref().unwrap().clone(), + }); let leaf_builder = NodeBuilder::new(Box::new(LeafIO {}), value_rc); self.map = Some((section, leaf_builder)); @@ -103,6 +135,7 @@ impl<'a> Pass1<'a> { impl<'a> MetadataVisitor for Pass1<'a> { fn superblock_b(&mut self, sb: &xml::Superblock) -> Result { self.sb = Some(sb.clone()); + self.data_sm = Some(core_sm(sb.nr_data_blocks, u32::MAX)); self.w.alloc()?; Ok(Visit::Continue) } @@ -196,13 +229,29 @@ impl<'a> MetadataVisitor for Pass1<'a> { } //------------------------------------------ -/* + /// Writes a data space map to disk. Returns the space map root that needs /// to be written to the superblock. -fn build_data_sm(batcher: WriteBatcher, sm: Box) -> Result> { +fn build_data_sm(w: &mut WriteBatcher, sm: &dyn SpaceMap) -> Result> { + let mut sm_root = vec![0u8; SPACE_MAP_ROOT_SIZE]; + let mut cur = Cursor::new(&mut sm_root); + let r = write_disk_sm(w, sm)?; + r.pack(&mut cur)?; + Ok(sm_root) +} + +/// Writes the metadata space map to disk. Returns the space map root that needs +/// to be written to the superblock. +fn build_metadata_sm(w: &mut WriteBatcher) -> Result> { + let mut sm_root = vec![0u8; SPACE_MAP_ROOT_SIZE]; + let mut cur = Cursor::new(&mut sm_root); + let sm_without_meta = clone_space_map(w.sm.lock().unwrap().deref())?; + let r = write_metadata_sm(w, sm_without_meta.deref())?; + r.pack(&mut cur)?; + + Ok(sm_root) } -*/ //------------------------------------------ @@ -279,11 +328,11 @@ pub fn restore(opts: ThinRestoreOptions) -> Result<()> { let mapping_root = builder.complete(&mut w)?; // Build data space map + let data_sm_root = build_data_sm(&mut w, pass.data_sm.lock().unwrap().deref())?; // FIXME: I think we need to decrement the shared leaves // Build metadata space map - - w.flush()?; + let metadata_sm_root = build_metadata_sm(&mut w)?; // Write the superblock let sb = superblock::Superblock { @@ -293,8 +342,8 @@ pub fn restore(opts: ThinRestoreOptions) -> Result<()> { time: pass.sb.time as u32, transaction_id: pass.sb.transaction, metadata_snap: 0, - data_sm_root: vec![0; SPACE_MAP_ROOT_SIZE], - metadata_sm_root: vec![0; SPACE_MAP_ROOT_SIZE], + data_sm_root, + metadata_sm_root, mapping_root, details_root, data_block_size: pass.sb.data_block_size, diff --git a/src/thin/superblock.rs b/src/thin/superblock.rs index af3eca8..e9c071c 100644 --- a/src/thin/superblock.rs +++ b/src/thin/superblock.rs @@ -116,8 +116,8 @@ fn pack_superblock(sb: &Superblock, w: &mut W) -> Result<()> { w.write_u32::(sb.time)?; w.write_u64::(sb.transaction_id)?; w.write_u64::(sb.metadata_snap)?; - w.write_all(&[0; SPACE_MAP_ROOT_SIZE])?; // data sm root - w.write_all(&[0; SPACE_MAP_ROOT_SIZE])?; // metadata sm root + w.write_all(&sb.data_sm_root)?; + w.write_all(&sb.metadata_sm_root)?; w.write_u64::(sb.mapping_root)?; w.write_u64::(sb.details_root)?; w.write_u32::(sb.data_block_size)?;