]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: lock notifications should be executed outside librados thread
authorJason Dillaman <dillaman@redhat.com>
Fri, 12 Feb 2016 18:24:10 +0000 (13:24 -0500)
committerJason Dillaman <dillaman@redhat.com>
Mon, 15 Feb 2016 17:35:22 +0000 (12:35 -0500)
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 <dillaman@redhat.com>
src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h

index 2c5331ccf168b28629d54c63301e6e1c3dbcd0b0..76ca7c558bdd5f0a5dc8ae5d254d16c0c5a2c492 100644 (file)
@@ -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;
 
index c82ca55a29612df33d199cfd8a92129c55210812..847b27e30a44631fcc8adb02d3a76cf76d9cbede 100644 (file)
@@ -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);