]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix lack of extent demotion in StupidAllocator::init_rm_free
authorIgor Fedotov <ifed@mail.ru>
Mon, 23 Oct 2017 16:32:23 +0000 (09:32 -0700)
committerIgor Fedotov <ifedotov@suse.com>
Thu, 12 Apr 2018 18:34:28 +0000 (21:34 +0300)
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
(cherry picked from commit 89aeea84f9ad24b2f9ca5ea3ee1dd9146e7eb664)

src/include/interval_set.h
src/os/bluestore/StupidAllocator.cc

index e7e0d3929404cff053b04b5eb2ac403a61e1e696..09475e52f15014f91d04bd8d5ff8ab424bf6af38 100644 (file)
@@ -517,7 +517,8 @@ class interval_set {
     erase(val, 1);
   }
 
-  void erase(T start, T len) {
+  void erase(T start, T len,
+    std::function<bool(T, T)> 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();
index 0fc8a0e1479edaae0e1c7707f5e90d9d007ba128..7e3402a720b6daf09c762a17dd91f125cfbe783f 100644 (file)
@@ -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);
     }
   }