]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PG: introduce all_missing_unfound helper
authorxie xingguo <xie.xingguo@zte.com.cn>
Tue, 26 Mar 2019 12:04:15 +0000 (20:04 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Wed, 27 Mar 2019 01:57:48 +0000 (09:57 +0800)
We use pg_log.missing to track each peer's missing objects separately,
whereas missing_loc records the location of all (probably existing) good copies
for both primary and replicas' missing objects. Hence an item from
pg_log.missing or missing_loc is of different meaning and is not comparable.

During recovery, we can skip recovering primary only if
- primary is good, e.g., has no missing at all
- or all of the primary's missing objects do exist in missing_loc and are
  currently unfound

Obviously, the current "all missing objects are unfound" checker is broken.
Fix by introducing an independent all_missing_unfound helper to make the
count of missing objects that are currently unfound correct.

Fixes: http://tracker.ceph.com/issues/38784
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/osd/PG.h
src/osd/PrimaryLogPG.cc

index 38c5dab2f392607beb3f3e8bbab5c0e9abbe1561..913822b84f3737147d7611839140043226c8bcd2 100644 (file)
@@ -1609,6 +1609,16 @@ protected:
   uint64_t get_num_unfound() const {
     return missing_loc.num_unfound();
   }
+  bool all_missing_unfound() const {
+    const auto& missing = pg_log.get_missing();
+    if (!missing.have_missing())
+      return false;
+    for (auto& m : missing.get_items()) {
+      if (!missing_loc.is_unfound(m.first))
+        return false;
+    }
+    return true;
+  }
 
   virtual void check_local() = 0;
 
index 51713b294145cd0891a813fdac86186eeae748a5..ae2f6d0c91faa99a585c5641cdd5797dd3f9b9bf 100644 (file)
@@ -12443,15 +12443,14 @@ bool PrimaryLogPG::start_recovery_ops(
 
   const auto &missing = pg_log.get_missing();
 
-  unsigned int num_missing = missing.num_missing();
   uint64_t num_unfound = get_num_unfound();
 
-  if (num_missing == 0) {
+  if (!missing.have_missing()) {
     info.last_complete = info.last_update;
   }
 
-  if (num_missing == num_unfound) {
-    // All of the missing objects we have are unfound.
+  if (!missing.have_missing() || // Primary does not have missing
+      all_missing_unfound()) { // or all of the missing objects are unfound.
     // Recover the replicas.
     started = recover_replicas(max, handle, &recovery_started);
   }