ostream& operator<<(ostream& out, const BlueStore::Buffer& b)
{
- return out << "buffer(space " << b.space << " 0x" << std::hex
- << b.offset << "~" << b.length << std::dec
- << " " << BlueStore::Buffer::get_state_name(b.state) << ")";
+ out << "buffer(space " << b.space << " 0x" << std::hex
+ << b.offset << "~" << b.length << std::dec
+ << " " << BlueStore::Buffer::get_state_name(b.state);
+ if (b.flags)
+ out << " " << BlueStore::Buffer::get_flag_name(b.flags);
+ return out << ")";
}
void BlueStore::BufferCache::trim(uint64_t keep)
}
}
+void BlueStore::BufferSpace::finish_write(uint64_t seq)
+{
+ auto i = writing.begin();
+ while (i != writing.end()) {
+ Buffer *b = &*i;
+ dout(20) << __func__ << " " << *b << dendl;
+ assert(b->is_writing());
+ if (b->seq <= seq) {
+ if (b->flags & Buffer::FLAG_NOCACHE) {
+ ++i;
+ _rm_buffer(b);
+ } else {
+ b->state = Buffer::STATE_CLEAN;
+ writing.erase(i++);
+ }
+ } else {
+ ++i;
+ }
+ }
+}
+
// Bnode
wctx.comp_blob_size = comp_min_blob_size;
// write in buffer cache
- o->bc.write(txc->seq, offset, bl);
+ o->bc.write(txc->seq, offset, bl, wctx.buffered ? 0 : Buffer::FLAG_NOCACHE);
bufferlist::iterator p = bl.begin();
if (offset / min_alloc_size == (end - 1) / min_alloc_size &&
default: return "???";
}
}
+ enum {
+ FLAG_NOCACHE = 1, ///< trim when done WRITING (do not become CLEAN)
+ // NOTE: fix operator<< when you define a second flag
+ };
+ static const char *get_flag_name(int s) {
+ switch (s) {
+ case FLAG_NOCACHE: return "nocache";
+ default: return "???";
+ }
+ }
BufferSpace *space;
- unsigned state; ///< STATE_*
+ uint32_t state; ///< STATE_*
+ uint32_t flags; ///< FLAG_*
uint64_t seq;
uint64_t offset, length;
bufferlist data;
boost::intrusive::list_member_hook<> lru_item;
boost::intrusive::list_member_hook<> state_item;
- Buffer(BufferSpace *space, unsigned s, uint64_t q, uint64_t o, uint64_t l)
- : space(space), state(s), seq(q), offset(o), length(l) {}
- Buffer(BufferSpace *space, unsigned s, uint64_t q, uint64_t o, bufferlist& b)
- : space(space), state(s), seq(q), offset(o), length(b.length()), data(b) {}
+ Buffer(BufferSpace *space, unsigned s, uint64_t q, uint64_t o, uint64_t l,
+ unsigned f = 0)
+ : space(space), state(s), flags(f), seq(q), offset(o), length(l) {}
+ Buffer(BufferSpace *space, unsigned s, uint64_t q, uint64_t o, bufferlist& b,
+ unsigned f = 0)
+ : space(space), state(s), flags(f), seq(q), offset(o),
+ length(b.length()), data(b) {}
bool is_clean() const {
return state == STATE_CLEAN;
writing.push_back(*b);
}
}
+ void _rm_buffer(Buffer *b) {
+ _rm_buffer(buffer_map.find(b->offset));
+ }
void _rm_buffer(map<uint64_t,std::unique_ptr<Buffer>>::iterator p) {
cache->size -= p->second->length;
cache->lru.erase(cache->lru.iterator_to(*p->second));
void discard(uint64_t offset, uint64_t length);
- void write(uint64_t seq, uint64_t offset, bufferlist& bl) {
+ void write(uint64_t seq, uint64_t offset, bufferlist& bl, unsigned flags) {
discard(offset, bl.length());
- _add_buffer(new Buffer(this, Buffer::STATE_WRITING, seq, offset, bl));
- }
- void finish_write(uint64_t seq) {
- auto i = writing.begin();
- while (i != writing.end()) {
- assert(i->is_writing());
- if (i->seq <= seq) {
- i->state = Buffer::STATE_CLEAN;
- writing.erase(i++);
- } else {
- ++i;
- }
- }
+ _add_buffer(new Buffer(this, Buffer::STATE_WRITING, seq, offset, bl,
+ flags));
}
+ void finish_write(uint64_t seq);
void did_read(uint64_t offset, bufferlist& bl) {
discard(offset, bl.length());
_add_buffer(new Buffer(this, Buffer::STATE_CLEAN, 0, offset, bl));