]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: split backoffs on PG split
authorSage Weil <sage@redhat.com>
Wed, 1 Feb 2017 22:27:32 +0000 (17:27 -0500)
committerSage Weil <sage@redhat.com>
Fri, 10 Feb 2017 22:59:50 +0000 (17:59 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PG.cc
src/osd/PG.h

index aaccffb521cb4be3947b07e028fe7ad3d13ff92c..d8c7ab93582d219c46e0329d1f8eb3da28573d90 100644 (file)
@@ -2308,6 +2308,12 @@ void PG::split_into(pg_t child_pgid, PG *child, unsigned split_bits)
   split_ops(child, split_bits);
   _split_into(child_pgid, child, split_bits);
 
+  // release all backoffs so that Objecter doesn't need to handle unblock
+  // on split backoffs
+  release_backoffs(hobject_t(), hobject_t::get_max());
+  // split any remaining (deleting) backoffs among child PGs
+  split_backoffs(child, split_bits);
+
   child->on_new_interval();
 
   child->dirty_info = true;
@@ -2411,6 +2417,71 @@ void PG::release_backoffs(const hobject_t& begin, const hobject_t& end)
   }
 }
 
+void PG::split_backoffs(PG *child, unsigned split_bits)
+{
+  dout(10) << __func__ << " split_bits " << split_bits << " child "
+          << child->info.pgid.pgid << dendl;
+  unsigned mask = ~((~0)<<split_bits);
+  vector<BackoffRef> backoffs_to_dup;   // pg backoffs
+  vector<BackoffRef> backoffs_to_move;  // oid backoffs
+  {
+    Mutex::Locker l(backoff_lock);
+    auto p = backoffs.begin();
+    while (p != backoffs.end()) {
+      if (p->first == info.pgid.pgid.get_hobj_start()) {
+       // if it is a full PG we always dup it for the child.
+       for (auto& q : p->second) {
+         dout(10) << __func__ << " pg backoff " << p->first
+                  << " " << q << dendl;
+         backoffs_to_dup.push_back(q);
+       }
+      } else {
+       // otherwise, we move it to the child only if falls into the
+       // childs hash range.
+       if ((p->first.get_hash() & mask) == child->info.pgid.pgid.ps()) {
+         for (auto& q : p->second) {
+           dout(20) << __func__ << " will move " << p->first
+                    << " " << q << dendl;
+           backoffs_to_move.push_back(q);
+         }
+         p = backoffs.erase(p);
+         continue;
+       } else {
+         dout(20) << __func__ << " will not move " << p->first
+                  << " " << p->second << dendl;
+       }
+      }
+      ++p;
+    }
+  }
+  for (auto b : backoffs_to_dup) {
+    SessionRef s;
+    {
+      Mutex::Locker l(b->lock);
+      b->end = info.pgid.pgid.get_hobj_end(split_bits);
+      dout(10) << __func__ << " pg backoff " << *b << dendl;
+      s = b->session;
+    }
+    if (s) {
+      child->add_pg_backoff(b->session);
+    } else {
+      dout(20) << __func__ << "  didn't dup pg backoff, session is null"
+              << dendl;
+    }
+  }
+  for (auto b : backoffs_to_move) {
+    Mutex::Locker l(b->lock);
+    if (b->pg == this) {
+      dout(10) << __func__ << " move backoff " << *b << " to child" << dendl;
+      b->pg = child;
+      child->backoffs[b->begin].insert(b);
+    } else {
+      dout(20) << __func__ << " move backoff " << *b << " nowhere... pg is null"
+              << dendl;
+    }
+  }
+}
+
 void PG::clear_backoffs()
 {
   dout(10) << __func__ << " " << dendl;
index 216195ff8af4be1026435ad09a3f3e4a7c81e02a..07a674df79b4e388346144163597897634fec5a6 100644 (file)
@@ -1094,6 +1094,7 @@ public:
     release_backoffs(o, o);
   }
   void clear_backoffs();
+  void split_backoffs(PG *child, unsigned split_bits);
 
   void add_pg_backoff(SessionRef s) {
     hobject_t begin = info.pgid.pgid.get_hobj_start();