Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_blist.c
Context not available. | |||||
*/ | */ | ||||
static daddr_t blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, | static daddr_t blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, | ||||
daddr_t cursor); | daddr_t cursor); | ||||
static daddr_t blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, | static daddr_t blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, | ||||
daddr_t radix, daddr_t cursor); | u_daddr_t radix); | ||||
static void blst_leaf_free(blmeta_t *scan, daddr_t relblk, int count); | static void blst_leaf_free(blmeta_t *scan, daddr_t relblk, int count); | ||||
static void blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, | static void blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, | ||||
daddr_t radix, daddr_t blk); | u_daddr_t radix); | ||||
static void blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, | static void blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, | ||||
blist_t dest, daddr_t count); | blist_t dest, daddr_t count); | ||||
static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count); | static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count); | ||||
static daddr_t blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, | static daddr_t blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, | ||||
daddr_t radix, daddr_t blk); | u_daddr_t radix); | ||||
static daddr_t blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count); | static daddr_t blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count); | ||||
#ifndef _KERNEL | #ifndef _KERNEL | ||||
static void blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, | static void blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, | ||||
Context not available. | |||||
* reduce the hint, stopping further iterations. | * reduce the hint, stopping further iterations. | ||||
*/ | */ | ||||
while (count <= bl->bl_root->bm_bighint) { | while (count <= bl->bl_root->bm_bighint) { | ||||
blk = blst_meta_alloc(bl->bl_root, 0, count, bl->bl_radix, | blk = blst_meta_alloc(bl->bl_root, bl->bl_cursor, count, | ||||
bl->bl_cursor); | bl->bl_radix); | ||||
if (blk != SWAPBLK_NONE) { | if (blk != SWAPBLK_NONE) { | ||||
bl->bl_cursor = blk + count; | bl->bl_cursor = blk + count; | ||||
return (blk); | return (blk); | ||||
Context not available. | |||||
blist_free(blist_t bl, daddr_t blkno, daddr_t count) | blist_free(blist_t bl, daddr_t blkno, daddr_t count) | ||||
{ | { | ||||
blst_meta_free(bl->bl_root, blkno, count, bl->bl_radix, 0); | blst_meta_free(bl->bl_root, blkno, count, bl->bl_radix); | ||||
} | } | ||||
/* | /* | ||||
Context not available. | |||||
blist_fill(blist_t bl, daddr_t blkno, daddr_t count) | blist_fill(blist_t bl, daddr_t blkno, daddr_t count) | ||||
{ | { | ||||
return (blst_meta_fill(bl->bl_root, blkno, count, bl->bl_radix, 0)); | return (blst_meta_fill(bl->bl_root, blkno, count, bl->bl_radix)); | ||||
} | } | ||||
/* | /* | ||||
Context not available. | |||||
* and we have a few optimizations strewn in as well. | * and we have a few optimizations strewn in as well. | ||||
*/ | */ | ||||
static daddr_t | static daddr_t | ||||
blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix, | blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix) | ||||
daddr_t cursor) | |||||
{ | { | ||||
daddr_t i, next_skip, r, skip; | daddr_t blk, i, next_skip, r, skip; | ||||
int child; | int child; | ||||
bool scan_from_start; | bool scan_from_start; | ||||
if (radix == BLIST_BMAP_RADIX) | if (radix == BLIST_BMAP_RADIX) | ||||
return (blst_leaf_alloc(scan, blk, count, cursor)); | return (blst_leaf_alloc(scan, cursor, count)); | ||||
if (scan->u.bmu_avail < count) { | if (scan->u.bmu_avail < count) { | ||||
/* | /* | ||||
* The meta node's hint must be too large if the allocation | * The meta node's hint must be too large if the allocation | ||||
Context not available. | |||||
} | } | ||||
skip = radix_to_skip(radix); | skip = radix_to_skip(radix); | ||||
next_skip = skip / BLIST_META_RADIX; | next_skip = skip / BLIST_META_RADIX; | ||||
blk = cursor & -radix; | |||||
/* | /* | ||||
* An ALL-FREE meta node requires special handling before allocating | * An ALL-FREE meta node requires special handling before allocating | ||||
Context not available. | |||||
/* | /* | ||||
* The allocation might fit in the i'th subtree. | * The allocation might fit in the i'th subtree. | ||||
*/ | */ | ||||
r = blst_meta_alloc(&scan[i], blk, count, radix, | r = blst_meta_alloc(&scan[i], | ||||
cursor > blk ? cursor : blk); | cursor > blk ? cursor : blk, count, radix); | ||||
if (r != SWAPBLK_NONE) { | if (r != SWAPBLK_NONE) { | ||||
scan->u.bmu_avail -= count; | scan->u.bmu_avail -= count; | ||||
return (r); | return (r); | ||||
Context not available. | |||||
* range). | * range). | ||||
*/ | */ | ||||
static void | static void | ||||
blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix, | blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, u_daddr_t radix) | ||||
daddr_t blk) | |||||
{ | { | ||||
daddr_t i, next_skip, skip, v; | daddr_t blk, i, next_skip, skip, v; | ||||
int child; | int child; | ||||
if (scan->bm_bighint == (daddr_t)-1) | if (scan->bm_bighint == (daddr_t)-1) | ||||
Context not available. | |||||
* Break the free down into its components | * Break the free down into its components | ||||
*/ | */ | ||||
blk = freeBlk & -radix; | |||||
radix /= BLIST_META_RADIX; | radix /= BLIST_META_RADIX; | ||||
child = (freeBlk - blk) / radix; | child = (freeBlk - blk) / radix; | ||||
Context not available. | |||||
v = blk + radix - freeBlk; | v = blk + radix - freeBlk; | ||||
if (v > count) | if (v > count) | ||||
v = count; | v = count; | ||||
blst_meta_free(&scan[i], freeBlk, v, radix, blk); | blst_meta_free(&scan[i], freeBlk, v, radix); | ||||
if (scan->bm_bighint < scan[i].bm_bighint) | if (scan->bm_bighint < scan[i].bm_bighint) | ||||
scan->bm_bighint = scan[i].bm_bighint; | scan->bm_bighint = scan[i].bm_bighint; | ||||
count -= v; | count -= v; | ||||
Context not available. | |||||
* number of blocks allocated by the call. | * number of blocks allocated by the call. | ||||
*/ | */ | ||||
static daddr_t | static daddr_t | ||||
blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix, | blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, u_daddr_t radix) | ||||
daddr_t blk) | |||||
{ | { | ||||
daddr_t i, nblks, next_skip, skip, v; | daddr_t blk, i, nblks, next_skip, skip, v; | ||||
int child; | int child; | ||||
if (scan->bm_bighint == (daddr_t)-1) | if (scan->bm_bighint == (daddr_t)-1) | ||||
Context not available. | |||||
} | } | ||||
skip = radix_to_skip(radix); | skip = radix_to_skip(radix); | ||||
next_skip = skip / BLIST_META_RADIX; | next_skip = skip / BLIST_META_RADIX; | ||||
blk = allocBlk & -radix; | |||||
/* | /* | ||||
* An ALL-FREE meta node requires special handling before allocating | * An ALL-FREE meta node requires special handling before allocating | ||||
Context not available. | |||||
v = blk + radix - allocBlk; | v = blk + radix - allocBlk; | ||||
if (v > count) | if (v > count) | ||||
v = count; | v = count; | ||||
nblks += blst_meta_fill(&scan[i], allocBlk, v, radix, blk); | nblks += blst_meta_fill(&scan[i], allocBlk, v, radix); | ||||
count -= v; | count -= v; | ||||
allocBlk += v; | allocBlk += v; | ||||
blk += radix; | blk += radix; | ||||
Context not available. |