void BlueStore::BufferSpace::finish_write(uint64_t seq)
{
std::lock_guard<std::mutex> l(cache->lock);
- auto i = writing.begin();
- while (i != writing.end()) {
- Buffer *b = &*i;
- dout(20) << __func__ << " " << *b << dendl;
- assert(b->is_writing());
- if (b->seq <= seq) {
+
+ auto i = writing_map.begin();
+ while (i != writing_map.end()) {
+ if (i->first > seq)
+ break;
+
+ auto l = i->second.begin();
+ while (l != i->second.end()) {
+ Buffer *b = &*l;
+ dout(20) << __func__ << " " << *b << dendl;
+ assert(b->is_writing());
+
if (b->flags & Buffer::FLAG_NOCACHE) {
- ++i;
- _rm_buffer(b);
+ i->second.erase(l++);
+ buffer_map.erase(b->offset);
} else {
- b->state = Buffer::STATE_CLEAN;
- writing.erase(i++);
- cache->_add_buffer(b, 1, nullptr);
+ b->state = Buffer::STATE_CLEAN;
+ i->second.erase(l++);
+ cache->_add_buffer(b, 1, nullptr);
}
- } else {
- ++i;
}
+
+ assert(i->second.empty());
+ writing_map.erase(i++);
}
+
cache->_audit("finish_write end");
}
map<uint64_t,std::unique_ptr<Buffer>> buffer_map;
Cache *cache;
- state_list_t writing;
+ map<uint64_t, state_list_t> writing_map;
BufferSpace(Cache *c) : cache(c) {}
~BufferSpace() {
assert(buffer_map.empty());
- assert(writing.empty());
+ assert(writing_map.empty());
}
void _add_buffer(Buffer *b, int level, Buffer *near) {
cache->_audit("_add_buffer start");
buffer_map[b->offset].reset(b);
if (b->is_writing()) {
- writing.push_back(*b);
+ writing_map[b->seq].push_back(*b);
} else {
cache->_add_buffer(b, level, near);
}
void _rm_buffer(map<uint64_t,std::unique_ptr<Buffer>>::iterator p) {
cache->_audit("_rm_buffer start");
if (p->second->is_writing()) {
- writing.erase(writing.iterator_to(*p->second));
+ uint64_t seq = (*p->second.get()).seq;
+ auto it = writing_map.find(seq);
+ assert(it != writing_map.end());
+ it->second.erase(it->second.iterator_to(*p->second));
+ if (it->second.empty())
+ writing_map.erase(it);
} else {
cache->_rm_buffer(p->second.get());
}