Changeset View
Changeset View
Standalone View
Standalone View
sys/contrib/openzfs/module/zfs/spa_misc.c
Show First 20 Lines • Show All 343 Lines • ▼ Show 20 Lines | |||||
* (VDEV_RAIDZ_MAXPARITY + 1) * SPA_DVAS_PER_BP * 2 == 24 | * (VDEV_RAIDZ_MAXPARITY + 1) * SPA_DVAS_PER_BP * 2 == 24 | ||||
*/ | */ | ||||
int spa_asize_inflation = 24; | int spa_asize_inflation = 24; | ||||
/* | /* | ||||
* Normally, we don't allow the last 3.2% (1/(2^spa_slop_shift)) of space in | * Normally, we don't allow the last 3.2% (1/(2^spa_slop_shift)) of space in | ||||
* the pool to be consumed. This ensures that we don't run the pool | * the pool to be consumed. This ensures that we don't run the pool | ||||
* completely out of space, due to unaccounted changes (e.g. to the MOS). | * completely out of space, due to unaccounted changes (e.g. to the MOS). | ||||
* It also limits the worst-case time to allocate space. If we have | * It also limits the worst-case time to allocate space. If we have less than | ||||
* less than this amount of free space, most ZPL operations (e.g. write, | * this amount of free space, most ZPL operations (e.g. write, create) will | ||||
* create) will return ENOSPC. | * return ENOSPC. The ZIL metaslabs (spa_embedded_log_class) are also part of | ||||
* this 3.2% of space which can't be consumed by normal writes; the slop space | |||||
* "proper" (spa_get_slop_space()) is decreased by the embedded log space. | |||||
* | * | ||||
* Certain operations (e.g. file removal, most administrative actions) can | * Certain operations (e.g. file removal, most administrative actions) can | ||||
* use half the slop space. They will only return ENOSPC if less than half | * use half the slop space. They will only return ENOSPC if less than half | ||||
* the slop space is free. Typically, once the pool has less than the slop | * the slop space is free. Typically, once the pool has less than the slop | ||||
* space free, the user will use these operations to free up space in the pool. | * space free, the user will use these operations to free up space in the pool. | ||||
* These are the operations that call dsl_pool_adjustedsize() with the netfree | * These are the operations that call dsl_pool_adjustedsize() with the netfree | ||||
* argument set to TRUE. | * argument set to TRUE. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 658 Lines • ▼ Show 20 Lines | spa_aux_activate(vdev_t *vd, avl_tree_t *avl) | ||||
ASSERT(found->aux_pool == 0ULL); | ASSERT(found->aux_pool == 0ULL); | ||||
found->aux_pool = spa_guid(vd->vdev_spa); | found->aux_pool = spa_guid(vd->vdev_spa); | ||||
} | } | ||||
/* | /* | ||||
* Spares are tracked globally due to the following constraints: | * Spares are tracked globally due to the following constraints: | ||||
* | * | ||||
* - A spare may be part of multiple pools. | * - A spare may be part of multiple pools. | ||||
* - A spare may be added to a pool even if it's actively in use within | * - A spare may be added to a pool even if it's actively in use within | ||||
* another pool. | * another pool. | ||||
* - A spare in use in any pool can only be the source of a replacement if | * - A spare in use in any pool can only be the source of a replacement if | ||||
* the target is a spare in the same pool. | * the target is a spare in the same pool. | ||||
* | * | ||||
* We keep track of all spares on the system through the use of a reference | * We keep track of all spares on the system through the use of a reference | ||||
* counted AVL tree. When a vdev is added as a spare, or used as a replacement | * counted AVL tree. When a vdev is added as a spare, or used as a replacement | ||||
* spare, then we bump the reference count in the AVL tree. In addition, we set | * spare, then we bump the reference count in the AVL tree. In addition, we set | ||||
* the 'vdev_isspare' member to indicate that the device is a spare (active or | * the 'vdev_isspare' member to indicate that the device is a spare (active or | ||||
* inactive). When a spare is made active (used to replace a device in the | * inactive). When a spare is made active (used to replace a device in the | ||||
* pool), we also keep track of which pool its been made a part of. | * pool), we also keep track of which pool its been made a part of. | ||||
▲ Show 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | if (error == 0 && !list_is_empty(&spa->spa_config_dirty_list)) { | ||||
spa->spa_config_generation++; | spa->spa_config_generation++; | ||||
} | } | ||||
/* | /* | ||||
* Verify the metaslab classes. | * Verify the metaslab classes. | ||||
*/ | */ | ||||
ASSERT(metaslab_class_validate(spa_normal_class(spa)) == 0); | ASSERT(metaslab_class_validate(spa_normal_class(spa)) == 0); | ||||
ASSERT(metaslab_class_validate(spa_log_class(spa)) == 0); | ASSERT(metaslab_class_validate(spa_log_class(spa)) == 0); | ||||
ASSERT(metaslab_class_validate(spa_embedded_log_class(spa)) == 0); | |||||
ASSERT(metaslab_class_validate(spa_special_class(spa)) == 0); | ASSERT(metaslab_class_validate(spa_special_class(spa)) == 0); | ||||
ASSERT(metaslab_class_validate(spa_dedup_class(spa)) == 0); | ASSERT(metaslab_class_validate(spa_dedup_class(spa)) == 0); | ||||
spa_config_exit(spa, SCL_ALL, spa); | spa_config_exit(spa, SCL_ALL, spa); | ||||
/* | /* | ||||
* Panic the system if the specified tag requires it. This | * Panic the system if the specified tag requires it. This | ||||
* is useful for ensuring that configurations are updated | * is useful for ensuring that configurations are updated | ||||
▲ Show 20 Lines • Show All 524 Lines • ▼ Show 20 Lines | |||||
spa_get_worst_case_asize(spa_t *spa, uint64_t lsize) | spa_get_worst_case_asize(spa_t *spa, uint64_t lsize) | ||||
{ | { | ||||
if (lsize == 0) | if (lsize == 0) | ||||
return (0); /* No inflation needed */ | return (0); /* No inflation needed */ | ||||
return (MAX(lsize, 1 << spa->spa_max_ashift) * spa_asize_inflation); | return (MAX(lsize, 1 << spa->spa_max_ashift) * spa_asize_inflation); | ||||
} | } | ||||
/* | /* | ||||
* Return the amount of slop space in bytes. It is 1/32 of the pool (3.2%), | * Return the amount of slop space in bytes. It is typically 1/32 of the pool | ||||
* or at least 128MB, unless that would cause it to be more than half the | * (3.2%), minus the embedded log space. On very small pools, it may be | ||||
* pool size. | * slightly larger than this. The embedded log space is not included in | ||||
* spa_dspace. By subtracting it, the usable space (per "zfs list") is a | |||||
* constant 97% of the total space, regardless of metaslab size (assuming the | |||||
* default spa_slop_shift=5 and a non-tiny pool). | |||||
* | * | ||||
* See the comment above spa_slop_shift for details. | * See the comment above spa_slop_shift for more details. | ||||
*/ | */ | ||||
uint64_t | uint64_t | ||||
spa_get_slop_space(spa_t *spa) | spa_get_slop_space(spa_t *spa) | ||||
{ | { | ||||
uint64_t space = spa_get_dspace(spa); | uint64_t space = spa_get_dspace(spa); | ||||
return (MAX(space >> spa_slop_shift, MIN(space >> 1, spa_min_slop))); | uint64_t slop = space >> spa_slop_shift; | ||||
/* | |||||
* Subtract the embedded log space, but no more than half the (3.2%) | |||||
* unusable space. Note, the "no more than half" is only relevant if | |||||
* zfs_embedded_slog_min_ms >> spa_slop_shift < 2, which is not true by | |||||
* default. | |||||
*/ | |||||
uint64_t embedded_log = | |||||
metaslab_class_get_dspace(spa_embedded_log_class(spa)); | |||||
slop -= MIN(embedded_log, slop >> 1); | |||||
/* | |||||
* Slop space should be at least spa_min_slop, but no more than half | |||||
* the entire pool. | |||||
*/ | |||||
slop = MAX(slop, MIN(space >> 1, spa_min_slop)); | |||||
return (slop); | |||||
} | } | ||||
uint64_t | uint64_t | ||||
spa_get_dspace(spa_t *spa) | spa_get_dspace(spa_t *spa) | ||||
{ | { | ||||
return (spa->spa_dspace); | return (spa->spa_dspace); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
metaslab_class_t * | metaslab_class_t * | ||||
spa_log_class(spa_t *spa) | spa_log_class(spa_t *spa) | ||||
{ | { | ||||
return (spa->spa_log_class); | return (spa->spa_log_class); | ||||
} | } | ||||
metaslab_class_t * | metaslab_class_t * | ||||
spa_embedded_log_class(spa_t *spa) | |||||
{ | |||||
return (spa->spa_embedded_log_class); | |||||
} | |||||
metaslab_class_t * | |||||
spa_special_class(spa_t *spa) | spa_special_class(spa_t *spa) | ||||
{ | { | ||||
return (spa->spa_special_class); | return (spa->spa_special_class); | ||||
} | } | ||||
metaslab_class_t * | metaslab_class_t * | ||||
spa_dedup_class(spa_t *spa) | spa_dedup_class(spa_t *spa) | ||||
{ | { | ||||
return (spa->spa_dedup_class); | return (spa->spa_dedup_class); | ||||
} | } | ||||
/* | /* | ||||
* Locate an appropriate allocation class | * Locate an appropriate allocation class | ||||
*/ | */ | ||||
metaslab_class_t * | metaslab_class_t * | ||||
spa_preferred_class(spa_t *spa, uint64_t size, dmu_object_type_t objtype, | spa_preferred_class(spa_t *spa, uint64_t size, dmu_object_type_t objtype, | ||||
uint_t level, uint_t special_smallblk) | uint_t level, uint_t special_smallblk) | ||||
{ | { | ||||
if (DMU_OT_IS_ZIL(objtype)) { | /* | ||||
if (spa->spa_log_class->mc_groups != 0) | * ZIL allocations determine their class in zio_alloc_zil(). | ||||
return (spa_log_class(spa)); | */ | ||||
else | ASSERT(objtype != DMU_OT_INTENT_LOG); | ||||
return (spa_normal_class(spa)); | |||||
} | |||||
boolean_t has_special_class = spa->spa_special_class->mc_groups != 0; | boolean_t has_special_class = spa->spa_special_class->mc_groups != 0; | ||||
if (DMU_OT_IS_DDT(objtype)) { | if (DMU_OT_IS_DDT(objtype)) { | ||||
if (spa->spa_dedup_class->mc_groups != 0) | if (spa->spa_dedup_class->mc_groups != 0) | ||||
return (spa_dedup_class(spa)); | return (spa_dedup_class(spa)); | ||||
else if (has_special_class && zfs_ddt_data_is_special) | else if (has_special_class && zfs_ddt_data_is_special) | ||||
return (spa_special_class(spa)); | return (spa_special_class(spa)); | ||||
▲ Show 20 Lines • Show All 519 Lines • ▼ Show 20 Lines | spa_fini(void) | ||||
cv_destroy(&spa_namespace_cv); | cv_destroy(&spa_namespace_cv); | ||||
mutex_destroy(&spa_namespace_lock); | mutex_destroy(&spa_namespace_lock); | ||||
mutex_destroy(&spa_spare_lock); | mutex_destroy(&spa_spare_lock); | ||||
mutex_destroy(&spa_l2cache_lock); | mutex_destroy(&spa_l2cache_lock); | ||||
} | } | ||||
/* | /* | ||||
* Return whether this pool has slogs. No locking needed. | * Return whether this pool has a dedicated slog device. No locking needed. | ||||
* It's not a problem if the wrong answer is returned as it's only for | * It's not a problem if the wrong answer is returned as it's only for | ||||
* performance and not correctness | * performance and not correctness. | ||||
*/ | */ | ||||
boolean_t | boolean_t | ||||
spa_has_slogs(spa_t *spa) | spa_has_slogs(spa_t *spa) | ||||
{ | { | ||||
return (spa->spa_log_class->mc_groups != 0); | return (spa->spa_log_class->mc_groups != 0); | ||||
} | } | ||||
spa_log_state_t | spa_log_state_t | ||||
▲ Show 20 Lines • Show All 481 Lines • Show Last 20 Lines |