* Open a top-level dRAID vdev. */
| 1718 | * Open a top-level dRAID vdev. |
| 1719 | */ |
| 1720 | static int |
| 1721 | vdev_draid_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize, |
| 1722 | uint64_t *logical_ashift, uint64_t *physical_ashift) |
| 1723 | { |
| 1724 | vdev_draid_config_t *vdc = vd->vdev_tsd; |
| 1725 | uint64_t nparity = vdc->vdc_nparity; |
| 1726 | int open_errors = 0; |
| 1727 | |
| 1728 | if (nparity > VDEV_DRAID_MAXPARITY || |
| 1729 | vd->vdev_children < nparity + 1) { |
| 1730 | vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; |
| 1731 | return (SET_ERROR(EINVAL)); |
| 1732 | } |
| 1733 | |
| 1734 | /* |
| 1735 | * First open the normal children then the distributed spares. This |
| 1736 | * ordering is important to ensure the distributed spares calculate |
| 1737 | * the correct psize in the event that the dRAID vdevs were expanded. |
| 1738 | */ |
| 1739 | vdev_open_children_subset(vd, vdev_draid_open_children); |
| 1740 | vdev_open_children_subset(vd, vdev_draid_open_spares); |
| 1741 | |
| 1742 | /* Verify enough of the children are available to continue. */ |
| 1743 | for (int c = 0; c < vd->vdev_children; c++) { |
| 1744 | if (vd->vdev_child[c]->vdev_open_error != 0) { |
| 1745 | if ((++open_errors) > nparity) { |
| 1746 | vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS; |
| 1747 | return (SET_ERROR(ENXIO)); |
| 1748 | } |
| 1749 | } |
| 1750 | } |
| 1751 | |
| 1752 | /* |
| 1753 | * Allocatable capacity is the sum of the space on all children less |
| 1754 | * the number of distributed spares rounded down to last full row |
| 1755 | * and then to the last full group. An additional 32MB of scratch |
| 1756 | * space is reserved at the end of each child for use by the dRAID |
| 1757 | * expansion feature. |
| 1758 | */ |
| 1759 | uint64_t child_asize, child_max_asize; |
| 1760 | vdev_draid_calculate_asize(vd, &child_asize, &child_max_asize, |
| 1761 | logical_ashift, physical_ashift); |
| 1762 | |
| 1763 | /* |
| 1764 | * Should be unreachable since the minimum child size is 64MB, but |
| 1765 | * we want to make sure an underflow absolutely cannot occur here. |
| 1766 | */ |
| 1767 | if (child_asize < VDEV_DRAID_REFLOW_RESERVE || |
| 1768 | child_max_asize < VDEV_DRAID_REFLOW_RESERVE) { |
| 1769 | return (SET_ERROR(ENXIO)); |
| 1770 | } |
| 1771 | |
| 1772 | child_asize = ((child_asize - VDEV_DRAID_REFLOW_RESERVE) / |
| 1773 | VDEV_DRAID_ROWHEIGHT) * VDEV_DRAID_ROWHEIGHT; |
| 1774 | child_max_asize = ((child_max_asize - VDEV_DRAID_REFLOW_RESERVE) / |
| 1775 | VDEV_DRAID_ROWHEIGHT) * VDEV_DRAID_ROWHEIGHT; |
| 1776 | |
| 1777 | *asize = (((child_asize * vdc->vdc_ndisks) / vdc->vdc_groupsz) * |
nothing calls this directly
no test coverage detected