From cb7f0f75d3dc1456b5be1908244f5c33801c5f40 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 31 May 2016 14:18:31 -0400 Subject: [PATCH] os/bluestore: add FLAG_NOCACHE flag; do not cache unbuffered writes Add a Buffer flag to mark that a buffer should not be cached once it is stable. Signed-off-by: Sage Weil --- src/os/bluestore/BlueStore.cc | 32 +++++++++++++++++++++---- src/os/bluestore/BlueStore.h | 45 ++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 96867224cbc..7e9ef9a3dc1 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -443,9 +443,12 @@ static void get_wal_key(uint64_t seq, string *out) 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) @@ -577,6 +580,27 @@ void BlueStore::BufferSpace::read( } } +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 @@ -5849,7 +5873,7 @@ int BlueStore::_do_write( 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 && diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 4dd0adc6a2f..ec959794748 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -117,9 +117,20 @@ public: 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; @@ -127,10 +138,13 @@ public: 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; @@ -203,6 +217,9 @@ public: writing.push_back(*b); } } + void _rm_buffer(Buffer *b) { + _rm_buffer(buffer_map.find(b->offset)); + } void _rm_buffer(map>::iterator p) { cache->size -= p->second->length; cache->lru.erase(cache->lru.iterator_to(*p->second)); @@ -236,22 +253,12 @@ public: 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)); -- 2.39.5