FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
/*
 * Compute a weight -- a selection preference value -- for the given metaslab.
 * This is based on the amount of free space, the level of fragmentation,
 * the LBA range, and whether the metaslab is loaded.
 */
Compute a weight -- a selection preference value -- for the given metaslab.
This is based on the amount of free space, the level of fragmentation,
the LBA range, and whether the metaslab is loaded.
Compute a weight -- a selection preference value -- for the given metaslab . This is based on the amount of free space the level of fragmentation the LBA range and whether the metaslab is loaded .
static uint64_t
metaslab_weight(metaslab_t *msp)
{
	metaslab_group_t *mg = msp->ms_group;
	vdev_t *vd = mg->mg_vd;
	uint64_t weight, space;
	ASSERT(MUTEX_HELD(&msp->ms_lock));
	if (vd->vdev_removing) {
		ASSERT0(space_map_allocated(msp->ms_sm));
		ASSERT0(vd->vdev_ms_shift);
		return (0);
	}
	space = msp->ms_size - space_map_allocated(msp->ms_sm);
	msp->ms_fragmentation = metaslab_fragmentation(msp);
	if (metaslab_fragmentation_factor_enabled &&
	    msp->ms_fragmentation != ZFS_FRAG_INVALID) {
		space = (space * (100 - (msp->ms_fragmentation - 1))) / 100;
		if (space > 0 && space < SPA_MINBLOCKSIZE)
			space = SPA_MINBLOCKSIZE;
	}
	weight = space;
	if (metaslab_lba_weighting_enabled) {
		weight = 2 * weight - (msp->ms_id * weight) / vd->vdev_ms_count;
		ASSERT(weight >= space && weight <= 2 * space);
	}
	if (msp->ms_loaded && msp->ms_fragmentation != ZFS_FRAG_INVALID &&
	    msp->ms_fragmentation <= zfs_metaslab_fragmentation_threshold) {
		weight |= (msp->ms_weight & METASLAB_ACTIVE_MASK);
	}
	return (weight);
}
static uint64_t metaslab_weight ( metaslab_t * msp ) { metaslab_group_t * mg = msp -> ms_group ; vdev_t * vd = mg -> mg_vd ; uint64_t weight , space ; ASSERT ( MUTEX_HELD ( & msp -> ms_lock ) ) ; if ( vd -> vdev_removing ) { ASSERT0 ( space_map_allocated ( msp -> ms_sm ) ) ; ASSERT0 ( vd -> vdev_ms_shift ) ; return ( 0 ) ; } space = msp -> ms_size - space_map_allocated ( msp -> ms_sm ) ; msp -> ms_fragmentation = metaslab_fragmentation ( msp ) ; if ( metaslab_fragmentation_factor_enabled && msp -> ms_fragmentation != ZFS_FRAG_INVALID ) { space = ( space * ( 100 - ( msp -> ms_fragmentation - 1 ) ) ) / 100 ; if ( space > 0 && space < SPA_MINBLOCKSIZE ) space = SPA_MINBLOCKSIZE ; } weight = space ; if ( metaslab_lba_weighting_enabled ) { weight = 2 * weight - ( msp -> ms_id * weight ) / vd -> vdev_ms_count ; ASSERT ( weight >= space && weight <= 2 * space ) ; } if ( msp -> ms_loaded && msp -> ms_fragmentation != ZFS_FRAG_INVALID && msp -> ms_fragmentation <= zfs_metaslab_fragmentation_threshold ) { weight |= ( msp -> ms_weight & METASLAB_ACTIVE_MASK ) ; } return ( weight ) ; }
Compute a weight -- a selection preference value -- for the given metaslab.
Compute a weight -- a selection preference value -- for the given metaslab .
/*
	 * This vdev is in the process of being removed so there is nothing
	 * for us to do here.
	 */ /*
	 * The baseline weight is the metaslab's free space.
	 */ /*
		 * Use the fragmentation information to inversely scale
		 * down the baseline weight. We need to ensure that we
		 * don't exclude this metaslab completely when it's 100%
		 * fragmented. To avoid this we reduce the fragmented value
		 * by 1.
		 */ /*
		 * If space < SPA_MINBLOCKSIZE, then we will not allocate from
		 * this metaslab again. The fragmentation metric may have
		 * decreased the space to something smaller than
		 * SPA_MINBLOCKSIZE, so reset the space to SPA_MINBLOCKSIZE
		 * so that we can consume any remaining space.
		 */ /*
	 * Modern disks have uniform bit density and constant angular velocity.
	 * Therefore, the outer recording zones are faster (higher bandwidth)
	 * than the inner zones by the ratio of outer to inner track diameter,
	 * which is typically around 2:1.  We account for this by assigning
	 * higher weight to lower metaslabs (multiplier ranging from 2x to 1x).
	 * In effect, this means that we'll select the metaslab with the most
	 * free bandwidth rather than simply the one with the most free space.
	 */ /*
	 * If this metaslab is one we're actively using, adjust its
	 * weight to make it preferable to any inactive metaslab so
	 * we'll polish it off. If the fragmentation on this metaslab
	 * has exceed our threshold, then don't mark it active.
	 */