]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PGLog: reset complete_to when appending lost_delete entries
authorJosh Durgin <jdurgin@redhat.com>
Tue, 27 Jun 2017 01:45:15 +0000 (21:45 -0400)
committerJosh Durgin <jdurgin@redhat.com>
Wed, 19 Jul 2017 06:47:44 +0000 (02:47 -0400)
Since lost_deletes queue recovery directly, and don't go through
activate_not_complete(), our complete_to iterator may still point at
log.end() (a list iterator pointing to .end() will still point to
.end() after a push_back().). Reset it to point before these new
lost_delete entries. This is needed now that lost_deletes are
performed during recovery, instead of inline when merging logs.

Signed-off-by: Josh Durgin <jdurgin@redhat.com>
src/osd/PGLog.h

index 42e06cf455aa6cabf3a6ace3329fc863d316b98d..0d484e335e601ca31798e5c066b6cfccb3112354 100644 (file)
@@ -675,21 +675,27 @@ public:
     assert(log.get_can_rollback_to() >= v);
   }
 
-  void activate_not_complete(pg_info_t &info) {
+  void reset_complete_to(pg_info_t *info) {
     log.complete_to = log.log.begin();
-    while (log.complete_to->version <
+    while (!missing.get_items().empty() && log.complete_to->version <
           missing.get_items().at(
             missing.get_rmissing().begin()->second
             ).need)
       ++log.complete_to;
     assert(log.complete_to != log.log.end());
     if (log.complete_to == log.log.begin()) {
-      info.last_complete = eversion_t();
+      if (info)
+       info->last_complete = eversion_t();
     } else {
       --log.complete_to;
-      info.last_complete = log.complete_to->version;
+      if (info)
+       info->last_complete = log.complete_to->version;
       ++log.complete_to;
     }
+  }
+
+  void activate_not_complete(pg_info_t &info) {
+    reset_complete_to(&info);
     log.last_requested = 0;
   }
 
@@ -1028,6 +1034,17 @@ public:
       this);
     if (!entries.empty()) {
       mark_writeout_from(entries.begin()->version);
+      if (entries.begin()->is_lost_delete()) {
+       // hack: since lost deletes queue recovery directly, and don't
+       // go through activate_not_complete() again, our complete_to
+       // iterator may still point at log.end(). Reset it to point
+       // before these new lost_delete entries.  This only occurs
+       // when lost+delete entries are initially added, which is
+       // always in a list of solely lost_delete entries, so it is
+       // sufficient to check whether the first entry is a
+       // lost_delete
+       reset_complete_to(nullptr);
+      }
     }
     return invalidate_stats;
   }