Merge pull request #171 from mingnus/rust-cache-tools

Fix bugs in array iteration and text outputs
This commit is contained in:
Joe Thornber 2021-05-13 15:02:41 +01:00 committed by GitHub
commit 4f192cea0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 33 deletions

14
src/cache/check.rs vendored
View File

@ -90,9 +90,7 @@ mod format1 {
fn visit(&self, _index: u64, b: ArrayBlock<Mapping>) -> array::Result<()> { fn visit(&self, _index: u64, b: ArrayBlock<Mapping>) -> array::Result<()> {
let mut errs: Vec<ArrayError> = Vec::new(); let mut errs: Vec<ArrayError> = Vec::new();
for i in 0..b.header.nr_entries as usize { for m in b.values.iter() {
let m = b.values[i];
if let Err(e) = self.check_flags(&m) { if let Err(e) = self.check_flags(&m) {
errs.push(e); errs.push(e);
} }
@ -180,12 +178,10 @@ mod format2 {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.lock().unwrap();
let mut errs: Vec<ArrayError> = Vec::new(); let mut errs: Vec<ArrayError> = Vec::new();
let begin = index as usize * b.header.max_entries as usize; let cbegin = index as u32 * b.header.max_entries;
for i in 0..b.header.nr_entries { let cend = cbegin + b.header.nr_entries;
let m = b.values[i as usize]; for (m, cblock) in b.values.iter().zip(cbegin..cend) {
if let Err(e) = self.check_flags(&m, inner.dirty_bits.contains(cblock as usize)) {
if let Err(e) = self.check_flags(&m, inner.dirty_bits.contains(begin + i as usize))
{
errs.push(e); errs.push(e);
} }
if let Err(e) = self.check_oblock(&m, &mut inner.seen_oblocks) { if let Err(e) = self.check_oblock(&m, &mut inner.seen_oblocks) {

35
src/cache/dump.rs vendored
View File

@ -47,20 +47,21 @@ mod format1 {
impl<'a> ArrayVisitor<Mapping> for MappingEmitter<'a> { impl<'a> ArrayVisitor<Mapping> for MappingEmitter<'a> {
fn visit(&self, index: u64, b: ArrayBlock<Mapping>) -> array::Result<()> { fn visit(&self, index: u64, b: ArrayBlock<Mapping>) -> array::Result<()> {
for i in 0..b.header.nr_entries as usize { let cbegin = index as u32 * b.header.max_entries;
let map = b.values[i]; let cend = cbegin + b.header.nr_entries;
for (map, cblock) in b.values.iter().zip(cbegin..cend) {
if !map.is_valid() { if !map.is_valid() {
continue; continue;
} }
let m = xml::Map { let m = xml::Map {
cblock: index as u32, cblock,
oblock: map.oblock, oblock: map.oblock,
dirty: map.is_dirty(), dirty: map.is_dirty(),
}; };
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.lock().unwrap();
inner.valid_mappings.set(index as usize, true); inner.valid_mappings.set(cblock as usize, true);
inner inner
.visitor .visitor
.mapping(&m) .mapping(&m)
@ -100,9 +101,7 @@ mod format2 {
impl ArrayVisitor<u64> for DirtyVisitor { impl ArrayVisitor<u64> for DirtyVisitor {
fn visit(&self, index: u64, b: ArrayBlock<u64>) -> array::Result<()> { fn visit(&self, index: u64, b: ArrayBlock<u64>) -> array::Result<()> {
let mut pos = (index as usize * (b.header.max_entries as usize)) << 6; let mut pos = (index as usize * (b.header.max_entries as usize)) << 6;
for i in 0..b.header.nr_entries as usize { for bits in b.values.iter() {
let bits = b.values[i];
for bi in 0..64u64 { for bi in 0..64u64 {
if pos >= self.nr_entries { if pos >= self.nr_entries {
break; break;
@ -152,22 +151,22 @@ mod format2 {
impl<'a> ArrayVisitor<Mapping> for MappingEmitter<'a> { impl<'a> ArrayVisitor<Mapping> for MappingEmitter<'a> {
fn visit(&self, index: u64, b: ArrayBlock<Mapping>) -> array::Result<()> { fn visit(&self, index: u64, b: ArrayBlock<Mapping>) -> array::Result<()> {
for i in 0..b.header.nr_entries as usize { let cbegin = index as u32 * b.header.max_entries;
let map = b.values[i]; let cend = cbegin + b.header.nr_entries;
for (map, cblock) in b.values.iter().zip(cbegin..cend) {
if !map.is_valid() { if !map.is_valid() {
continue; continue;
} }
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.lock().unwrap();
let dirty = inner.dirty_bits.contains(index as usize); let dirty = inner.dirty_bits.contains(cblock as usize);
let m = xml::Map { let m = xml::Map {
cblock: index as u32, cblock,
oblock: map.oblock, oblock: map.oblock,
dirty, dirty,
}; };
inner.valid_mappings.set(index as usize, true); inner.valid_mappings.set(cblock as usize, true);
inner inner
.visitor .visitor
.mapping(&m) .mapping(&m)
@ -196,13 +195,13 @@ impl<'a> HintEmitter<'a> {
impl<'a> ArrayVisitor<Hint> for HintEmitter<'a> { impl<'a> ArrayVisitor<Hint> for HintEmitter<'a> {
fn visit(&self, index: u64, b: ArrayBlock<Hint>) -> array::Result<()> { fn visit(&self, index: u64, b: ArrayBlock<Hint>) -> array::Result<()> {
let mut cblock = index as u32 * b.header.max_entries; let cbegin = index as u32 * b.header.max_entries;
for i in 0..b.header.nr_entries as usize { let cend = cbegin + b.header.nr_entries;
for (hint, cblock) in b.values.iter().zip(cbegin..cend) {
if !self.valid_mappings.contains(cblock as usize) { if !self.valid_mappings.contains(cblock as usize) {
continue; continue;
} }
let hint = b.values[i];
let h = xml::Hint { let h = xml::Hint {
cblock, cblock,
data: hint.hint.to_vec(), data: hint.hint.to_vec(),
@ -213,8 +212,6 @@ impl<'a> ArrayVisitor<Hint> for HintEmitter<'a> {
.unwrap() .unwrap()
.hint(&h) .hint(&h)
.map_err(|e| array::value_err(format!("{}", e)))?; .map_err(|e| array::value_err(format!("{}", e)))?;
cblock += 1;
} }
Ok(()) Ok(())
@ -254,7 +251,7 @@ fn dump_metadata(ctx: &Context, sb: &Superblock, _repair: bool) -> anyhow::Resul
uuid: "".to_string(), uuid: "".to_string(),
block_size: sb.data_block_size, block_size: sb.data_block_size,
nr_cache_blocks: sb.cache_blocks, nr_cache_blocks: sb.cache_blocks,
policy: std::str::from_utf8(&sb.policy_name[..])?.to_string(), policy: std::str::from_utf8(&sb.policy_name)?.to_string(),
hint_width: sb.policy_hint_size, hint_width: sb.policy_hint_size,
}; };
out.superblock_b(&xml_sb)?; out.superblock_b(&xml_sb)?;

View File

@ -104,7 +104,7 @@ fn unpack(data: &[u8]) -> IResult<&[u8], Superblock> {
}, },
block, block,
version, version,
policy_name: policy_name.to_vec(), policy_name: policy_name.splitn(2, |c| *c == 0).next().unwrap().to_vec(),
policy_version: vec![vsn_major, vsn_minor, vsn_patch], policy_version: vec![vsn_major, vsn_minor, vsn_patch],
policy_hint_size, policy_hint_size,
metadata_sm_root: metadata_sm_root.to_vec(), metadata_sm_root: metadata_sm_root.to_vec(),

2
src/cache/xml.rs vendored
View File

@ -119,7 +119,7 @@ impl<W: Write> MetadataVisitor for XmlWriter<W> {
} }
fn mapping(&mut self, m: &Map) -> Result<Visit> { fn mapping(&mut self, m: &Map) -> Result<Visit> {
let tag = b"map"; let tag = b"mapping";
let mut elem = BytesStart::owned(tag.to_vec(), tag.len()); let mut elem = BytesStart::owned(tag.to_vec(), tag.len());
elem.push_attribute(mk_attr(b"cache_block", m.cblock)); elem.push_attribute(mk_attr(b"cache_block", m.cblock));
elem.push_attribute(mk_attr(b"origin_block", m.oblock)); elem.push_attribute(mk_attr(b"origin_block", m.oblock));

View File

@ -53,7 +53,9 @@ impl<'a, V: Unpack + Copy> NodeVisitor<u64> for BlockValueVisitor<'a, V> {
keys: &[u64], keys: &[u64],
values: &[u64], values: &[u64],
) -> btree::Result<()> { ) -> btree::Result<()> {
let mut path = path.to_vec(); if keys.is_empty() {
return Ok(());
}
// The ordering of array indices had been verified in unpack_node(), // The ordering of array indices had been verified in unpack_node(),
// thus checking the upper bound implies key continuity among siblings. // thus checking the upper bound implies key continuity among siblings.
@ -86,6 +88,7 @@ impl<'a, V: Unpack + Copy> NodeVisitor<u64> for BlockValueVisitor<'a, V> {
array_errs.push(array::io_err(&path, values[i]).index_context(keys[i])); array_errs.push(array::io_err(&path, values[i]).index_context(keys[i]));
} }
Ok(b) => { Ok(b) => {
let mut path = path.to_vec();
path.push(b.loc); path.push(b.loc);
match unpack_array_block::<V>(&path, b.get_data()) { match unpack_array_block::<V>(&path, b.get_data()) {
Ok(array_block) => { Ok(array_block) => {

View File

@ -58,10 +58,9 @@ impl ArrayVisitor<u64> for BitsetVisitor {
))); )));
} }
for i in 0..b.header.nr_entries as usize { for bits in b.values.iter() {
let end: usize = std::cmp::min(begin + 64, self.nr_bits as usize); let end: usize = std::cmp::min(begin + 64, self.nr_bits as usize);
let mut mask = 1; let mut mask = 1;
let bits = b.values[i];
for bi in begin..end { for bi in begin..end {
self.bits.lock().unwrap().set(bi, bits & mask != 0); self.bits.lock().unwrap().set(bi, bits & mask != 0);