| 8442 | } |
| 8443 | |
| 8444 | static void |
| 8445 | spa_sync_config_object(spa_t *spa, dmu_tx_t *tx) |
| 8446 | { |
| 8447 | nvlist_t *config; |
| 8448 | |
| 8449 | /* |
| 8450 | * If the pool is being imported from a pre-per-vdev-ZAP version of ZFS, |
| 8451 | * its config may not be dirty but we still need to build per-vdev ZAPs. |
| 8452 | * Similarly, if the pool is being assembled (e.g. after a split), we |
| 8453 | * need to rebuild the AVZ although the config may not be dirty. |
| 8454 | */ |
| 8455 | if (list_is_empty(&spa->spa_config_dirty_list) && |
| 8456 | spa->spa_avz_action == AVZ_ACTION_NONE) |
| 8457 | return; |
| 8458 | |
| 8459 | spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); |
| 8460 | |
| 8461 | ASSERT(spa->spa_avz_action == AVZ_ACTION_NONE || |
| 8462 | spa->spa_avz_action == AVZ_ACTION_INITIALIZE || |
| 8463 | spa->spa_all_vdev_zaps != 0); |
| 8464 | |
| 8465 | if (spa->spa_avz_action == AVZ_ACTION_REBUILD) { |
| 8466 | /* Make and build the new AVZ */ |
| 8467 | uint64_t new_avz = zap_create(spa->spa_meta_objset, |
| 8468 | DMU_OTN_ZAP_METADATA, DMU_OT_NONE, 0, tx); |
| 8469 | spa_avz_build(spa->spa_root_vdev, new_avz, tx); |
| 8470 | |
| 8471 | /* Diff old AVZ with new one */ |
| 8472 | zap_cursor_t zc; |
| 8473 | zap_attribute_t za; |
| 8474 | |
| 8475 | for (zap_cursor_init(&zc, spa->spa_meta_objset, |
| 8476 | spa->spa_all_vdev_zaps); |
| 8477 | zap_cursor_retrieve(&zc, &za) == 0; |
| 8478 | zap_cursor_advance(&zc)) { |
| 8479 | uint64_t vdzap = za.za_first_integer; |
| 8480 | if (zap_lookup_int(spa->spa_meta_objset, new_avz, |
| 8481 | vdzap) == ENOENT) { |
| 8482 | /* |
| 8483 | * ZAP is listed in old AVZ but not in new one; |
| 8484 | * destroy it |
| 8485 | */ |
| 8486 | VERIFY0(zap_destroy(spa->spa_meta_objset, vdzap, |
| 8487 | tx)); |
| 8488 | } |
| 8489 | } |
| 8490 | |
| 8491 | zap_cursor_fini(&zc); |
| 8492 | |
| 8493 | /* Destroy the old AVZ */ |
| 8494 | VERIFY0(zap_destroy(spa->spa_meta_objset, |
| 8495 | spa->spa_all_vdev_zaps, tx)); |
| 8496 | |
| 8497 | /* Replace the old AVZ in the dir obj with the new one */ |
| 8498 | VERIFY0(zap_update(spa->spa_meta_objset, |
| 8499 | DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_VDEV_ZAP_MAP, |
| 8500 | sizeof (new_avz), 1, &new_avz, tx)); |
| 8501 |
no test coverage detected