blist: Correct the node count computed in blist_create()
Commit bb4a27f927
added the ability to allocate a span of blocks
crossing a meta node boundary. To ensure that blst_next_leaf_alloc()
does not walk past the end of the tree, an extra all-zero meta node
needs to be present at the end of the allocation, and
blst_next_leaf_alloc() is implemented such that the presence of this
node terminates the search.
blist_create() computes the number of nodes required. It had two
problems:
1. When the size of the blist is a power of BLIST_RADIX, we would
unnecessarily allocate an extra level in the tree.
2. When the size of the blist is a multiple of BLIST_RADIX, we would
fail to allocate a terminator node. In this case,
blst_next_leaf_alloc() could scan beyond the bounds of the
allocation. This was found using KASAN.
Modify blist_create() to handle these cases correctly.
Reported by: pho
Reviewed by: dougm
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D31158
This commit is contained in:
parent
45e2357113
commit
2783335cae
@ -244,8 +244,16 @@ blist_create(daddr_t blocks, int flags)
|
||||
* 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 (radix = 1; (blocks - 1) / BLIST_RADIX / radix > 0;
|
||||
radix *= BLIST_RADIX)
|
||||
nodes += 1 + (blocks - 1) / BLIST_RADIX / 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);
|
||||
|
Loading…
Reference in New Issue
Block a user