]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PG: skip rollforward when !transaction_applied during append_log()
authorNeha Ojha <nojha@redhat.com>
Mon, 4 Mar 2019 04:29:05 +0000 (20:29 -0800)
committerNathan Cutler <ncutler@suse.com>
Fri, 3 May 2019 09:27:13 +0000 (11:27 +0200)
Earlier, we did pg_log.roll_forward(&handler), when
!transaction_applied, which advanced the crt and trimmed the entries
in rollforward(). Due to this, during _merge_object_divergent_entries(),
when we tried to rollback entries, those objects were not found in the
backend, and thus we hit this bug http://tracker.ceph.com/issues/36739.

With this change, we are advancing the crt value, without deleting the
objects, so that _merge_object_divergent_entries() does not fail
because of deleted objects.

Fixes: http://tracker.ceph.com/issues/36739
Signed-off-by: Neha Ojha <nojha@redhat.com>
(cherry picked from commit 17419ee39342257f5a6f41c792e8e45a8e243720)

src/osd/PG.cc
src/osd/PGLog.h

index 4613e8f89f348a6f2de5b49f8066bffabc1ea903..f874c0ba2db4df8a381726ff57b2ad990ca8716b 100644 (file)
@@ -3628,8 +3628,13 @@ void PG::append_log(
      /* We must be a backfill peer, so it's ok if we apply
       * out-of-turn since we won't be considered when
       * determining a min possible last_update.
+      *
+      * We skip_rollforward() here, which advances the crt, without
+      * doing an actual rollforward. This avoids cleaning up entries
+      * from the backend and we do not end up in a situation, where the
+      * object is deleted before we can _merge_object_divergent_entries().
       */
-    pg_log.roll_forward(&handler);
+    pg_log.skip_rollforward();
   }
 
   for (vector<pg_log_entry_t>::const_iterator p = logv.begin();
index 6cf3cd99d0c1e3c007bdd1ebfcb1e077a9a04d25..756cc6b141eee3fdd61868612d681585fbb7d225 100644 (file)
@@ -726,6 +726,10 @@ public:
       h);
   }
 
+  void skip_rollforward() {
+    log.skip_can_rollback_to_to_head();
+  }
+
   //////////////////// get or set log & missing ////////////////////
 
   void reset_backfill_claim_log(const pg_log_t &o, LogEntryHandler *h) {