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 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 | 516 |
517 return state; | 517 return state; |
518 | 518 |
519 nomem: | 519 nomem: |
520 DMCRIT("failed to allocate memory for entry->nodes from pool"); | 520 DMCRIT("failed to allocate memory for entry->nodes from pool"); |
521 return -ENOMEM; | 521 return -ENOMEM; |
522 | 522 |
523 | 523 |
524 } | 524 } |
525 | 525 |
526 static int dm_bht_compare_hash(struct dm_bht *bht, u8 *known, u8 *computed) | |
527 { | |
528 return memcmp(known, computed, bht->digest_size); | |
529 } | |
530 | |
531 /* dm_bht_verify_path | 526 /* dm_bht_verify_path |
532 * Verifies the path. Returns 0 on ok. | 527 * Verifies the path. Returns 0 on ok. |
533 */ | 528 */ |
534 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index, | 529 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index, |
535 struct page *pg, unsigned int offset) | 530 struct page *pg, unsigned int offset) |
536 { | 531 { |
537 unsigned int depth = bht->depth; | 532 unsigned int depth = bht->depth; |
538 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; | 533 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; |
539 struct dm_bht_entry *entry; | 534 struct dm_bht_entry *entry; |
540 u8 *node; | 535 u8 *node; |
541 int state; | 536 int state; |
542 | 537 |
543 do { | 538 do { |
544 /* Need to check that the hash of the current block is accurate | 539 /* Need to check that the hash of the current block is accurate |
545 * in its parent. | 540 * in its parent. |
546 */ | 541 */ |
547 entry = dm_bht_get_entry(bht, depth - 1, block_index); | 542 entry = dm_bht_get_entry(bht, depth - 1, block_index); |
548 state = atomic_read(&entry->state); | 543 state = atomic_read(&entry->state); |
549 /* This call is only safe if all nodes along the path | 544 /* This call is only safe if all nodes along the path |
550 * are already populated (i.e. READY) via dm_bht_populate. | 545 * are already populated (i.e. READY) via dm_bht_populate. |
551 */ | 546 */ |
552 BUG_ON(state < DM_BHT_ENTRY_READY); | 547 BUG_ON(state < DM_BHT_ENTRY_READY); |
553 node = dm_bht_get_node(bht, entry, depth, block_index); | 548 node = dm_bht_get_node(bht, entry, depth, block_index); |
554 | 549 |
555 if (dm_bht_compute_hash(bht, pg, offset, digest) || | 550 if (dm_bht_compute_hash(bht, pg, offset, digest) || |
556 » » dm_bht_compare_hash(bht, digest, node)) | 551 » » memcmp(digest, node, bht->digest_size)) |
557 goto mismatch; | 552 goto mismatch; |
558 | 553 |
559 /* Keep the containing block of hashes to be verified in the | 554 /* Keep the containing block of hashes to be verified in the |
560 * next pass. | 555 * next pass. |
561 */ | 556 */ |
562 pg = virt_to_page(entry->nodes); | 557 pg = virt_to_page(entry->nodes); |
563 offset = 0; | 558 offset = 0; |
564 } while (--depth > 0 && state != DM_BHT_ENTRY_VERIFIED); | 559 } while (--depth > 0 && state != DM_BHT_ENTRY_VERIFIED); |
565 | 560 |
566 if (depth == 0 && state != DM_BHT_ENTRY_VERIFIED) { | 561 if (depth == 0 && state != DM_BHT_ENTRY_VERIFIED) { |
567 if (dm_bht_compute_hash(bht, pg, offset, digest) || | 562 if (dm_bht_compute_hash(bht, pg, offset, digest) || |
568 » » dm_bht_compare_hash(bht, digest, bht->root_digest)) | 563 » » memcmp(digest, bht->root_digest, bht->digest_size)) |
569 goto mismatch; | 564 goto mismatch; |
570 atomic_set(&entry->state, DM_BHT_ENTRY_VERIFIED); | 565 atomic_set(&entry->state, DM_BHT_ENTRY_VERIFIED); |
571 } | 566 } |
572 | 567 |
573 /* Mark path to leaf as verified. */ | 568 /* Mark path to leaf as verified. */ |
574 for (depth++; depth < bht->depth; depth++) { | 569 for (depth++; depth < bht->depth; depth++) { |
575 entry = dm_bht_get_entry(bht, depth, block_index); | 570 entry = dm_bht_get_entry(bht, depth, block_index); |
576 /* At this point, entry can only be in VERIFIED or READY state. | 571 /* At this point, entry can only be in VERIFIED or READY state. |
577 * So it is safe to use atomic_set instead of atomic_cmpxchg. | 572 * So it is safe to use atomic_set instead of atomic_cmpxchg. |
578 */ | 573 */ |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 if (!bht->root_digest) { | 1011 if (!bht->root_digest) { |
1017 DMERR("no root digest exists to export"); | 1012 DMERR("no root digest exists to export"); |
1018 if (available > 0) | 1013 if (available > 0) |
1019 *hexdigest = 0; | 1014 *hexdigest = 0; |
1020 return -1; | 1015 return -1; |
1021 } | 1016 } |
1022 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); | 1017 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); |
1023 return 0; | 1018 return 0; |
1024 } | 1019 } |
1025 EXPORT_SYMBOL(dm_bht_root_hexdigest); | 1020 EXPORT_SYMBOL(dm_bht_root_hexdigest); |
OLD | NEW |