]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
PG: merge_log always use stats from authoritative replica
authorSamuel Just <sam.just@inktank.com>
Fri, 13 Jul 2012 00:19:43 +0000 (17:19 -0700)
committerSamuel Just <sam.just@inktank.com>
Fri, 13 Jul 2012 17:19:24 +0000 (10:19 -0700)
If the osd recieving the log has divergent entries, it will
also have a "divergent" stat structure.  In general, it suffices
to simply trust the stat structure shipped with the authoritative
log and info since merge_log is only used to merge an authoritative
log.

Probably fixes #2769.

In cases like #2769, this bug can result in a primary with a stat
structure which double counts an operation: once for the
divergent operation, and once for the replay.  It turned up
in a regression suite run as a scrub stat mismatch.

Signed-off-by: Samuel Just <sam.just@inktank.com>
src/osd/PG.cc
src/osd/PG.h

index 14c5d581a3980f6067833f9710c35e06eaa8a783..f026c2c719cc5511f2ef465adeb31298a01518cb 100644 (file)
@@ -483,6 +483,11 @@ void PG::merge_log(ObjectStore::Transaction& t,
     changed = true;
   }
 
+  if (oinfo.stats.reported < info.stats.reported)   // make sure reported always increases
+    oinfo.stats.reported = info.stats.reported;
+  if (info.last_backfill.is_max())
+    info.stats = oinfo.stats;
+
   // do we have divergent entries to throw out?
   if (olog.head < log.head) {
     rewind_divergent_log(t, olog.head);
@@ -548,10 +553,6 @@ void PG::merge_log(ObjectStore::Transaction& t,
     log.index();   
 
     info.last_update = log.head = olog.head;
-    if (oinfo.stats.reported < info.stats.reported)   // make sure reported always increases
-      oinfo.stats.reported = info.stats.reported;
-    if (info.last_backfill.is_max())
-      info.stats = oinfo.stats;
 
     // process divergent items
     if (!divergent.empty()) {
index f5a1070beed6bdeb3698f4c91548a081918459e8..d3eda0b927dbedf8b17a7c064f7958ed02579331 100644 (file)
@@ -697,6 +697,15 @@ public:
                       pg_missing_t& omissing, int from);
   bool proc_replica_info(int from, const pg_info_t &info);
   bool merge_old_entry(ObjectStore::Transaction& t, pg_log_entry_t& oe);
+
+  /**
+   * Merges authoratative log/info into current log/info/store
+   *
+   * @param [in,out] t used to delete obsolete objects
+   * @param [in,out] oinfo recieved authoritative info
+   * @param [in,out] olog recieved authoritative log
+   * @param [in] from peer which sent the information
+   */
   void merge_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog, int from);
   void rewind_divergent_log(ObjectStore::Transaction& t, eversion_t newhead);
   bool search_for_missing(const pg_info_t &oinfo, const pg_missing_t *omissing,