* Load from disk the top-level vdev's rebuild information. */
| 687 | * Load from disk the top-level vdev's rebuild information. |
| 688 | */ |
| 689 | int |
| 690 | vdev_rebuild_load(vdev_t *vd) |
| 691 | { |
| 692 | vdev_rebuild_t *vr = &vd->vdev_rebuild_config; |
| 693 | vdev_rebuild_phys_t *vrp = &vr->vr_rebuild_phys; |
| 694 | spa_t *spa = vd->vdev_spa; |
| 695 | int err = 0; |
| 696 | |
| 697 | mutex_enter(&vd->vdev_rebuild_lock); |
| 698 | vd->vdev_rebuilding = B_FALSE; |
| 699 | |
| 700 | if (!spa_feature_is_enabled(spa, SPA_FEATURE_DEVICE_REBUILD)) { |
| 701 | bzero(vrp, sizeof (uint64_t) * REBUILD_PHYS_ENTRIES); |
| 702 | mutex_exit(&vd->vdev_rebuild_lock); |
| 703 | return (SET_ERROR(ENOTSUP)); |
| 704 | } |
| 705 | |
| 706 | ASSERT(vd->vdev_top == vd); |
| 707 | |
| 708 | err = zap_lookup(spa->spa_meta_objset, vd->vdev_top_zap, |
| 709 | VDEV_TOP_ZAP_VDEV_REBUILD_PHYS, sizeof (uint64_t), |
| 710 | REBUILD_PHYS_ENTRIES, vrp); |
| 711 | |
| 712 | /* |
| 713 | * A missing or damaged VDEV_TOP_ZAP_VDEV_REBUILD_PHYS should |
| 714 | * not prevent a pool from being imported. Clear the rebuild |
| 715 | * status allowing a new resilver/rebuild to be started. |
| 716 | */ |
| 717 | if (err == ENOENT || err == EOVERFLOW || err == ECKSUM) { |
| 718 | bzero(vrp, sizeof (uint64_t) * REBUILD_PHYS_ENTRIES); |
| 719 | } else if (err) { |
| 720 | mutex_exit(&vd->vdev_rebuild_lock); |
| 721 | return (err); |
| 722 | } |
| 723 | |
| 724 | vr->vr_prev_scan_time_ms = vrp->vrp_scan_time_ms; |
| 725 | vr->vr_top_vdev = vd; |
| 726 | |
| 727 | mutex_exit(&vd->vdev_rebuild_lock); |
| 728 | |
| 729 | return (0); |
| 730 | } |
| 731 | |
| 732 | /* |
| 733 | * Each scan thread is responsible for rebuilding a top-level vdev. The |
no test coverage detected