| 1337 | } |
| 1338 | |
| 1339 | int |
| 1340 | spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error) |
| 1341 | { |
| 1342 | boolean_t config_changed = B_FALSE; |
| 1343 | vdev_t *vdev_top; |
| 1344 | |
| 1345 | if (vd == NULL || vd == spa->spa_root_vdev) { |
| 1346 | vdev_top = spa->spa_root_vdev; |
| 1347 | } else { |
| 1348 | vdev_top = vd->vdev_top; |
| 1349 | } |
| 1350 | |
| 1351 | if (vd != NULL || error == 0) |
| 1352 | vdev_dtl_reassess(vdev_top, 0, 0, B_FALSE, B_FALSE); |
| 1353 | |
| 1354 | if (vd != NULL) { |
| 1355 | if (vd != spa->spa_root_vdev) |
| 1356 | vdev_state_dirty(vdev_top); |
| 1357 | |
| 1358 | config_changed = B_TRUE; |
| 1359 | spa->spa_config_generation++; |
| 1360 | } |
| 1361 | |
| 1362 | if (spa_is_root(spa)) |
| 1363 | vdev_rele(spa->spa_root_vdev); |
| 1364 | |
| 1365 | ASSERT3U(spa->spa_vdev_locks, >=, SCL_STATE_ALL); |
| 1366 | spa_config_exit(spa, spa->spa_vdev_locks, spa); |
| 1367 | |
| 1368 | /* |
| 1369 | * If anything changed, wait for it to sync. This ensures that, |
| 1370 | * from the system administrator's perspective, zpool(8) commands |
| 1371 | * are synchronous. This is important for things like zpool offline: |
| 1372 | * when the command completes, you expect no further I/O from ZFS. |
| 1373 | */ |
| 1374 | if (vd != NULL) |
| 1375 | txg_wait_synced(spa->spa_dsl_pool, 0); |
| 1376 | |
| 1377 | /* |
| 1378 | * If the config changed, update the config cache. |
| 1379 | */ |
| 1380 | if (config_changed) { |
| 1381 | mutex_enter(&spa_namespace_lock); |
| 1382 | spa_write_cachefile(spa, B_FALSE, B_TRUE); |
| 1383 | mutex_exit(&spa_namespace_lock); |
| 1384 | } |
| 1385 | |
| 1386 | return (error); |
| 1387 | } |
| 1388 | |
| 1389 | /* |
| 1390 | * ========================================================================== |