From: Jason Dillaman Date: Fri, 12 Feb 2016 18:24:10 +0000 (-0500) Subject: librbd: lock notifications should be executed outside librados thread X-Git-Tag: v10.1.0~377^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d898995b0e3ea301b1325f68a0532d57afa3c816;p=ceph.git librbd: lock notifications should be executed outside librados thread Otherwise it's possible that the notification will be blocked if the librados AIO thread isn't available to invoke the notification handler. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 2c5331ccf168..76ca7c558bdd 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -284,6 +284,13 @@ ClientId ImageWatcher::get_client_id() { } void ImageWatcher::notify_acquired_lock() { + // might be invoked from librados AIO thread + FunctionContext *ctx = new FunctionContext( + boost::bind(&ImageWatcher::execute_acquired_lock, this)); + m_task_finisher->queue(TASK_CODE_ACQUIRED_LOCK, ctx); +} + +void ImageWatcher::execute_acquired_lock() { ldout(m_image_ctx.cct, 10) << this << " notify acquired lock" << dendl; ClientId client_id = get_client_id(); @@ -298,6 +305,13 @@ void ImageWatcher::notify_acquired_lock() { } void ImageWatcher::notify_released_lock() { + // might be invoked from librados AIO thread + FunctionContext *ctx = new FunctionContext( + boost::bind(&ImageWatcher::execute_released_lock, this)); + m_task_finisher->queue(TASK_CODE_RELEASED_LOCK, ctx); +} + +void ImageWatcher::execute_released_lock() { ldout(m_image_ctx.cct, 10) << this << " notify released lock" << dendl; { @@ -325,7 +339,7 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { ldout(m_image_ctx.cct, 15) << this << " requesting exclusive lock" << dendl; FunctionContext *ctx = new FunctionContext( - boost::bind(&ImageWatcher::notify_request_lock, this)); + boost::bind(&ImageWatcher::execute_request_lock, this)); if (use_timer) { if (timer_delay < 0) { timer_delay = RETRY_DELAY_SECONDS; @@ -339,6 +353,13 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { } void ImageWatcher::notify_request_lock() { + // might be invoked from librados AIO thread + FunctionContext *ctx = new FunctionContext( + boost::bind(&ImageWatcher::execute_request_lock, this)); + m_task_finisher->queue(TASK_CODE_REQUEST_LOCK, ctx); +} + +void ImageWatcher::execute_request_lock() { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); ldout(m_image_ctx.cct, 10) << this << " notify request lock" << dendl; diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index c82ca55a2961..847b27e30a44 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -229,6 +229,9 @@ private: void set_owner_client_id(const watch_notify::ClientId &client_id); watch_notify::ClientId get_client_id(); + void execute_acquired_lock(); + void execute_released_lock(); + void execute_request_lock(); void schedule_request_lock(bool use_timer, int timer_delay = -1); int notify_lock_owner(bufferlist &bl);