]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: invalidate cache outside cache callback context
authorJason Dillaman <dillaman@redhat.com>
Tue, 23 Jun 2015 18:18:20 +0000 (14:18 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 29 Jul 2015 17:41:36 +0000 (13:41 -0400)
When shrinking an image, it's possible that the op flush callback
will be from within the cache callback context.  This would result
in a deadlock when attempting to re-lock the cache lock in order to
invalidate the cache.

Fixes: #11743
Backport: hammer
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 726d699b7790c7e371279281ab32cd3aeb8ece7b)

src/librbd/AsyncRequest.cc
src/librbd/AsyncRequest.h
src/librbd/AsyncResizeRequest.cc

index 543e723bca7415b9943df2db78b5187267c9b7a2..2f0c2d9c27230da602fd66f505b12f0e3c7eb428 100644 (file)
@@ -35,4 +35,9 @@ Context *AsyncRequest::create_callback_context() {
   return new FunctionContext(boost::bind(&AsyncRequest::complete, this, _1));
 }
 
+Context *AsyncRequest::create_async_callback_context() {
+  return new FunctionContext(boost::bind(&AsyncRequest::async_complete, this,
+                                         _1));;
+}
+
 } // namespace librbd
index 9f7ba244a0645b02c43c64e5a85ce3a2552e2212..7324a224a5d037c9f740104b1b693fdb1f8dd002 100644 (file)
@@ -43,6 +43,7 @@ protected:
 
   librados::AioCompletion *create_callback_completion();
   Context *create_callback_context();
+  Context *create_async_callback_context();
 
   void async_complete(int r);
 
index a8143bbc5e41cfbc408ca12ec4a0494399a9be3b..7a4f65b43738801c666f201381b4003a2c1139e3 100644 (file)
@@ -161,8 +161,9 @@ void AsyncResizeRequest::send_flush() {
   m_state = STATE_FLUSH;
 
   // with clipping adjusted, ensure that write / copy-on-read operations won't
-  // (re-)create objects that we just removed
-  m_image_ctx.flush_async_operations(create_callback_context());
+  // (re-)create objects that we just removed. need async callback to ensure
+  // we don't have cache_lock already held
+  m_image_ctx.flush_async_operations(create_async_callback_context());
 }
 
 void AsyncResizeRequest::send_invalidate_cache() {