]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Revert "osd: simplify finalizing scrub on replica"
authorSamuel Just <samuel.just@dreamhost.com>
Fri, 18 Nov 2011 01:17:06 +0000 (17:17 -0800)
committerSamuel Just <samuel.just@dreamhost.com>
Fri, 18 Nov 2011 23:57:00 +0000 (15:57 -0800)
This reverts commit dd5087fabb2a743741a96ee4610379afa8431f68.

Calling osr.flush() is not quite enough since the onreadable callbacks
may not have been called (thus, last_update_applied may still lag behind
the tail of the log).

Signed-off-by: Samuel Just <samuel.just@dreamhost.com>
src/osd/PG.cc
src/osd/PG.h
src/osd/ReplicatedPG.cc

index 384a5eb852196f06b8ecb6805d27e8c1123d8c25..d8548e029f047ef1e992c8d98742c800dd8f33ad 100644 (file)
@@ -2840,11 +2840,15 @@ void PG::repair_object(const hobject_t& soid, ScrubMap::object *po, int bad_peer
  * If msg->scrub_from is not set, replica_scrub calls build_scrubmap to
  * build a complete map (with the pg lock dropped).
  *
- * If msg->scrub_from is set, we build an incremental scrub map with
- * the pg lock held.
+ * If msg->scrub_from is set, replica_scrub sets finalizing_scrub.
+ * Similarly to scrub, if last_update_applied is behind info.last_update
+ * replica_scrub returns to be requeued by sub_op_modify_applied.
+ * replica_scrub then builds an incremental scrub map with the 
+ * pg lock held.
  */
 void PG::replica_scrub(MOSDRepScrub *msg)
 {
+  assert(!active_rep_scrub);
   dout(7) << "replica_scrub" << dendl;
 
   if (msg->map_epoch < info.history.same_interval_since) {
@@ -2862,10 +2866,17 @@ void PG::replica_scrub(MOSDRepScrub *msg)
 
   ScrubMap map;
   if (msg->scrub_from > eversion_t()) {
-    // flush out in-flight writes to disk, so we can scrub the
-    // resulting on-disk state.
-    osr.flush();
+    if (finalizing_scrub) {
+      assert(last_update_applied == info.last_update);
+    } else {
+      finalizing_scrub = 1;
+      if (last_update_applied != info.last_update) {
+       active_rep_scrub = msg;
+       return;
+      }
+    }
     build_inc_scrub_map(map, msg->scrub_from);
+    finalizing_scrub = 0;
   } else {
     build_scrub_map(map);
   }
index 2084f89a24c76919d14add4c3703cfb5a05a8a7f..5b6353bb2fd2988cd68e20c315ed3517eab4803b 100644 (file)
@@ -1517,6 +1517,7 @@ public:
   int scrub_waiting_on;
   epoch_t scrub_epoch_start;
   ScrubMap primary_scrubmap;
+  MOSDRepScrub *active_rep_scrub;
 
   void repair_object(const hobject_t& soid, ScrubMap::object *po, int bad_peer, int ok_peer);
   bool _compare_scrub_objects(ScrubMap::object &auth,
@@ -1569,7 +1570,8 @@ public:
     finish_sync_event(NULL),
     finalizing_scrub(false),
     scrub_reserved(false), scrub_reserve_failed(false),
-    scrub_waiting_on(0)
+    scrub_waiting_on(0),
+    active_rep_scrub(0)
   {
     pool->get();
   }
index d277016692bde79240b1f54ef16b34eed16e9e3a..5a35686254116600f89e97724d03ffcc32ec9661 100644 (file)
@@ -3450,6 +3450,12 @@ void ReplicatedPG::sub_op_modify_applied(RepModify *rm)
   bool done = rm->applied && rm->committed;
 
   last_update_applied = rm->op->version;
+  if (last_update_applied == info.last_update && finalizing_scrub) {
+    assert(active_rep_scrub);
+    osd->rep_scrub_wq.queue(active_rep_scrub);
+    active_rep_scrub->put();
+    active_rep_scrub = 0;
+  }
 
   unlock();
   if (done) {