[cache (rust)] Fix bugs in array iteration and text outputs
- Fix array indexing - Fix panic on empty array - Remove trailing null characters from the policy name - Change XML tag naming for backward compatibility
This commit is contained in:
parent
11c354b3b1
commit
7e53c36d6b
14
src/cache/check.rs
vendored
14
src/cache/check.rs
vendored
@ -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
35
src/cache/dump.rs
vendored
@ -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)?;
|
||||||
|
2
src/cache/superblock.rs
vendored
2
src/cache/superblock.rs
vendored
@ -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
2
src/cache/xml.rs
vendored
@ -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));
|
||||||
|
@ -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) => {
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user