virtual int reserve(uint64_t need) = 0;
virtual void unreserve(uint64_t unused) = 0;
- virtual int allocate(
- uint64_t need_size, uint64_t alloc_unit, int64_t hint,
- uint64_t *offset, uint32_t *length) = 0;
-
/*
* Allocate required number of blocks in n number of extents.
* Min and Max number of extents are limited by:
*/
virtual int alloc_extents(uint64_t want_size, uint64_t alloc_unit,
uint64_t max_alloc_size, int64_t hint,
- AllocExtentVector *extents, int *count) = 0;
+ AllocExtentVector *extents, int *count, uint64_t *ret_len) = 0;
int alloc_extents(uint64_t want_size, uint64_t alloc_unit,
- int64_t hint, AllocExtentVector *extents, int *count) {
- return alloc_extents(want_size, alloc_unit, want_size, hint, extents, count);
+ int64_t hint, AllocExtentVector *extents, int *count, uint64_t *ret_len) {
+ return alloc_extents(want_size, alloc_unit, want_size, hint, extents, count, ret_len);
}
virtual int release(
m_bit_alloc->unreserve_blocks(nblks);
}
-int BitMapAllocator::allocate(
- uint64_t want_size, uint64_t alloc_unit, int64_t hint,
- uint64_t *offset, uint32_t *length)
-{
- if (want_size == 0)
- return 0;
-
- assert(!(alloc_unit % m_block_size));
- int64_t nblks = (want_size + m_block_size - 1) / m_block_size;
-
- assert(alloc_unit);
-
- int64_t start_blk = 0;
- int64_t count = 0;
-
- dout(10) << __func__ << " instance " << (uint64_t) this
- << " want_size 0x" << std::hex << want_size
- << " alloc_unit 0x" << alloc_unit
- << " hint 0x" << hint << std::dec
- << dendl;
-
- *offset = 0;
- *length = 0;
-
- count = m_bit_alloc->alloc_blocks_res(nblks, hint / m_block_size, &start_blk);
- if (count == 0) {
- return -ENOSPC;
- }
- *offset = start_blk * m_block_size;
- *length = count * m_block_size;
-
- dout(20) << __func__ <<" instance "<< (uint64_t) this
- << " offset 0x" << std::hex << *offset
- << " length 0x" << *length << std::dec
- << dendl;
-
- return 0;
-}
-
int BitMapAllocator::alloc_extents(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
- int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count)
+ int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len)
{
assert(!(alloc_unit % m_block_size));
<< dendl;
return alloc_extents_dis(want_size, alloc_unit / m_block_size,
- max_alloc_size, hint / m_block_size, extents, count);
-}
-
-/*
- * Allocator extents with min alloc unit > bitmap block size.
- */
-int BitMapAllocator::alloc_extents_cont(
- uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size, int64_t hint,
- mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count)
-{
- *count = 0;
- assert(alloc_unit);
- assert(!(alloc_unit % m_block_size));
- assert(!(want_size % alloc_unit));
- assert(!(max_alloc_size % m_block_size));
-
- int64_t nblks = (want_size + m_block_size - 1) / m_block_size;
- int64_t start_blk = 0;
- int64_t need_blks = nblks;
- int64_t cont_blks = alloc_unit / m_block_size;
-
- ExtentList block_list = ExtentList(extents, m_block_size, max_alloc_size);
-
- while (need_blks > 0) {
- int64_t count = 0;
- count = m_bit_alloc->alloc_blocks_res(cont_blks, hint, &start_blk);
- if (count == 0) {
- break;
- }
- assert(cont_blks == count);
- dout(30) << __func__ <<" instance "<< (uint64_t) this
- << " offset " << start_blk << " length " << count << dendl;
- need_blks -= count;
- block_list.add_extents(start_blk, count);
- hint = start_blk + count;
- }
-
- if (need_blks > 0) {
- m_bit_alloc->free_blocks_dis(nblks - need_blks, &block_list);
- return -ENOSPC;
- }
- *count = block_list.get_extent_count();
-
- return 0;
+ max_alloc_size, hint / m_block_size, extents, count, ret_len);
}
int BitMapAllocator::alloc_extents_dis(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
- int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count)
+ int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len)
{
ExtentList block_list = ExtentList(extents, m_block_size, max_alloc_size);
int64_t nblks = (want_size + m_block_size - 1) / m_block_size;
int64_t num = 0;
*count = 0;
+ *ret_len = 0;
num = m_bit_alloc->alloc_blocks_dis_res(nblks, alloc_unit, hint, &block_list);
- if (num < nblks) {
- m_bit_alloc->free_blocks_dis(num, &block_list);
+ if (num == 0) {
return -ENOSPC;
}
*count = block_list.get_extent_count();
+ *ret_len = num * m_block_size;
return 0;
}
BitAllocator *m_bit_alloc; // Bit allocator instance
void insert_free(uint64_t offset, uint64_t len);
-
int alloc_extents_cont(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count);
int alloc_extents_dis(uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
- int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count);
+ int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
public:
BitMapAllocator();
int reserve(uint64_t need);
void unreserve(uint64_t unused);
- int allocate(
- uint64_t want_size, uint64_t alloc_unit, int64_t hint,
- uint64_t *offset, uint32_t *length);
-
int alloc_extents(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
- int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count);
+ int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
int release(
uint64_t offset, uint64_t length);
assert(alloc[id]);
int r = alloc[id]->reserve(want);
assert(r == 0); // caller shouldn't ask for more than they can get
+ int count = 0;
+ uint64_t alloc_len = 0;;
+ AllocExtentVector extents = AllocExtentVector(want / g_conf->bluefs_alloc_size);
+
+ r = alloc[id]->alloc_extents(want, g_conf->bluefs_alloc_size, 0,
+ &extents, &count, &alloc_len);
- r = alloc[id]->allocate(want, g_conf->bluefs_alloc_size, 0,
- offset, length);
+ *length = alloc_len;
assert(r >= 0);
- if (*length < want)
+ if (*length < want)
alloc[id]->unreserve(want - *length);
- block_all[id].erase(*offset, *length);
- block_total[id] -= *length;
- log_t.op_alloc_rm(id, *offset, *length);
+ for (int i = 0; i < count; i++) {
+ block_all[id].erase(extents[i].offset, extents[i].length);
+ block_total[id] -= extents[i].length;
+ log_t.op_alloc_rm(id, extents[i].offset, extents[i].length);
+ }
+
r = _flush_and_sync_log(l);
assert(r == 0);
}
int count = 0;
+ uint64_t alloc_len = 0;
AllocExtentVector extents = AllocExtentVector(left / min_alloc_size);
- r = alloc[id]->alloc_extents(left, min_alloc_size,
- hint, &extents, &count);
- if (r < 0) {
+ r = alloc[id]->alloc_extents(left, min_alloc_size, hint,
+ &extents, &count, &alloc_len);
+ if (r < 0 || alloc_len < left) {
derr << __func__ << " allocate failed on 0x" << std::hex << left
<< " min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
alloc[id]->dump();
assert(0 == "allocate failed... wtf");
return r;
}
+
for (int i = 0; i < count; i++) {
bluefs_extent_t e = bluefs_extent_t(id, extents[i].offset, extents[i].length);
if (!ev->empty() &&
assert(r == 0);
int count = 0;
+ uint64_t alloc_len = 0;
AllocExtentVector exts = AllocExtentVector(gift / min_alloc_size);
- r = alloc->alloc_extents(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count);
+ r = alloc->alloc_extents(gift, g_conf->bluefs_alloc_size, 0, 0, &exts, &count, &alloc_len);
- if (r < 0) {
+ if (r < 0 || alloc_len < gift) {
derr << __func__ << " allocate failed on 0x" << std::hex << gift
<< " min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
alloc->dump();
}
int count = 0;
+ uint64_t alloc_len = 0;
AllocExtentVector extents = AllocExtentVector(final_length / min_alloc_size);
int r = alloc->alloc_extents(final_length, min_alloc_size, max_alloc_size,
- hint, &extents, &count);
- assert(r == 0);
+ hint, &extents, &count, &alloc_len);
+ assert(r == 0 && alloc_len == final_length);
need -= final_length;
txc->statfs_delta.allocated() += final_length;
assert(count > 0);
uint64_t max_alloc_size,
int64_t hint,
mempool::bluestore_alloc::vector<AllocExtent> *extents,
- int *count)
+ int *count,
+ uint64_t *ret_len)
{
uint64_t allocated_size = 0;
uint64_t offset = 0;
if (max_alloc_size == 0) {
max_alloc_size = want_size;
}
+ *count = 0;
+ *ret_len = 0;
ExtentList block_list = ExtentList(extents, 1, max_alloc_size);
}
*count = block_list.get_extent_count();
- if (want_size - allocated_size > 0) {
- release_extents(extents, *count);
+ *ret_len = allocated_size;
+ if (allocated_size == 0) {
return -ENOSPC;
}
int alloc_extents(
uint64_t want_size, uint64_t alloc_unit, uint64_t max_alloc_size,
- int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count);
+ int64_t hint, mempool::bluestore_alloc::vector<AllocExtent> *extents, int *count, uint64_t *ret_len);
int allocate(
uint64_t want_size, uint64_t alloc_unit, int64_t hint,