]> git-server-git.apps.pok.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>
Tue, 23 Jun 2015 18:18:20 +0000 (14:18 -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>
src/librbd/AsyncRequest.cc
src/librbd/AsyncRequest.h
src/librbd/AsyncResizeRequest.cc

index 71985073c802d7ec41386109c19699be6fb4d956..4fcb7afb09476cd899779356d6ea1c0b75236fe8 100644 (file)
@@ -34,4 +34,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 7d0bf3687b5b4f510d27f22f8eecae564ed895a6..bbd697f7cffe89ab2fbea2c072a365be2623b337 100644 (file)
@@ -159,8 +159,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() {