diff --git a/block-cache/block_cache.h b/block-cache/block_cache.h index 4bc6667..5de2c44 100644 --- a/block-cache/block_cache.h +++ b/block-cache/block_cache.h @@ -26,12 +26,14 @@ namespace bcache { virtual ~validator() {} virtual void check(void const *data, block_address location) const = 0; + virtual bool check_raw(void const *data) const = 0; virtual void prepare(void *data, block_address location) const = 0; }; class noop_validator : public validator { public: void check(void const *data, block_address location) const {} + bool check_raw(void const *data) const {return true;} void prepare(void *data, block_address location) const {} }; diff --git a/caching/superblock.cc b/caching/superblock.cc index 2edd6c1..3270b3f 100644 --- a/caching/superblock.cc +++ b/caching/superblock.cc @@ -292,6 +292,15 @@ namespace validator { throw checksum_error("bad checksum in superblock"); } + virtual bool check_raw(void const *raw) const { + superblock_disk const *sbd = reinterpret_cast(raw); + crc32c sum(SUPERBLOCK_CSUM_SEED); + sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(sbd->csum)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { superblock_disk *sbd = reinterpret_cast(raw); crc32c sum(SUPERBLOCK_CSUM_SEED); diff --git a/era/superblock.cc b/era/superblock.cc index e013064..f61a542 100644 --- a/era/superblock.cc +++ b/era/superblock.cc @@ -219,6 +219,15 @@ namespace era_validator { throw checksum_error("bad checksum in superblock"); } + virtual bool check_raw(void const *raw) const { + superblock_disk const *sbd = reinterpret_cast(raw); + crc32c sum(SUPERBLOCK_CSUM_SEED); + sum.append(&sbd->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(sbd->csum)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { superblock_disk *sbd = reinterpret_cast(raw); crc32c sum(SUPERBLOCK_CSUM_SEED); diff --git a/persistent-data/data-structures/array.h b/persistent-data/data-structures/array.h index 1b87160..d7b1f70 100644 --- a/persistent-data/data-structures/array.h +++ b/persistent-data/data-structures/array.h @@ -43,6 +43,15 @@ namespace persistent_data { throw checksum_error("bad block nr in array block"); } + virtual bool check_raw(void const *raw) const { + array_block_disk const *data = reinterpret_cast(raw); + crc32c sum(ARRAY_CSUM_XOR); + sum.append(&data->max_entries, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(data->csum)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { array_block_disk *data = reinterpret_cast(raw); data->blocknr = to_disk(location); diff --git a/persistent-data/data-structures/btree.tcc b/persistent-data/data-structures/btree.tcc index 06d0deb..3fc96e4 100644 --- a/persistent-data/data-structures/btree.tcc +++ b/persistent-data/data-structures/btree.tcc @@ -32,7 +32,6 @@ namespace { using namespace persistent_data; using namespace btree_detail; using namespace std; - } //---------------------------------------------------------------- diff --git a/persistent-data/space-maps/disk.cc b/persistent-data/space-maps/disk.cc index cab9583..ed7bae8 100644 --- a/persistent-data/space-maps/disk.cc +++ b/persistent-data/space-maps/disk.cc @@ -50,6 +50,15 @@ namespace { throw checksum_error("bad block nr in space map bitmap"); } + virtual bool check_raw(void const *raw) const { + bitmap_header const *data = reinterpret_cast(raw); + crc32c sum(BITMAP_CSUM_XOR); + sum.append(&data->not_used, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(data->csum)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { bitmap_header *data = reinterpret_cast(raw); data->blocknr = to_disk(location); @@ -77,6 +86,15 @@ namespace { throw checksum_error("bad block nr in metadata index block"); } + virtual bool check_raw(void const *raw) const { + metadata_index const *mi = reinterpret_cast(raw); + crc32c sum(INDEX_CSUM_XOR); + sum.append(&mi->padding_, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(mi->csum_)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { metadata_index *mi = reinterpret_cast(raw); mi->blocknr_ = to_disk(location); diff --git a/persistent-data/validators.cc b/persistent-data/validators.cc index b9c163c..a50947d 100644 --- a/persistent-data/validators.cc +++ b/persistent-data/validators.cc @@ -31,6 +31,16 @@ namespace { } } + virtual bool check_raw(void const *raw) const { + disk_node const *data = reinterpret_cast(raw); + node_header const *n = &data->header; + crc32c sum(BTREE_CSUM_XOR); + sum.append(&n->flags, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(n->csum)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { disk_node *data = reinterpret_cast(raw); node_header *n = &data->header; diff --git a/thin-provisioning/superblock.cc b/thin-provisioning/superblock.cc index fb0d17e..f63ed52 100644 --- a/thin-provisioning/superblock.cc +++ b/thin-provisioning/superblock.cc @@ -98,6 +98,15 @@ namespace { } } + virtual bool check_raw(void const *raw) const { + superblock_disk const *sbd = reinterpret_cast(raw); + crc32c sum(SUPERBLOCK_CSUM_SEED); + sum.append(&sbd->flags_, MD_BLOCK_SIZE - sizeof(uint32_t)); + if (sum.get_sum() != to_cpu(sbd->csum_)) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { superblock_disk *sbd = reinterpret_cast(raw); crc32c sum(SUPERBLOCK_CSUM_SEED); diff --git a/unit-tests/block_t.cc b/unit-tests/block_t.cc index c2a6d58..1a61d2b 100644 --- a/unit-tests/block_t.cc +++ b/unit-tests/block_t.cc @@ -44,6 +44,14 @@ namespace { throw runtime_error("validator check zero"); } + virtual bool check_raw(void const *raw) const { + unsigned char const *data = reinterpret_cast(raw); + for (unsigned b = 0; b < BlockSize; b++) + if (data[b] != 0) + return false; + return true; + } + virtual void prepare(void *raw, block_address location) const { unsigned char *data = reinterpret_cast(raw); for (unsigned b = 0; b < BlockSize; b++)