Fix multilist_alloc_t bug (not triggerable in real operation but still a bug)
This commit is contained in:
@@ -2322,7 +2322,8 @@ void blockstore_heap_t::use_buffer_area(inode_t inode, uint64_t location, uint64
|
||||
return;
|
||||
}
|
||||
assert(!(size % dsk->bitmap_granularity));
|
||||
buffer_alloc->use(location / dsk->bitmap_granularity, size / dsk->bitmap_granularity);
|
||||
bool ok = buffer_alloc->use(location / dsk->bitmap_granularity, size / dsk->bitmap_granularity);
|
||||
assert(ok);
|
||||
buffer_area_used_space += size;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ void multilist_alloc_t::print()
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void multilist_alloc_t::use(uint32_t pos, uint32_t size)
|
||||
bool multilist_alloc_t::use(uint32_t pos, uint32_t size)
|
||||
{
|
||||
assert(pos+size <= count && size > 0);
|
||||
if (sizes[pos] <= 0)
|
||||
@@ -182,7 +182,8 @@ void multilist_alloc_t::use(uint32_t pos, uint32_t size)
|
||||
else
|
||||
while (start > 0 && !sizes[start])
|
||||
start--;
|
||||
assert(sizes[start] >= size);
|
||||
if (sizes[start] < size+(pos-start))
|
||||
return false;
|
||||
use_full(start);
|
||||
uint32_t full = sizes[start];
|
||||
sizes[pos-1] = -pos+start;
|
||||
@@ -199,7 +200,8 @@ void multilist_alloc_t::use(uint32_t pos, uint32_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(sizes[pos] >= size);
|
||||
if (sizes[pos] < size)
|
||||
return false;
|
||||
use_full(pos);
|
||||
if (sizes[pos] > size)
|
||||
{
|
||||
@@ -214,12 +216,13 @@ void multilist_alloc_t::use(uint32_t pos, uint32_t size)
|
||||
#ifdef MULTILIST_TRACE
|
||||
print();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void multilist_alloc_t::use_full(uint32_t pos)
|
||||
{
|
||||
uint32_t prevsize = sizes[pos];
|
||||
assert(prevsize);
|
||||
assert(prevsize > 0);
|
||||
assert(nexts[pos]);
|
||||
uint32_t pi = (prevsize < maxn ? prevsize : maxn)-1;
|
||||
if (heads[pi] == pos+1)
|
||||
|
||||
@@ -17,7 +17,7 @@ struct multilist_alloc_t
|
||||
bool is_free(uint32_t pos);
|
||||
uint32_t find(uint32_t size);
|
||||
void use_full(uint32_t pos);
|
||||
void use(uint32_t pos, uint32_t size);
|
||||
bool use(uint32_t pos, uint32_t size);
|
||||
void do_free(uint32_t pos);
|
||||
void free(uint32_t pos);
|
||||
void verify();
|
||||
|
||||
@@ -1902,6 +1902,19 @@ void test_alloc_buffer()
|
||||
alloc.verify();
|
||||
}
|
||||
|
||||
{
|
||||
multilist_alloc_t alloc(100, 10);
|
||||
|
||||
alloc.use(50, 10);
|
||||
alloc.verify();
|
||||
|
||||
// 48, 5 overlaps with 50, 10 -> should fail to allocate
|
||||
bool ok = alloc.use(48, 5);
|
||||
assert(!ok);
|
||||
|
||||
alloc.verify();
|
||||
}
|
||||
|
||||
blockstore_heap_t heap(&dsk, buffer_area.data());
|
||||
heap.finish_recheck();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user