From 389d3eb33d96e486bcaf7b9385ae45f19499e0dc Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Wed, 12 Oct 2016 19:13:00 +0300 Subject: [PATCH] os/bluestore: isolate GC stuff to be able to cover it with UT Signed-off-by: Igor Fedotov --- src/os/bluestore/BlueStore.cc | 166 +++++++++++++++++----------------- src/os/bluestore/BlueStore.h | 17 ++-- 2 files changed, 92 insertions(+), 91 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index e75ab1f4145de..f1f02419e2354 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -2149,6 +2149,83 @@ BlueStore::BlobRef BlueStore::ExtentMap::split_blob( return rb; } +bool BlueStore::ExtentMap::do_write_check_depth( + uint64_t onode_size, + uint64_t start_offset, + uint64_t end_offset, + uint8_t *blob_depth, + uint64_t *gc_start_offset, + uint64_t *gc_end_offset) +{ + uint8_t depth = 0; + bool head_overlap = false; + bool tail_overlap = false; + + *gc_start_offset = start_offset; + *gc_end_offset = end_offset; + *blob_depth = 1; + + auto hp = seek_lextent(start_offset); + if (hp != extent_map.end() && + hp->logical_offset < start_offset && + start_offset < hp->logical_offset + hp->length) { + depth = hp->blob_depth; + head_overlap = true; + } + + auto tp = seek_lextent(end_offset); + if (tp != extent_map.end() && + tp->logical_offset < end_offset && + end_offset < tp->logical_offset + tp->length) { + tail_overlap = true; + if (depth < tp->blob_depth) { + depth = tp->blob_depth; + } + } + + if (depth >= g_conf->bluestore_gc_max_blob_depth) { + if (head_overlap) { + auto hp_next = hp; + while (hp != extent_map.begin() && hp->blob_depth > 1) { + hp_next = hp; + --hp; + if (hp->logical_offset + hp->length != hp_next->logical_offset) { + hp = hp_next; + break; + } + } + *gc_start_offset = hp->logical_offset; + } + if (tail_overlap) { + auto tp_prev = tp; + + while (tp->blob_depth > 1) { + tp_prev = tp; + tp++; + if (tp == extent_map.end() || + (tp_prev->logical_offset + tp_prev->length) != tp->logical_offset) { + tp = tp_prev; + break; + } + } + *gc_end_offset = tp->logical_offset + tp_prev->length; + } + } + if (*gc_end_offset > onode_size) { + *gc_end_offset = MAX(end_offset, onode_size); + } + + bool do_collect = true; + if (depth < g_conf->bluestore_gc_max_blob_depth) { + *blob_depth = 1 + depth; + do_collect = false;; + } + dout(20) << __func__ << " GC depth " << (int)*blob_depth + << ", gc 0x" << std::hex << *gc_start_offset << "~" + << (*gc_end_offset - *gc_start_offset) + << std::dec << dendl; + return do_collect; +} // Onode @@ -2164,8 +2241,6 @@ void BlueStore::Onode::flush() dout(20) << __func__ << " done" << dendl; } - - // ======================================================= // Collection @@ -2310,8 +2385,6 @@ void BlueStore::Collection::trim_cache() g_conf->bluestore_buffer_cache_size / store->cache_shards.size()); } - - // ======================================================= #undef dout_prefix @@ -7632,83 +7705,6 @@ void BlueStore::_wctx_finish( } } -bool BlueStore::_do_write_check_depth( - OnodeRef o, - uint64_t start_offset, - uint64_t end_offset, - uint8_t *blob_depth, - uint64_t *gc_start_offset, - uint64_t *gc_end_offset) -{ - uint8_t depth = 0; - bool head_overlap = false; - bool tail_overlap = false; - - *gc_start_offset = start_offset; - *gc_end_offset = end_offset; - *blob_depth = 1; - - auto hp = o->extent_map.seek_lextent(start_offset); - if (hp != o->extent_map.extent_map.end() && - hp->logical_offset < start_offset && - start_offset < hp->logical_offset + hp->length) { - depth = hp->blob_depth; - head_overlap = true; - } - - auto tp = o->extent_map.seek_lextent(end_offset); - if (tp != o->extent_map.extent_map.end() && - tp->logical_offset < end_offset && - end_offset < tp->logical_offset + tp->length) { - tail_overlap = true; - if (depth < tp->blob_depth) { - depth = tp->blob_depth; - } - } - - if (depth >= g_conf->bluestore_gc_max_blob_depth) { - if (head_overlap) { - auto hp_next = hp; - while (hp != o->extent_map.extent_map.begin() && hp->blob_depth > 1) { - hp_next = hp; - --hp; - if (hp->logical_offset + hp->length != hp_next->logical_offset) { - hp = hp_next; - break; - } - } - *gc_start_offset = hp->logical_offset; - } - if (tail_overlap) { - auto tp_prev = tp; - - while (tp->blob_depth > 1) { - tp_prev = tp; - tp++; - if (tp == o->extent_map.extent_map.end() || - (tp_prev->logical_offset + tp_prev->length) != tp->logical_offset) { - tp = tp_prev; - break; - } - } - *gc_end_offset = tp->logical_offset + tp_prev->length; - } - } - if (*gc_end_offset > o->onode.size) { - *gc_end_offset = MAX(end_offset, o->onode.size); - } - dout(20) << __func__ << " depth " << (int)depth - << ", gc 0x" << std::hex << *gc_start_offset << "~" - << (*gc_end_offset - *gc_start_offset) - << std::dec << dendl; - if (depth >= g_conf->bluestore_gc_max_blob_depth) { - return true; - } else { - *blob_depth = 1 + depth; - return false; - } -} - void BlueStore::_do_write_data( TransContext *txc, CollectionRef& c, @@ -7836,8 +7832,12 @@ int BlueStore::_do_write( << std::dec << dendl; uint64_t gc_start_offset = offset, gc_end_offset = end; - if (_do_write_check_depth(o, offset, end, &wctx.blob_depth, - &gc_start_offset, &gc_end_offset)) { + bool do_collect = + o->extent_map.do_write_check_depth(o->extent_map, o->onode.size, + offset, end, &wctx.blob_depth, + &gc_start_offset, + &gc_end_offset); + if (do_collect) { // we need garbage collection of blobs. if (offset > gc_start_offset) { bufferlist head_bl; diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 689b37939a386..50dd2343fa578 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -690,6 +690,14 @@ public: /// split a blob (and referring extents) BlobRef split_blob(BlobRef lb, uint32_t blob_offset, uint32_t pos); + + bool do_write_check_depth( + uint64_t onode_size, + uint64_t start_offset, + uint64_t end_offset, + uint8_t *blob_depth, + uint64_t *gc_start_offset, + uint64_t *gc_end_offset); }; struct OnodeSpace; @@ -735,6 +743,7 @@ public: }; typedef boost::intrusive_ptr OnodeRef; + /// a cache (shard) of onodes and buffers struct Cache { PerfCounters *logger; @@ -1873,14 +1882,6 @@ private: void _pad_zeros(bufferlist *bl, uint64_t *offset, uint64_t chunk_size); - bool _do_write_check_depth( - OnodeRef o, - uint64_t start_offset, - uint64_t end_offset, - uint8_t *blob_depth, - uint64_t *gc_start_offset, - uint64_t *gc_end_offset); - int _do_write(TransContext *txc, CollectionRef &c, OnodeRef o, -- 2.39.5