From: Yan, Zheng Date: Tue, 24 Apr 2018 07:59:37 +0000 (+0800) Subject: cephfs-journal-tool: wait prezero ops before destroying journal X-Git-Tag: v12.2.6~83^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=347eab6b5927543739388f2adbaa5e6403082f91;p=ceph.git 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 (cherry picked from commit 9299a1ceb607199d2ea09662ee1ef280a7b9f920) --- diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc index 94386101a1d3..8ca0c4b27188 100644 --- a/src/osdc/Journaler.cc +++ b/src/osdc/Journaler.cc @@ -853,6 +853,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); } @@ -862,6 +869,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 d65419a652be..521752017529 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 58465c2ffc79..7741db44352b 100644 --- a/src/tools/cephfs/Resetter.cc +++ b/src/tools/cephfs/Resetter.cc @@ -170,12 +170,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; }