Changeset View
Changeset View
Standalone View
Standalone View
sys/contrib/openzfs/module/zfs/spa.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 297 Lines • ▼ Show 20 Lines | spa_prop_get_config(spa_t *spa, nvlist_t **nvp) | ||||
metaslab_class_t *mc = spa_normal_class(spa); | metaslab_class_t *mc = spa_normal_class(spa); | ||||
ASSERT(MUTEX_HELD(&spa->spa_props_lock)); | ASSERT(MUTEX_HELD(&spa->spa_props_lock)); | ||||
if (rvd != NULL) { | if (rvd != NULL) { | ||||
alloc = metaslab_class_get_alloc(mc); | alloc = metaslab_class_get_alloc(mc); | ||||
alloc += metaslab_class_get_alloc(spa_special_class(spa)); | alloc += metaslab_class_get_alloc(spa_special_class(spa)); | ||||
alloc += metaslab_class_get_alloc(spa_dedup_class(spa)); | alloc += metaslab_class_get_alloc(spa_dedup_class(spa)); | ||||
alloc += metaslab_class_get_alloc(spa_embedded_log_class(spa)); | |||||
size = metaslab_class_get_space(mc); | size = metaslab_class_get_space(mc); | ||||
size += metaslab_class_get_space(spa_special_class(spa)); | size += metaslab_class_get_space(spa_special_class(spa)); | ||||
size += metaslab_class_get_space(spa_dedup_class(spa)); | size += metaslab_class_get_space(spa_dedup_class(spa)); | ||||
size += metaslab_class_get_space(spa_embedded_log_class(spa)); | |||||
spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src); | spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src); | ||||
spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src); | spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src); | ||||
spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src); | spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src); | ||||
spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL, | spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL, | ||||
size - alloc, src); | size - alloc, src); | ||||
spa_prop_add_list(*nvp, ZPOOL_PROP_CHECKPOINT, NULL, | spa_prop_add_list(*nvp, ZPOOL_PROP_CHECKPOINT, NULL, | ||||
spa->spa_checkpoint_info.sci_dspace, src); | spa->spa_checkpoint_info.sci_dspace, src); | ||||
▲ Show 20 Lines • Show All 873 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); | ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); | ||||
spa->spa_state = POOL_STATE_ACTIVE; | spa->spa_state = POOL_STATE_ACTIVE; | ||||
spa->spa_mode = mode; | spa->spa_mode = mode; | ||||
spa->spa_normal_class = metaslab_class_create(spa, zfs_metaslab_ops); | spa->spa_normal_class = metaslab_class_create(spa, zfs_metaslab_ops); | ||||
spa->spa_log_class = metaslab_class_create(spa, zfs_metaslab_ops); | spa->spa_log_class = metaslab_class_create(spa, zfs_metaslab_ops); | ||||
spa->spa_embedded_log_class = | |||||
metaslab_class_create(spa, zfs_metaslab_ops); | |||||
spa->spa_special_class = metaslab_class_create(spa, zfs_metaslab_ops); | spa->spa_special_class = metaslab_class_create(spa, zfs_metaslab_ops); | ||||
spa->spa_dedup_class = metaslab_class_create(spa, zfs_metaslab_ops); | spa->spa_dedup_class = metaslab_class_create(spa, zfs_metaslab_ops); | ||||
/* Try to create a covering process */ | /* Try to create a covering process */ | ||||
mutex_enter(&spa->spa_proc_lock); | mutex_enter(&spa->spa_proc_lock); | ||||
ASSERT(spa->spa_proc_state == SPA_PROC_NONE); | ASSERT(spa->spa_proc_state == SPA_PROC_NONE); | ||||
ASSERT(spa->spa_proc == &p0); | ASSERT(spa->spa_proc == &p0); | ||||
spa->spa_did = 0; | spa->spa_did = 0; | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | spa_deactivate(spa_t *spa) | ||||
} | } | ||||
metaslab_class_destroy(spa->spa_normal_class); | metaslab_class_destroy(spa->spa_normal_class); | ||||
spa->spa_normal_class = NULL; | spa->spa_normal_class = NULL; | ||||
metaslab_class_destroy(spa->spa_log_class); | metaslab_class_destroy(spa->spa_log_class); | ||||
spa->spa_log_class = NULL; | spa->spa_log_class = NULL; | ||||
metaslab_class_destroy(spa->spa_embedded_log_class); | |||||
spa->spa_embedded_log_class = NULL; | |||||
metaslab_class_destroy(spa->spa_special_class); | metaslab_class_destroy(spa->spa_special_class); | ||||
spa->spa_special_class = NULL; | spa->spa_special_class = NULL; | ||||
metaslab_class_destroy(spa->spa_dedup_class); | metaslab_class_destroy(spa->spa_dedup_class); | ||||
spa->spa_dedup_class = NULL; | spa->spa_dedup_class = NULL; | ||||
/* | /* | ||||
* If this was part of an import or the open otherwise failed, we may | * If this was part of an import or the open otherwise failed, we may | ||||
▲ Show 20 Lines • Show All 740 Lines • ▼ Show 20 Lines | rv = (dmu_objset_find_dp(dp, dp->dp_root_dir_obj, | ||||
zil_check_log_chain, NULL, DS_FIND_CHILDREN) != 0); | zil_check_log_chain, NULL, DS_FIND_CHILDREN) != 0); | ||||
if (rv) | if (rv) | ||||
spa_set_log_state(spa, SPA_LOG_MISSING); | spa_set_log_state(spa, SPA_LOG_MISSING); | ||||
break; | break; | ||||
} | } | ||||
return (rv); | return (rv); | ||||
} | } | ||||
/* | |||||
* Passivate any log vdevs (note, does not apply to embedded log metaslabs). | |||||
*/ | |||||
static boolean_t | static boolean_t | ||||
spa_passivate_log(spa_t *spa) | spa_passivate_log(spa_t *spa) | ||||
{ | { | ||||
vdev_t *rvd = spa->spa_root_vdev; | vdev_t *rvd = spa->spa_root_vdev; | ||||
boolean_t slog_found = B_FALSE; | boolean_t slog_found = B_FALSE; | ||||
ASSERT(spa_config_held(spa, SCL_ALLOC, RW_WRITER)); | ASSERT(spa_config_held(spa, SCL_ALLOC, RW_WRITER)); | ||||
for (int c = 0; c < rvd->vdev_children; c++) { | for (int c = 0; c < rvd->vdev_children; c++) { | ||||
vdev_t *tvd = rvd->vdev_child[c]; | vdev_t *tvd = rvd->vdev_child[c]; | ||||
metaslab_group_t *mg = tvd->vdev_mg; | |||||
if (tvd->vdev_islog) { | if (tvd->vdev_islog) { | ||||
metaslab_group_passivate(mg); | ASSERT3P(tvd->vdev_log_mg, ==, NULL); | ||||
metaslab_group_passivate(tvd->vdev_mg); | |||||
slog_found = B_TRUE; | slog_found = B_TRUE; | ||||
} | } | ||||
} | } | ||||
return (slog_found); | return (slog_found); | ||||
} | } | ||||
/* | |||||
* Activate any log vdevs (note, does not apply to embedded log metaslabs). | |||||
*/ | |||||
static void | static void | ||||
spa_activate_log(spa_t *spa) | spa_activate_log(spa_t *spa) | ||||
{ | { | ||||
vdev_t *rvd = spa->spa_root_vdev; | vdev_t *rvd = spa->spa_root_vdev; | ||||
ASSERT(spa_config_held(spa, SCL_ALLOC, RW_WRITER)); | ASSERT(spa_config_held(spa, SCL_ALLOC, RW_WRITER)); | ||||
for (int c = 0; c < rvd->vdev_children; c++) { | for (int c = 0; c < rvd->vdev_children; c++) { | ||||
vdev_t *tvd = rvd->vdev_child[c]; | vdev_t *tvd = rvd->vdev_child[c]; | ||||
metaslab_group_t *mg = tvd->vdev_mg; | |||||
if (tvd->vdev_islog) | if (tvd->vdev_islog) { | ||||
metaslab_group_activate(mg); | ASSERT3P(tvd->vdev_log_mg, ==, NULL); | ||||
metaslab_group_activate(tvd->vdev_mg); | |||||
} | } | ||||
} | } | ||||
} | |||||
int | int | ||||
spa_reset_logs(spa_t *spa) | spa_reset_logs(spa_t *spa) | ||||
{ | { | ||||
int error; | int error; | ||||
error = dmu_objset_find(spa_name(spa), zil_reset, | error = dmu_objset_find(spa_name(spa), zil_reset, | ||||
NULL, DS_FIND_CHILDREN); | NULL, DS_FIND_CHILDREN); | ||||
▲ Show 20 Lines • Show All 4,081 Lines • ▼ Show 20 Lines | |||||
* update the pool state and sync all the labels to disk, removing the | * update the pool state and sync all the labels to disk, removing the | ||||
* configuration from the cache afterwards. If the 'hardforce' flag is set, then | * configuration from the cache afterwards. If the 'hardforce' flag is set, then | ||||
* we don't sync the labels or remove the configuration cache. | * we don't sync the labels or remove the configuration cache. | ||||
*/ | */ | ||||
static int | static int | ||||
spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig, | spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig, | ||||
boolean_t force, boolean_t hardforce) | boolean_t force, boolean_t hardforce) | ||||
{ | { | ||||
int error; | |||||
spa_t *spa; | spa_t *spa; | ||||
if (oldconfig) | if (oldconfig) | ||||
*oldconfig = NULL; | *oldconfig = NULL; | ||||
if (!(spa_mode_global & SPA_MODE_WRITE)) | if (!(spa_mode_global & SPA_MODE_WRITE)) | ||||
return (SET_ERROR(EROFS)); | return (SET_ERROR(EROFS)); | ||||
Show All 36 Lines | if (spa->spa_sync_on) { | ||||
spa_evicting_os_wait(spa); | spa_evicting_os_wait(spa); | ||||
} | } | ||||
/* | /* | ||||
* A pool cannot be exported or destroyed if there are active | * A pool cannot be exported or destroyed if there are active | ||||
* references. If we are resetting a pool, allow references by | * references. If we are resetting a pool, allow references by | ||||
* fault injection handlers. | * fault injection handlers. | ||||
*/ | */ | ||||
if (!spa_refcount_zero(spa) || | if (!spa_refcount_zero(spa) || (spa->spa_inject_ref != 0)) { | ||||
(spa->spa_inject_ref != 0 && | error = SET_ERROR(EBUSY); | ||||
new_state != POOL_STATE_UNINITIALIZED)) { | goto fail; | ||||
spa_async_resume(spa); | |||||
spa->spa_is_exporting = B_FALSE; | |||||
mutex_exit(&spa_namespace_lock); | |||||
return (SET_ERROR(EBUSY)); | |||||
} | } | ||||
if (spa->spa_sync_on) { | if (spa->spa_sync_on) { | ||||
/* | /* | ||||
* A pool cannot be exported if it has an active shared spare. | * A pool cannot be exported if it has an active shared spare. | ||||
* This is to prevent other pools stealing the active spare | * This is to prevent other pools stealing the active spare | ||||
* from an exported pool. At user's own will, such pool can | * from an exported pool. At user's own will, such pool can | ||||
* be forcedly exported. | * be forcedly exported. | ||||
*/ | */ | ||||
if (!force && new_state == POOL_STATE_EXPORTED && | if (!force && new_state == POOL_STATE_EXPORTED && | ||||
spa_has_active_shared_spare(spa)) { | spa_has_active_shared_spare(spa)) { | ||||
spa_async_resume(spa); | error = SET_ERROR(EXDEV); | ||||
spa->spa_is_exporting = B_FALSE; | goto fail; | ||||
mutex_exit(&spa_namespace_lock); | |||||
return (SET_ERROR(EXDEV)); | |||||
} | } | ||||
/* | /* | ||||
* We're about to export or destroy this pool. Make sure | * We're about to export or destroy this pool. Make sure | ||||
* we stop all initialization and trim activity here before | * we stop all initialization and trim activity here before | ||||
* we set the spa_final_txg. This will ensure that all | * we set the spa_final_txg. This will ensure that all | ||||
* dirty data resulting from the initialization is | * dirty data resulting from the initialization is | ||||
* committed to disk before we unload the pool. | * committed to disk before we unload the pool. | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (new_state != POOL_STATE_UNINITIALIZED) { | ||||
* there is any possibility that it can be reused, | * there is any possibility that it can be reused, | ||||
* we make sure to reset the exporting flag. | * we make sure to reset the exporting flag. | ||||
*/ | */ | ||||
spa->spa_is_exporting = B_FALSE; | spa->spa_is_exporting = B_FALSE; | ||||
} | } | ||||
mutex_exit(&spa_namespace_lock); | mutex_exit(&spa_namespace_lock); | ||||
return (0); | return (0); | ||||
fail: | |||||
spa->spa_is_exporting = B_FALSE; | |||||
spa_async_resume(spa); | |||||
mutex_exit(&spa_namespace_lock); | |||||
return (error); | |||||
} | } | ||||
/* | /* | ||||
* Destroy a storage pool. | * Destroy a storage pool. | ||||
*/ | */ | ||||
int | int | ||||
spa_destroy(const char *pool) | spa_destroy(const char *pool) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,646 Lines • ▼ Show 20 Lines | spa_async_thread(void *arg) | ||||
*/ | */ | ||||
if (tasks & SPA_ASYNC_CONFIG_UPDATE) { | if (tasks & SPA_ASYNC_CONFIG_UPDATE) { | ||||
uint64_t old_space, new_space; | uint64_t old_space, new_space; | ||||
mutex_enter(&spa_namespace_lock); | mutex_enter(&spa_namespace_lock); | ||||
old_space = metaslab_class_get_space(spa_normal_class(spa)); | old_space = metaslab_class_get_space(spa_normal_class(spa)); | ||||
old_space += metaslab_class_get_space(spa_special_class(spa)); | old_space += metaslab_class_get_space(spa_special_class(spa)); | ||||
old_space += metaslab_class_get_space(spa_dedup_class(spa)); | old_space += metaslab_class_get_space(spa_dedup_class(spa)); | ||||
old_space += metaslab_class_get_space( | |||||
spa_embedded_log_class(spa)); | |||||
spa_config_update(spa, SPA_CONFIG_UPDATE_POOL); | spa_config_update(spa, SPA_CONFIG_UPDATE_POOL); | ||||
new_space = metaslab_class_get_space(spa_normal_class(spa)); | new_space = metaslab_class_get_space(spa_normal_class(spa)); | ||||
new_space += metaslab_class_get_space(spa_special_class(spa)); | new_space += metaslab_class_get_space(spa_special_class(spa)); | ||||
new_space += metaslab_class_get_space(spa_dedup_class(spa)); | new_space += metaslab_class_get_space(spa_dedup_class(spa)); | ||||
new_space += metaslab_class_get_space( | |||||
spa_embedded_log_class(spa)); | |||||
mutex_exit(&spa_namespace_lock); | mutex_exit(&spa_namespace_lock); | ||||
/* | /* | ||||
* If the pool grew as a result of the config update, | * If the pool grew as a result of the config update, | ||||
* then log an internal history event. | * then log an internal history event. | ||||
*/ | */ | ||||
if (new_space != old_space) { | if (new_space != old_space) { | ||||
spa_history_log_internal(spa, "vdev online", NULL, | spa_history_log_internal(spa, "vdev online", NULL, | ||||
▲ Show 20 Lines • Show All 1,787 Lines • Show Last 20 Lines |