| 667 | } |
| 668 | |
| 669 | ddt_entry_t * |
| 670 | ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add) |
| 671 | { |
| 672 | ddt_entry_t *dde, dde_search; |
| 673 | enum ddt_type type; |
| 674 | enum ddt_class class; |
| 675 | avl_index_t where; |
| 676 | int error; |
| 677 | |
| 678 | ASSERT(MUTEX_HELD(&ddt->ddt_lock)); |
| 679 | |
| 680 | ddt_key_fill(&dde_search.dde_key, bp); |
| 681 | |
| 682 | dde = avl_find(&ddt->ddt_tree, &dde_search, &where); |
| 683 | if (dde == NULL) { |
| 684 | if (!add) |
| 685 | return (NULL); |
| 686 | dde = ddt_alloc(&dde_search.dde_key); |
| 687 | avl_insert(&ddt->ddt_tree, dde, where); |
| 688 | } |
| 689 | |
| 690 | while (dde->dde_loading) |
| 691 | cv_wait(&dde->dde_cv, &ddt->ddt_lock); |
| 692 | |
| 693 | if (dde->dde_loaded) |
| 694 | return (dde); |
| 695 | |
| 696 | dde->dde_loading = B_TRUE; |
| 697 | |
| 698 | ddt_exit(ddt); |
| 699 | |
| 700 | error = ENOENT; |
| 701 | |
| 702 | for (type = 0; type < DDT_TYPES; type++) { |
| 703 | for (class = 0; class < DDT_CLASSES; class++) { |
| 704 | error = ddt_object_lookup(ddt, type, class, dde); |
| 705 | if (error != ENOENT) { |
| 706 | ASSERT0(error); |
| 707 | break; |
| 708 | } |
| 709 | } |
| 710 | if (error != ENOENT) |
| 711 | break; |
| 712 | } |
| 713 | |
| 714 | ddt_enter(ddt); |
| 715 | |
| 716 | ASSERT(dde->dde_loaded == B_FALSE); |
| 717 | ASSERT(dde->dde_loading == B_TRUE); |
| 718 | |
| 719 | dde->dde_type = type; /* will be DDT_TYPES if no entry found */ |
| 720 | dde->dde_class = class; /* will be DDT_CLASSES if no entry found */ |
| 721 | dde->dde_loaded = B_TRUE; |
| 722 | dde->dde_loading = B_FALSE; |
| 723 | |
| 724 | if (error == 0) |
| 725 | ddt_stat_update(ddt, dde, -1ULL); |
| 726 |
no test coverage detected