From: Igor Fedotov Date: Mon, 23 Oct 2017 16:32:23 +0000 (-0700) Subject: os/bluestore: fix lack of extent demotion in StupidAllocator::init_rm_free X-Git-Tag: v12.2.5~17^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ca478a5371ecf8bbd7abcb7b3ab5fe2c4c90c156;p=ceph.git os/bluestore: fix lack of extent demotion in StupidAllocator::init_rm_free Signed-off-by: Igor Fedotov (cherry picked from commit 89aeea84f9ad24b2f9ca5ea3ee1dd9146e7eb664) --- diff --git a/src/include/interval_set.h b/src/include/interval_set.h index e7e0d3929404..09475e52f150 100644 --- a/src/include/interval_set.h +++ b/src/include/interval_set.h @@ -517,7 +517,8 @@ class interval_set { erase(val, 1); } - void erase(T start, T len) { + void erase(T start, T len, + std::function post_process = {}) { typename Map::iterator p = find_inc_m(start); _size -= len; @@ -529,16 +530,16 @@ class interval_set { T before = start - p->first; assert(p->second >= before+len); T after = p->second - before - len; - - if (before) + if (before && (post_process ? post_process(p->first, before) : true)) { p->second = before; // shorten bit before - else + } else { m.erase(p); - if (after) - m[start+len] = after; + } + if (after && (post_process ? post_process(start + len, after) : true)) { + m[start + len] = after; + } } - void subtract(const interval_set &a) { for (typename Map::const_iterator p = a.m.begin(); p != a.m.end(); diff --git a/src/os/bluestore/StupidAllocator.cc b/src/os/bluestore/StupidAllocator.cc index 0fc8a0e1479e..7e3402a720b6 100644 --- a/src/os/bluestore/StupidAllocator.cc +++ b/src/os/bluestore/StupidAllocator.cc @@ -293,7 +293,26 @@ void StupidAllocator::init_rm_free(uint64_t offset, uint64_t length) if (!overlap.empty()) { dout(20) << __func__ << " bin " << i << " rm 0x" << std::hex << overlap << std::dec << dendl; - free[i].subtract(overlap); + auto it = overlap.begin(); + auto it_end = overlap.end(); + while (it != it_end) { + auto o = it.get_start(); + auto l = it.get_len(); + + free[i].erase(o, l, + [&](uint64_t off, uint64_t len) { + unsigned newbin = _choose_bin(len); + if (newbin != i) { + ldout(cct, 30) << __func__ << " demoting1 0x" << std::hex << off << "~" << len + << std::dec << " to bin " << newbin << dendl; + _insert_free(off, len); + return false; + } + return true; + }); + ++it; + } + rm.subtract(overlap); } }