Index: sys/kern/subr_blist.c =================================================================== --- sys/kern/subr_blist.c +++ sys/kern/subr_blist.c @@ -236,16 +236,27 @@ blist_create(daddr_t blocks, int flags) { blist_t bl; - u_daddr_t nodes, radix; + u_daddr_t n, nodes, radix; KASSERT(blocks > 0, ("invalid block count")); /* * Calculate the radix and node count used for scanning. */ - nodes = 1; - for (radix = 1; radix <= blocks / BLIST_RADIX; radix *= BLIST_RADIX) - nodes += 1 + (blocks - 1) / radix / BLIST_RADIX; + for (n = blocks, nodes = 0, radix = 1;;) { + n = (n - 1) / BLIST_RADIX + 1; + nodes += n; + if (n == 1) + break; + radix *= BLIST_RADIX; + } + + /* + * Include a sentinel node to ensure that cross-leaf scans stay within + * the bounds of the allocation. + */ + if (blocks % BLIST_RADIX == 0) + nodes++; bl = malloc(offsetof(struct blist, bl_root[nodes]), M_SWAP, flags | M_ZERO);