alloc = Allocator::create("stupid");
uint64_t num = 0, bytes = 0;
- const auto& fl = fm->get_freelist();
- for (auto& p : fl) {
- alloc->init_add_free(p.first, p.second);
+ fm->enumerate_reset();
+ uint64_t offset, length;
+ while (fm->enumerate_next(&offset, &length)) {
+ alloc->init_add_free(offset, length);
++num;
- bytes += p.second;
+ bytes += length;
}
dout(10) << __func__ << " loaded " << pretty_si_t(bytes)
<< " in " << num << " extents"
dout(1) << __func__ << " checking freelist vs allocated" << dendl;
{
- const auto& free = fm->get_freelist();
- for (auto p = free.begin();
- p != free.end(); ++p) {
- if (used_blocks.intersects(p->first, p->second)) {
- derr << __func__ << " free extent " << p->first << "~" << p->second
+ fm->enumerate_reset();
+ uint64_t offset, length;
+ while (fm->enumerate_next(&offset, &length)) {
+ if (used_blocks.intersects(offset, length)) {
+ derr << __func__ << " free extent " << offset << "~" << length
<< " intersects allocated blocks" << dendl;
interval_set<uint64_t> free, overlap;
- free.insert(p->first, p->second);
+ free.insert(offset, length);
overlap.intersection_of(free, used_blocks);
derr << __func__ << " overlap: " << overlap << dendl;
++errors;
continue;
}
- used_blocks.insert(p->first, p->second);
+ used_blocks.insert(offset, length);
}
if (!used_blocks.contains(0, bdev->get_size())) {
derr << __func__ << " leaked some space; free+used = "
_dump();
}
+void FreelistManager::enumerate_reset()
+{
+ std::lock_guard<std::mutex> l(lock);
+ enumerate_p = kv_free.begin();
+}
+
+bool FreelistManager::enumerate_next(uint64_t *offset, uint64_t *length)
+{
+ std::lock_guard<std::mutex> l(lock);
+ if (enumerate_p == kv_free.end())
+ return false;
+ *offset = enumerate_p->first;
+ *length = enumerate_p->second;
+ ++enumerate_p;
+ return true;
+}
+
void FreelistManager::_dump()
{
dout(30) << __func__ << " " << total_free
map_t kv_free; ///< mirrors our kv values in the db
+ map_t::const_iterator enumerate_p;
+
void _audit();
void _dump();
return total_free;
}
- const map_t& get_freelist() {
- return kv_free;
- }
+ void enumerate_reset();
+ bool enumerate_next(uint64_t *offset, uint64_t *length);
void allocate(
uint64_t offset, uint64_t length,