auto min_alloc_size = cct->_conf->bluefs_alloc_size;
int id = _get_slow_device_id();
ceph_assert(id <= (int)alloc.size() && alloc[id]);
+ auto min_need = round_up_to(need, min_alloc_size);
need = std::max(need,
slow_dev_expander->get_recommended_expansion_delta(
alloc[id]->get_free(), block_all[id].size()));
dout(10) << __func__ << " expanding slow device by 0x"
<< std::hex << need << std::dec
<< dendl;
- r = slow_dev_expander->allocate_freespace(need, extents);
+ r = slow_dev_expander->allocate_freespace(min_need, need, extents);
}
return r;
}
}
-int BlueStore::allocate_bluefs_freespace(uint64_t size, PExtentVector* extents_out)
+int BlueStore::allocate_bluefs_freespace(
+ uint64_t min_size,
+ uint64_t size,
+ PExtentVector* extents_out)
{
+ ceph_assert(min_size <= size);
if (size) {
// round up to alloc size
+ min_size = p2roundup(min_size, cct->_conf->bluefs_alloc_size);
size = p2roundup(size, cct->_conf->bluefs_alloc_size);
PExtentVector extents_local;
uint64_t gift;
+ uint64_t allocated = 0;
+ int64_t alloc_len;
do {
// hard cap to fit into 32 bits
gift = std::min<uint64_t>(size, 1ull << 31);
dout(10) << __func__ << " gifting " << gift
<< " (" << byte_u_t(gift) << ")" << dendl;
- int64_t alloc_len = alloc->allocate(gift, cct->_conf->bluefs_alloc_size,
- 0, 0, extents);
+ alloc_len = alloc->allocate(gift, cct->_conf->bluefs_alloc_size,
+ 0, 0, extents);
+ if (alloc_len) {
+ allocated += alloc_len;
+ size -= alloc_len;
+ }
- if (alloc_len < (int64_t)gift) {
+ if (alloc_len < (int64_t)gift && (min_size > allocated)) {
derr << __func__
- << " failed to allocate on 0x" << std::hex << gift
- << " bluefs_alloc_size 0x" << cct->_conf->bluefs_alloc_size
- << " allocated 0x" << alloc_len
- << " available 0x " << alloc->get_free()
- << std::dec << dendl;
-
- alloc->dump();
- alloc->release(*extents);
- extents->clear();
+ << " failed to allocate on 0x" << std::hex << gift
+ << " min_size 0x" << min_size
+ << " > allocated total 0x" << allocated
+ << " bluefs_alloc_size 0x" << cct->_conf->bluefs_alloc_size
+ << " allocated 0x" << alloc_len
+ << " available 0x " << alloc->get_free()
+ << std::dec << dendl;
+
+ alloc->dump();
+ alloc->release(*extents);
+ extents->clear();
return -ENOSPC;
}
- size -= gift;
- } while (size);
+ } while (size && alloc_len > 0);
for (auto& e : *extents) {
- dout(1) << __func__ << " gifting " << e << " to bluefs" << dendl;
+ dout(5) << __func__ << " gifting " << e << " to bluefs" << dendl;
bluefs_extents.insert(e.offset, e.length);
++out_of_sync_fm;
// apply to bluefs if not requested from outside
dout(1) << __func__
<< " Allocating more space at slow device for BlueFS: +"
<< used_space - target_free << " bytes" << dendl;
- r = allocate_bluefs_freespace(used_space - target_free, nullptr);
+ r = allocate_bluefs_freespace(
+ used_space - target_free,
+ used_space - target_free,
+ nullptr);
umount();
if (r != 0) {
Either automatically applies allocated extents to underlying
BlueFS (extents == nullptr) or just return them (non-null extents) provided
*/
- int allocate_bluefs_freespace(uint64_t size, PExtentVector* extents);
+ int allocate_bluefs_freespace(
+ uint64_t min_size,
+ uint64_t size,
+ PExtentVector* extents);
void log_latency_fn(int idx,
const ceph::timespan& lat,
auto delta = _get_bluefs_size_delta(bluefs_free, bluefs_total);
return delta > 0 ? delta : 0;
}
- int allocate_freespace(uint64_t size, PExtentVector& extents) override {
- return allocate_bluefs_freespace(size, &extents);
+ int allocate_freespace(
+ uint64_t min_size,
+ uint64_t size,
+ PExtentVector& extents) override {
+ return allocate_bluefs_freespace(min_size, size, &extents);
};
};
uint64_t to_alloc = g_conf().get_val<Option::size_t>("bluefs_alloc_size");
- int r = bstore->allocate_bluefs_freespace(to_alloc, nullptr);
+ int r = bstore->allocate_bluefs_freespace(to_alloc, to_alloc, nullptr);
ASSERT_EQ(r, 0);
- r = bstore->allocate_bluefs_freespace(statfs.total, nullptr);
+ r = bstore->allocate_bluefs_freespace(statfs.total, statfs.total, nullptr);
ASSERT_EQ(r, -ENOSPC);
- r = bstore->allocate_bluefs_freespace(to_alloc * 16, nullptr);
+ r = bstore->allocate_bluefs_freespace(to_alloc * 16, to_alloc * 16, nullptr);
ASSERT_EQ(r, 0);
store->umount();
ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly