From 9299a1ceb607199d2ea09662ee1ef280a7b9f920 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 24 Apr 2018 15:59:37 +0800 Subject: [PATCH] cephfs-journal-tool: wait prezero ops before destroying journal There still can be pending prezero requests after Journal::flush() return. We should wait until all prezero requests are done, then destroy the on-stack journaler. Signed-off-by: "Yan, Zheng" Fixes: http://tracker.ceph.com/issues/20549 --- src/osdc/Journaler.cc | 18 ++++++++++++++++++ src/osdc/Journaler.h | 3 +++ src/tools/cephfs/Resetter.cc | 21 +++++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc index 9ac942baa6a..63cf435e4c0 100644 --- a/src/osdc/Journaler.cc +++ b/src/osdc/Journaler.cc @@ -848,6 +848,13 @@ void Journaler::_finish_prezero(int r, uint64_t start, uint64_t len) if (waiting_for_zero_pos > flush_pos) { _do_flush(waiting_for_zero_pos - flush_pos); } + + if (prezero_pos == prezeroing_pos && + !waitfor_prezero.empty()) { + list ls; + ls.swap(waitfor_prezero); + finish_contexts(cct, ls, 0); + } } else { pending_zero.insert(start, len); } @@ -857,6 +864,17 @@ void Journaler::_finish_prezero(int r, uint64_t start, uint64_t len) << dendl; } +void Journaler::wait_for_prezero(Context *onfinish) +{ + assert(onfinish); + lock_guard l(lock); + + if (prezero_pos == prezeroing_pos) { + finisher->queue(onfinish, 0); + return; + } + waitfor_prezero.push_back(wrap_finisher(onfinish)); +} /***************** READING *******************/ diff --git a/src/osdc/Journaler.h b/src/osdc/Journaler.h index 4caa65fdad0..0b8caa09ac7 100644 --- a/src/osdc/Journaler.h +++ b/src/osdc/Journaler.h @@ -312,6 +312,8 @@ private: uint64_t waiting_for_zero_pos; interval_set pending_zero; // non-contig bits we've zeroed + list waitfor_prezero; + std::map pending_safe; // flush_pos -> safe_pos // when safe through given offset std::map > waitfor_safe; @@ -459,6 +461,7 @@ public: void flush(Context *onsafe = 0); void wait_for_readable(Context *onfinish); bool have_waiter() const; + void wait_for_prezero(Context *onfinish); // Synchronous setters // =================== diff --git a/src/tools/cephfs/Resetter.cc b/src/tools/cephfs/Resetter.cc index cbc9a353ce1..9573e6a6239 100644 --- a/src/tools/cephfs/Resetter.cc +++ b/src/tools/cephfs/Resetter.cc @@ -200,12 +200,25 @@ int Resetter::_write_reset_event(Journaler *journaler) bufferlist bl; le->encode_with_header(bl, CEPH_FEATURES_SUPPORTED_DEFAULT); - + cout << "writing EResetJournal entry" << std::endl; - C_SaferCond cond; journaler->append_entry(bl); - journaler->flush(&cond); - return cond.wait(); + int ret; + { + C_SaferCond cond; + journaler->flush(&cond); + ret = cond.wait(); + if (ret < 0) + return ret; + } + { + // wait until all journal prezero ops are done + C_SaferCond cond; + journaler->wait_for_prezero(&cond); + cond.wait(); + } + + return ret; } -- 2.39.5