]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: scrub: record whole-object digest on scrub
authorSage Weil <sage@redhat.com>
Wed, 10 Dec 2014 17:25:54 +0000 (09:25 -0800)
committerSage Weil <sage@redhat.com>
Sat, 20 Dec 2014 15:30:03 +0000 (07:30 -0800)
If we do not have a whole-object digest, record one after a deep scrub.

Note that we make no particular attempt to avoid this on frequently
changing objects where the digest will quickly be invalidated.

Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PG.cc
src/osd/PG.h
src/osd/PGBackend.cc
src/osd/PGBackend.h
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h

index 1066b96f04cfc7609a182e9e4b4fb2647343d20c..fd68039ad37c35a201eee9cf8dad8c85fb324b92 100644 (file)
@@ -4089,6 +4089,7 @@ void PG::scrub_compare_maps()
       scrubber.missing,
       scrubber.inconsistent,
       authoritative,
+      scrubber.missing_digest,
       scrubber.shallow_errors,
       scrubber.deep_errors,
       info.pgid, acting,
index 9dfa2b9b018f01000774f544bee650ed00ca19d2..b76178d65bcb3bfe9538b918f469247c20e9a3ca 100644 (file)
@@ -1064,6 +1064,9 @@ public:
     // Map from object with errors to good peer
     map<hobject_t, pair<ScrubMap::object, pg_shard_t> > authoritative;
 
+    // Objects who need digest updates
+    map<hobject_t, pair<uint32_t,uint32_t> > missing_digest;
+
     // chunky scrub
     hobject_t start, end;
     eversion_t subset_last_update;
@@ -1158,6 +1161,7 @@ public:
       inconsistent.clear();
       missing.clear();
       authoritative.clear();
+      missing_digest.clear();
     }
 
   } scrubber;
index 2f2f96965fb1923118c2d1c766dbcd6ad9e1ad6b..1576678a9ca89d69730cd3d2dcf54ab9798bdd73 100644 (file)
@@ -537,6 +537,7 @@ void PGBackend::be_compare_scrubmaps(
   map<hobject_t, set<pg_shard_t> > &missing,
   map<hobject_t, set<pg_shard_t> > &inconsistent,
   map<hobject_t, pg_shard_t> &authoritative,
+  map<hobject_t, pair<uint32_t,uint32_t> > &missing_digest,
   int &shallow_errors, int &deep_errors,
   const spg_t& pgid,
   const vector<int> &acting,
@@ -573,6 +574,7 @@ void PGBackend::be_compare_scrubmaps(
     }
 
     assert(auth != maps.end());
+    ScrubMap::object& auth_object = auth->second->objects[*k];
     set<pg_shard_t> cur_missing;
     set<pg_shard_t> cur_inconsistent;
     for (j = maps.begin(); j != maps.end(); ++j) {
@@ -583,7 +585,7 @@ void PGBackend::be_compare_scrubmaps(
        stringstream ss;
        enum scrub_error_type error =
          be_compare_scrub_objects(auth->first,
-                                  auth->second->objects[*k],
+                                  auth_object,
                                   auth_oi,
                                   okseed,
                                   j->second->objects[*k],
@@ -614,5 +616,13 @@ void PGBackend::be_compare_scrubmaps(
     if (!cur_inconsistent.empty() || !cur_missing.empty()) {
       authoritative[*k] = auth->first;
     }
+    if (okseed &&
+       auth_object.digest_present && auth_object.omap_digest_present &&
+       (!auth_oi.is_data_digest() || !auth_oi.is_omap_digest())) {
+      dout(20) << __func__ << " noting missing digest on " << *k << dendl;
+      missing_digest[*k] = make_pair(auth_object.digest,
+                                    auth_object.omap_digest);
+    }
+
   }
 }
index 32d2a39ed9957d73d355c2a158b22641fbafec0e..614cb9f0232ccf5b72313fc459d37655b6befbb2 100644 (file)
      map<hobject_t, set<pg_shard_t> > &missing,
      map<hobject_t, set<pg_shard_t> > &inconsistent,
      map<hobject_t, pg_shard_t> &authoritative,
+     map<hobject_t, pair<uint32_t,uint32_t> > &missing_digest,
      int &shallow_errors, int &deep_errors,
      const spg_t& pgid,
      const vector<int> &acting,
index 970dac096311bd269aeebb40e53064cf6fd7d4ac..b059ce1dcfa8c8aff03cba91e5cf226bfc353040 100644 (file)
@@ -5563,7 +5563,8 @@ int ReplicatedPG::prepare_transaction(OpContext *ctx)
   return result;
 }
 
-void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc)
+void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc,
+                             bool scrub_ok)
 {
   const hobject_t& soid = ctx->obs->oi.soid;
   dout(20) << __func__ << " " << soid << " " << ctx
@@ -5751,7 +5752,7 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc
       pending_backfill_updates[soid].stats.add(ctx->delta_stats);
   }
 
-  if (scrubber.active) {
+  if (!scrub_ok && scrubber.active) {
     assert(soid < scrubber.start || soid >= scrubber.end);
     if (soid < scrubber.start)
       scrub_cstat.add(ctx->delta_stats);
@@ -12402,6 +12403,24 @@ void ReplicatedPG::_scrub(ScrubMap& scrubmap)
                      << " expected clone " << next_clone;
     ++scrubber.shallow_errors;
   }
+
+  if (scrubber.shallow_errors == 0) {
+    for (map<hobject_t,pair<uint32_t,uint32_t> >::iterator p =
+          scrubber.missing_digest.begin();
+        p != scrubber.missing_digest.end();
+        ++p) {
+      dout(10) << __func__ << " recording digests for " << p->first << dendl;
+      ObjectContextRef obc = get_object_context(p->first, false);
+      assert(obc);
+      RepGather *repop = simple_repop_create(obc);
+      OpContext *ctx = repop->ctx;
+      ctx->at_version = get_next_version();
+      ctx->new_obs.oi.set_data_digest(p->second.first);
+      ctx->new_obs.oi.set_omap_digest(p->second.second);
+      finish_ctx(ctx, pg_log_entry_t::MODIFY, true, true);
+      simple_repop_submit(repop);
+    }
+  }
   
   dout(10) << "_scrub (" << mode << ") finish" << dendl;
 }
index b1e27a72a4e81421fb68b984902929c301950527..9fb64d9594f8d5f5ef5c97d501864646df421a5d 100644 (file)
@@ -1052,7 +1052,8 @@ protected:
     const hobject_t& head, const hobject_t& coid,
     object_info_t *poi);
   void execute_ctx(OpContext *ctx);
-  void finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc=true);
+  void finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc=true,
+                 bool scrub_ok=false);
   void reply_ctx(OpContext *ctx, int err);
   void reply_ctx(OpContext *ctx, int err, eversion_t v, version_t uv);
   void make_writeable(OpContext *ctx);