]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
OSD: rollforward may need to mark pglog dirty
authorZengran Zhang <zhangzengran@sangfor.com.cn>
Sun, 17 Mar 2019 02:05:11 +0000 (10:05 +0800)
committerNathan Cutler <ncutler@suse.com>
Tue, 22 Oct 2019 06:22:58 +0000 (08:22 +0200)
if we rollforward at the end of PG::activate(), we may advance the *crt*,
but we did not mart the log dirty, this means we will not update the crt
within the transaction of rollforward, so it is inconsistent.

Signed-off-by: Zengran Zhang <zhangzengran@sangfor.com.cn>
(cherry picked from commit 10d0990dc69310864b4845ee57b32610a642464f)

Conflicts:
src/osd/PGLog.h
dfbe5e070cc978253abcb30b86de5faa7e6a1efc is not being backported
- retain !touched_log as part of conditional in is_dirty()

src/osd/PGLog.h

index 42100cf3973a4c86cb859b47aeda33b38c3282ca..c7eea6a8c53d85896effcbd87d316f8fa88827f4 100644 (file)
@@ -104,13 +104,19 @@ public:
     mempool::osd_pglog::list<pg_log_entry_t>::reverse_iterator
       rollback_info_trimmed_to_riter;
 
+    /*
+     * return true if we need to mark the pglog as dirty
+     */
     template <typename F>
-    void advance_can_rollback_to(eversion_t to, F &&f) {
-      if (to > can_rollback_to)
-       can_rollback_to = to;
-
-      if (to > rollback_info_trimmed_to)
-       rollback_info_trimmed_to = to;
+    bool advance_can_rollback_to(eversion_t to, F &&f) {
+      bool dirty_log = to > can_rollback_to || to > rollback_info_trimmed_to;
+      if (dirty_log) {
+       if (to > can_rollback_to)
+         can_rollback_to = to;
+
+       if (to > rollback_info_trimmed_to)
+         rollback_info_trimmed_to = to;
+      }
 
       while (rollback_info_trimmed_to_riter != log.rbegin()) {
        --rollback_info_trimmed_to_riter;
@@ -120,6 +126,8 @@ public:
        }
        f(*rollback_info_trimmed_to_riter);
       }
+
+      return dirty_log;
     }
 
     void reset_rollback_info_trimmed_to_riter() {
@@ -174,8 +182,8 @@ public:
          h->trim(entry);
        });
     }
-    void roll_forward_to(eversion_t to, LogEntryHandler *h) {
-      advance_can_rollback_to(
+    bool roll_forward_to(eversion_t to, LogEntryHandler *h) {
+      return advance_can_rollback_to(
        to,
        [&](pg_log_entry_t &entry) {
          h->rollforward(entry);
@@ -562,6 +570,7 @@ protected:
   bool pg_log_debug;
   /// Log is clean on [dirty_to, dirty_from)
   bool touched_log;
+  bool dirty_log;
   bool clear_divergent_priors;
   bool rebuilt_missing_with_deletes = false;
 
@@ -587,7 +596,7 @@ protected:
   }
 public:
   bool is_dirty() const {
-    return !touched_log ||
+    return !touched_log || dirty_log ||
       (dirty_to != eversion_t()) ||
       (dirty_from != eversion_t::max()) ||
       (writeout_from != eversion_t::max()) ||
@@ -633,6 +642,7 @@ protected:
     dirty_to = eversion_t();
     dirty_from = eversion_t::max();
     touched_log = true;
+    dirty_log = false;
     trimmed.clear();
     trimmed_dups.clear();
     writeout_from = eversion_t::max();
@@ -654,6 +664,7 @@ public:
     cct(cct),
     pg_log_debug(!(cct && !(cct->_conf->osd_debug_pg_log_writeout))),
     touched_log(false),
+    dirty_log(false),
     clear_divergent_priors(false)
   { }
 
@@ -711,9 +722,10 @@ public:
   void roll_forward_to(
     eversion_t roll_forward_to,
     LogEntryHandler *h) {
-    log.roll_forward_to(
-      roll_forward_to,
-      h);
+    if (log.roll_forward_to(
+         roll_forward_to,
+         h))
+      dirty_log = false;
   }
 
   eversion_t get_can_rollback_to() const {