OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> | 2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> |
3 * | 3 * |
4 * Device-Mapper block hash tree interface. | 4 * Device-Mapper block hash tree interface. |
5 * See Documentation/device-mapper/dm-bht.txt for details. | 5 * See Documentation/device-mapper/dm-bht.txt for details. |
6 * | 6 * |
7 * This file is released under the GPL. | 7 * This file is released under the GPL. |
8 */ | 8 */ |
9 | 9 |
10 #include <asm/atomic.h> | 10 #include <asm/atomic.h> |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 while (depth > 0) { | 686 while (depth > 0) { |
687 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; | 687 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; |
688 struct dm_bht_entry *parent; | 688 struct dm_bht_entry *parent; |
689 struct page *page; | 689 struct page *page; |
690 u8 *node; | 690 u8 *node; |
691 int state; | 691 int state; |
692 | 692 |
693 DMDEBUG("verify_path for b=%u on d=%d", block_index, depth); | 693 DMDEBUG("verify_path for b=%u on d=%d", block_index, depth); |
694 state = atomic_read(&entry->state); | 694 state = atomic_read(&entry->state); |
695 if (state == DM_BHT_ENTRY_VERIFIED) { | 695 if (state == DM_BHT_ENTRY_VERIFIED) { |
696 » » » DMDEBUG("verify_path node %u is verified in parent", | 696 » » » DMDEBUG("verify_path node %u is verified to root", |
697 block_index); | 697 block_index); |
698 » » » entry = dm_bht_get_entry(bht, --depth, block_index); | 698 » » » break; |
Will Drewry
2011/03/10 22:42:50
Nice! I *think* this works :)
You're going to wan
| |
699 » » » continue; | |
700 } else if (state <= DM_BHT_ENTRY_ERROR) { | 699 } else if (state <= DM_BHT_ENTRY_ERROR) { |
701 DMCRIT("entry(d=%u,b=%u) is in an error state: %d", | 700 DMCRIT("entry(d=%u,b=%u) is in an error state: %d", |
702 depth, block_index, state); | 701 depth, block_index, state); |
703 DMCRIT("verification is not possible"); | 702 DMCRIT("verification is not possible"); |
704 goto mismatch; | 703 goto mismatch; |
705 } else if (state <= DM_BHT_ENTRY_PENDING) { | 704 } else if (state <= DM_BHT_ENTRY_PENDING) { |
706 DMERR("entry not ready for verify: d=%u,b=%u", | 705 DMERR("entry not ready for verify: d=%u,b=%u", |
707 depth, block_index); | 706 depth, block_index); |
708 goto mismatch; | 707 goto mismatch; |
709 } | 708 } |
710 | 709 |
711 /* We need to check that this entry matches the expected | 710 /* We need to check that this entry matches the expected |
712 * hash in the parent->nodes. | 711 * hash in the parent->nodes. |
713 */ | 712 */ |
714 parent = dm_bht_get_entry(bht, depth - 1, block_index); | 713 parent = dm_bht_get_entry(bht, depth - 1, block_index); |
715 /* This call is only safe if all nodes along the path | 714 /* This call is only safe if all nodes along the path |
716 * are already populated (i.e. READY) via dm_bht_populate. | 715 * are already populated (i.e. READY) via dm_bht_populate. |
717 */ | 716 */ |
718 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY); | 717 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY); |
Will Drewry
2011/03/10 22:42:50
unrelated note for either of us later :)
we can p
| |
719 node = dm_bht_get_node(bht, parent, depth, block_index); | 718 node = dm_bht_get_node(bht, parent, depth, block_index); |
720 page = virt_to_page(entry->nodes); | 719 page = virt_to_page(entry->nodes); |
721 | 720 |
722 if (dm_bht_compute_hash(bht, page, digest) || | 721 if (dm_bht_compute_hash(bht, page, digest) || |
723 dm_bht_compare_hash(bht, digest, node)) { | 722 dm_bht_compare_hash(bht, digest, node)) { |
724 DMERR("failed to verify entry's hash against parent " | 723 DMERR("failed to verify entry's hash against parent " |
725 "(d=%u,bi=%u)", depth, block_index); | 724 "(d=%u,bi=%u)", depth, block_index); |
726 goto mismatch; | 725 goto mismatch; |
727 } | 726 } |
728 | 727 |
729 atomic_cmpxchg(&entry->state, | |
730 DM_BHT_ENTRY_READY, | |
731 DM_BHT_ENTRY_VERIFIED); | |
732 | |
733 entry = parent; | 728 entry = parent; |
734 depth--; | 729 depth--; |
735 } | 730 } |
731 /* Mark path to leaf as verified. */ | |
732 for (; depth < bht->depth; depth++) { | |
Will Drewry
2011/03/10 22:42:50
Interesting tradeoffs here. If we did root-to-lea
| |
733 entry = dm_bht_get_entry(bht, depth, block_index); | |
734 atomic_cmpxchg(&entry->state, | |
735 DM_BHT_ENTRY_READY, | |
736 DM_BHT_ENTRY_VERIFIED); | |
737 } | |
736 | 738 |
737 return 0; | 739 return 0; |
738 | 740 |
739 mismatch: | 741 mismatch: |
740 return DM_BHT_ENTRY_ERROR_MISMATCH; | 742 return DM_BHT_ENTRY_ERROR_MISMATCH; |
741 } | 743 } |
742 | 744 |
743 /** | 745 /** |
744 * dm_bht_store_block - sets a given block's hash in the tree | 746 * dm_bht_store_block - sets a given block's hash in the tree |
745 * @bht: pointer to a dm_bht_create()d bht | 747 * @bht: pointer to a dm_bht_create()d bht |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1226 DMERR("no root digest exists to export"); | 1228 DMERR("no root digest exists to export"); |
1227 if (available > 0) | 1229 if (available > 0) |
1228 *hexdigest = 0; | 1230 *hexdigest = 0; |
1229 return -1; | 1231 return -1; |
1230 } | 1232 } |
1231 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); | 1233 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); |
1232 return 0; | 1234 return 0; |
1233 } | 1235 } |
1234 EXPORT_SYMBOL(dm_bht_root_hexdigest); | 1236 EXPORT_SYMBOL(dm_bht_root_hexdigest); |
1235 | 1237 |
OLD | NEW |