| 7189 | } |
| 7190 | |
| 7191 | int |
| 7192 | spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, |
| 7193 | nvlist_t *vdev_errlist) |
| 7194 | { |
| 7195 | int total_errors = 0; |
| 7196 | list_t vd_list; |
| 7197 | |
| 7198 | list_create(&vd_list, sizeof (vdev_t), |
| 7199 | offsetof(vdev_t, vdev_initialize_node)); |
| 7200 | |
| 7201 | /* |
| 7202 | * We hold the namespace lock through the whole function |
| 7203 | * to prevent any changes to the pool while we're starting or |
| 7204 | * stopping initialization. The config and state locks are held so that |
| 7205 | * we can properly assess the vdev state before we commit to |
| 7206 | * the initializing operation. |
| 7207 | */ |
| 7208 | mutex_enter(&spa_namespace_lock); |
| 7209 | |
| 7210 | for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL); |
| 7211 | pair != NULL; pair = nvlist_next_nvpair(nv, pair)) { |
| 7212 | uint64_t vdev_guid = fnvpair_value_uint64(pair); |
| 7213 | |
| 7214 | int error = spa_vdev_initialize_impl(spa, vdev_guid, cmd_type, |
| 7215 | &vd_list); |
| 7216 | if (error != 0) { |
| 7217 | char guid_as_str[MAXNAMELEN]; |
| 7218 | |
| 7219 | (void) snprintf(guid_as_str, sizeof (guid_as_str), |
| 7220 | "%llu", (unsigned long long)vdev_guid); |
| 7221 | fnvlist_add_int64(vdev_errlist, guid_as_str, error); |
| 7222 | total_errors++; |
| 7223 | } |
| 7224 | } |
| 7225 | |
| 7226 | /* Wait for all initialize threads to stop. */ |
| 7227 | vdev_initialize_stop_wait(spa, &vd_list); |
| 7228 | |
| 7229 | /* Sync out the initializing state */ |
| 7230 | txg_wait_synced(spa->spa_dsl_pool, 0); |
| 7231 | mutex_exit(&spa_namespace_lock); |
| 7232 | |
| 7233 | list_destroy(&vd_list); |
| 7234 | |
| 7235 | return (total_errors); |
| 7236 | } |
| 7237 | |
| 7238 | static int |
| 7239 | spa_vdev_trim_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type, |