FreeBSD/sys/kern/subr_blist.c
/*
 * BLIST_RADIX_COPY() - copy one radix tree to another
 *
 *	Locates free space in the source tree and frees it in the destination
 *	tree.  The space may not already be free in the destination.
 */
copy one radix tree to another
Locates free space in the source tree and frees it in the destination
tree.  The space may not already be free in the destination.
copy one radix tree to another Locates free space in the source tree and frees it in the destination tree . The space may not already be free in the destination .
static void blst_copy(
	blmeta_t *scan, 
	daddr_t blk,
	daddr_t radix, 
	daddr_t skip, 
	blist_t dest,
	daddr_t count
) {
	int next_skip;
	int i;
	if (radix == BLIST_BMAP_RADIX) {
		u_daddr_t v = scan->u.bmu_bitmap;
		if (v == (u_daddr_t)-1) {
			blist_free(dest, blk, count);
		} else if (v != 0) {
			int i;
			for (i = 0; i < BLIST_BMAP_RADIX && i < count; ++i) {
				if (v & (1 << i))
					blist_free(dest, blk + i, 1);
			}
		}
		return;
	}
	if (scan->u.bmu_avail == 0) {
		return;
	} 
	if (scan->u.bmu_avail == radix) {
		if (count < radix)
			blist_free(dest, blk, count);
		else
			blist_free(dest, blk, radix);
		return;
	}
	radix /= BLIST_META_RADIX;
	next_skip = ((u_int)skip / BLIST_META_RADIX);
	for (i = 1; count && i <= skip; i += next_skip) {
		if (scan[i].bm_bighint == (daddr_t)-1)
			break;
		if (count >= radix) {
			blst_copy(
			    &scan[i],
			    blk,
			    radix,
			    next_skip - 1,
			    dest,
			    radix
			);
			count -= radix;
		} else {
			if (count) {
				blst_copy(
				    &scan[i],
				    blk,
				    radix,
				    next_skip - 1,
				    dest,
				    count
				);
			}
			count = 0;
		}
		blk += radix;
	}
}
static void blst_copy ( blmeta_t * scan , daddr_t blk , daddr_t radix , daddr_t skip , blist_t dest , daddr_t count ) { int next_skip ; int i ; if ( radix == BLIST_BMAP_RADIX ) { u_daddr_t v = scan -> u . bmu_bitmap ; if ( v == ( u_daddr_t ) - 1 ) { blist_free ( dest , blk , count ) ; } else if ( v != 0 ) { int i ; for ( i = 0 ; i < BLIST_BMAP_RADIX && i < count ; ++ i ) { if ( v & ( 1 << i ) ) blist_free ( dest , blk + i , 1 ) ; } } return ; } if ( scan -> u . bmu_avail == 0 ) { return ; } if ( scan -> u . bmu_avail == radix ) { if ( count < radix ) blist_free ( dest , blk , count ) ; else blist_free ( dest , blk , radix ) ; return ; } radix /= BLIST_META_RADIX ; next_skip = ( ( u_int ) skip / BLIST_META_RADIX ) ; for ( i = 1 ; count && i <= skip ; i += next_skip ) { if ( scan [ i ] . bm_bighint == ( daddr_t ) - 1 ) break ; if ( count >= radix ) { blst_copy ( & scan [ i ] , blk , radix , next_skip - 1 , dest , radix ) ; count -= radix ; } else { if ( count ) { blst_copy ( & scan [ i ] , blk , radix , next_skip - 1 , dest , count ) ; } count = 0 ; } blk += radix ; } }
BLIST_RADIX_COPY() - copy one radix tree to another
      Locates free space in the source tree and frees it in the destination
      tree.
BLIST_RADIX_COPY () - copy one radix tree to another Locates free space in the source tree and frees it in the destination tree .
/*
	 * Leaf node
	 */ /*
	 * Meta node
	 */ /*
		 * Source all allocated, leave dest allocated
		 */ /*
		 * Source all free, free entire dest
		 */