From: Jason Dillaman Date: Fri, 31 Jul 2015 01:34:51 +0000 (-0400) Subject: librbd: async version of AioImageRequestWQ::block_writes X-Git-Tag: v10.0.2~193^2~35 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=daa75945f34f2c185c8ab4db2af942c3aee07623;p=ceph.git librbd: async version of AioImageRequestWQ::block_writes Snapshot create will uses the async version to block write ops prior to creating the new snapshot context. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/AioImageRequestWQ.cc b/src/librbd/AioImageRequestWQ.cc index 789865348bb..ff9d8e4a3e1 100644 --- a/src/librbd/AioImageRequestWQ.cc +++ b/src/librbd/AioImageRequestWQ.cc @@ -152,17 +152,25 @@ void AioImageRequestWQ::aio_flush(AioCompletion *c) { } void AioImageRequestWQ::block_writes() { + C_SaferCond cond_ctx; + block_writes(&cond_ctx); + cond_ctx.wait(); +} + +void AioImageRequestWQ::block_writes(Context *on_blocked) { CephContext *cct = m_image_ctx.cct; - Mutex::Locker locker(m_lock); - ++m_write_blockers; - ldout(cct, 5) << __func__ << ": " << &m_image_ctx << ", " - << "num=" << m_write_blockers << dendl; - if (m_write_blockers == 1) { - while (m_in_progress_writes > 0) { - m_cond.Wait(m_lock); + { + Mutex::Locker locker(m_lock); + ++m_write_blockers; + ldout(cct, 5) << __func__ << ": " << &m_image_ctx << ", " + << "num=" << m_write_blockers << dendl; + if (m_in_progress_writes > 0) { + m_write_blocker_contexts.push_back(on_blocked); + return; } } + on_blocked->complete(0); } void AioImageRequestWQ::unblock_writes() { @@ -222,6 +230,7 @@ void AioImageRequestWQ::process(AioImageRequest *req) { req->send(); } + Contexts contexts; { Mutex::Locker locker(m_lock); if (req->is_write_op()) { @@ -230,11 +239,15 @@ void AioImageRequestWQ::process(AioImageRequest *req) { assert(m_in_progress_writes > 0); if (--m_in_progress_writes == 0) { - m_cond.Signal(); + contexts.swap(m_write_blocker_contexts); } } } delete req; + + for (Contexts::iterator it = contexts.begin(); it != contexts.end(); ++it) { + (*it)->complete(0); + } } bool AioImageRequestWQ::is_journal_required() const { diff --git a/src/librbd/AioImageRequestWQ.h b/src/librbd/AioImageRequestWQ.h index 20169f59002..f668c9f03f1 100644 --- a/src/librbd/AioImageRequestWQ.h +++ b/src/librbd/AioImageRequestWQ.h @@ -45,6 +45,7 @@ public: } void block_writes(); + void block_writes(Context *on_blocked); void unblock_writes(); void register_lock_listener(); @@ -54,6 +55,8 @@ protected: virtual void process(AioImageRequest *req); private: + typedef std::list Contexts; + struct LockListener : public ImageWatcher::Listener { AioImageRequestWQ *aio_work_queue; LockListener(AioImageRequestWQ *_aio_work_queue) @@ -70,7 +73,7 @@ private: ImageCtx &m_image_ctx; mutable Mutex m_lock; - Cond m_cond; + Contexts m_write_blocker_contexts; uint32_t m_write_blockers; uint32_t m_in_progress_writes; uint32_t m_queued_writes;