Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: dm-bht.c

Issue 5361004: CHROMIUM: verity: Cleanup dm_bht_verify_path. (Closed) Base URL: http://git.chromium.org/git/dm-verity.git@master
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 return leaf >> dm_bht_get_level_shift(bht, depth); 148 return leaf >> dm_bht_get_level_shift(bht, depth);
149 } 149 }
150 150
151 static __always_inline u8 *dm_bht_node(struct dm_bht *bht, 151 static __always_inline u8 *dm_bht_node(struct dm_bht *bht,
152 struct dm_bht_entry *entry, 152 struct dm_bht_entry *entry,
153 unsigned int node_index) 153 unsigned int node_index)
154 { 154 {
155 return &entry->nodes[node_index * bht->digest_size]; 155 return &entry->nodes[node_index * bht->digest_size];
156 } 156 }
157 157
158 static inline struct dm_bht_entry *dm_bht_get_entry(struct dm_bht *bht,
159 unsigned int depth,
160 unsigned int block_index)
161 {
162 unsigned int index = dm_bht_index_at_level(bht, depth, block_index);
163 struct dm_bht_level *level = dm_bht_get_level(bht, depth);
164
Will Drewry 2010/11/29 17:13:13 I'd like to bring back the BUG_ON(index >= level->
Mandeep Singh Baines 2010/11/29 20:20:38 Fixed.
165 return &level->entries[index];
166 }
167
168 static inline u8 *dm_bht_get_node(struct dm_bht *bht,
169 struct dm_bht_entry *parent,
170 unsigned int depth,
171 unsigned int block_index)
172 {
173 unsigned int index = dm_bht_index_at_level(bht, depth, block_index);
174
Will Drewry 2010/11/29 17:13:13 Same here!
Mandeep Singh Baines 2010/11/29 20:20:38 Fixed.
175 return dm_bht_node(bht, parent, index % bht->node_count);
176 }
177
158 178
159 /*----------------------------------------------- 179 /*-----------------------------------------------
160 * Implementation functions 180 * Implementation functions
161 *-----------------------------------------------*/ 181 *-----------------------------------------------*/
162 182
163 static int dm_bht_initialize_entries(struct dm_bht *bht); 183 static int dm_bht_initialize_entries(struct dm_bht *bht);
164 184
165 static int dm_bht_read_callback_stub(void *ctx, sector_t start, u8 *dst, 185 static int dm_bht_read_callback_stub(void *ctx, sector_t start, u8 *dst,
166 sector_t count, 186 sector_t count,
167 struct dm_bht_entry *entry); 187 struct dm_bht_entry *entry);
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 atomic_set(&bht->root_state, DM_BHT_ENTRY_VERIFIED); 707 atomic_set(&bht->root_state, DM_BHT_ENTRY_VERIFIED);
688 return 0; 708 return 0;
689 } 709 }
690 710
691 /* dm_bht_verify_path 711 /* dm_bht_verify_path
692 * Verifies the path from block_index to depth=0. Returns 0 on ok. 712 * Verifies the path from block_index to depth=0. Returns 0 on ok.
693 */ 713 */
694 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index, 714 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index,
695 dm_bht_compare_cb compare_cb) 715 dm_bht_compare_cb compare_cb)
696 { 716 {
697 » unsigned int depth = bht->depth; 717 » unsigned int depth = bht->depth - 1;
698 » struct dm_bht_level *level; 718 » struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index);
699 » struct dm_bht_entry *entry; 719 » struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()];
700 » struct dm_bht_entry *parent = NULL;
701 » u8 *node;
702 » unsigned int node_index;
703 » unsigned int entry_index;
704 » unsigned int parent_index = 0; /* for logging */
705 » struct hash_desc *hash_desc;
706 » int state;
707 » int ret = 0;
708 720
709 » hash_desc = &bht->hash_desc[smp_processor_id()]; 721 » while (depth > 0) {
710 » while (depth-- > 0) { 722 » » struct dm_bht_entry *parent;
Will Drewry 2010/11/29 17:13:13 In the past, I used to avoid setting up scoped var
Mandeep Singh Baines 2010/11/29 20:20:38 http://stackoverflow.com/questions/982963/is-there
711 » » level = dm_bht_get_level(bht, depth); 723 » » u8 *node;
712 » » entry_index = dm_bht_index_at_level(bht, depth, block_index); 724 » » int state;
713 » » DMDEBUG("verify_path for bi=%u on d=%d ei=%u (max=%u)",
714 » » » block_index, depth, entry_index, level->count);
715 » » BUG_ON(entry_index >= level->count);
716 » » entry = &level->entries[entry_index];
717 725
718 » » /* Catch any existing errors */ 726 » » DMDEBUG("verify_path for bi=%u on d=%d", block_index, depth);
727
719 state = atomic_read(&entry->state); 728 state = atomic_read(&entry->state);
720 » » if (state <= DM_BHT_ENTRY_ERROR) { 729 » » if (state == DM_BHT_ENTRY_VERIFIED) {
721 » » » DMCRIT("entry(d=%u,idx=%u) is in an error state: %d", 730 » » » DMDEBUG("verify_path node %u is verified in parent",
722 » » » depth, entry_index, state); 731 » » » » block_index);
732 » » » break;
Will Drewry 2010/11/29 17:13:13 Why is this a break and not a continue now? Just
Mandeep Singh Baines 2010/11/29 20:20:38 Fixed.
733 » » } else if (state <= DM_BHT_ENTRY_ERROR) {
734 » » » DMCRIT("entry(d=%u,b=%u) is in an error state: %d",
735 » » » depth, block_index, state);
723 DMCRIT("verification is not possible"); 736 DMCRIT("verification is not possible");
724 » » » ret = 1; 737 » » » return 1;
725 » » » break;
726 } else if (state <= DM_BHT_ENTRY_PENDING) { 738 } else if (state <= DM_BHT_ENTRY_PENDING) {
727 » » » DMERR("entry not ready for verify: d=%u,e=%u", 739 » » » DMERR("entry not ready for verify: d=%u,b=%u",
728 » » » depth, entry_index); 740 » » » depth, block_index);
729 » » » ret = 1; 741 » » » return 1;
730 » » » break;
731 } 742 }
732 743
733 /* At depth 0, we're at the page underneath the root node and 744 /* At depth 0, we're at the page underneath the root node and
734 * leave its validation to a separate path. 745 * leave its validation to a separate path.
735 */ 746 */
736 if (depth == 0) 747 if (depth == 0)
737 break; 748 break;
738 749
739 /* Grab the parent entry where the current entry hash is. */
740 parent_index = dm_bht_index_at_level(bht, depth - 1,
741 block_index);
742 level = dm_bht_get_level(bht, depth - 1);
743 BUG_ON(parent_index >= level->count);
744 parent = &level->entries[parent_index];
745
746 /* Because we are one level down, the node_index into the
747 * the parent's node list modulo the number of nodes.
748 */
749 node_index = entry_index % bht->node_count;
750
751 /* If the nodes in entry have already been checked against the
752 * parent, then we're done.
753 */
754 if (state == DM_BHT_ENTRY_VERIFIED) {
755 DMDEBUG("verify_path node %u is verified in parent %u",
756 node_index, parent_index);
757 /* If this entry has been checked, move along. */
758 continue;
759 }
760
761 /* We need to check that this entry matches the expected 750 /* We need to check that this entry matches the expected
762 * hash in the parent->nodes. 751 * hash in the parent->nodes.
763 */ 752 */
764 » » node = dm_bht_node(bht, parent, node_index); 753 » » parent = dm_bht_get_entry(bht, depth - 1, block_index);
Will Drewry 2010/11/29 17:13:13 So I just noticed a problem with the last change I
Mandeep Singh Baines 2010/11/29 20:20:38 Fixed per discussion over chat.
765 » » DMDEBUG("verify_path: node is not verified in parent " 754 » » node = dm_bht_get_node(bht, parent, depth, block_index);
766 » » "(d=%u,ei=%u,p=%u,pnode=%u)",
767 » » depth, entry_index, parent_index, node_index);
768 755
769 if (dm_bht_compute_and_compare(bht, hash_desc, 756 if (dm_bht_compute_and_compare(bht, hash_desc,
770 virt_to_page(entry->nodes), 757 virt_to_page(entry->nodes),
771 node, compare_cb)) { 758 node, compare_cb)) {
772 DMERR("failed to verify entry's hash against parent " 759 DMERR("failed to verify entry's hash against parent "
773 » » » "(d=%u,ei=%u,p=%u,pnode=%u)", 760 » » » "(d=%u,bi=%u)", depth, block_index);
774 » » » depth, entry_index, parent_index, node_index); 761 » » » return DM_BHT_ENTRY_ERROR_MISMATCH;
775 » » » ret = DM_BHT_ENTRY_ERROR_MISMATCH;
776 » » » break;
777 } 762 }
778 763
779 /* Instead of keeping a bitmap of which children have been
780 * checked, this data is kept in the child state. If full
781 * reverifies have been set, then no intermediate entry/node is
782 * ever marked as verified.
783 */
784 if (bht->verify_mode != DM_BHT_FULL_REVERIFY) 764 if (bht->verify_mode != DM_BHT_FULL_REVERIFY)
785 atomic_cmpxchg(&entry->state, 765 atomic_cmpxchg(&entry->state,
786 DM_BHT_ENTRY_READY, 766 DM_BHT_ENTRY_READY,
787 DM_BHT_ENTRY_VERIFIED); 767 DM_BHT_ENTRY_VERIFIED);
768
769 entry = parent;
770 depth--;
788 } 771 }
789 » return ret; 772
773 » return 0;
790 } 774 }
791 775
792 /** 776 /**
793 * dm_bht_store_block - sets a given block's hash in the tree 777 * dm_bht_store_block - sets a given block's hash in the tree
794 * @bht: pointer to a dm_bht_create()d bht 778 * @bht: pointer to a dm_bht_create()d bht
795 * @block_index:numeric index of the block in the tree 779 * @block_index:numeric index of the block in the tree
796 * @digest: array of u8s containing the digest of length @bht->digest_size 780 * @digest: array of u8s containing the digest of length @bht->digest_size
797 * 781 *
798 * Returns 0 on success, >0 when data is pending, and <0 when a IO or other 782 * Returns 0 on success, >0 when data is pending, and <0 when a IO or other
799 * error has occurred. 783 * error has occurred.
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 DMERR("no root digest exists to export"); 1286 DMERR("no root digest exists to export");
1303 if (available > 0) 1287 if (available > 0)
1304 *hexdigest = 0; 1288 *hexdigest = 0;
1305 return -1; 1289 return -1;
1306 } 1290 }
1307 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1291 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1308 return 0; 1292 return 0;
1309 } 1293 }
1310 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1294 EXPORT_SYMBOL(dm_bht_root_hexdigest);
1311 1295
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698