FreeBSD/sys/kern/subr_blist.c
/*
 * BLST_META_FREE() - free allocated blocks from radix tree meta info
 *
 *	This support routine frees a range of blocks from the bitmap.
 *	The range must be entirely enclosed by this radix node.  If a
 *	meta node, we break the range down recursively to free blocks
 *	in subnodes (which means that this code can free an arbitrary
 *	range whereas the allocation code cannot allocate an arbitrary
 *	range).
 */
free allocated blocks from radix tree meta info
This support routine frees a range of blocks from the bitmap.
The range must be entirely enclosed by this radix node.  If a
meta node, we break the range down recursively to free blocks
in subnodes (which means that this code can free an arbitrary
range whereas the allocation code cannot allocate an arbitrary
range).
free allocated blocks from radix tree meta info This support routine frees a range of blocks from the bitmap . The range must be entirely enclosed by this radix node . If a meta node we break the range down recursively to free blocks in subnodes ( which means that this code can free an arbitrary range whereas the allocation code cannot allocate an arbitrary range ) .
static void 
blst_meta_free(
	blmeta_t *scan, 
	daddr_t freeBlk,
	daddr_t count,
	daddr_t radix, 
	int skip,
	daddr_t blk
) {
	int i;
	int next_skip = ((u_int)skip / BLIST_META_RADIX);
#if 0
	printf("free (%llx,%lld) FROM (%llx,%lld)\n",
	    (long long)freeBlk, (long long)count,
	    (long long)blk, (long long)radix
	);
#endif
	if (scan->u.bmu_avail == 0) {
		scan->u.bmu_avail = count;
		scan->bm_bighint = count;
		if (count != radix)  {
			for (i = 1; i <= skip; i += next_skip) {
				if (scan[i].bm_bighint == (daddr_t)-1)
					break;
				scan[i].bm_bighint = 0;
				if (next_skip == 1) {
					scan[i].u.bmu_bitmap = 0;
				} else {
					scan[i].u.bmu_avail = 0;
				}
			}
		}
	} else {
		scan->u.bmu_avail += count;
	}
	if (scan->u.bmu_avail == radix)
		return;
	if (scan->u.bmu_avail > radix)
		panic("blst_meta_free: freeing already free blocks (%lld) %lld/%lld",
		    (long long)count, (long long)scan->u.bmu_avail,
		    (long long)radix);
	radix /= BLIST_META_RADIX;
	i = (freeBlk - blk) / radix;
	blk += i * radix;
	i = i * next_skip + 1;
	while (i <= skip && blk < freeBlk + count) {
		daddr_t v;
		v = blk + radix - freeBlk;
		if (v > count)
			v = count;
		if (scan->bm_bighint == (daddr_t)-1)
			panic("blst_meta_free: freeing unexpected range");
		if (next_skip == 1) {
			blst_leaf_free(&scan[i], freeBlk, v);
		} else {
			blst_meta_free(&scan[i], freeBlk, v, radix, next_skip - 1, blk);
		}
		if (scan->bm_bighint < scan[i].bm_bighint)
		    scan->bm_bighint = scan[i].bm_bighint;
		count -= v;
		freeBlk += v;
		blk += radix;
		i += next_skip;
	}
}
static void blst_meta_free ( blmeta_t * scan , daddr_t freeBlk , daddr_t count , daddr_t radix , int skip , daddr_t blk ) { int i ; int next_skip = ( ( u_int ) skip / BLIST_META_RADIX ) ; #if 0 printf ( " \n " , ( long long ) freeBlk , ( long long ) count , ( long long ) blk , ( long long ) radix ) ; #endif if ( scan -> u . bmu_avail == 0 ) { scan -> u . bmu_avail = count ; scan -> bm_bighint = count ; if ( count != radix ) { for ( i = 1 ; i <= skip ; i += next_skip ) { if ( scan [ i ] . bm_bighint == ( daddr_t ) - 1 ) break ; scan [ i ] . bm_bighint = 0 ; if ( next_skip == 1 ) { scan [ i ] . u . bmu_bitmap = 0 ; } else { scan [ i ] . u . bmu_avail = 0 ; } } } } else { scan -> u . bmu_avail += count ; } if ( scan -> u . bmu_avail == radix ) return ; if ( scan -> u . bmu_avail > radix ) panic ( " " , ( long long ) count , ( long long ) scan -> u . bmu_avail , ( long long ) radix ) ; radix /= BLIST_META_RADIX ; i = ( freeBlk - blk ) / radix ; blk += i * radix ; i = i * next_skip + 1 ; while ( i <= skip && blk < freeBlk + count ) { daddr_t v ; v = blk + radix - freeBlk ; if ( v > count ) v = count ; if ( scan -> bm_bighint == ( daddr_t ) - 1 ) panic ( " " ) ; if ( next_skip == 1 ) { blst_leaf_free ( & scan [ i ] , freeBlk , v ) ; } else { blst_meta_free ( & scan [ i ] , freeBlk , v , radix , next_skip - 1 , blk ) ; } if ( scan -> bm_bighint < scan [ i ] . bm_bighint ) scan -> bm_bighint = scan [ i ] . bm_bighint ; count -= v ; freeBlk += v ; blk += radix ; i += next_skip ; } }
BLST_META_FREE() - free allocated blocks from radix tree meta info
      This support routine frees a range of blocks from the bitmap.
BLST_META_FREE () - free allocated blocks from radix tree meta info This support routine frees a range of blocks from the bitmap .
/*
		 * ALL-ALLOCATED special case, with possible
		 * shortcut to ALL-FREE special case.
		 */ /* fall through */ /* scan->bm_bighint = radix; */ /*
	 * ALL-FREE special case.
	 */ /*
	 * Break the free down into its components
	 */