* Propagate vdev state up from children to parent. */
| 4698 | * Propagate vdev state up from children to parent. |
| 4699 | */ |
| 4700 | void |
| 4701 | vdev_propagate_state(vdev_t *vd) |
| 4702 | { |
| 4703 | spa_t *spa = vd->vdev_spa; |
| 4704 | vdev_t *rvd = spa->spa_root_vdev; |
| 4705 | int degraded = 0, faulted = 0; |
| 4706 | int corrupted = 0; |
| 4707 | vdev_t *child; |
| 4708 | |
| 4709 | if (vd->vdev_children > 0) { |
| 4710 | for (int c = 0; c < vd->vdev_children; c++) { |
| 4711 | child = vd->vdev_child[c]; |
| 4712 | |
| 4713 | /* |
| 4714 | * Don't factor holes or indirect vdevs into the |
| 4715 | * decision. |
| 4716 | */ |
| 4717 | if (!vdev_is_concrete(child)) |
| 4718 | continue; |
| 4719 | |
| 4720 | if (!vdev_readable(child) || |
| 4721 | (!vdev_writeable(child) && spa_writeable(spa))) { |
| 4722 | /* |
| 4723 | * Root special: if there is a top-level log |
| 4724 | * device, treat the root vdev as if it were |
| 4725 | * degraded. |
| 4726 | */ |
| 4727 | if (child->vdev_islog && vd == rvd) |
| 4728 | degraded++; |
| 4729 | else |
| 4730 | faulted++; |
| 4731 | } else if (child->vdev_state <= VDEV_STATE_DEGRADED) { |
| 4732 | degraded++; |
| 4733 | } |
| 4734 | |
| 4735 | if (child->vdev_stat.vs_aux == VDEV_AUX_CORRUPT_DATA) |
| 4736 | corrupted++; |
| 4737 | } |
| 4738 | |
| 4739 | vd->vdev_ops->vdev_op_state_change(vd, faulted, degraded); |
| 4740 | |
| 4741 | /* |
| 4742 | * Root special: if there is a top-level vdev that cannot be |
| 4743 | * opened due to corrupted metadata, then propagate the root |
| 4744 | * vdev's aux state as 'corrupt' rather than 'insufficient |
| 4745 | * replicas'. |
| 4746 | */ |
| 4747 | if (corrupted && vd == rvd && |
| 4748 | rvd->vdev_state == VDEV_STATE_CANT_OPEN) |
| 4749 | vdev_set_state(rvd, B_FALSE, VDEV_STATE_CANT_OPEN, |
| 4750 | VDEV_AUX_CORRUPT_DATA); |
| 4751 | } |
| 4752 | |
| 4753 | if (vd->vdev_parent) |
| 4754 | vdev_propagate_state(vd->vdev_parent); |
| 4755 | } |
| 4756 | |
| 4757 | /* |
no test coverage detected