src/fs/zfs/metaslab.c
/*
 * Determine if the space map's on-disk footprint is past our tolerance
 * for inefficiency. We would like to use the following criteria to make
 * our decision:
 *
 * 1. The size of the space map object should not dramatically increase as a
 * result of writing out the free space range tree.
 *
 * 2. The minimal on-disk space map representation is zfs_condense_pct/100
 * times the size than the free space range tree representation
 * (i.e. zfs_condense_pct = 110 and in-core = 1MB, minimal = 1.1.MB).
 *
 * 3. The on-disk size of the space map should actually decrease.
 *
 * Checking the first condition is tricky since we don't want to walk
 * the entire AVL tree calculating the estimated on-disk size. Instead we
 * use the size-ordered range tree in the metaslab and calculate the
 * size required to write out the largest segment in our free tree. If the
 * size required to represent that segment on disk is larger than the space
 * map object then we avoid condensing this map.
 *
 * To determine the second criterion we use a best-case estimate and assume
 * each segment can be represented on-disk as a single 64-bit entry. We refer
 * to this best-case estimate as the space map's minimal form.
 *
 * Unfortunately, we cannot compute the on-disk size of the space map in this
 * context because we cannot accurately compute the effects of compression, etc.
 * Instead, we apply the heuristic described in the block comment for
 * zfs_metaslab_condense_block_threshold - we only condense if the space used
 * is greater than a threshold number of blocks.
 */
Determine if the space map's on-disk footprint is past our tolerance
for inefficiency. We would like to use the following criteria to make
our decision.

1. The size of the space map object should not dramatically increase as a
result of writing out the free space range tree.

2. The minimal on-disk space map representation is zfs_condense_pct/100
times the size than the free space range tree representation
.

3. The on-disk size of the space map should actually decrease.

Checking the first condition is tricky since we don't want to walk
the entire AVL tree calculating the estimated on-disk size. Instead we
use the size-ordered range tree in the metaslab and calculate the
size required to write out the largest segment in our free tree. If the
size required to represent that segment on disk is larger than the space
map object then we avoid condensing this map.

To determine the second criterion we use a best-case estimate and assume
each segment can be represented on-disk as a single 64-bit entry. We refer
to this best-case estimate as the space map's minimal form.

Unfortunately, we cannot compute the on-disk size of the space map in this
context because we cannot accurately compute the effects of compression, etc.
Instead, we apply the heuristic described in the block comment for
zfs_metaslab_condense_block_threshold - we only condense if the space used
is greater than a threshold number of blocks.
Determine if the space map ' s on - disk footprint is past our tolerance for inefficiency . We would like to use the following criteria to make our decision . 1 . The size of the space map object should not dramatically increase as a result of writing out the free space range tree . 2 . The minimal on - disk space map representation is zfs_condense_pct / 100 times the size than the free space range tree representation . 3 . The on - disk size of the space map should actually decrease . Checking the first condition is tricky since we don ' t want to walk the entire AVL tree calculating the estimated on - disk size . Instead we use the size - ordered range tree in the metaslab and calculate the size required to write out the largest segment in our free tree . If the size required to represent that segment on disk is larger than the space map object then we avoid condensing this map . To determine the second criterion we use a best - case estimate and assume each segment can be represented on - disk as a single 64 - bit entry . We refer to this best - case estimate as the space map ' s minimal form . Unfortunately we cannot compute the on - disk size of the space map in this context because we cannot accurately compute the effects of compression etc . Instead we apply the heuristic described in the block comment for zfs_metaslab_condense_block_threshold - we only condense if the space used is greater than a threshold number of blocks .
static boolean_t
metaslab_should_condense(metaslab_t *msp)
{
	space_map_t *sm = msp->ms_sm;
	range_seg_t *rs;
	uint64_t size, entries, segsz, object_size, optimal_size, record_size;
	dmu_object_info_t doi;
	uint64_t vdev_blocksize = 1 << msp->ms_group->mg_vd->vdev_ashift;
	ASSERT(MUTEX_HELD(&msp->ms_lock));
	ASSERT(msp->ms_loaded);
	rs = avl_last(&msp->ms_size_tree);
	if (rs == NULL || msp->ms_condense_wanted)
		return (B_TRUE);
	size = (rs->rs_end - rs->rs_start) >> sm->sm_shift;
	entries = size / (MIN(size, SM_RUN_MAX));
	segsz = entries * sizeof (uint64_t);
	optimal_size = sizeof (uint64_t) * avl_numnodes(&msp->ms_tree->rt_root);
	object_size = space_map_length(msp->ms_sm);
	dmu_object_info_from_db(sm->sm_dbuf, &doi);
	record_size = MAX(doi.doi_data_block_size, vdev_blocksize);
	return (segsz <= object_size &&
	    object_size >= (optimal_size * zfs_condense_pct / 100) &&
	    object_size > zfs_metaslab_condense_block_threshold * record_size);
}
static boolean_t metaslab_should_condense ( metaslab_t * msp ) { space_map_t * sm = msp -> ms_sm ; range_seg_t * rs ; uint64_t size , entries , segsz , object_size , optimal_size , record_size ; dmu_object_info_t doi ; uint64_t vdev_blocksize = 1 << msp -> ms_group -> mg_vd -> vdev_ashift ; ASSERT ( MUTEX_HELD ( & msp -> ms_lock ) ) ; ASSERT ( msp -> ms_loaded ) ; rs = avl_last ( & msp -> ms_size_tree ) ; if ( rs == NULL || msp -> ms_condense_wanted ) return ( B_TRUE ) ; size = ( rs -> rs_end - rs -> rs_start ) >> sm -> sm_shift ; entries = size / ( MIN ( size , SM_RUN_MAX ) ) ; segsz = entries * sizeof ( uint64_t ) ; optimal_size = sizeof ( uint64_t ) * avl_numnodes ( & msp -> ms_tree -> rt_root ) ; object_size = space_map_length ( msp -> ms_sm ) ; dmu_object_info_from_db ( sm -> sm_dbuf , & doi ) ; record_size = MAX ( doi . doi_data_block_size , vdev_blocksize ) ; return ( segsz <= object_size && object_size >= ( optimal_size * zfs_condense_pct / 100 ) && object_size > zfs_metaslab_condense_block_threshold * record_size ) ; }
Determine if the space map's on-disk footprint is past our tolerance
 for inefficiency.
Determine if the space map ' s on - disk footprint is past our tolerance for inefficiency .
/*
	 * Use the ms_size_tree range tree, which is ordered by size, to
	 * obtain the largest segment in the free tree. We always condense
	 * metaslabs that are empty and metaslabs for which a condense
	 * request has been made.
	 */ /*
	 * Calculate the number of 64-bit entries this segment would
	 * require when written to disk. If this single segment would be
	 * larger on-disk than the entire current on-disk structure, then
	 * clearly condensing will increase the on-disk structure size.
	 */