* Returns true if the txg range does not exist on any leaf vdev. * * A dRAID spare does not fit into the DTL model. While it has child vdevs * there is no redundancy among them, and the effective child vdev is * determined by offset. Essentially we do a vdev_dtl_reassess() on the * fly by replacing a dRAID spare with the child vdev under the offset. * Note that it is a recursive process beca
| 1396 | * another dRAID spare and so on. |
| 1397 | */ |
| 1398 | boolean_t |
| 1399 | vdev_draid_missing(vdev_t *vd, uint64_t physical_offset, uint64_t txg, |
| 1400 | uint64_t size) |
| 1401 | { |
| 1402 | if (vd->vdev_ops == &vdev_spare_ops || |
| 1403 | vd->vdev_ops == &vdev_replacing_ops) { |
| 1404 | /* |
| 1405 | * Check all of the readable children, if any child |
| 1406 | * contains the txg range the data it is not missing. |
| 1407 | */ |
| 1408 | for (int c = 0; c < vd->vdev_children; c++) { |
| 1409 | vdev_t *cvd = vd->vdev_child[c]; |
| 1410 | |
| 1411 | if (!vdev_readable(cvd)) |
| 1412 | continue; |
| 1413 | |
| 1414 | if (!vdev_draid_missing(cvd, physical_offset, |
| 1415 | txg, size)) |
| 1416 | return (B_FALSE); |
| 1417 | } |
| 1418 | |
| 1419 | return (B_TRUE); |
| 1420 | } |
| 1421 | |
| 1422 | if (vd->vdev_ops == &vdev_draid_spare_ops) { |
| 1423 | /* |
| 1424 | * When sequentially resilvering we don't have a proper |
| 1425 | * txg range so instead we must presume all txgs are |
| 1426 | * missing on this vdev until the resilver completes. |
| 1427 | */ |
| 1428 | if (vd->vdev_rebuild_txg != 0) |
| 1429 | return (B_TRUE); |
| 1430 | |
| 1431 | /* |
| 1432 | * DTL_MISSING is set for all prior txgs when a resilver |
| 1433 | * is started in spa_vdev_attach(). |
| 1434 | */ |
| 1435 | if (vdev_dtl_contains(vd, DTL_MISSING, txg, size)) |
| 1436 | return (B_TRUE); |
| 1437 | |
| 1438 | /* |
| 1439 | * Consult the DTL on the relevant vdev. Either a vdev |
| 1440 | * leaf or spare/replace mirror child may be returned so |
| 1441 | * we must recursively call vdev_draid_missing_impl(). |
| 1442 | */ |
| 1443 | vd = vdev_draid_spare_get_child(vd, physical_offset); |
| 1444 | if (vd == NULL) |
| 1445 | return (B_TRUE); |
| 1446 | |
| 1447 | return (vdev_draid_missing(vd, physical_offset, |
| 1448 | txg, size)); |
| 1449 | } |
| 1450 | |
| 1451 | return (vdev_dtl_contains(vd, DTL_MISSING, txg, size)); |
| 1452 | } |
| 1453 | |
| 1454 | /* |
| 1455 | * Returns true if the txg is only partially replicated on the leaf vdevs. |
no test coverage detected