From: Jason Dillaman Date: Tue, 23 Jun 2015 18:18:20 +0000 (-0400) Subject: librbd: invalidate cache outside cache callback context X-Git-Tag: v9.0.2~10^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=726d699b7790c7e371279281ab32cd3aeb8ece7b;p=ceph.git librbd: invalidate cache outside cache callback context 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 --- diff --git a/src/librbd/AsyncRequest.cc b/src/librbd/AsyncRequest.cc index 71985073c802..4fcb7afb0947 100644 --- a/src/librbd/AsyncRequest.cc +++ b/src/librbd/AsyncRequest.cc @@ -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 diff --git a/src/librbd/AsyncRequest.h b/src/librbd/AsyncRequest.h index 9f7ba244a064..7324a224a5d0 100644 --- a/src/librbd/AsyncRequest.h +++ b/src/librbd/AsyncRequest.h @@ -43,6 +43,7 @@ protected: librados::AioCompletion *create_callback_completion(); Context *create_callback_context(); + Context *create_async_callback_context(); void async_complete(int r); diff --git a/src/librbd/AsyncResizeRequest.cc b/src/librbd/AsyncResizeRequest.cc index 7d0bf3687b5b..bbd697f7cffe 100644 --- a/src/librbd/AsyncResizeRequest.cc +++ b/src/librbd/AsyncResizeRequest.cc @@ -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() {