[space_map (rust)] Fix uninitialized bytes in index block

This commit is contained in:
Ming-Hung Tsai 2021-06-03 16:43:14 +08:00
parent 01aac6c1c1
commit 60b65ebe7a
3 changed files with 20 additions and 9 deletions

View File

@ -190,14 +190,6 @@ fn gather_metadata_index_entries(
) -> Result<Vec<IndexEntry>> { ) -> Result<Vec<IndexEntry>> {
let b = engine.read(bitmap_root)?; let b = engine.read(bitmap_root)?;
let entries = unpack::<MetadataIndex>(b.get_data())?.indexes; let entries = unpack::<MetadataIndex>(b.get_data())?.indexes;
// Filter out unused entries with block 0
let entries: Vec<IndexEntry> = entries
.iter()
.take_while(|e| e.blocknr != 0)
.cloned()
.collect();
metadata_sm.lock().unwrap().inc(bitmap_root, 1)?; metadata_sm.lock().unwrap().inc(bitmap_root, 1)?;
inc_entries(&metadata_sm, &entries[0..])?; inc_entries(&metadata_sm, &entries[0..])?;

View File

@ -34,6 +34,13 @@ impl Unpack for MetadataIndex {
let (i, blocknr) = le_u64(i)?; let (i, blocknr) = le_u64(i)?;
let (i, indexes) = nom::multi::count(IndexEntry::unpack, MAX_METADATA_BITMAPS)(i)?; let (i, indexes) = nom::multi::count(IndexEntry::unpack, MAX_METADATA_BITMAPS)(i)?;
// Filter out unused entries
let indexes: Vec<IndexEntry> = indexes
.iter()
.take_while(|e| e.blocknr != 0)
.cloned()
.collect();
Ok((i, MetadataIndex { blocknr, indexes })) Ok((i, MetadataIndex { blocknr, indexes }))
} }
} }
@ -100,7 +107,7 @@ pub fn write_metadata_sm(w: &mut WriteBatcher, sm: &dyn SpaceMap) -> Result<SMRo
w.clear_allocations(); w.clear_allocations();
let (mut indexes, ref_count_root) = write_common(w, sm)?; let (mut indexes, ref_count_root) = write_common(w, sm)?;
let bitmap_root = w.alloc()?; let bitmap_root = w.alloc_zeroed()?;
// Now we need to patch up the counts for the metadata that was used for storing // Now we need to patch up the counts for the metadata that was used for storing
// the space map itself. These ref counts all went from 0 to 1. // the space map itself. These ref counts all went from 0 to 1.

View File

@ -47,6 +47,18 @@ impl WriteBatcher {
Ok(Block::new(b.unwrap())) Ok(Block::new(b.unwrap()))
} }
pub fn alloc_zeroed(&mut self) -> Result<Block> {
let mut sm = self.sm.lock().unwrap();
let b = sm.alloc()?;
if b.is_none() {
return Err(anyhow!("out of metadata space"));
}
self.allocations.insert(b.unwrap());
Ok(Block::zeroed(b.unwrap()))
}
pub fn clear_allocations(&mut self) -> BTreeSet<u64> { pub fn clear_allocations(&mut self) -> BTreeSet<u64> {
let mut tmp = BTreeSet::new(); let mut tmp = BTreeSet::new();
std::mem::swap(&mut tmp, &mut self.allocations); std::mem::swap(&mut tmp, &mut self.allocations);