From 28d4dd89c432a7d0f8854d8470b2f1215410fe77 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 10 Dec 2014 09:25:54 -0800 Subject: [PATCH] osd: scrub: record whole-object digest on scrub 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 --- src/osd/PG.cc | 1 + src/osd/PG.h | 4 ++++ src/osd/PGBackend.cc | 12 +++++++++++- src/osd/PGBackend.h | 1 + src/osd/ReplicatedPG.cc | 23 +++++++++++++++++++++-- src/osd/ReplicatedPG.h | 3 ++- 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 1066b96f04cfc..fd68039ad37c3 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -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, diff --git a/src/osd/PG.h b/src/osd/PG.h index 9dfa2b9b018f0..b76178d65bcb3 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -1064,6 +1064,9 @@ public: // Map from object with errors to good peer map > authoritative; + // Objects who need digest updates + map > 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; diff --git a/src/osd/PGBackend.cc b/src/osd/PGBackend.cc index 2f2f96965fb19..1576678a9ca89 100644 --- a/src/osd/PGBackend.cc +++ b/src/osd/PGBackend.cc @@ -537,6 +537,7 @@ void PGBackend::be_compare_scrubmaps( map > &missing, map > &inconsistent, map &authoritative, + map > &missing_digest, int &shallow_errors, int &deep_errors, const spg_t& pgid, const vector &acting, @@ -573,6 +574,7 @@ void PGBackend::be_compare_scrubmaps( } assert(auth != maps.end()); + ScrubMap::object& auth_object = auth->second->objects[*k]; set cur_missing; set 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); + } + } } diff --git a/src/osd/PGBackend.h b/src/osd/PGBackend.h index 32d2a39ed9957..614cb9f0232cc 100644 --- a/src/osd/PGBackend.h +++ b/src/osd/PGBackend.h @@ -605,6 +605,7 @@ map > &missing, map > &inconsistent, map &authoritative, + map > &missing_digest, int &shallow_errors, int &deep_errors, const spg_t& pgid, const vector &acting, diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 970dac096311b..b059ce1dcfa8c 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -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 >::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; } diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index b1e27a72a4e81..9fb64d9594f8d 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -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); -- 2.39.5