Chromium Code Reviews| Index: drivers/md/dm-bht.c |
| diff --git a/drivers/md/dm-bht.c b/drivers/md/dm-bht.c |
| index 35713de9bdd0b7f20dc8975443faa4f541087c36..726f210ab724178c21f82148ffa6ba385e3c2ddf 100644 |
| --- a/drivers/md/dm-bht.c |
| +++ b/drivers/md/dm-bht.c |
| @@ -163,9 +163,6 @@ static inline u8 *dm_bht_get_node(struct dm_bht *bht, |
| unsigned int block_index) |
| { |
| unsigned int index = dm_bht_index_at_level(bht, depth, block_index); |
| - struct dm_bht_level *level = dm_bht_get_level(bht, depth); |
| - |
| - BUG_ON(index >= level->count); |
| return dm_bht_node(bht, entry, index % bht->node_count); |
| } |
| @@ -590,32 +587,26 @@ static int dm_bht_update_hash(struct dm_bht *bht, u8 *known, u8 *computed) |
| /* digest length and bht must be checked already */ |
| static int dm_bht_check_block(struct dm_bht *bht, unsigned int block_index, |
| - u8 *digest, int *entry_state) |
| + const void *buf, int *entry_state) |
|
Will Drewry
2011/03/08 20:53:59
nit: might prefer something more meaningful like "
|
| { |
| - int depth; |
| - unsigned int index; |
| - struct dm_bht_entry *entry; |
| - |
| - /* The leaves contain the block hashes */ |
| - depth = bht->depth - 1; |
| - |
| - /* Index into the bottom level. Each entry in this level contains |
| - * nodes whose hashes are the direct hashes of one block of data on |
| - * disk. |
| - */ |
| - index = block_index >> bht->node_count_shift; |
| - entry = &bht->levels[depth].entries[index]; |
| + unsigned int depth = bht->depth; |
| + struct dm_bht_entry *parent = dm_bht_get_entry(bht, depth - 1, |
| + block_index); |
| + struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()]; |
| + u8 digest[DM_BHT_MAX_DIGEST_SIZE]; |
| + u8 *node; |
| /* This call is only safe if all nodes along the path |
| * are already populated (i.e. READY) via dm_bht_populate. |
| */ |
| - BUG_ON(atomic_read(&entry->state) < DM_BHT_ENTRY_READY); |
| - |
| - /* Index into the entry data */ |
| - index = (block_index % bht->node_count) * bht->digest_size; |
| - if (memcmp(&entry->nodes[index], digest, bht->digest_size)) { |
| - DMCRIT("digest mismatch for block %u", block_index); |
| - dm_bht_log_mismatch(bht, &entry->nodes[index], digest); |
| + *entry_state = atomic_read(&parent->state); |
| + BUG_ON(*entry_state < DM_BHT_ENTRY_READY); |
| + |
| + node = dm_bht_get_node(bht, parent, depth, block_index); |
| + if (dm_bht_compute_hash(bht, hash_desc, virt_to_page(buf), digest) || |
| + dm_bht_compare_hash(bht, digest, node)) { |
| + DMERR("failed to verify entry's hash against parent " |
| + "(d=%u,bi=%u)", depth, block_index); |
| return DM_BHT_ENTRY_ERROR_MISMATCH; |
| } |
| return 0; |
| @@ -1069,17 +1060,11 @@ EXPORT_SYMBOL(dm_bht_populate); |
| * should return similarly. |
| */ |
| int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index, |
| - u8 *digest, unsigned int digest_len) |
| + const void *buf) |
|
Will Drewry
2011/03/08 20:53:59
Please update the comments.
|
| { |
| int unverified = 0; |
| int entry_state = 0; |
| - /* TODO(wad) do we really need this? */ |
| - if (digest_len != bht->digest_size) { |
| - DMERR("invalid digest_len passed to verify_block"); |
| - return -EINVAL; |
| - } |
| - |
| /* Make sure that the root has been verified */ |
| if (atomic_read(&bht->root_state) != DM_BHT_ENTRY_VERIFIED) { |
| unverified = dm_bht_verify_root(bht, dm_bht_compare_hash); |
| @@ -1090,7 +1075,7 @@ int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index, |
| } |
| /* Now check that the digest supplied matches the leaf hash */ |
| - unverified = dm_bht_check_block(bht, block_index, digest, &entry_state); |
| + unverified = dm_bht_check_block(bht, block_index, buf, &entry_state); |
| if (unverified) { |
| DMERR_LIMIT("Block check failed for %u: %d", block_index, |
| unverified); |