diff --git a/src/blockstore/blockstore_heap.cpp b/src/blockstore/blockstore_heap.cpp index 8d4f6928..47581320 100644 --- a/src/blockstore/blockstore_heap.cpp +++ b/src/blockstore/blockstore_heap.cpp @@ -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; } diff --git a/src/blockstore/multilist.cpp b/src/blockstore/multilist.cpp index df831e36..d571700e 100644 --- a/src/blockstore/multilist.cpp +++ b/src/blockstore/multilist.cpp @@ -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) diff --git a/src/blockstore/multilist.h b/src/blockstore/multilist.h index 3c80eafa..bcee68ed 100644 --- a/src/blockstore/multilist.h +++ b/src/blockstore/multilist.h @@ -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(); diff --git a/src/test/test_heap.cpp b/src/test/test_heap.cpp index e44bbea1..b88eb944 100644 --- a/src/test/test_heap.cpp +++ b/src/test/test_heap.cpp @@ -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();